├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── Directory.Build.props ├── LICENSE.txt ├── Logo-low.png ├── Logo.png ├── Makefile ├── README.md ├── SQLite.sln ├── global.json ├── nuget ├── Logo-low.png ├── SQLite-net-base │ └── SQLite-net-base.csproj ├── SQLite-net-sqlcipher │ └── SQLite-net-sqlcipher.csproj ├── SQLite-net-static │ └── SQLite-net-static.csproj └── SQLite-net-std │ └── SQLite-net-std.csproj ├── src ├── AssemblyInfo.cs ├── SQLite.cs └── SQLiteAsync.cs └── tests ├── ApiDiff ├── ApiDiff.csproj └── Program.cs ├── SQLite.Tests.iOS ├── Entitlements.plist ├── Info.plist ├── LaunchScreen.storyboard ├── Main.cs ├── SQLiteTestsiOS.csproj └── UnitTestAppDelegate.cs └── SQLite.Tests ├── AsyncTests.cs ├── AttributesTest.cs ├── BackupTest.cs ├── BooleanTest.cs ├── ByteArrayTest.cs ├── CollateTest.cs ├── ConcurrencyTest.cs ├── ContainsTest.cs ├── CreateTableImplicitTest.cs ├── CreateTableTest.cs ├── DateTimeOffsetTest.cs ├── DateTimeTest.cs ├── DbCommandTest.cs ├── DeleteTest.cs ├── DropTableTest.cs ├── EnumCacheTest.cs ├── EnumNullableTest.cs ├── EnumTest.cs ├── EqualsTest.cs ├── ExceptionAssert.cs ├── GuidTests.cs ├── IgnoreTest.cs ├── InheritanceTest.cs ├── InsertTest.cs ├── JoinTest.cs ├── LinqTest.cs ├── MappingTest.cs ├── MigrationTest.cs ├── NotNullAttributeTest.cs ├── NullableTest.cs ├── OpenTests.cs ├── QueryTest.cs ├── ReadmeTest.cs ├── SQLCipherTest.cs ├── SQLite.Tests.csproj ├── ScalarTest.cs ├── SkipTest.cs ├── StringQueryTest.cs ├── TableChangedTest.cs ├── TestDb.cs ├── TimeSpanTest.cs ├── TransactionTest.cs ├── UnicodeTest.cs └── UniqueTest.cs /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Default settings: 7 | # A newline ending every file 8 | # Use 4 spaces as indentation 9 | [*] 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 4 13 | end_of_line = lf 14 | 15 | # C# files 16 | [*.cs] 17 | end_of_line = lf 18 | indent_style = tab 19 | tab_width = 4 20 | 21 | # New line preferences 22 | csharp_new_line_before_open_brace = methods, types 23 | csharp_new_line_before_else = true 24 | csharp_new_line_before_catch = true 25 | csharp_new_line_before_finally = true 26 | csharp_new_line_before_members_in_object_initializers = true 27 | csharp_new_line_before_members_in_anonymous_types = true 28 | csharp_new_line_within_query_expression_clauses = true 29 | 30 | # Indentation preferences 31 | csharp_indent_block_contents = true 32 | csharp_indent_braces = false 33 | csharp_indent_case_contents = true 34 | csharp_indent_switch_labels = true 35 | csharp_indent_labels = flush_left 36 | 37 | # avoid this. unless absolutely necessary 38 | dotnet_style_qualification_for_field = false:suggestion 39 | dotnet_style_qualification_for_property = false:suggestion 40 | dotnet_style_qualification_for_method = false:suggestion 41 | dotnet_style_qualification_for_event = false:suggestion 42 | 43 | # only use var when it's obvious what the variable type is 44 | csharp_style_var_for_built_in_types = true:none 45 | csharp_style_var_when_type_is_apparent = true:none 46 | csharp_style_var_elsewhere = true:suggestion 47 | 48 | # use language keywords instead of BCL types 49 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 50 | dotnet_style_predefined_type_for_member_access = true:suggestion 51 | 52 | # name all constant fields using PascalCase 53 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion 54 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields 55 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style 56 | 57 | dotnet_naming_symbols.constant_fields.applicable_kinds = field 58 | dotnet_naming_symbols.constant_fields.required_modifiers = const 59 | 60 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case 61 | 62 | # static fields should have s_ prefix 63 | dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion 64 | dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields 65 | dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style 66 | 67 | dotnet_naming_symbols.static_fields.applicable_kinds = field 68 | dotnet_naming_symbols.static_fields.required_modifiers = static 69 | 70 | dotnet_naming_style.static_prefix_style.required_prefix = 71 | dotnet_naming_style.static_prefix_style.capitalization = camel_case 72 | 73 | # internal and private fields should be _camelCase 74 | dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion 75 | dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields 76 | dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style 77 | 78 | dotnet_naming_symbols.private_internal_fields.applicable_kinds = field 79 | dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal 80 | 81 | dotnet_naming_style.camel_case_underscore_style.required_prefix = 82 | dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case 83 | 84 | # Code style defaults 85 | dotnet_sort_system_directives_first = true 86 | csharp_preserve_single_line_blocks = true 87 | csharp_preserve_single_line_statements = false 88 | 89 | # Expression-level preferences 90 | dotnet_style_object_initializer = true:suggestion 91 | dotnet_style_collection_initializer = true:suggestion 92 | dotnet_style_explicit_tuple_names = true:suggestion 93 | dotnet_style_coalesce_expression = true:suggestion 94 | dotnet_style_null_propagation = true:suggestion 95 | 96 | # Expression-bodied members 97 | csharp_style_expression_bodied_methods = false:none 98 | csharp_style_expression_bodied_constructors = false:none 99 | csharp_style_expression_bodied_operators = false:none 100 | csharp_style_expression_bodied_properties = true:none 101 | csharp_style_expression_bodied_indexers = true:none 102 | csharp_style_expression_bodied_accessors = true:none 103 | 104 | # Pattern matching 105 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion 106 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion 107 | csharp_style_inlined_variable_declaration = true:suggestion 108 | 109 | # Null checking preferences 110 | csharp_style_throw_expression = true:suggestion 111 | csharp_style_conditional_delegate_call = true:suggestion 112 | 113 | # Space preferences 114 | csharp_space_after_cast = false 115 | csharp_space_after_colon_in_inheritance_clause = true 116 | csharp_space_after_comma = true 117 | csharp_space_after_dot = false 118 | csharp_space_after_keywords_in_control_flow_statements = true 119 | csharp_space_after_semicolon_in_for_statement = true 120 | csharp_space_around_binary_operators = before_and_after 121 | csharp_space_around_declaration_statements = do_not_ignore 122 | csharp_space_before_colon_in_inheritance_clause = true 123 | csharp_space_before_comma = false 124 | csharp_space_before_dot = false 125 | csharp_space_before_open_square_brackets = false 126 | csharp_space_before_semicolon_in_for_statement = false 127 | csharp_space_between_empty_square_brackets = false 128 | csharp_space_between_method_call_empty_parameter_list_parentheses = false 129 | csharp_space_between_method_call_name_and_opening_parenthesis = true 130 | csharp_space_between_method_call_parameter_list_parentheses = false 131 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false 132 | csharp_space_between_method_declaration_name_and_open_parenthesis = true 133 | csharp_space_between_method_declaration_parameter_list_parentheses = false 134 | csharp_space_between_parentheses = false 135 | csharp_space_between_square_brackets = false 136 | 137 | # C++ Files 138 | [*.{cpp,h,in}] 139 | curly_bracket_next_line = true 140 | indent_brace_style = Allman 141 | 142 | # Xml project files 143 | [*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}] 144 | indent_size = 2 145 | end_of_line = crlf 146 | indent_style = space 147 | 148 | # Xml build files 149 | [*.builds] 150 | indent_size = 2 151 | 152 | # Xml files 153 | [*.{xml,stylecop,resx,ruleset}] 154 | indent_size = 2 155 | 156 | # Xml config files 157 | [*.{props,targets,config,nuspec}] 158 | indent_size = 2 159 | 160 | # Shell scripts 161 | [*.sh] 162 | end_of_line = lf 163 | [*.{cmd, bat}] 164 | end_of_line = crlf 165 | 166 | [Makefile] 167 | indent_style = tab 168 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: praeclarum 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | 18 | - uses: actions/checkout@v1 19 | 20 | - name: Update Versions 21 | env: 22 | VERSION_BUILD: ${{github.run_number}} 23 | run: | 24 | sed -i.bak "s::.$VERSION_BUILD:g" Directory.Build.props 25 | 26 | - name: Set up .NET 27 | uses: actions/setup-dotnet@v4 28 | with: 29 | global-json-file: global.json 30 | 31 | - name: Install Code Coverarage Tool 32 | run: dotnet tool install --global dotnet-reportgenerator-globaltool 33 | 34 | - name: Restore NuGets 35 | run: dotnet restore SQLite.sln 36 | 37 | - name: Build and Test 38 | run: | 39 | set -e 40 | cd tests/SQLite.Tests 41 | dotnet test /p:AltCover=true /p:AltCoverForce=true "/p:AltCoverTypeFilter=SQLite.Tests.*" 42 | 43 | - name: Verify Async API Matches Sync API 44 | run: | 45 | set -e 46 | dotnet run --project tests/ApiDiff/ApiDiff.csproj 47 | 48 | - name: Generate Code Coverage Report 49 | uses: danielpalme/ReportGenerator-GitHub-Action@5.2.4 50 | if: github.event_name == 'push' 51 | with: 52 | reports: 'tests/SQLite.Tests/coverage.xml' # REQUIRED # The coverage reports that should be parsed (separated by semicolon). Globbing is supported. 53 | targetdir: 'CoverageReport' # REQUIRED # The directory where the generated report should be saved. 54 | reporttypes: 'HtmlInline;Cobertura' # The output formats and scope (separated by semicolon) Values: Badges, Clover, Cobertura, CsvSummary, Html, HtmlChart, HtmlInline, HtmlInline_AzurePipelines, HtmlInline_AzurePipelines_Dark, HtmlSummary, JsonSummary, Latex, LatexSummary, lcov, MHtml, PngChart, SonarQube, TeamCitySummary, TextSummary, Xml, XmlSummary 55 | sourcedirs: '' # Optional directories which contain the corresponding source code (separated by semicolon). The source directories are used if coverage report contains classes without path information. 56 | historydir: '' # Optional directory for storing persistent coverage information. Can be used in future reports to show coverage evolution. 57 | plugins: '' # Optional plugin files for custom reports or custom history storage (separated by semicolon). 58 | assemblyfilters: '+SQLite.Tests;-NUnit3.TestAdapter' # Optional list of assemblies that should be included or excluded in the report. Exclusion filters take precedence over inclusion filters. Wildcards are allowed. 59 | classfilters: '+*;-SQLite.Tests.*' # Optional list of classes that should be included or excluded in the report. Exclusion filters take precedence over inclusion filters. Wildcards are allowed. 60 | filefilters: '+*' # Optional list of files that should be included or excluded in the report. Exclusion filters take precedence over inclusion filters. Wildcards are allowed. 61 | verbosity: 'Info' # The verbosity level of the log messages. Values: Verbose, Info, Warning, Error, Off 62 | title: '' # Optional title. 63 | tag: '${{ github.run_number }}_${{ github.run_id }}' # Optional tag or build version. 64 | customSettings: '' # Optional custom settings (separated by semicolon). See: https://github.com/danielpalme/ReportGenerator/wiki/Settings. 65 | 66 | - name: Deploy Code Coverage Report 67 | uses: peaceiris/actions-gh-pages@v3 68 | if: github.event_name == 'push' 69 | with: 70 | github_token: ${{ secrets.GITHUB_TOKEN }} 71 | publish_dir: CoverageReport 72 | destination_dir: coverage 73 | enable_jekyll: true 74 | 75 | - name: Package 76 | if: github.event_name == 'push' 77 | run: | 78 | make nuget 79 | 80 | - uses: actions/upload-artifact@master 81 | if: github.event_name == 'push' 82 | with: 83 | name: Packages 84 | path: PackagesOut 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.* 2 | CoverageReport 3 | .DS_Store 4 | .dropbox.attr 5 | test-results 6 | 7 | /PackagesOut 8 | 9 | ## Ignore Visual Studio temporary files, build results, and 10 | ## files generated by popular Visual Studio add-ons. 11 | 12 | # User-specific files 13 | *.suo 14 | *.user 15 | *.userosscache 16 | *.sln.docstates 17 | 18 | # User-specific files (MonoDevelop/Xamarin Studio) 19 | *.userprefs 20 | 21 | # Build results 22 | [Dd]ebug/ 23 | [Dd]ebugPublic/ 24 | [Rr]elease/ 25 | [Rr]eleases/ 26 | x64/ 27 | x86/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | 33 | # Visual Studio 2015 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | dist/ 38 | 39 | # MSTest test Results 40 | [Tt]est[Rr]esult*/ 41 | [Bb]uild[Ll]og.* 42 | 43 | # NUNIT 44 | *.VisualState.xml 45 | TestResult.xml 46 | 47 | # Build Results of an ATL Project 48 | [Dd]ebugPS/ 49 | [Rr]eleasePS/ 50 | dlldata.c 51 | 52 | # DNX 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | *_i.c 58 | *_p.c 59 | *_i.h 60 | *.ilk 61 | *.meta 62 | *.obj 63 | *.pch 64 | *.pdb 65 | *.pgc 66 | *.pgd 67 | *.rsp 68 | *.sbr 69 | *.tlb 70 | *.tli 71 | *.tlh 72 | *.tmp 73 | *.tmp_proj 74 | *.log 75 | *.vspscc 76 | *.vssscc 77 | .builds 78 | *.pidb 79 | *.svclog 80 | *.scc 81 | 82 | # Chutzpah Test files 83 | _Chutzpah* 84 | 85 | # Visual C++ cache files 86 | ipch/ 87 | *.aps 88 | *.ncb 89 | *.opendb 90 | *.opensdf 91 | *.sdf 92 | *.cachefile 93 | *.VC.db 94 | *.VC.VC.opendb 95 | 96 | # Visual Studio profiler 97 | *.psess 98 | *.vsp 99 | *.vspx 100 | *.sap 101 | 102 | # TFS 2012 Local Workspace 103 | $tf/ 104 | 105 | # Guidance Automation Toolkit 106 | *.gpState 107 | 108 | # ReSharper is a .NET coding add-in 109 | _ReSharper*/ 110 | *.[Rr]e[Ss]harper 111 | *.DotSettings.user 112 | 113 | # JustCode is a .NET coding add-in 114 | .JustCode 115 | 116 | # TeamCity is a build add-in 117 | _TeamCity* 118 | 119 | # DotCover is a Code Coverage Tool 120 | *.dotCover 121 | 122 | # NCrunch 123 | _NCrunch_* 124 | .*crunch*.local.xml 125 | nCrunchTemp_* 126 | 127 | # MightyMoose 128 | *.mm.* 129 | AutoTest.Net/ 130 | 131 | # Web workbench (sass) 132 | .sass-cache/ 133 | 134 | # Installshield output folder 135 | [Ee]xpress/ 136 | 137 | # DocProject is a documentation generator add-in 138 | DocProject/buildhelp/ 139 | DocProject/Help/*.HxT 140 | DocProject/Help/*.HxC 141 | DocProject/Help/*.hhc 142 | DocProject/Help/*.hhk 143 | DocProject/Help/*.hhp 144 | DocProject/Help/Html2 145 | DocProject/Help/html 146 | 147 | # Click-Once directory 148 | publish/ 149 | 150 | # Publish Web Output 151 | *.[Pp]ublish.xml 152 | *.azurePubxml 153 | # TODO: Comment the next line if you want to checkin your web deploy settings 154 | # but database connection strings (with potential passwords) will be unencrypted 155 | #*.pubxml 156 | *.publishproj 157 | 158 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 159 | # checkin your Azure Web App publish settings, but sensitive information contained 160 | # in these scripts will be unencrypted 161 | PublishScripts/ 162 | 163 | # NuGet Packages 164 | *.nupkg 165 | # The packages folder can be ignored because of Package Restore 166 | **/packages/* 167 | # except build/, which is used as an MSBuild target. 168 | !**/packages/build/ 169 | # Uncomment if necessary however generally it will be regenerated when needed 170 | #!**/packages/repositories.config 171 | # NuGet v3's project.json files produces more ignoreable files 172 | *.nuget.props 173 | *.nuget.targets 174 | 175 | # Microsoft Azure Build Output 176 | csx/ 177 | *.build.csdef 178 | 179 | # Microsoft Azure Emulator 180 | ecf/ 181 | rcf/ 182 | 183 | # Windows Store app package directories and files 184 | AppPackages/ 185 | BundleArtifacts/ 186 | Package.StoreAssociation.xml 187 | _pkginfo.txt 188 | 189 | # Visual Studio cache files 190 | # files ending in .cache can be ignored 191 | *.[Cc]ache 192 | # but keep track of directories ending in .cache 193 | !*.[Cc]ache/ 194 | 195 | # Others 196 | ClientBin/ 197 | ~$* 198 | *~ 199 | *.dbmdl 200 | *.dbproj.schemaview 201 | *.jfm 202 | *.pfx 203 | *.publishsettings 204 | node_modules/ 205 | orleans.codegen.cs 206 | 207 | # Since there are multiple workflows, uncomment next line to ignore bower_components 208 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 209 | 210 | 211 | # RIA/Silverlight projects 212 | Generated_Code/ 213 | 214 | # Backup & report files from converting an old project file 215 | # to a newer Visual Studio version. Backup files are not needed, 216 | # because we have git ;-) 217 | _UpgradeReport_Files/ 218 | Backup*/ 219 | UpgradeLog*.XML 220 | UpgradeLog*.htm 221 | 222 | # SQL Server files 223 | *.mdf 224 | *.ldf 225 | 226 | # Business Intelligence projects 227 | *.rdl.data 228 | *.bim.layout 229 | *.bim_*.settings 230 | 231 | # Microsoft Fakes 232 | FakesAssemblies/ 233 | 234 | # GhostDoc plugin setting file 235 | *.GhostDoc.xml 236 | 237 | # Node.js Tools for Visual Studio 238 | .ntvs_analysis.dat 239 | 240 | # Visual Studio 6 build log 241 | *.plg 242 | 243 | # Visual Studio 6 workspace options file 244 | *.opt 245 | 246 | # Visual Studio LightSwitch build output 247 | **/*.HTMLClient/GeneratedArtifacts 248 | **/*.DesktopClient/GeneratedArtifacts 249 | **/*.DesktopClient/ModelManifest.xml 250 | **/*.Server/GeneratedArtifacts 251 | **/*.Server/ModelManifest.xml 252 | _Pvt_Extensions 253 | 254 | # Paket dependency manager 255 | .paket/paket.exe 256 | paket-files/ 257 | 258 | # FAKE - F# Make 259 | .fake/ 260 | 261 | # JetBrains Rider 262 | .idea/ 263 | *.sln.iml 264 | 265 | # CodeRush 266 | .cr/ 267 | 268 | # NCrunch 269 | *.ncrunchsolution 270 | *.ncrunchproject 271 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1.10 4 | beta 5 | 6 | Logo-low.png 7 | https://github.com/praeclarum/sqlite-net 8 | https://github.com/praeclarum/sqlite-net.git 9 | sqlite-net;sqlite;database;orm 10 | LICENSE.txt 11 | 12 | Krueger Systems, Inc. 13 | 14 | true 15 | 16 | true 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Krueger Systems, Inc. 2 | 3 | All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Logo-low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/praeclarum/sqlite-net/bf1eb50278d0ace79c3754575b34823cf7fb0934/Logo-low.png -------------------------------------------------------------------------------- /Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/praeclarum/sqlite-net/bf1eb50278d0ace79c3754575b34823cf7fb0934/Logo.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | SRC=src/SQLite.cs src/SQLiteAsync.cs 3 | 4 | PACKAGES_OUT=$(abspath PackagesOut) 5 | 6 | all: nuget 7 | 8 | nuget: pclnuget basenuget sqlciphernuget staticnuget 9 | 10 | pclnuget: nuget/SQLite-net-std/SQLite-net-std.csproj $(SRC) 11 | dotnet pack -c Release -o $(PACKAGES_OUT) $< 12 | 13 | basenuget: nuget/SQLite-net-base/SQLite-net-base.csproj $(SRC) 14 | dotnet pack -c Release -o $(PACKAGES_OUT) $< 15 | 16 | sqlciphernuget: nuget/SQLite-net-sqlcipher/SQLite-net-sqlcipher.csproj $(SRC) 17 | dotnet pack -c Release -o $(PACKAGES_OUT) $< 18 | 19 | staticnuget: nuget/SQLite-net-static/SQLite-net-static.csproj $(SRC) 20 | dotnet pack -c Release -o $(PACKAGES_OUT) $< 21 | 22 | codecoverage: 23 | cd tests/SQLite.Tests && dotnet test /p:AltCover=true /p:AltCoverForce=true "/p:AltCoverTypeFilter=SQLite.Tests.*" && reportgenerator -reports:coverage.xml -targetdir:./CoverageReport 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # SQLite-net 3 | 4 | [[GitHub Action](https://github.com/praeclarum/sqlite-net/actions)] [[Code Coverage Report](https://praeclarum.org/sqlite-net/coverage/)] 5 | 6 | Use one of these packages: 7 | 8 | | Version | Package | Description | 9 | | ------- | ------- | ----------- | 10 | | [![NuGet Package](https://img.shields.io/nuget/v/sqlite-net-pcl.svg)](https://www.nuget.org/packages/sqlite-net-pcl) | [sqlite-net-pcl](https://www.nuget.org/packages/sqlite-net-pcl) | .NET Standard Library | 11 | | [![NuGet Package with Encryption](https://img.shields.io/nuget/v/sqlite-net-sqlcipher.svg)](https://www.nuget.org/packages/sqlite-net-sqlcipher) | [sqlite-net-sqlcipher](https://www.nuget.org/packages/sqlite-net-sqlcipher) | With Encryption Support | 12 | | [![NuGet Package using P/Invoke](https://img.shields.io/nuget/v/sqlite-net-static.svg)](https://www.nuget.org/packages/sqlite-net-static) | [sqlite-net-static](https://www.nuget.org/packages/sqlite-net-static) | Special version that uses P/Invokes to platform-provided sqlite3 | 13 | | [![NuGet Package without a SQLitePCLRaw bundle](https://img.shields.io/nuget/v/sqlite-net-base.svg)](https://www.nuget.org/packages/sqlite-net-base) | [sqlite-net-base](https://www.nuget.org/packages/sqlite-net-base) | without a SQLitePCLRaw bundle so you can choose your own provider | 14 | 15 | SQLite-net is an open source, minimal library to allow .NET, .NET Core, and Mono applications to store data in 16 | [SQLite 3 databases](http://www.sqlite.org). It was first designed to work with [Xamarin.iOS](http://xamarin.com), 17 | but has since grown up to work on all the platforms (Xamarin.*, .NET, UWP, Azure, etc.). 18 | 19 | SQLite-net was designed as a quick and convenient database layer. Its design follows from these *goals*: 20 | 21 | * Very easy to integrate with existing projects and runs on all the .NET platforms. 22 | 23 | * Thin wrapper over SQLite that is fast and efficient. (This library should not be the performance bottleneck of your queries.) 24 | 25 | * Very simple methods for executing CRUD operations and queries safely (using parameters) and for retrieving the results of those query in a strongly typed fashion. 26 | 27 | * Works with your data model without forcing you to change your classes. (Contains a small reflection-driven ORM layer.) 28 | 29 | ## NuGet Installation 30 | 31 | Install [sqlite-net-pcl](https://www.nuget.org/packages/sqlite-net-pcl) from NuGet. 32 | 33 | **Important:** You will need to add the NuGet package to **both** your *.NET Standard library project* and your *platform-dependent app project*. 34 | 35 | ## Source Installation 36 | 37 | SQLite-net is all contained in 1 file (I know, so cool right?) and is easy to add to your project. Just add [SQLite.cs](https://github.com/praeclarum/sqlite-net/blob/master/src/SQLite.cs) to your project, and you're ready to start creating tables. An asynchronous implementation can be found in [SQLiteAsync.cs](https://github.com/praeclarum/sqlite-net/blob/master/src/SQLiteAsync.cs). 38 | 39 | ## Please Contribute! 40 | 41 | This is an open source project that welcomes contributions/suggestions/bug reports from those who use it. If you have any ideas on how to improve the library, please [post an issue here on GitHub](https://github.com/praeclarum/sqlite-net/issues). Please check out the [How to Contribute](https://github.com/praeclarum/sqlite-net/wiki/How-to-Contribute). 42 | 43 | 44 | # Example Time! 45 | 46 | Please consult the Wiki for, ahem, [complete documentation](https://github.com/praeclarum/sqlite-net/wiki). 47 | 48 | The library contains simple attributes that you can use to control the construction of tables. In a simple stock program, you might use: 49 | 50 | ```csharp 51 | public class Stock 52 | { 53 | [PrimaryKey, AutoIncrement] 54 | public int Id { get; set; } 55 | public string Symbol { get; set; } 56 | } 57 | 58 | public class Valuation 59 | { 60 | [PrimaryKey, AutoIncrement] 61 | public int Id { get; set; } 62 | [Indexed] 63 | public int StockId { get; set; } 64 | public DateTime Time { get; set; } 65 | public decimal Price { get; set; } 66 | [Ignore] 67 | public string IgnoreField { get; set; } 68 | } 69 | ``` 70 | 71 | Once you've defined the objects in your model you have a choice of APIs. You can use the "synchronous API" where calls 72 | block one at a time, or you can use the "asynchronous API" where calls do not block. You may care to use the asynchronous 73 | API for mobile applications in order to increase responsiveness. 74 | 75 | Both APIs are explained in the two sections below. 76 | 77 | ## Synchronous API 78 | 79 | Once you have defined your entity, you can automatically generate tables in your database by calling `CreateTable`: 80 | 81 | ```csharp 82 | // Get an absolute path to the database file 83 | var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db"); 84 | 85 | var db = new SQLiteConnection(databasePath); 86 | db.CreateTable(); 87 | db.CreateTable(); 88 | ``` 89 | 90 | You can insert rows in the database using `Insert`. If the table contains an auto-incremented primary key, then the value for that key will be available to you after the insert: 91 | 92 | ```csharp 93 | public static void AddStock(SQLiteConnection db, string symbol) { 94 | var stock = new Stock() { 95 | Symbol = symbol 96 | }; 97 | db.Insert(stock); 98 | Console.WriteLine("{0} == {1}", stock.Symbol, stock.Id); 99 | } 100 | ``` 101 | 102 | Similar methods exist for `Update` and `Delete`. 103 | 104 | The most straightforward way to query for data is using the `Table` method. This can take predicates for constraining via WHERE clauses and/or adding ORDER BY clauses: 105 | 106 | ```csharp 107 | var query = db.Table().Where(v => v.Symbol.StartsWith("A")); 108 | 109 | foreach (var stock in query) 110 | Console.WriteLine("Stock: " + stock.Symbol); 111 | ``` 112 | 113 | You can also query the database at a low-level using the `Query` method: 114 | 115 | ```csharp 116 | public static IEnumerable QueryValuations (SQLiteConnection db, Stock stock) { 117 | return db.Query ("select * from Valuation where StockId = ?", stock.Id); 118 | } 119 | ``` 120 | 121 | The generic parameter to the `Query` method specifies the type of object to create for each row. It can be one of your table classes, or any other class whose public properties match the column returned by the query. For instance, we could rewrite the above query as: 122 | 123 | ```csharp 124 | public class Val 125 | { 126 | public decimal Money { get; set; } 127 | public DateTime Date { get; set; } 128 | } 129 | 130 | public static IEnumerable QueryVals (SQLiteConnection db, Stock stock) { 131 | return db.Query ("select \"Price\" as \"Money\", \"Time\" as \"Date\" from Valuation where StockId = ?", stock.Id); 132 | } 133 | ``` 134 | 135 | You can perform low-level updates of the database using the `Execute` method. 136 | 137 | ## Asynchronous API 138 | 139 | The asynchronous library uses the Task Parallel Library (TPL). As such, normal use of `Task` objects, and the `async` and `await` keywords 140 | will work for you. 141 | 142 | Once you have defined your entity, you can automatically generate tables by calling `CreateTableAsync`: 143 | 144 | ```csharp 145 | // Get an absolute path to the database file 146 | var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData.db"); 147 | 148 | var db = new SQLiteAsyncConnection(databasePath); 149 | 150 | await db.CreateTableAsync(); 151 | 152 | Console.WriteLine("Table created!"); 153 | ``` 154 | 155 | You can insert rows in the database using `Insert`. If the table contains an auto-incremented primary key, then the value for that key will be available to you after the insert: 156 | 157 | ```csharp 158 | var stock = new Stock() 159 | { 160 | Symbol = "AAPL" 161 | }; 162 | 163 | await db.InsertAsync(stock); 164 | 165 | Console.WriteLine("Auto stock id: {0}", stock.Id); 166 | ``` 167 | 168 | Similar methods exist for `UpdateAsync` and `DeleteAsync`. 169 | 170 | Querying for data is most straightforwardly done using the `Table` method. This will return an `AsyncTableQuery` instance back, whereupon 171 | you can add predicates for constraining via WHERE clauses and/or adding ORDER BY. The database is not physically touched until one of the special 172 | retrieval methods - `ToListAsync`, `FirstAsync`, or `FirstOrDefaultAsync` - is called. 173 | 174 | ```csharp 175 | var query = db.Table().Where(s => s.Symbol.StartsWith("A")); 176 | 177 | var result = await query.ToListAsync(); 178 | 179 | foreach (var s in result) 180 | Console.WriteLine("Stock: " + s.Symbol); 181 | ``` 182 | 183 | There are a number of low-level methods available. You can also query the database directly via the `QueryAsync` method. Over and above the change 184 | operations provided by `InsertAsync` etc you can issue `ExecuteAsync` methods to change sets of data directly within the database. 185 | 186 | Another helpful method is `ExecuteScalarAsync`. This allows you to return a scalar value from the database easily: 187 | 188 | ```csharp 189 | var count = await db.ExecuteScalarAsync("select count(*) from Stock"); 190 | 191 | Console.WriteLine(string.Format("Found '{0}' stock items.", count)); 192 | ``` 193 | 194 | ## Manual SQL 195 | 196 | **sqlite-net** is normally used as a light ORM (object-relational-mapper) using the methods `CreateTable` and `Table`. 197 | However, you can also use it as a convenient way to manually execute queries. 198 | 199 | Here is an example of creating a table, inserting into it (with a parameterized command), and querying it without using ORM features. 200 | 201 | ```csharp 202 | db.Execute ("create table Stock(Symbol varchar(100) not null)"); 203 | db.Execute ("insert into Stock(Symbol) values (?)", "MSFT"); 204 | var stocks = db.Query ("select * from Stock"); 205 | ``` 206 | 207 | ## Using SQLCipher 208 | 209 | You can use an encrypted database by using the [sqlite-net-sqlcipher NuGet package](https://www.nuget.org/packages/sqlite-net-sqlcipher). 210 | 211 | The database key is set in the `SqliteConnectionString` passed to the connection constructor: 212 | 213 | ```csharp 214 | var options = new SQLiteConnectionString(databasePath, true, 215 | key: "password"); 216 | var encryptedDb = new SQLiteAsyncConnection(options); 217 | ``` 218 | 219 | If you need set pragmas to control the encryption, actions can be passed to the connection string: 220 | 221 | ```csharp 222 | var options2 = new SQLiteConnectionString (databasePath, true, 223 | key: "password", 224 | preKeyAction: db => db.Execute("PRAGMA cipher_default_use_hmac = OFF;"), 225 | postKeyAction: db => db.Execute ("PRAGMA kdf_iter = 128000;")); 226 | var encryptedDb2 = new SQLiteAsyncConnection (options2); 227 | ``` 228 | 229 | 230 | ## Thank you! 231 | 232 | Thank you to the .NET community for embracing this project, and thank you to all the contributors who have helped to make this great. 233 | 234 | Thanks also to Tirza van Dijk (@tirzavdijk) for the great logo! 235 | 236 | -------------------------------------------------------------------------------- /SQLite.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A0E59A10-7BD0-4554-B133-66FA850159BE}" 5 | ProjectSection(SolutionItems) = preProject 6 | Makefile = Makefile 7 | README.md = README.md 8 | EndProjectSection 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{FECC0E44-E626-49CB-BD8B-0CFBD93FBEFF}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite-net-std", "nuget\SQLite-net-std\SQLite-net-std.csproj", "{081D08D6-10F1-431B-88FE-469FD9FE898C}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDiff", "tests\ApiDiff\ApiDiff.csproj", "{1DEF735C-B973-4ED9-8446-7FFA6D0B410B}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite-net-base", "nuget\SQLite-net-base\SQLite-net-base.csproj", "{53D1953C-3641-47D0-BE08-14DB853CC576}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite-net-sqlcipher", "nuget\SQLite-net-sqlcipher\SQLite-net-sqlcipher.csproj", "{59DB03EF-E28D-431E-9058-74AF316800EE}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite.Tests", "tests\SQLite.Tests\SQLite.Tests.csproj", "{80B66A43-B358-4438-BF06-6351B86B121A}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLite-net-static", "nuget\SQLite-net-static\SQLite-net-static.csproj", "{7CD60DAE-D505-4C2E-80B3-296556CE711E}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | Debug|iPhoneSimulator = Debug|iPhoneSimulator 29 | Release|iPhone = Release|iPhone 30 | Release|iPhoneSimulator = Release|iPhoneSimulator 31 | Debug|iPhone = Debug|iPhone 32 | EndGlobalSection 33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 34 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 39 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 40 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Release|iPhone.ActiveCfg = Release|Any CPU 41 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Release|iPhone.Build.0 = Release|Any CPU 42 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 43 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 44 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Debug|iPhone.ActiveCfg = Debug|Any CPU 45 | {081D08D6-10F1-431B-88FE-469FD9FE898C}.Debug|iPhone.Build.0 = Debug|Any CPU 46 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 51 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 52 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Release|iPhone.ActiveCfg = Release|Any CPU 53 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Release|iPhone.Build.0 = Release|Any CPU 54 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 55 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 56 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Debug|iPhone.ActiveCfg = Debug|Any CPU 57 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B}.Debug|iPhone.Build.0 = Debug|Any CPU 58 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 63 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 64 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Release|iPhone.ActiveCfg = Release|Any CPU 65 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Release|iPhone.Build.0 = Release|Any CPU 66 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 67 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 68 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Debug|iPhone.ActiveCfg = Debug|Any CPU 69 | {53D1953C-3641-47D0-BE08-14DB853CC576}.Debug|iPhone.Build.0 = Debug|Any CPU 70 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 75 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 76 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Release|iPhone.ActiveCfg = Release|Any CPU 77 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Release|iPhone.Build.0 = Release|Any CPU 78 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 79 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 80 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Debug|iPhone.ActiveCfg = Debug|Any CPU 81 | {59DB03EF-E28D-431E-9058-74AF316800EE}.Debug|iPhone.Build.0 = Debug|Any CPU 82 | {80B66A43-B358-4438-BF06-6351B86B121A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 83 | {80B66A43-B358-4438-BF06-6351B86B121A}.Debug|Any CPU.Build.0 = Debug|Any CPU 84 | {80B66A43-B358-4438-BF06-6351B86B121A}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {80B66A43-B358-4438-BF06-6351B86B121A}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {80B66A43-B358-4438-BF06-6351B86B121A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 87 | {80B66A43-B358-4438-BF06-6351B86B121A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 88 | {80B66A43-B358-4438-BF06-6351B86B121A}.Release|iPhone.ActiveCfg = Release|Any CPU 89 | {80B66A43-B358-4438-BF06-6351B86B121A}.Release|iPhone.Build.0 = Release|Any CPU 90 | {80B66A43-B358-4438-BF06-6351B86B121A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 91 | {80B66A43-B358-4438-BF06-6351B86B121A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 92 | {80B66A43-B358-4438-BF06-6351B86B121A}.Debug|iPhone.ActiveCfg = Debug|Any CPU 93 | {80B66A43-B358-4438-BF06-6351B86B121A}.Debug|iPhone.Build.0 = Debug|Any CPU 94 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 95 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Debug|Any CPU.Build.0 = Debug|Any CPU 96 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Release|Any CPU.ActiveCfg = Release|Any CPU 97 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Release|Any CPU.Build.0 = Release|Any CPU 98 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU 99 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU 100 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Release|iPhone.ActiveCfg = Release|Any CPU 101 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Release|iPhone.Build.0 = Release|Any CPU 102 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU 103 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU 104 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Debug|iPhone.ActiveCfg = Debug|Any CPU 105 | {7CD60DAE-D505-4C2E-80B3-296556CE711E}.Debug|iPhone.Build.0 = Debug|Any CPU 106 | EndGlobalSection 107 | GlobalSection(NestedProjects) = preSolution 108 | {1DEF735C-B973-4ED9-8446-7FFA6D0B410B} = {FECC0E44-E626-49CB-BD8B-0CFBD93FBEFF} 109 | {80B66A43-B358-4438-BF06-6351B86B121A} = {FECC0E44-E626-49CB-BD8B-0CFBD93FBEFF} 110 | EndGlobalSection 111 | GlobalSection(MonoDevelopProperties) = preSolution 112 | StartupItem = tests\SQLite.Tests.csproj 113 | Policies = $0 114 | $0.TextStylePolicy = $1 115 | $1.FileWidth = 128 116 | $1.NoTabsAfterNonTabs = True 117 | $1.EolMarker = Unix 118 | $1.scope = text/x-csharp 119 | $0.CSharpFormattingPolicy = $2 120 | $2.NewLinesForBracesInProperties = False 121 | $2.NewLinesForBracesInAccessors = False 122 | $2.NewLinesForBracesInAnonymousMethods = False 123 | $2.NewLinesForBracesInControlBlocks = False 124 | $2.NewLinesForBracesInAnonymousTypes = False 125 | $2.NewLinesForBracesInObjectCollectionArrayInitializers = False 126 | $2.NewLinesForBracesInLambdaExpressionBody = False 127 | $2.scope = text/x-csharp 128 | $2.SpacingAfterMethodDeclarationName = True 129 | $2.SpaceAfterMethodCallName = True 130 | EndGlobalSection 131 | EndGlobal 132 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.100", 4 | "rollForward": "latestFeature" 5 | } 6 | } -------------------------------------------------------------------------------- /nuget/Logo-low.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/praeclarum/sqlite-net/bf1eb50278d0ace79c3754575b34823cf7fb0934/nuget/Logo-low.png -------------------------------------------------------------------------------- /nuget/SQLite-net-base/SQLite-net-base.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net8.0;net9.0 5 | SQLite-net 6 | sqlite-net-base 7 | SQLite-net .NET Standard Base Library 8 | 9 | This is a special version of SQLite-net-pcl that does not include a SQLitePCLRaw bundle. 10 | It is meant to give you all the power of SQLite-net but with the freedom to choose your own provider. 11 | Please use the package sqlite-net-pcl if you have no idea what any of this means. 12 | 13 | true 14 | 15 | 16 | 17 | USE_SQLITEPCL_RAW;NO_SQLITEPCL_RAW_BATTERIES;RELEASE 18 | bin\Release\$(TargetFramework)\SQLite-net.xml 19 | 20 | 21 | USE_SQLITEPCL_RAW;NO_SQLITEPCL_RAW_BATTERIES;DEBUG 22 | bin\Debug\$(TargetFramework)\SQLite-net.xml 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | SQLite.cs 31 | 32 | 33 | SQLiteAsync.cs 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /nuget/SQLite-net-sqlcipher/SQLite-net-sqlcipher.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net8.0;net9.0 5 | SQLite-net 6 | sqlite-net-sqlcipher 7 | SQLite-net SQLCipher .NET Standard Library 8 | 9 | SQLite-net is an open source and light weight library providing easy SQLite database storage for .NET, Mono, and Xamarin applications. 10 | This version uses SQLitePCLRaw to provide platform independent versions of SQLite with the SQLCipher extension. 11 | This enables secure access to the database with password (key) access. 12 | 13 | sqlite-net;sqlite;database;orm;encryption;sqlcipher 14 | true 15 | 16 | 17 | 18 | USE_SQLITEPCL_RAW;RELEASE 19 | bin\Release\$(TargetFramework)\SQLite-net.xml 20 | 21 | 22 | USE_SQLITEPCL_RAW;DEBUG 23 | bin\Debug\$(TargetFramework)\SQLite-net.xml 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | SQLite.cs 32 | 33 | 34 | SQLiteAsync.cs 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /nuget/SQLite-net-static/SQLite-net-static.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net8.0;net9.0 5 | SQLite-net 6 | sqlite-net-static 7 | SQLite-net .NET Standard P/Invoke Library 8 | 9 | SQLite-net is an open source and light weight library providing easy SQLite database storage for .NET, Mono, and Xamarin applications. 10 | This version uses P/Invokes to the "sqlite3" native library provided by the operating system. 11 | This works on Xamarin.iOS, Xamarin.Mac, Wilderness Labs' Meadow, and any other platform that has a "sqlite3" library in the path. 12 | 13 | true 14 | 15 | 16 | 17 | RELEASE 18 | bin\Release\$(TargetFramework)\SQLite-net.xml 19 | 20 | 21 | DEBUG 22 | bin\Debug\$(TargetFramework)\SQLite-net.xml 23 | 24 | 25 | 26 | 27 | SQLite.cs 28 | 29 | 30 | SQLiteAsync.cs 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /nuget/SQLite-net-std/SQLite-net-std.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net8.0;net9.0 5 | SQLite-net 6 | sqlite-net-pcl 7 | SQLite-net Official .NET Standard Library 8 | 9 | SQLite-net is an open source and light weight library providing easy SQLite database storage for .NET, Mono, and Xamarin applications. 10 | This version uses SQLitePCLRaw to provide platform independent versions of SQLite. 11 | 12 | true 13 | 14 | 15 | 16 | USE_SQLITEPCL_RAW;RELEASE 17 | bin\Release\$(TargetFramework)\SQLite-net.xml 18 | 19 | 20 | USE_SQLITEPCL_RAW;DEBUG 21 | bin\Debug\$(TargetFramework)\SQLite-net.xml 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | SQLite.cs 30 | 31 | 32 | SQLiteAsync.cs 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("SQLite-net Official Portable Library")] 10 | [assembly: AssemblyDescription("Light weight library providing easy SQLite database storage")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("Krueger Systems, Inc.")] 13 | [assembly: AssemblyProduct("SQLite-net")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | [assembly: NeutralResourcesLanguage("en")] 17 | 18 | // Version information for an assembly consists of the following four values: 19 | // 20 | // Major Version 21 | // Minor Version 22 | // Build Number 23 | // Revision 24 | // 25 | // You can specify all the values or you can default the Build and Revision Numbers 26 | // by using the '*' as shown below: 27 | // [assembly: AssemblyVersion("1.0.*")] 28 | [assembly: AssemblyVersion("1.0.0.0")] 29 | [assembly: AssemblyFileVersion("1.0.0.0")] 30 | -------------------------------------------------------------------------------- /tests/ApiDiff/ApiDiff.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | Exe 5 | 6 | 7 | 8 | SQLite.cs 9 | 10 | 11 | SQLiteAsync.cs 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/ApiDiff/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Linq; 5 | using System.Text.RegularExpressions; 6 | using SQLite; 7 | using ListDiff; 8 | 9 | namespace ApiDiff 10 | { 11 | class Api 12 | { 13 | public string Name; 14 | public string Declaration; 15 | public string Index; 16 | 17 | static readonly Regex task1Re = new Regex (@"System\.Threading\.Tasks\.Task`1\[([^\]]*)\]"); 18 | static readonly Regex taskRe = new Regex (@"System\.Threading\.Tasks\.Task(\s*)"); 19 | 20 | public Api (MemberInfo member, string nameSuffix) 21 | { 22 | Name = member.Name; 23 | Declaration = member.ToString (); 24 | Index = Declaration.Replace ("AsyncTableQuery`1", "TableQuery`1"); 25 | 26 | if (nameSuffix.Length > 0 && Name.EndsWith (nameSuffix)) { 27 | var indexName = Name.Substring (0, Name.IndexOf (nameSuffix)); 28 | Index = taskRe 29 | .Replace (task1Re.Replace (Index.Replace (Name, indexName), "$1"), "Void$1") 30 | .Replace ("System.Int32", "Int32"); 31 | Name = indexName; 32 | } 33 | } 34 | } 35 | 36 | class Apis 37 | { 38 | public List All; 39 | readonly string nameSuffix; 40 | readonly Type type; 41 | 42 | public static readonly HashSet connectionIgnores = new HashSet { 43 | "RunInTransaction", 44 | "RunInTransactionAsync", 45 | "BeginTransaction", 46 | "SaveTransactionPoint", 47 | "Commit", 48 | "Rollback", 49 | "RollbackTo", 50 | "IsInTransaction", 51 | "Release", 52 | "EndTransaction", 53 | 54 | "BusyTimeout", 55 | "GetBusyTimeout", 56 | "SetBusyTimeoutAsync", 57 | 58 | "GetConnection", 59 | "Handle", 60 | 61 | "Dispose", 62 | 63 | "Table", 64 | "CreateCommand", 65 | "TableChanged", 66 | }; 67 | 68 | public static readonly HashSet queryIgnores = new HashSet { 69 | ".ctor", 70 | "Clone", 71 | "Connection", 72 | "Deferred", 73 | "Table", 74 | "GetEnumerator", 75 | }; 76 | 77 | public Apis (Type type, HashSet ignores, string nameSuffix = "") 78 | { 79 | this.type = type; 80 | this.nameSuffix = nameSuffix; 81 | All = type.GetMembers (BindingFlags.Public|BindingFlags.Instance) 82 | .Where (x => !ignores.Contains(x.Name)) 83 | .Where (x => x.MemberType != MemberTypes.NestedType) 84 | .Where (x => !x.Name.StartsWith("get_") && !x.Name.StartsWith ("set_") && !x.Name.StartsWith ("remove_") && !x.Name.StartsWith ("add_")) 85 | .Select (x => new Api(x, nameSuffix)) 86 | .OrderBy (x => x.Index) 87 | .OrderBy (x => x.Name) 88 | .ToList (); 89 | } 90 | 91 | public int DumpComparison (Apis other) 92 | { 93 | Console.ForegroundColor = ConsoleColor.Cyan; 94 | Console.WriteLine ("## " + type.FullName); 95 | Console.WriteLine (); 96 | 97 | var diff = new ListDiff (All, other.All, (x, y) => x.Index == y.Index); 98 | 99 | var n = 0; 100 | 101 | foreach (var a in diff.Actions) { 102 | switch (a.ActionType) { 103 | case ListDiffActionType.Add: 104 | Console.ForegroundColor = ConsoleColor.Green; 105 | Console.WriteLine ($"- [ ] *add* `{a.DestinationItem.Index.Replace('`', '_')}`"); 106 | n++; 107 | break; 108 | case ListDiffActionType.Remove: 109 | Console.ForegroundColor = ConsoleColor.Red; 110 | Console.WriteLine ($"- [ ] *remove* `{a.SourceItem.Index.Replace('`', '_')}`"); 111 | n++; 112 | break; 113 | case ListDiffActionType.Update: 114 | Console.ForegroundColor = ConsoleColor.Gray; 115 | Console.WriteLine ($"- [x] `{a.SourceItem.Index.Replace('`', '_')}`"); 116 | break; 117 | } 118 | } 119 | Console.ResetColor (); 120 | Console.WriteLine (); 121 | Console.WriteLine ($"**{n}** differences"); 122 | Console.WriteLine (); 123 | 124 | return n; 125 | } 126 | } 127 | 128 | class MainClass 129 | { 130 | public static int Main (string[] args) 131 | { 132 | var synchronousConnection = new Apis (typeof (SQLiteConnection), Apis.connectionIgnores); 133 | var asynchronousConnection = new Apis (typeof (SQLiteAsyncConnection), Apis.connectionIgnores, "Async"); 134 | var n = asynchronousConnection.DumpComparison (synchronousConnection); 135 | 136 | var synchronousQuery = new Apis (typeof (TableQuery<>), Apis.queryIgnores); 137 | var asynchronousQuery = new Apis (typeof (AsyncTableQuery<>), Apis.queryIgnores, "Async"); 138 | n += asynchronousQuery.DumpComparison (synchronousQuery); 139 | 140 | return n > 0 ? 1 : 0; 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /tests/SQLite.Tests.iOS/Entitlements.plist: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/SQLite.Tests.iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleName 6 | SQLite-net 7 | CFBundleIdentifier 8 | com.kruegersystems.sqlite-net 9 | CFBundleShortVersionString 10 | 1.0 11 | CFBundleVersion 12 | 1.0 13 | LSRequiresIPhoneOS 14 | 15 | MinimumOSVersion 16 | 10.0 17 | UIDeviceFamily 18 | 19 | 1 20 | 2 21 | 22 | UISupportedInterfaceOrientations 23 | 24 | UIInterfaceOrientationPortrait 25 | UIInterfaceOrientationLandscapeLeft 26 | UIInterfaceOrientationLandscapeRight 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | NSAppTransportSecurity 31 | 32 | NSAllowsArbitraryLoads 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /tests/SQLite.Tests.iOS/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/SQLite.Tests.iOS/Main.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | using Foundation; 6 | using UIKit; 7 | 8 | namespace SQLite.Tests.iOS 9 | { 10 | public class Application 11 | { 12 | // This is the main entry point of the application. 13 | static void Main(string[] args) 14 | { 15 | // if you want to use a different Application Delegate class from "UnitTestAppDelegate" 16 | // you can specify it here. 17 | UIApplication.Main(args, null, "UnitTestAppDelegate"); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/SQLite.Tests.iOS/SQLiteTestsiOS.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | iPhoneSimulator 6 | 8.0.30703 7 | 2.0 8 | {81850129-71C3-40C7-A48B-AA5D2C2E365E} 9 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10 | Exe 11 | SQLite.Tests.iOS 12 | SQLiteTestsiOS 13 | Resources 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\iPhoneSimulator\Debug 20 | __UNIFIED__;__MOBILE__;__IOS__;DEBUG;NO_VB 21 | prompt 22 | 4 23 | iPhone Developer 24 | true 25 | true 26 | true 27 | None 28 | x86_64 29 | HttpClientHandler 30 | Default 31 | false 32 | true 33 | 34 | 35 | 36 | 37 | true 38 | bin\iPhone\Release 39 | __UNIFIED__;__MOBILE__;__IOS__;NO_VB 40 | prompt 41 | 4 42 | iPhone Developer 43 | true 44 | 45 | 46 | SdkOnly 47 | ARMv7, ARM64 48 | HttpClientHandler 49 | Default 50 | 51 | 52 | 53 | 54 | true 55 | bin\iPhoneSimulator\Release 56 | __UNIFIED__;__MOBILE__;__IOS__;NO_VB 57 | prompt 58 | 4 59 | iPhone Developer 60 | None 61 | x86_64 62 | HttpClientHandler 63 | Default 64 | 65 | 66 | true 67 | full 68 | false 69 | bin\iPhone\Debug 70 | __UNIFIED__;__MOBILE__;__IOS__;DEBUG;NO_VB 71 | prompt 72 | 4 73 | iPhone Developer 74 | false 75 | true 76 | false 77 | true 78 | true 79 | 80 | 81 | SdkOnly 82 | ARM64 83 | HttpClientHandler 84 | Default 85 | true 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | SQLite.cs 106 | 107 | 108 | SQLiteAsync.cs 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /tests/SQLite.Tests.iOS/UnitTestAppDelegate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | using Foundation; 6 | using UIKit; 7 | using MonoTouch.NUnit.UI; 8 | 9 | namespace SQLite.Tests.iOS 10 | { 11 | // The UIApplicationDelegate for the application. This class is responsible for launching the 12 | // User Interface of the application, as well as listening (and optionally responding) to 13 | // application events from iOS. 14 | [Register("UnitTestAppDelegate")] 15 | public partial class UnitTestAppDelegate : UIApplicationDelegate 16 | { 17 | // class-level declarations 18 | UIWindow window; 19 | TouchRunner runner; 20 | 21 | // 22 | // This method is invoked when the application has loaded and is ready to run. In this 23 | // method you should instantiate the window, load the UI into it and then make the window 24 | // visible. 25 | // 26 | // You have 17 seconds to return from this method, or iOS will terminate your application. 27 | // 28 | public override bool FinishedLaunching(UIApplication app, NSDictionary options) 29 | { 30 | // create a new window instance based on the screen size 31 | window = new UIWindow(UIScreen.MainScreen.Bounds); 32 | runner = new TouchRunner(window); 33 | 34 | // register every tests included in the main application/assembly 35 | runner.Add(System.Reflection.Assembly.GetExecutingAssembly()); 36 | 37 | window.RootViewController = new UINavigationController(runner.GetViewController()); 38 | 39 | // make the window visible 40 | window.MakeKeyAndVisible(); 41 | 42 | return true; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/AttributesTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 10 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 11 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 12 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 13 | #else 14 | using NUnit.Framework; 15 | #endif 16 | 17 | using System.Diagnostics; 18 | 19 | namespace SQLite.Tests 20 | { 21 | [TestFixture] 22 | public class AttributesTest 23 | { 24 | public AttributesTest () 25 | { 26 | } 27 | 28 | [Test] 29 | public void TestCtors () 30 | { 31 | Assert.DoesNotThrow (() => new CollationAttribute ("NOCASE")); 32 | Assert.DoesNotThrow (() => new ColumnAttribute ("Bar")); 33 | Assert.DoesNotThrow (() => new IgnoreAttribute ()); 34 | Assert.DoesNotThrow (() => new IndexedAttribute ()); 35 | Assert.DoesNotThrow (() => new NotNullAttribute ()); 36 | Assert.DoesNotThrow (() => new PreserveAttribute ()); 37 | Assert.DoesNotThrow (() => new PrimaryKeyAttribute ()); 38 | Assert.DoesNotThrow (() => new StoreAsTextAttribute ()); 39 | Assert.DoesNotThrow (() => new TableAttribute ("Foo")); 40 | Assert.DoesNotThrow (() => new UniqueAttribute ()); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/BackupTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text; 3 | using SQLite; 4 | using System.Threading.Tasks; 5 | 6 | #if NETFX_CORE 7 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 8 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 9 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 10 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 11 | #else 12 | using NUnit.Framework; 13 | #endif 14 | 15 | using System.IO; 16 | 17 | namespace SQLite.Tests 18 | { 19 | [TestFixture] 20 | public class BackupTest 21 | { 22 | [Test] 23 | public async Task BackupOneTable () 24 | { 25 | var pathSrc = Path.GetTempFileName (); 26 | var pathDest = Path.GetTempFileName (); 27 | 28 | var db = new SQLiteAsyncConnection (pathSrc); 29 | await db.CreateTableAsync ().ConfigureAwait (false); 30 | await db.InsertAsync (new OrderLine { }); 31 | var lines = await db.Table ().ToListAsync (); 32 | Assert.AreEqual (1, lines.Count); 33 | 34 | await db.BackupAsync (pathDest); 35 | 36 | var destLen = new FileInfo (pathDest).Length; 37 | Assert.True (destLen >= 4096); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/BooleanTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | using System.Diagnostics; 9 | 10 | #if NETFX_CORE 11 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 12 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 13 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 14 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 15 | #else 16 | using NUnit.Framework; 17 | #endif 18 | 19 | 20 | namespace SQLite.Tests 21 | { 22 | [TestFixture] 23 | public class BooleanTest 24 | { 25 | public class VO 26 | { 27 | [AutoIncrement, PrimaryKey] 28 | public int ID { get; set; } 29 | public bool Flag { get; set; } 30 | public String Text { get; set; } 31 | 32 | public override string ToString() 33 | { 34 | return string.Format("VO:: ID:{0} Flag:{1} Text:{2}", ID, Flag, Text); 35 | } 36 | } 37 | public class DbAcs : SQLiteConnection 38 | { 39 | public DbAcs(String path) 40 | : base(path) 41 | { 42 | } 43 | 44 | public void buildTable() 45 | { 46 | CreateTable(); 47 | } 48 | 49 | public int CountWithFlag(Boolean flag) 50 | { 51 | var cmd = CreateCommand("SELECT COUNT(*) FROM VO Where Flag = ?", flag); 52 | return cmd.ExecuteScalar(); 53 | } 54 | } 55 | 56 | [Test] 57 | public void TestBoolean() 58 | { 59 | var tmpFile = TestPath.GetTempFileName(); 60 | var db = new DbAcs(tmpFile); 61 | db.buildTable(); 62 | for (int i = 0; i < 10; i++) 63 | db.Insert(new VO() { Flag = (i % 3 == 0), Text = String.Format("VO{0}", i) }); 64 | 65 | // count vo which flag is true 66 | Assert.AreEqual(4, db.CountWithFlag(true)); 67 | Assert.AreEqual(6, db.CountWithFlag(false)); 68 | 69 | Debug.WriteLine("VO with true flag:"); 70 | foreach (var vo in db.Query("SELECT * FROM VO Where Flag = ?", true)) 71 | Debug.WriteLine (vo.ToString ()); 72 | 73 | Debug.WriteLine ("VO with false flag:"); 74 | foreach (var vo in db.Query("SELECT * FROM VO Where Flag = ?", false)) 75 | Debug.WriteLine (vo.ToString ()); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/ByteArrayTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 10 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 11 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 12 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 13 | #else 14 | using NUnit.Framework; 15 | #endif 16 | 17 | 18 | namespace SQLite.Tests 19 | { 20 | [TestFixture] 21 | public class ByteArrayTest 22 | { 23 | public class ByteArrayClass 24 | { 25 | [PrimaryKey, AutoIncrement] 26 | public int ID { get; set; } 27 | 28 | public byte[] bytes { get; set; } 29 | 30 | public void AssertEquals(ByteArrayClass other) 31 | { 32 | Assert.AreEqual(other.ID, ID); 33 | if (other.bytes == null || bytes == null) { 34 | Assert.IsNull (other.bytes); 35 | Assert.IsNull (bytes); 36 | } 37 | else { 38 | Assert.AreEqual(other.bytes.Length, bytes.Length); 39 | for (var i = 0; i < bytes.Length; i++) { 40 | Assert.AreEqual(other.bytes[i], bytes[i]); 41 | } 42 | } 43 | } 44 | } 45 | 46 | [Test] 47 | [Description("Create objects with various byte arrays and check they can be stored and retrieved correctly")] 48 | public void ByteArrays() 49 | { 50 | //Byte Arrays for comparisson 51 | ByteArrayClass[] byteArrays = new ByteArrayClass[] { 52 | new ByteArrayClass() { bytes = new byte[] { 1, 2, 3, 4, 250, 252, 253, 254, 255 } }, //Range check 53 | new ByteArrayClass() { bytes = new byte[] { 0 } }, //null bytes need to be handled correctly 54 | new ByteArrayClass() { bytes = new byte[] { 0, 0 } }, 55 | new ByteArrayClass() { bytes = new byte[] { 0, 1, 0 } }, 56 | new ByteArrayClass() { bytes = new byte[] { 1, 0, 1 } }, 57 | new ByteArrayClass() { bytes = new byte[] { } }, //Empty byte array should stay empty (and not become null) 58 | new ByteArrayClass() { bytes = null } //Null should be supported 59 | }; 60 | 61 | SQLiteConnection database = new SQLiteConnection(TestPath.GetTempFileName()); 62 | database.CreateTable(); 63 | 64 | //Insert all of the ByteArrayClass 65 | foreach (ByteArrayClass b in byteArrays) 66 | database.Insert(b); 67 | 68 | //Get them back out 69 | ByteArrayClass[] fetchedByteArrays = database.Table().OrderBy(x => x.ID).ToArray(); 70 | 71 | Assert.AreEqual(fetchedByteArrays.Length, byteArrays.Length); 72 | //Check they are the same 73 | for (int i = 0; i < byteArrays.Length; i++) 74 | { 75 | byteArrays[i].AssertEquals(fetchedByteArrays[i]); 76 | } 77 | } 78 | 79 | [Test] 80 | [Description("Uses a byte array to find a record")] 81 | public void ByteArrayWhere() 82 | { 83 | //Byte Arrays for comparisson 84 | ByteArrayClass[] byteArrays = new ByteArrayClass[] { 85 | new ByteArrayClass() { bytes = new byte[] { 1, 2, 3, 4, 250, 252, 253, 254, 255 } }, //Range check 86 | new ByteArrayClass() { bytes = new byte[] { 0 } }, //null bytes need to be handled correctly 87 | new ByteArrayClass() { bytes = new byte[] { 0, 0 } }, 88 | new ByteArrayClass() { bytes = new byte[] { 0, 1, 0 } }, 89 | new ByteArrayClass() { bytes = new byte[] { 1, 0, 1 } }, 90 | new ByteArrayClass() { bytes = new byte[] { } }, //Empty byte array should stay empty (and not become null) 91 | new ByteArrayClass() { bytes = null } //Null should be supported 92 | }; 93 | 94 | SQLiteConnection database = new SQLiteConnection(TestPath.GetTempFileName()); 95 | database.CreateTable(); 96 | 97 | byte[] criterion = new byte[] { 1, 0, 1 }; 98 | 99 | //Insert all of the ByteArrayClass 100 | int id = 0; 101 | foreach (ByteArrayClass b in byteArrays) 102 | { 103 | database.Insert(b); 104 | if (b.bytes != null && criterion.SequenceEqual(b.bytes)) 105 | id = b.ID; 106 | } 107 | Assert.AreNotEqual(0, id, "An ID wasn't set"); 108 | 109 | //Get it back out 110 | ByteArrayClass fetchedByteArray = database.Table().Where(x => x.bytes == criterion).First(); 111 | Assert.IsNotNull(fetchedByteArray); 112 | //Check they are the same 113 | Assert.AreEqual(id, fetchedByteArray.ID); 114 | } 115 | 116 | [Test] 117 | [Description("Uses a null byte array to find a record")] 118 | public void ByteArrayWhereNull() 119 | { 120 | //Byte Arrays for comparisson 121 | ByteArrayClass[] byteArrays = new ByteArrayClass[] { 122 | new ByteArrayClass() { bytes = new byte[] { 1, 2, 3, 4, 250, 252, 253, 254, 255 } }, //Range check 123 | new ByteArrayClass() { bytes = new byte[] { 0 } }, //null bytes need to be handled correctly 124 | new ByteArrayClass() { bytes = new byte[] { 0, 0 } }, 125 | new ByteArrayClass() { bytes = new byte[] { 0, 1, 0 } }, 126 | new ByteArrayClass() { bytes = new byte[] { 1, 0, 1 } }, 127 | new ByteArrayClass() { bytes = new byte[] { } }, //Empty byte array should stay empty (and not become null) 128 | new ByteArrayClass() { bytes = null } //Null should be supported 129 | }; 130 | 131 | SQLiteConnection database = new SQLiteConnection(TestPath.GetTempFileName()); 132 | database.CreateTable(); 133 | 134 | byte[] criterion = null; 135 | 136 | //Insert all of the ByteArrayClass 137 | int id = 0; 138 | foreach (ByteArrayClass b in byteArrays) 139 | { 140 | database.Insert(b); 141 | if (b.bytes == null) 142 | id = b.ID; 143 | } 144 | Assert.AreNotEqual(0, id, "An ID wasn't set"); 145 | 146 | //Get it back out 147 | ByteArrayClass fetchedByteArray = database.Table().Where(x => x.bytes == criterion).First(); 148 | 149 | Assert.IsNotNull(fetchedByteArray); 150 | //Check they are the same 151 | Assert.AreEqual(id, fetchedByteArray.ID); 152 | } 153 | 154 | [Test] 155 | [Description("Create A large byte array and check it can be stored and retrieved correctly")] 156 | public void LargeByteArray() 157 | { 158 | const int byteArraySize = 1024 * 1024; 159 | byte[] bytes = new byte[byteArraySize]; 160 | for (int i = 0; i < byteArraySize; i++) 161 | bytes[i] = (byte)(i % 256); 162 | 163 | ByteArrayClass byteArray = new ByteArrayClass() { bytes = bytes }; 164 | 165 | SQLiteConnection database = new SQLiteConnection(TestPath.GetTempFileName()); 166 | database.CreateTable(); 167 | 168 | //Insert the ByteArrayClass 169 | database.Insert(byteArray); 170 | 171 | //Get it back out 172 | ByteArrayClass[] fetchedByteArrays = database.Table().ToArray(); 173 | 174 | Assert.AreEqual(fetchedByteArrays.Length, 1); 175 | 176 | //Check they are the same 177 | byteArray.AssertEquals(fetchedByteArrays[0]); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/CollateTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 10 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 11 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 12 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 13 | #else 14 | using NUnit.Framework; 15 | #endif 16 | 17 | using System.Diagnostics; 18 | 19 | namespace SQLite.Tests 20 | { 21 | [TestFixture] 22 | public class CollateTest 23 | { 24 | public class TestObj 25 | { 26 | [AutoIncrement, PrimaryKey] 27 | public int Id { get; set; } 28 | 29 | public string CollateDefault { get; set; } 30 | 31 | [Collation("BINARY")] 32 | public string CollateBinary { get; set; } 33 | 34 | [Collation("RTRIM")] 35 | public string CollateRTrim { get; set; } 36 | 37 | [Collation("NOCASE")] 38 | public string CollateNoCase { get; set; } 39 | 40 | public override string ToString () 41 | { 42 | return string.Format("[TestObj: Id={0}]", Id); 43 | } 44 | } 45 | 46 | public class TestDb : SQLiteConnection 47 | { 48 | public TestDb(String path) 49 | : base(path) 50 | { 51 | Trace = true; 52 | CreateTable(); 53 | } 54 | } 55 | 56 | [Test] 57 | public void Collate() 58 | { 59 | var obj = new TestObj() { 60 | CollateDefault = "Alpha ", 61 | CollateBinary = "Alpha ", 62 | CollateRTrim = "Alpha ", 63 | CollateNoCase = "Alpha ", 64 | }; 65 | 66 | var db = new TestDb(TestPath.GetTempFileName()); 67 | 68 | db.Insert(obj); 69 | 70 | Assert.AreEqual(1, (from o in db.Table() where o.CollateDefault == "Alpha " select o).Count()); 71 | Assert.AreEqual(0, (from o in db.Table() where o.CollateDefault == "ALPHA " select o).Count()); 72 | Assert.AreEqual(0, (from o in db.Table() where o.CollateDefault == "Alpha" select o).Count()); 73 | Assert.AreEqual(0, (from o in db.Table() where o.CollateDefault == "ALPHA" select o).Count()); 74 | 75 | Assert.AreEqual(1, (from o in db.Table() where o.CollateBinary == "Alpha " select o).Count()); 76 | Assert.AreEqual(0, (from o in db.Table() where o.CollateBinary == "ALPHA " select o).Count()); 77 | Assert.AreEqual(0, (from o in db.Table() where o.CollateBinary == "Alpha" select o).Count()); 78 | Assert.AreEqual(0, (from o in db.Table() where o.CollateBinary == "ALPHA" select o).Count()); 79 | 80 | Assert.AreEqual(1, (from o in db.Table() where o.CollateRTrim == "Alpha " select o).Count()); 81 | Assert.AreEqual(0, (from o in db.Table() where o.CollateRTrim == "ALPHA " select o).Count()); 82 | Assert.AreEqual(1, (from o in db.Table() where o.CollateRTrim == "Alpha" select o).Count()); 83 | Assert.AreEqual(0, (from o in db.Table() where o.CollateRTrim == "ALPHA" select o).Count()); 84 | 85 | Assert.AreEqual(1, (from o in db.Table() where o.CollateNoCase == "Alpha " select o).Count()); 86 | Assert.AreEqual(1, (from o in db.Table() where o.CollateNoCase == "ALPHA " select o).Count()); 87 | Assert.AreEqual(0, (from o in db.Table() where o.CollateNoCase == "Alpha" select o).Count()); 88 | Assert.AreEqual(0, (from o in db.Table() where o.CollateNoCase == "ALPHA" select o).Count()); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/ConcurrencyTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 10 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 11 | using TearDown = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestCleanupAttribute; 12 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 13 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 14 | #else 15 | using NUnit.Framework; 16 | #endif 17 | 18 | namespace SQLite.Tests 19 | { 20 | [TestFixture, NUnit.Framework.Ignore("Fails to run on .NET Core 3.1 Mac")] 21 | public class ConcurrencyTest 22 | { 23 | public class TestObj 24 | { 25 | [AutoIncrement, PrimaryKey] 26 | public int Id { get; set; } 27 | 28 | public override string ToString() 29 | { 30 | return string.Format("[TestObj: Id={0}]", Id); 31 | } 32 | } 33 | 34 | public class DbReader 35 | { 36 | private CancellationToken cancellationToken; 37 | 38 | public DbReader(CancellationToken cancellationToken) 39 | { 40 | this.cancellationToken = cancellationToken; 41 | } 42 | 43 | public Task Run() 44 | { 45 | var t = Task.Run(() => 46 | { 47 | try 48 | { 49 | while (true) 50 | { 51 | // 52 | // NOTE: Change this to readwrite and then it does work ??? 53 | // No more IOERROR 54 | // 55 | 56 | var flags = SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadOnly; 57 | #if __IOS__ 58 | flags = SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadWrite; 59 | #endif 60 | using (var dbConnection = new DbConnection(flags)) 61 | { 62 | var records = dbConnection.Table().ToList(); 63 | System.Diagnostics.Debug.WriteLine($"{Environment.CurrentManagedThreadId} Read records: {records.Count}"); 64 | } 65 | 66 | // No await so we stay on the same thread 67 | Task.Delay(10).GetAwaiter().GetResult(); 68 | cancellationToken.ThrowIfCancellationRequested(); 69 | } 70 | } 71 | catch (OperationCanceledException) 72 | { 73 | } 74 | }); 75 | 76 | return t; 77 | } 78 | 79 | } 80 | 81 | public class DbWriter 82 | { 83 | private CancellationToken cancellationToken; 84 | 85 | public DbWriter(CancellationToken cancellationToken) 86 | { 87 | this.cancellationToken = cancellationToken; 88 | } 89 | 90 | public Task Run() 91 | { 92 | var t = Task.Run(() => 93 | { 94 | try 95 | { 96 | while (true) 97 | { 98 | using (var dbConnection = new DbConnection(SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadWrite)) 99 | { 100 | System.Diagnostics.Debug.WriteLine($"{Environment.CurrentManagedThreadId} Start insert"); 101 | 102 | for (var i = 0; i < 50; i++) 103 | { 104 | var newRecord = new TestObj() 105 | { 106 | }; 107 | 108 | dbConnection.Insert(newRecord); 109 | } 110 | 111 | System.Diagnostics.Debug.WriteLine($"{Environment.CurrentManagedThreadId} Inserted records"); 112 | } 113 | 114 | // No await so we stay on the same thread 115 | Task.Delay(1).GetAwaiter().GetResult(); 116 | cancellationToken.ThrowIfCancellationRequested(); 117 | } 118 | } 119 | catch (OperationCanceledException) 120 | { 121 | } 122 | }); 123 | 124 | return t; 125 | } 126 | 127 | } 128 | 129 | public class DbConnection : SQLiteConnection 130 | { 131 | private static string DbPath = GetTempFileName(); 132 | 133 | private static string GetTempFileName() 134 | { 135 | #if NETFX_CORE 136 | var name = Guid.NewGuid() + ".sqlite"; 137 | return Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, name); 138 | #else 139 | return Path.GetTempFileName(); 140 | #endif 141 | } 142 | 143 | 144 | public DbConnection(SQLiteOpenFlags openflags) : base(DbPath, openflags) 145 | { 146 | this.BusyTimeout = TimeSpan.FromSeconds(5); 147 | } 148 | 149 | public void CreateTables() 150 | { 151 | CreateTable(); 152 | } 153 | } 154 | 155 | [SetUp] 156 | public void Setup() 157 | { 158 | using (var dbConenction = new DbConnection(SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create)) 159 | { 160 | dbConenction.CreateTables(); 161 | } 162 | } 163 | 164 | 165 | [Test] 166 | public void TestLoad() 167 | { 168 | try 169 | { 170 | //var result = SQLitePCL.raw.sqlite3_threadsafe(); 171 | //Assert.AreEqual(2, result); 172 | // Yes it's threadsafe on iOS 173 | 174 | var tokenSource = new CancellationTokenSource(); 175 | var tasks = new List(); 176 | tasks.Add(new DbReader(tokenSource.Token).Run()); 177 | tasks.Add(new DbWriter(tokenSource.Token).Run()); 178 | 179 | // Wait 5sec 180 | tokenSource.CancelAfter(5000); 181 | 182 | Task.WhenAll(tasks).GetAwaiter().GetResult(); 183 | } 184 | catch (Exception ex) 185 | { 186 | Assert.Fail(ex.ToString()); 187 | } 188 | } 189 | 190 | /// 191 | /// Test for issue #761. Because the nature of this test is a race condition, 192 | /// it is not guaranteed to fail if the issue is present. It does appear to 193 | /// fail most of the time, though. 194 | /// 195 | [Test] 196 | public void TestInsertCommandCreation () 197 | { 198 | using (var dbConnection = 199 | new DbConnection (SQLiteOpenFlags.FullMutex | SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create)) { 200 | var obj1 = new TestObj (); 201 | var obj2 = new TestObj (); 202 | var taskA = Task.Run (() => { 203 | dbConnection.Insert (obj1); 204 | }); 205 | var taskB = Task.Run (() => { 206 | dbConnection.Insert (obj2); 207 | }); 208 | 209 | Task.WhenAll (taskA, taskB).Wait (); 210 | } 211 | } 212 | } 213 | } 214 | 215 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/ContainsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 10 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 11 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 12 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 13 | #else 14 | using NUnit.Framework; 15 | #endif 16 | 17 | using System.Diagnostics; 18 | 19 | namespace SQLite.Tests 20 | { 21 | [TestFixture] 22 | public class ContainsTest 23 | { 24 | public class TestObj 25 | { 26 | [AutoIncrement, PrimaryKey] 27 | public int Id { get; set; } 28 | 29 | public string Name { get; set; } 30 | 31 | public override string ToString () 32 | { 33 | return string.Format("[TestObj: Id={0}, Name={1}]", Id, Name); 34 | } 35 | } 36 | 37 | public class TestDb : SQLiteConnection 38 | { 39 | public TestDb(String path) 40 | : base(path) 41 | { 42 | CreateTable(); 43 | } 44 | } 45 | 46 | [Test] 47 | public void ContainsConstantData() 48 | { 49 | int n = 20; 50 | var cq =from i in Enumerable.Range(1, n) 51 | select new TestObj() { 52 | Name = i.ToString() 53 | }; 54 | 55 | var db = new TestDb(TestPath.GetTempFileName()); 56 | 57 | db.InsertAll(cq); 58 | 59 | db.Trace = true; 60 | 61 | var tensq = new string[] { "0", "10", "20" }; 62 | var tens = (from o in db.Table() where tensq.Contains(o.Name) select o).ToList(); 63 | Assert.AreEqual(2, tens.Count); 64 | 65 | var moreq = new string[] { "0", "x", "99", "10", "20", "234324" }; 66 | var more = (from o in db.Table() where moreq.Contains(o.Name) select o).ToList(); 67 | Assert.AreEqual(2, more.Count); 68 | } 69 | 70 | [Test] 71 | public void ContainsQueriedData() 72 | { 73 | int n = 20; 74 | var cq =from i in Enumerable.Range(1, n) 75 | select new TestObj() { 76 | Name = i.ToString() 77 | }; 78 | 79 | var db = new TestDb(TestPath.GetTempFileName()); 80 | 81 | db.InsertAll(cq); 82 | 83 | db.Trace = true; 84 | 85 | var tensq = new string[] { "0", "10", "20" }; 86 | var tens = (from o in db.Table() where tensq.Contains(o.Name) select o).ToList(); 87 | Assert.AreEqual(2, tens.Count); 88 | 89 | var moreq = new string[] { "0", "x", "99", "10", "20", "234324" }; 90 | var more = (from o in db.Table() where moreq.Contains(o.Name) select o).ToList(); 91 | Assert.AreEqual(2, more.Count); 92 | 93 | // https://github.com/praeclarum/sqlite-net/issues/28 94 | var moreq2 = moreq.ToList (); 95 | var more2 = (from o in db.Table() where moreq2.Contains(o.Name) select o).ToList(); 96 | Assert.AreEqual(2, more2.Count); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/CreateTableImplicitTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | 6 | #if NETFX_CORE 7 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 8 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 9 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 10 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 11 | #else 12 | using NUnit.Framework; 13 | #endif 14 | 15 | namespace SQLite.Tests 16 | { 17 | [TestFixture] 18 | public class CreateTableImplicitTest 19 | { 20 | 21 | class NoAttributes 22 | { 23 | public int Id { get; set; } 24 | public string AColumn { get; set; } 25 | public int IndexedId { get; set; } 26 | } 27 | 28 | class NoAttributesNoOptions 29 | { 30 | public int Id { get; set; } 31 | public string AColumn { get; set; } 32 | public int IndexedId { get; set; } 33 | } 34 | 35 | class PkAttribute 36 | { 37 | [PrimaryKey] 38 | public int Id { get; set; } 39 | public string AColumn { get; set; } 40 | public int IndexedId { get; set; } 41 | } 42 | 43 | private void CheckPK(TestDb db) 44 | { 45 | for (int i = 1; i <= 10; i++) 46 | { 47 | var na = new NoAttributes { Id = i, AColumn = i.ToString(), IndexedId = 0 }; 48 | db.Insert(na); 49 | } 50 | var item = db.Get(2); 51 | Assert.IsNotNull(item); 52 | Assert.AreEqual(2, item.Id); 53 | } 54 | 55 | [Test] 56 | public void WithoutImplicitMapping () 57 | { 58 | var db = new TestDb (); 59 | 60 | db.CreateTable(); 61 | 62 | var mapping = db.GetMapping (); 63 | 64 | Assert.IsNull (mapping.PK, "Should not be a key"); 65 | 66 | var column = mapping.Columns[2]; 67 | Assert.AreEqual("IndexedId", column.Name); 68 | Assert.IsFalse(column.Indices.Any()); 69 | } 70 | 71 | [Test] 72 | public void ImplicitPK() 73 | { 74 | var db = new TestDb(); 75 | 76 | db.CreateTable(CreateFlags.ImplicitPK); 77 | 78 | var mapping = db.GetMapping(); 79 | 80 | Assert.IsNotNull(mapping.PK); 81 | Assert.AreEqual("Id", mapping.PK.Name); 82 | Assert.IsTrue(mapping.PK.IsPK); 83 | Assert.IsFalse(mapping.PK.IsAutoInc); 84 | 85 | CheckPK(db); 86 | } 87 | 88 | 89 | [Test] 90 | public void ImplicitAutoInc() 91 | { 92 | var db = new TestDb(); 93 | 94 | db.CreateTable(CreateFlags.AutoIncPK); 95 | 96 | var mapping = db.GetMapping(); 97 | 98 | Assert.IsNotNull(mapping.PK); 99 | Assert.AreEqual("Id", mapping.PK.Name); 100 | Assert.IsTrue(mapping.PK.IsPK); 101 | Assert.IsTrue(mapping.PK.IsAutoInc); 102 | } 103 | 104 | [Test] 105 | public void ImplicitIndex() 106 | { 107 | var db = new TestDb(); 108 | 109 | db.CreateTable(CreateFlags.ImplicitIndex); 110 | 111 | var mapping = db.GetMapping(); 112 | var column = mapping.Columns[2]; 113 | Assert.AreEqual("IndexedId", column.Name); 114 | Assert.IsTrue(column.Indices.Any()); 115 | } 116 | 117 | [Test] 118 | public void ImplicitPKAutoInc() 119 | { 120 | var db = new TestDb(); 121 | 122 | db.CreateTable(typeof(NoAttributes), CreateFlags.ImplicitPK | CreateFlags.AutoIncPK); 123 | 124 | var mapping = db.GetMapping(); 125 | 126 | Assert.IsNotNull(mapping.PK); 127 | Assert.AreEqual("Id", mapping.PK.Name); 128 | Assert.IsTrue(mapping.PK.IsPK); 129 | Assert.IsTrue(mapping.PK.IsAutoInc); 130 | } 131 | 132 | [Test] 133 | public void ImplicitAutoIncAsPassedInTypes() 134 | { 135 | var db = new TestDb(); 136 | 137 | db.CreateTable(typeof(PkAttribute), CreateFlags.AutoIncPK); 138 | 139 | var mapping = db.GetMapping(); 140 | 141 | Assert.IsNotNull(mapping.PK); 142 | Assert.AreEqual("Id", mapping.PK.Name); 143 | Assert.IsTrue(mapping.PK.IsPK); 144 | Assert.IsTrue(mapping.PK.IsAutoInc); 145 | } 146 | 147 | [Test] 148 | public void ImplicitPkAsPassedInTypes() 149 | { 150 | var db = new TestDb(); 151 | 152 | db.CreateTable(typeof(NoAttributes), CreateFlags.ImplicitPK); 153 | 154 | var mapping = db.GetMapping(); 155 | 156 | Assert.IsNotNull(mapping.PK); 157 | Assert.AreEqual("Id", mapping.PK.Name); 158 | Assert.IsTrue(mapping.PK.IsPK); 159 | Assert.IsFalse(mapping.PK.IsAutoInc); 160 | } 161 | 162 | [Test] 163 | public void ImplicitPKAutoIncAsPassedInTypes() 164 | { 165 | var db = new TestDb(); 166 | 167 | db.CreateTable(typeof(NoAttributes), CreateFlags.ImplicitPK | CreateFlags.AutoIncPK); 168 | 169 | var mapping = db.GetMapping(); 170 | 171 | Assert.IsNotNull(mapping.PK); 172 | Assert.AreEqual("Id", mapping.PK.Name); 173 | Assert.IsTrue(mapping.PK.IsPK); 174 | Assert.IsTrue(mapping.PK.IsAutoInc); 175 | } 176 | } 177 | } 178 | 179 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/CreateTableTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class CreateTableTest 18 | { 19 | class NoPropObject 20 | { 21 | } 22 | 23 | [Test] 24 | public void CreateTypeWithNoProps () 25 | { 26 | var db = new TestDb (); 27 | Assert.Throws (() => db.CreateTable ()); 28 | } 29 | 30 | [Test] 31 | public void CreateThem () 32 | { 33 | var db = new TestDb (); 34 | 35 | db.CreateTable (); 36 | db.CreateTable (); 37 | db.CreateTable (); 38 | db.CreateTable (); 39 | 40 | VerifyCreations(db); 41 | } 42 | 43 | [Test] 44 | public void CreateAsPassedInTypes () 45 | { 46 | var db = new TestDb(); 47 | 48 | db.CreateTable(typeof(Product)); 49 | db.CreateTable(typeof(Order)); 50 | db.CreateTable(typeof(OrderLine)); 51 | db.CreateTable(typeof(OrderHistory)); 52 | 53 | VerifyCreations(db); 54 | } 55 | 56 | [Test] 57 | public void CreateTwice () 58 | { 59 | var db = new TestDb (); 60 | 61 | db.CreateTable (); 62 | db.CreateTable (); 63 | db.CreateTable (); 64 | db.CreateTable (); 65 | db.CreateTable (); 66 | 67 | VerifyCreations(db); 68 | } 69 | 70 | private static void VerifyCreations(TestDb db) 71 | { 72 | var orderLine = db.GetMapping(typeof(OrderLine)); 73 | Assert.AreEqual(6, orderLine.Columns.Length); 74 | 75 | var l = new OrderLine() 76 | { 77 | Status = OrderLineStatus.Shipped 78 | }; 79 | db.Insert(l); 80 | var lo = db.Table().First(x => x.Status == OrderLineStatus.Shipped); 81 | Assert.AreEqual(lo.Id, l.Id); 82 | } 83 | 84 | class Issue115_MyObject 85 | { 86 | [PrimaryKey] 87 | public string UniqueId { get; set; } 88 | public byte OtherValue { get; set; } 89 | } 90 | 91 | [Test] 92 | public void Issue115_MissingPrimaryKey () 93 | { 94 | using (var conn = new TestDb ()) { 95 | 96 | conn.CreateTable (); 97 | conn.InsertAll (from i in Enumerable.Range (0, 10) select new Issue115_MyObject { 98 | UniqueId = i.ToString (), 99 | OtherValue = (byte)(i * 10), 100 | }); 101 | 102 | var query = conn.Table (); 103 | foreach (var itm in query) { 104 | itm.OtherValue++; 105 | Assert.AreEqual (1, conn.Update (itm, typeof(Issue115_MyObject))); 106 | } 107 | } 108 | } 109 | 110 | [Table("WantsNoRowId", WithoutRowId = true)] 111 | class WantsNoRowId 112 | { 113 | [PrimaryKey] 114 | public int Id { get; set; } 115 | public string Name { get; set; } 116 | } 117 | 118 | [Table("sqlite_master")] 119 | class SqliteMaster 120 | { 121 | [Column ("type")] 122 | public string Type { get; set; } 123 | 124 | [Column ("name")] 125 | public string Name { get; set; } 126 | 127 | [Column ("tbl_name")] 128 | public string TableName { get; set; } 129 | 130 | [Column ("rootpage")] 131 | public int RootPage { get; set; } 132 | 133 | [Column ("sql")] 134 | public string Sql { get; set; } 135 | } 136 | 137 | [Test] 138 | public void WithoutRowId () 139 | { 140 | using(var conn = new TestDb ()) 141 | { 142 | conn.CreateTable (); 143 | var info = conn.Table().Where(m => m.TableName=="OrderLine").First (); 144 | Assert.That (!info.Sql.Contains ("without rowid")); 145 | 146 | conn.CreateTable (); 147 | info = conn.Table().Where(m => m.TableName=="WantsNoRowId").First (); 148 | Assert.That (info.Sql.Contains ("without rowid")); 149 | } 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/DateTimeOffsetTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | #if NETFX_CORE 4 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 5 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 6 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 7 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 8 | #else 9 | using NUnit.Framework; 10 | #endif 11 | 12 | namespace SQLite.Tests 13 | { 14 | [TestFixture] 15 | public class DateTimeOffsetTest 16 | { 17 | class TestObj 18 | { 19 | [PrimaryKey, AutoIncrement] 20 | public int Id { get; set; } 21 | 22 | public string Name { get; set; } 23 | public DateTimeOffset ModifiedTime { get; set; } 24 | } 25 | 26 | 27 | [Test] 28 | public void AsTicks () 29 | { 30 | var db = new TestDb (); 31 | TestDateTimeOffset (db); 32 | } 33 | 34 | 35 | [Test] 36 | public void AsyncAsTicks () 37 | { 38 | var db = new SQLiteAsyncConnection (TestPath.GetTempFileName ()); 39 | TestAsyncDateTimeOffset (db); 40 | } 41 | 42 | void TestAsyncDateTimeOffset (SQLiteAsyncConnection db) 43 | { 44 | db.CreateTableAsync ().Wait (); 45 | 46 | TestObj o, o2; 47 | 48 | // 49 | // Ticks 50 | // 51 | o = new TestObj { 52 | ModifiedTime = new DateTimeOffset (2012, 1, 14, 3, 2, 1, TimeSpan.Zero), 53 | }; 54 | db.InsertAsync (o).Wait (); 55 | o2 = db.GetAsync (o.Id).Result; 56 | Assert.AreEqual (o.ModifiedTime, o2.ModifiedTime); 57 | } 58 | 59 | void TestDateTimeOffset (TestDb db) 60 | { 61 | db.CreateTable (); 62 | 63 | TestObj o, o2; 64 | 65 | // 66 | // Ticks 67 | // 68 | o = new TestObj { 69 | ModifiedTime = new DateTimeOffset (2012, 1, 14, 3, 2, 1, TimeSpan.Zero), 70 | }; 71 | db.Insert (o); 72 | o2 = db.Get (o.Id); 73 | Assert.AreEqual (o.ModifiedTime, o2.ModifiedTime); 74 | } 75 | 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/DateTimeTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | namespace SQLite.Tests 14 | { 15 | [TestFixture] 16 | public class DateTimeTest 17 | { 18 | const string DefaultSQLiteDateTimeString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff"; 19 | 20 | class TestObj 21 | { 22 | [PrimaryKey, AutoIncrement] 23 | public int Id { get; set; } 24 | 25 | public string Name { get; set; } 26 | public DateTime ModifiedTime { get; set; } 27 | } 28 | 29 | 30 | [Test] 31 | public void AsTicks () 32 | { 33 | var dateTime = new DateTime (2012, 1, 14, 3, 2, 1, 234); 34 | var db = new TestDb (storeDateTimeAsTicks: true); 35 | TestDateTime (db, dateTime, dateTime.Ticks.ToString ()); 36 | } 37 | 38 | [Test] 39 | public void AsStrings () 40 | { 41 | var dateTime = new DateTime (2012, 1, 14, 3, 2, 1, 234); 42 | var db = new TestDb (storeDateTimeAsTicks: false); 43 | TestDateTime (db, dateTime, dateTime.ToString (DefaultSQLiteDateTimeString)); 44 | } 45 | 46 | [TestCase ("o")] 47 | [TestCase ("MMM'-'dd'-'yyyy' 'HH':'mm':'ss'.'fffffff")] 48 | public void AsCustomStrings (string format) 49 | { 50 | var dateTime = new DateTime (2012, 1, 14, 3, 2, 1, 234); 51 | var db = new TestDb (CustomDateTimeString (format)); 52 | TestDateTime (db, dateTime, dateTime.ToString (format, System.Globalization.CultureInfo.InvariantCulture)); 53 | } 54 | 55 | [Test] 56 | public void AsyncAsTicks () 57 | { 58 | var dateTime = new DateTime (2012, 1, 14, 3, 2, 1, 234); 59 | var db = new SQLiteAsyncConnection (TestPath.GetTempFileName (), true); 60 | TestAsyncDateTime (db, dateTime, dateTime.Ticks.ToString ()); 61 | } 62 | 63 | [Test] 64 | public void AsyncAsString () 65 | { 66 | var dateTime = new DateTime (2012, 1, 14, 3, 2, 1, 234); 67 | var db = new SQLiteAsyncConnection (TestPath.GetTempFileName (), false); 68 | TestAsyncDateTime (db, dateTime, dateTime.ToString (DefaultSQLiteDateTimeString)); 69 | } 70 | 71 | [TestCase ("o")] 72 | [TestCase ("MMM'-'dd'-'yyyy' 'HH':'mm':'ss'.'fffffff")] 73 | public void AsyncAsCustomStrings (string format) 74 | { 75 | var dateTime = new DateTime (2012, 1, 14, 3, 2, 1, 234); 76 | var db = new SQLiteAsyncConnection (CustomDateTimeString (format)); 77 | TestAsyncDateTime (db, dateTime, dateTime.ToString (format,System.Globalization.CultureInfo.InvariantCulture)); 78 | } 79 | 80 | SQLiteConnectionString CustomDateTimeString (string dateTimeFormat) => new SQLiteConnectionString (TestPath.GetTempFileName (), SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite, false, dateTimeStringFormat: dateTimeFormat); 81 | 82 | void TestAsyncDateTime (SQLiteAsyncConnection db, DateTime dateTime, string expected) 83 | { 84 | db.CreateTableAsync ().Wait (); 85 | 86 | TestObj o, o2; 87 | 88 | // 89 | // Ticks 90 | // 91 | o = new TestObj { 92 | ModifiedTime = dateTime, 93 | }; 94 | db.InsertAsync (o).Wait (); 95 | o2 = db.GetAsync (o.Id).Result; 96 | Assert.AreEqual (o.ModifiedTime, o2.ModifiedTime); 97 | 98 | var stored = db.ExecuteScalarAsync ("SELECT ModifiedTime FROM TestObj;").Result; 99 | Assert.AreEqual (expected, stored); 100 | } 101 | 102 | void TestDateTime (TestDb db, DateTime dateTime, string expected) 103 | { 104 | db.CreateTable (); 105 | 106 | TestObj o, o2; 107 | 108 | // 109 | // Ticks 110 | // 111 | o = new TestObj { 112 | ModifiedTime = dateTime, 113 | }; 114 | db.Insert (o); 115 | o2 = db.Get (o.Id); 116 | Assert.AreEqual (o.ModifiedTime, o2.ModifiedTime); 117 | 118 | var stored = db.ExecuteScalar ("SELECT ModifiedTime FROM TestObj;"); 119 | Assert.AreEqual (expected, stored); 120 | } 121 | 122 | class NullableDateObj 123 | { 124 | public DateTime? Time { get; set; } 125 | } 126 | 127 | [Test] 128 | public async Task LinqNullable () 129 | { 130 | foreach (var option in new[] { true, false }) { 131 | var db = new SQLiteAsyncConnection (TestPath.GetTempFileName (), option); 132 | await db.CreateTableAsync ().ConfigureAwait (false); 133 | 134 | var epochTime = new DateTime (1970, 1, 1); 135 | 136 | await db.InsertAsync (new NullableDateObj { Time = epochTime }); 137 | await db.InsertAsync (new NullableDateObj { Time = new DateTime (1980, 7, 23) }); 138 | await db.InsertAsync (new NullableDateObj { Time = null }); 139 | await db.InsertAsync (new NullableDateObj { Time = new DateTime (2019, 1, 23) }); 140 | 141 | var res = await db.Table ().Where (x => x.Time == epochTime).ToListAsync (); 142 | Assert.AreEqual (1, res.Count); 143 | 144 | res = await db.Table ().Where (x => x.Time > epochTime).ToListAsync (); 145 | Assert.AreEqual (2, res.Count); 146 | } 147 | } 148 | } 149 | } 150 | 151 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/DbCommandTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text; 3 | using SQLite; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class DbCommandTest 20 | { 21 | [Test] 22 | public void QueryCommand() 23 | { 24 | var db = new SQLiteConnection (Path.GetTempFileName(), true); 25 | db.CreateTable(); 26 | var b = new Product(); 27 | db.Insert(b); 28 | 29 | var test = db.CreateCommand("select * from Product") 30 | .ExecuteDeferredQuery(new TableMapping(typeof(Product))).ToList(); 31 | 32 | 33 | Assert.AreEqual (test.Count, 1); 34 | } 35 | 36 | #region Issue #1048 37 | 38 | [Test] 39 | public void QueryCommandCastToObject() 40 | { 41 | var db = new SQLiteConnection (Path.GetTempFileName(), true); 42 | db.CreateTable(); 43 | var b = new Product(); 44 | db.Insert(b); 45 | 46 | var test = db.CreateCommand("select * from Product") 47 | .ExecuteDeferredQuery(new TableMapping(typeof(Product))).ToList(); 48 | 49 | 50 | Assert.AreEqual (test.Count, 1); 51 | } 52 | 53 | #endregion 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/DeleteTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class DeleteTest 18 | { 19 | class TestTable 20 | { 21 | [PrimaryKey, AutoIncrement] 22 | public int Id { get; set; } 23 | public int Datum { get; set; } 24 | public string Test { get; set;} 25 | } 26 | 27 | const int Count = 100; 28 | 29 | SQLiteConnection CreateDb () 30 | { 31 | var db = new TestDb (); 32 | db.CreateTable (); 33 | var items = from i in Enumerable.Range (0, Count) 34 | select new TestTable { Datum = 1000+i, Test = "Hello World" }; 35 | db.InsertAll (items); 36 | Assert.AreEqual (Count, db.Table ().Count ()); 37 | return db; 38 | } 39 | 40 | async Task CreateDbAsync () 41 | { 42 | var db = new SQLiteAsyncConnection (new SQLiteConnectionString (TestPath.GetTempFileName ())); 43 | await db.CreateTableAsync (); 44 | var items = from i in Enumerable.Range (0, Count) 45 | select new TestTable { Datum = 1000+i, Test = "Hello World" }; 46 | await db.InsertAllAsync (items); 47 | Assert.AreEqual (Count, await db.Table ().CountAsync ()); 48 | return db; 49 | } 50 | 51 | [Test] 52 | public void DeleteEntityOne () 53 | { 54 | var db = CreateDb (); 55 | 56 | var r = db.Delete (db.Get (1)); 57 | 58 | Assert.AreEqual (1, r); 59 | Assert.AreEqual (Count - 1, db.Table ().Count ()); 60 | } 61 | 62 | [Test] 63 | public async Task DeleteEntityOneAsync () 64 | { 65 | var db = await CreateDbAsync (); 66 | 67 | var r = await db.DeleteAsync (await db.GetAsync (1)); 68 | 69 | Assert.AreEqual (1, r); 70 | Assert.AreEqual (Count - 1, await db.Table ().CountAsync ()); 71 | } 72 | 73 | [Test] 74 | public void DeletePKOne () 75 | { 76 | var db = CreateDb (); 77 | 78 | var r = db.Delete (1); 79 | 80 | Assert.AreEqual (1, r); 81 | Assert.AreEqual (Count - 1, db.Table ().Count ()); 82 | } 83 | 84 | [Test] 85 | public void DeletePKNone () 86 | { 87 | var db = CreateDb (); 88 | 89 | var r = db.Delete (348597); 90 | 91 | Assert.AreEqual (0, r); 92 | Assert.AreEqual (Count, db.Table ().Count ()); 93 | } 94 | 95 | [Test] 96 | public void DeleteAll () 97 | { 98 | var db = CreateDb (); 99 | 100 | var r = db.DeleteAll (); 101 | 102 | Assert.AreEqual (Count, r); 103 | Assert.AreEqual (0, db.Table ().Count ()); 104 | } 105 | 106 | [Test] 107 | public void DeleteWithPredicate() 108 | { 109 | var db = CreateDb(); 110 | 111 | var r = db.Table().Delete (p => p.Test == "Hello World"); 112 | 113 | Assert.AreEqual (Count, r); 114 | Assert.AreEqual (0, db.Table ().Count ()); 115 | } 116 | 117 | [Test] 118 | public void DeleteWithPredicateHalf() 119 | { 120 | var db = CreateDb(); 121 | db.Insert(new TestTable() { Datum = 1, Test = "Hello World 2" }); 122 | 123 | var r = db.Table().Delete (p => p.Test == "Hello World"); 124 | 125 | Assert.AreEqual (Count, r); 126 | Assert.AreEqual (1, db.Table ().Count ()); 127 | } 128 | 129 | [Test] 130 | public void DeleteWithWherePredicate () 131 | { 132 | var db = CreateDb (); 133 | 134 | var r = db.Table ().Where (p => p.Test == "Hello World").Delete (); 135 | 136 | Assert.AreEqual (Count, r); 137 | Assert.AreEqual (0, db.Table ().Count ()); 138 | } 139 | 140 | [Test] 141 | public void DeleteWithoutPredicate () 142 | { 143 | var db = CreateDb (); 144 | 145 | try { 146 | var r = db.Table ().Delete (); 147 | Assert.Fail (); 148 | } 149 | catch (InvalidOperationException) { 150 | } 151 | } 152 | 153 | [Test] 154 | public void DeleteWithTake () 155 | { 156 | var db = CreateDb (); 157 | 158 | try { 159 | var r = db.Table ().Where (p => p.Test == "Hello World").Take (2).Delete (); 160 | Assert.Fail (); 161 | } 162 | catch (InvalidOperationException) { 163 | } 164 | } 165 | 166 | [Test] 167 | public void DeleteWithSkip () 168 | { 169 | var db = CreateDb (); 170 | 171 | try { 172 | var r = db.Table ().Where (p => p.Test == "Hello World").Skip (2).Delete (); 173 | Assert.Fail (); 174 | } 175 | catch (InvalidOperationException) { 176 | } 177 | } 178 | } 179 | } 180 | 181 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/DropTableTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.IO; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using SQLite; 8 | using System.Threading.Tasks; 9 | 10 | #if NETFX_CORE 11 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 12 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 13 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 14 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 15 | #else 16 | using NUnit.Framework; 17 | #endif 18 | 19 | 20 | namespace SQLite.Tests 21 | { 22 | [TestFixture] 23 | public class DropTableTest 24 | { 25 | public class Product 26 | { 27 | [AutoIncrement, PrimaryKey] 28 | public int Id { get; set; } 29 | public string Name { get; set; } 30 | public decimal Price { get; set; } 31 | } 32 | 33 | public class TestDb : SQLiteConnection 34 | { 35 | public TestDb () : base(TestPath.GetTempFileName ()) 36 | { 37 | Trace = true; 38 | } 39 | } 40 | 41 | public class TestDbAsync : SQLiteAsyncConnection 42 | { 43 | public TestDbAsync () : base(TestPath.GetTempFileName ()) 44 | { 45 | Trace = true; 46 | } 47 | } 48 | 49 | [Test] 50 | public void CreateInsertDrop () 51 | { 52 | var db = new TestDb (); 53 | 54 | db.CreateTable (); 55 | 56 | db.Insert (new Product { 57 | Name = "Hello", 58 | Price = 16, 59 | }); 60 | 61 | var n = db.Table ().Count (); 62 | 63 | Assert.AreEqual (1, n); 64 | 65 | db.DropTable (); 66 | 67 | ExceptionAssert.Throws(() => db.Table ().Count ()); 68 | } 69 | 70 | [Test] 71 | public async Task CreateInsertDropAsync () 72 | { 73 | var db = new TestDbAsync (); 74 | 75 | await db.CreateTableAsync (); 76 | 77 | await db.InsertAsync (new Product { 78 | Name = "Hello", 79 | Price = 16, 80 | }); 81 | 82 | var n = await db.Table ().CountAsync (); 83 | 84 | Assert.AreEqual (1, n); 85 | 86 | await db.DropTableAsync (); 87 | 88 | try { 89 | await db.Table ().CountAsync (); 90 | Assert.Fail ("Should have thrown"); 91 | } catch (SQLiteException) { 92 | // Expected 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/EnumCacheTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class EnumCacheTests 20 | { 21 | [StoreAsText] 22 | public enum TestEnumStoreAsText 23 | { 24 | Value1, 25 | 26 | Value2, 27 | 28 | Value3 29 | } 30 | 31 | public enum TestEnumStoreAsInt 32 | { 33 | Value1, 34 | 35 | Value2, 36 | 37 | Value3 38 | } 39 | 40 | public enum TestByteEnumStoreAsInt : byte 41 | { 42 | Value1, 43 | 44 | Value2, 45 | 46 | Value3 47 | } 48 | 49 | public enum TestEnumWithRepeats 50 | { 51 | Value1 = 1, 52 | 53 | Value2 = 2, 54 | 55 | Value2Again = 2, 56 | 57 | Value3 = 3, 58 | } 59 | 60 | [StoreAsText] 61 | public enum TestEnumWithRepeatsAsText 62 | { 63 | Value1 = 1, 64 | 65 | Value2 = 2, 66 | 67 | Value2Again = 2, 68 | 69 | Value3 = 3, 70 | } 71 | 72 | public class TestClassThusNotEnum 73 | { 74 | 75 | } 76 | 77 | [Test] 78 | public void ShouldReturnTrueForEnumStoreAsText() 79 | { 80 | var info = EnumCache.GetInfo(); 81 | 82 | Assert.IsTrue(info.IsEnum); 83 | Assert.IsTrue(info.StoreAsText); 84 | Assert.IsNotNull(info.EnumValues); 85 | 86 | var values = Enum.GetValues(typeof(TestEnumStoreAsText)).Cast().ToList(); 87 | 88 | for (int i = 0; i < values.Count; i++) 89 | { 90 | Assert.AreEqual(values[i].ToString(), info.EnumValues[i]); 91 | } 92 | } 93 | 94 | [Test] 95 | public void ShouldReturnTrueForEnumStoreAsInt() 96 | { 97 | var info = EnumCache.GetInfo(); 98 | 99 | Assert.IsTrue(info.IsEnum); 100 | Assert.IsFalse(info.StoreAsText); 101 | Assert.IsNull(info.EnumValues); 102 | } 103 | 104 | [Test] 105 | public void ShouldReturnTrueForByteEnumStoreAsInt() 106 | { 107 | var info = EnumCache.GetInfo(); 108 | 109 | Assert.IsTrue(info.IsEnum); 110 | Assert.IsFalse(info.StoreAsText); 111 | } 112 | 113 | [Test] 114 | public void ShouldReturnFalseForClass() 115 | { 116 | var info = EnumCache.GetInfo(); 117 | 118 | Assert.IsFalse(info.IsEnum); 119 | Assert.IsFalse(info.StoreAsText); 120 | Assert.IsNull(info.EnumValues); 121 | } 122 | 123 | [Test] 124 | public void Issue598_EnumsWithRepeatedValues () 125 | { 126 | var info = EnumCache.GetInfo (); 127 | 128 | Assert.IsTrue (info.IsEnum); 129 | Assert.IsFalse (info.StoreAsText); 130 | Assert.IsNull (info.EnumValues); 131 | } 132 | 133 | [Test] 134 | public void Issue598_EnumsWithRepeatedValuesAsText () 135 | { 136 | var info = EnumCache.GetInfo (); 137 | 138 | Assert.IsTrue (info.IsEnum); 139 | Assert.IsTrue (info.StoreAsText); 140 | Assert.IsNotNull (info.EnumValues); 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/EnumNullableTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class EnumNullableTests 20 | { 21 | public enum TestEnum 22 | { 23 | Value1, 24 | 25 | Value2, 26 | 27 | Value3 28 | } 29 | 30 | public class TestObj 31 | { 32 | [PrimaryKey] 33 | public int Id { get; set; } 34 | public TestEnum? Value { get; set; } 35 | 36 | public override string ToString() 37 | { 38 | return string.Format("[TestObj: Id={0}, Value={1}]", Id, Value); 39 | } 40 | 41 | } 42 | 43 | public class TestDb : SQLiteConnection 44 | { 45 | public TestDb(String path) 46 | : base(path) 47 | { 48 | CreateTable(); 49 | } 50 | } 51 | 52 | [Test] 53 | public void ShouldPersistAndReadEnum() 54 | { 55 | var db = new TestDb(TestPath.GetTempFileName()); 56 | 57 | var obj1 = new TestObj() { Id = 1, Value = TestEnum.Value2 }; 58 | var obj2 = new TestObj() { Id = 2, Value = TestEnum.Value3 }; 59 | 60 | var numIn1 = db.Insert(obj1); 61 | var numIn2 = db.Insert(obj2); 62 | Assert.AreEqual(1, numIn1); 63 | Assert.AreEqual(1, numIn2); 64 | 65 | var result = db.Query("select * from TestObj").ToList(); 66 | Assert.AreEqual(2, result.Count); 67 | Assert.AreEqual(obj1.Value, result[0].Value); 68 | Assert.AreEqual(obj2.Value, result[1].Value); 69 | 70 | Assert.AreEqual(obj1.Id, result[0].Id); 71 | Assert.AreEqual(obj2.Id, result[1].Id); 72 | 73 | db.Close(); 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /tests/SQLite.Tests/EnumTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class EnumTests 20 | { 21 | public enum TestEnum 22 | { 23 | Value1, 24 | 25 | Value2, 26 | 27 | Value3 28 | } 29 | 30 | [StoreAsText] 31 | public enum StringTestEnum 32 | { 33 | Value1, 34 | 35 | Value2, 36 | 37 | Value3 38 | } 39 | 40 | public class TestObj 41 | { 42 | [PrimaryKey] 43 | public int Id { get; set; } 44 | public TestEnum Value { get; set; } 45 | 46 | public override string ToString() 47 | { 48 | return string.Format("[TestObj: Id={0}, Value={1}]", Id, Value); 49 | } 50 | 51 | } 52 | 53 | public class StringTestObj 54 | { 55 | [PrimaryKey] 56 | public int Id { get; set; } 57 | public StringTestEnum Value { get; set; } 58 | 59 | public override string ToString () 60 | { 61 | return string.Format("[StringTestObj: Id={0}, Value={1}]", Id, Value); 62 | } 63 | 64 | } 65 | 66 | public class TestDb : SQLiteConnection 67 | { 68 | public TestDb(String path) 69 | : base(path) 70 | { 71 | CreateTable(); 72 | CreateTable(); 73 | CreateTable (); 74 | } 75 | } 76 | 77 | [Test] 78 | public void ShouldPersistAndReadEnum() 79 | { 80 | var db = new TestDb(TestPath.GetTempFileName()); 81 | 82 | var obj1 = new TestObj() { Id = 1, Value = TestEnum.Value2 }; 83 | var obj2 = new TestObj() { Id = 2, Value = TestEnum.Value3 }; 84 | 85 | var numIn1 = db.Insert(obj1); 86 | var numIn2 = db.Insert(obj2); 87 | Assert.AreEqual(1, numIn1); 88 | Assert.AreEqual(1, numIn2); 89 | 90 | var result = db.Query("select * from TestObj").ToList(); 91 | Assert.AreEqual(2, result.Count); 92 | Assert.AreEqual(obj1.Value, result[0].Value); 93 | Assert.AreEqual(obj2.Value, result[1].Value); 94 | 95 | Assert.AreEqual(obj1.Id, result[0].Id); 96 | Assert.AreEqual(obj2.Id, result[1].Id); 97 | 98 | db.Close(); 99 | } 100 | 101 | [Test] 102 | public void ShouldPersistAndReadStringEnum () 103 | { 104 | var db = new TestDb(TestPath.GetTempFileName()); 105 | 106 | var obj1 = new StringTestObj() { Id = 1, Value = StringTestEnum.Value2 }; 107 | var obj2 = new StringTestObj() { Id = 2, Value = StringTestEnum.Value3 }; 108 | 109 | var numIn1 = db.Insert(obj1); 110 | var numIn2 = db.Insert(obj2); 111 | Assert.AreEqual(1, numIn1); 112 | Assert.AreEqual(1, numIn2); 113 | 114 | var result = db.Query("select * from StringTestObj").ToList(); 115 | Assert.AreEqual(2, result.Count); 116 | Assert.AreEqual(obj1.Value, result[0].Value); 117 | Assert.AreEqual(obj2.Value, result[1].Value); 118 | 119 | Assert.AreEqual(obj1.Id, result[0].Id); 120 | Assert.AreEqual(obj2.Id, result[1].Id); 121 | 122 | db.Close(); 123 | } 124 | 125 | public enum ByteTestEnum : byte 126 | { 127 | Value1 = 1, 128 | 129 | Value2 = 2, 130 | 131 | Value3 = 3 132 | } 133 | 134 | public class ByteTestObj 135 | { 136 | [PrimaryKey] 137 | public int Id { get; set; } 138 | public ByteTestEnum Value { get; set; } 139 | 140 | public override string ToString () 141 | { 142 | return string.Format ("[ByteTestObj: Id={0}, Value={1}]", Id, Value); 143 | } 144 | } 145 | 146 | [Test] 147 | public void Issue33_ShouldPersistAndReadByteEnum () 148 | { 149 | var db = new TestDb (TestPath.GetTempFileName ()); 150 | 151 | var obj1 = new ByteTestObj () { Id = 1, Value = ByteTestEnum.Value2 }; 152 | var obj2 = new ByteTestObj () { Id = 2, Value = ByteTestEnum.Value3 }; 153 | 154 | var numIn1 = db.Insert (obj1); 155 | var numIn2 = db.Insert (obj2); 156 | Assert.AreEqual (1, numIn1); 157 | Assert.AreEqual (1, numIn2); 158 | 159 | var result = db.Query ("select * from ByteTestObj order by Id").ToList (); 160 | Assert.AreEqual (2, result.Count); 161 | Assert.AreEqual (obj1.Value, result[0].Value); 162 | Assert.AreEqual (obj2.Value, result[1].Value); 163 | 164 | Assert.AreEqual (obj1.Id, result[0].Id); 165 | Assert.AreEqual (obj2.Id, result[1].Id); 166 | 167 | db.Close (); 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/EqualsTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | #if NETFX_CORE 4 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 5 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 6 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 7 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 8 | #else 9 | using NUnit.Framework; 10 | #endif 11 | 12 | namespace SQLite.Tests 13 | { 14 | [TestFixture] 15 | class EqualsTest 16 | { 17 | public abstract class TestObjBase 18 | { 19 | [AutoIncrement, PrimaryKey] 20 | public int Id { get; set; } 21 | 22 | public T Data { get; set; } 23 | 24 | public DateTime Date { get; set; } 25 | } 26 | 27 | public class TestObjString : TestObjBase { } 28 | 29 | public class TestDb : SQLiteConnection 30 | { 31 | public TestDb(String path) 32 | : base(path) 33 | { 34 | CreateTable(); 35 | } 36 | } 37 | 38 | [Test] 39 | public void CanCompareAnyField() 40 | { 41 | var n = 20; 42 | var cq =from i in Enumerable.Range(1, n) 43 | select new TestObjString { 44 | Data = Convert.ToString(i), 45 | Date = new DateTime(2013, 1, i) 46 | }; 47 | 48 | var db = new TestDb(TestPath.GetTempFileName()); 49 | db.InsertAll(cq); 50 | 51 | var results = db.Table().Where(o => o.Data.Equals("10")); 52 | Assert.AreEqual(results.Count(), 1); 53 | Assert.AreEqual(results.FirstOrDefault().Data, "10"); 54 | 55 | results = db.Table().Where(o => o.Id.Equals(10)); 56 | Assert.AreEqual(results.Count(), 1); 57 | Assert.AreEqual(results.FirstOrDefault().Data, "10"); 58 | 59 | var date = new DateTime(2013, 1, 10); 60 | results = db.Table().Where(o => o.Date.Equals(date)); 61 | Assert.AreEqual(results.Count(), 1); 62 | Assert.AreEqual(results.FirstOrDefault().Data, "10"); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/ExceptionAssert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | namespace SQLite.Tests 14 | { 15 | public class ExceptionAssert 16 | { 17 | public static T Throws(Action action) where T : Exception 18 | { 19 | try 20 | { 21 | action(); 22 | } 23 | catch (T ex) 24 | { 25 | return ex; 26 | } 27 | 28 | Assert.Fail("Expected exception of type {0}.", typeof(T)); 29 | 30 | return null; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/GuidTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | 17 | namespace SQLite.Tests { 18 | [TestFixture] 19 | public class GuidTests { 20 | public class TestObj { 21 | [PrimaryKey] 22 | public Guid Id { get; set; } 23 | public String Text { get; set; } 24 | 25 | public override string ToString() { 26 | return string.Format("[TestObj: Id={0}, Text={1}]", Id, Text); 27 | } 28 | 29 | } 30 | 31 | public class TestDb : SQLiteConnection { 32 | public TestDb(String path) 33 | : base(path) { 34 | CreateTable(); 35 | } 36 | } 37 | 38 | [Test] 39 | public void ShouldPersistAndReadGuid() { 40 | var db = new TestDb(TestPath.GetTempFileName()); 41 | 42 | var obj1 = new TestObj() { Id=new Guid("36473164-C9E4-4CDF-B266-A0B287C85623"), Text = "First Guid Object" }; 43 | var obj2 = new TestObj() { Id=new Guid("BC5C4C4A-CA57-4B61-8B53-9FD4673528B6"), Text = "Second Guid Object" }; 44 | 45 | var numIn1 = db.Insert(obj1); 46 | var numIn2 = db.Insert(obj2); 47 | Assert.AreEqual(1, numIn1); 48 | Assert.AreEqual(1, numIn2); 49 | 50 | var result = db.Query("select * from TestObj").ToList(); 51 | Assert.AreEqual(2, result.Count); 52 | Assert.AreEqual(obj1.Text, result[0].Text); 53 | Assert.AreEqual(obj2.Text, result[1].Text); 54 | 55 | Assert.AreEqual(obj1.Id, result[0].Id); 56 | Assert.AreEqual(obj2.Id, result[1].Id); 57 | 58 | db.Close(); 59 | } 60 | 61 | [Test] 62 | public void AutoGuid_HasGuid() 63 | { 64 | var db = new SQLiteConnection(TestPath.GetTempFileName()); 65 | db.CreateTable(CreateFlags.AutoIncPK); 66 | 67 | var guid1 = new Guid("36473164-C9E4-4CDF-B266-A0B287C85623"); 68 | var guid2 = new Guid("BC5C4C4A-CA57-4B61-8B53-9FD4673528B6"); 69 | 70 | var obj1 = new TestObj() { Id = guid1, Text = "First Guid Object" }; 71 | var obj2 = new TestObj() { Id = guid2, Text = "Second Guid Object" }; 72 | 73 | var numIn1 = db.Insert(obj1); 74 | var numIn2 = db.Insert(obj2); 75 | Assert.AreEqual(guid1, obj1.Id); 76 | Assert.AreEqual(guid2, obj2.Id); 77 | 78 | db.Close(); 79 | } 80 | 81 | [Test] 82 | public void AutoGuid_EmptyGuid() 83 | { 84 | var db = new SQLiteConnection(TestPath.GetTempFileName()); 85 | db.CreateTable(CreateFlags.AutoIncPK); 86 | 87 | var guid1 = new Guid("36473164-C9E4-4CDF-B266-A0B287C85623"); 88 | var guid2 = new Guid("BC5C4C4A-CA57-4B61-8B53-9FD4673528B6"); 89 | 90 | var obj1 = new TestObj() { Text = "First Guid Object" }; 91 | var obj2 = new TestObj() { Text = "Second Guid Object" }; 92 | 93 | Assert.AreEqual(Guid.Empty, obj1.Id); 94 | Assert.AreEqual(Guid.Empty, obj2.Id); 95 | 96 | var numIn1 = db.Insert(obj1); 97 | var numIn2 = db.Insert(obj2); 98 | Assert.AreNotEqual(Guid.Empty, obj1.Id); 99 | Assert.AreNotEqual(Guid.Empty, obj2.Id); 100 | Assert.AreNotEqual(obj1.Id, obj2.Id); 101 | 102 | db.Close(); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/IgnoreTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using SQLite; 5 | 6 | #if NETFX_CORE 7 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 8 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 9 | using TearDown = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestCleanupAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class IgnoreTest 20 | { 21 | public class TestObj 22 | { 23 | [AutoIncrement, PrimaryKey] 24 | public int Id { get; set; } 25 | 26 | public string Text { get; set; } 27 | 28 | [SQLite.Ignore] 29 | public Dictionary Edibles 30 | { 31 | get { return this._edibles; } 32 | set { this._edibles = value; } 33 | } protected Dictionary _edibles = new Dictionary(); 34 | 35 | [SQLite.Ignore] 36 | public string IgnoredText { get; set; } 37 | 38 | public override string ToString () 39 | { 40 | return string.Format("[TestObj: Id={0}]", Id); 41 | } 42 | } 43 | 44 | [Test] 45 | public void MappingIgnoreColumn () 46 | { 47 | var db = new TestDb (); 48 | var m = db.GetMapping (); 49 | 50 | Assert.AreEqual (2, m.Columns.Length); 51 | } 52 | 53 | [Test] 54 | public void CreateTableSucceeds () 55 | { 56 | var db = new TestDb (); 57 | db.CreateTable (); 58 | } 59 | 60 | [Test] 61 | public void InsertSucceeds () 62 | { 63 | var db = new TestDb (); 64 | db.CreateTable (); 65 | 66 | var o = new TestObj { 67 | Text = "Hello", 68 | IgnoredText = "World", 69 | }; 70 | 71 | db.Insert (o); 72 | 73 | Assert.AreEqual (1, o.Id); 74 | } 75 | 76 | [Test] 77 | public void GetDoesntHaveIgnores () 78 | { 79 | var db = new TestDb (); 80 | db.CreateTable (); 81 | 82 | var o = new TestObj { 83 | Text = "Hello", 84 | IgnoredText = "World", 85 | }; 86 | 87 | db.Insert (o); 88 | 89 | var oo = db.Get (o.Id); 90 | 91 | Assert.AreEqual ("Hello", oo.Text); 92 | Assert.AreEqual (null, oo.IgnoredText); 93 | } 94 | 95 | public class BaseClass 96 | { 97 | [Ignore] 98 | public string ToIgnore { 99 | get; 100 | set; 101 | } 102 | } 103 | 104 | public class TableClass : BaseClass 105 | { 106 | public string Name { get; set; } 107 | } 108 | 109 | [Test] 110 | public void BaseIgnores () 111 | { 112 | var db = new TestDb (); 113 | db.CreateTable (); 114 | 115 | var o = new TableClass { 116 | ToIgnore = "Hello", 117 | Name = "World", 118 | }; 119 | 120 | db.Insert (o); 121 | 122 | var oo = db.Table ().First (); 123 | 124 | Assert.AreEqual (null, oo.ToIgnore); 125 | Assert.AreEqual ("World", oo.Name); 126 | } 127 | 128 | public class RedefinedBaseClass 129 | { 130 | public string Name { get; set; } 131 | public List Values { get; set; } 132 | } 133 | 134 | public class RedefinedClass : RedefinedBaseClass 135 | { 136 | [Ignore] 137 | public new List Values { get; set; } 138 | public string Value { get; set; } 139 | } 140 | 141 | [Test] 142 | public void RedefinedIgnores () 143 | { 144 | var db = new TestDb (); 145 | db.CreateTable (); 146 | 147 | var o = new RedefinedClass { 148 | Name = "Foo", 149 | Value = "Bar", 150 | Values = new List { "hello", "world" }, 151 | }; 152 | 153 | db.Insert (o); 154 | 155 | var oo = db.Table ().First (); 156 | 157 | Assert.AreEqual ("Foo", oo.Name); 158 | Assert.AreEqual ("Bar", oo.Value); 159 | Assert.AreEqual (null, oo.Values); 160 | } 161 | 162 | [AttributeUsage (AttributeTargets.Property, AllowMultiple = false, Inherited = true)] 163 | class DerivedIgnoreAttribute : IgnoreAttribute 164 | { 165 | } 166 | 167 | class DerivedIgnoreClass 168 | { 169 | [PrimaryKey, AutoIncrement] 170 | public int Id { get; set; } 171 | 172 | public string NotIgnored { get; set; } 173 | 174 | [DerivedIgnore] 175 | public string Ignored { get; set; } 176 | } 177 | 178 | [Test] 179 | public void DerivedIgnore () 180 | { 181 | var db = new TestDb (); 182 | db.CreateTable (); 183 | 184 | var o = new DerivedIgnoreClass { 185 | Ignored = "Hello", 186 | NotIgnored = "World", 187 | }; 188 | 189 | db.Insert (o); 190 | 191 | var oo = db.Table ().First (); 192 | 193 | Assert.AreEqual (null, oo.Ignored); 194 | Assert.AreEqual ("World", oo.NotIgnored); 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/InheritanceTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class InheritanceTest 18 | { 19 | class Base 20 | { 21 | [PrimaryKey] 22 | public int Id { get; set; } 23 | 24 | public string BaseProp { get; set; } 25 | } 26 | 27 | class Derived : Base 28 | { 29 | public string DerivedProp { get; set; } 30 | } 31 | 32 | 33 | [Test] 34 | public void InheritanceWorks () 35 | { 36 | var db = new TestDb (); 37 | 38 | var mapping = db.GetMapping (); 39 | 40 | Assert.AreEqual (3, mapping.Columns.Length); 41 | Assert.AreEqual ("Id", mapping.PK.Name); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/InsertTest.cs: -------------------------------------------------------------------------------- 1 | 2 | using System; 3 | using System.IO; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using SQLite; 8 | 9 | #if NETFX_CORE 10 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 11 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 12 | using TearDown = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestCleanupAttribute; 13 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 14 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 15 | #else 16 | using NUnit.Framework; 17 | #endif 18 | 19 | using System.Diagnostics; 20 | 21 | namespace SQLite.Tests 22 | { 23 | [TestFixture] 24 | public class InsertTest 25 | { 26 | private TestDb _db; 27 | 28 | public class TestObj 29 | { 30 | [AutoIncrement, PrimaryKey] 31 | public int Id { get; set; } 32 | public String Text { get; set; } 33 | 34 | public override string ToString () 35 | { 36 | return string.Format("[TestObj: Id={0}, Text={1}]", Id, Text); 37 | } 38 | 39 | } 40 | 41 | public class TestObj2 42 | { 43 | [PrimaryKey] 44 | public int Id { get; set; } 45 | public String Text { get; set; } 46 | 47 | public override string ToString() 48 | { 49 | return string.Format("[TestObj: Id={0}, Text={1}]", Id, Text); 50 | } 51 | 52 | } 53 | 54 | public class OneColumnObj 55 | { 56 | [AutoIncrement, PrimaryKey] 57 | public int Id { get; set; } 58 | } 59 | 60 | public class UniqueObj 61 | { 62 | [PrimaryKey] 63 | public int Id { get; set; } 64 | } 65 | 66 | public class TestDb : SQLiteConnection 67 | { 68 | public TestDb(String path) 69 | : base(path) 70 | { 71 | CreateTable(); 72 | CreateTable(); 73 | CreateTable(); 74 | CreateTable(); 75 | } 76 | } 77 | 78 | [SetUp] 79 | public void Setup() 80 | { 81 | _db = new TestDb(TestPath.GetTempFileName()); 82 | } 83 | [TearDown] 84 | public void TearDown() 85 | { 86 | if (_db != null) _db.Close(); 87 | } 88 | 89 | [Test] 90 | public void InsertALot() 91 | { 92 | int n = 10000; 93 | var q = from i in Enumerable.Range(1, n) 94 | select new TestObj() { 95 | Text = "I am" 96 | }; 97 | var objs = q.ToArray(); 98 | _db.Trace = false; 99 | 100 | var sw = new Stopwatch(); 101 | sw.Start(); 102 | 103 | var numIn = _db.InsertAll(objs); 104 | 105 | sw.Stop(); 106 | 107 | Assert.AreEqual(numIn, n, "Num inserted must = num objects"); 108 | 109 | var inObjs = _db.CreateCommand("select * from TestObj").ExecuteQuery().ToArray(); 110 | 111 | for (var i = 0; i < inObjs.Length; i++) { 112 | Assert.AreEqual(i+1, objs[i].Id); 113 | Assert.AreEqual(i+1, inObjs[i].Id); 114 | Assert.AreEqual("I am", inObjs[i].Text); 115 | } 116 | 117 | var numCount = _db.CreateCommand("select count(*) from TestObj").ExecuteScalar(); 118 | 119 | Assert.AreEqual(numCount, n, "Num counted must = num objects"); 120 | } 121 | 122 | [Test] 123 | public void InsertTraces () 124 | { 125 | var oldTracer = _db.Tracer; 126 | var oldTrace = _db.Trace; 127 | 128 | var traces = new List (); 129 | _db.Tracer = traces.Add; 130 | _db.Trace = true; 131 | 132 | var obj1 = new TestObj () { Text = "GLaDOS loves tracing!" }; 133 | var numIn1 = _db.Insert (obj1); 134 | 135 | Assert.AreEqual (1, numIn1); 136 | Assert.AreEqual (1, traces.Count); 137 | 138 | _db.Tracer = oldTracer; 139 | _db.Trace = oldTrace; 140 | } 141 | 142 | [Test] 143 | public void InsertTwoTimes() 144 | { 145 | var obj1 = new TestObj() { Text = "GLaDOS loves testing!" }; 146 | var obj2 = new TestObj() { Text = "Keep testing, just keep testing" }; 147 | 148 | 149 | var numIn1 = _db.Insert(obj1); 150 | var numIn2 = _db.Insert(obj2); 151 | Assert.AreEqual(1, numIn1); 152 | Assert.AreEqual(1, numIn2); 153 | 154 | var result = _db.Query("select * from TestObj").ToList(); 155 | Assert.AreEqual(2, result.Count); 156 | Assert.AreEqual(obj1.Text, result[0].Text); 157 | Assert.AreEqual(obj2.Text, result[1].Text); 158 | } 159 | 160 | [Test] 161 | public void InsertIntoTwoTables() 162 | { 163 | var obj1 = new TestObj() { Text = "GLaDOS loves testing!" }; 164 | var obj2 = new TestObj2() { Text = "Keep testing, just keep testing" }; 165 | 166 | var numIn1 = _db.Insert(obj1); 167 | Assert.AreEqual(1, numIn1); 168 | var numIn2 = _db.Insert(obj2); 169 | Assert.AreEqual(1, numIn2); 170 | 171 | var result1 = _db.Query("select * from TestObj").ToList(); 172 | Assert.AreEqual(numIn1, result1.Count); 173 | Assert.AreEqual(obj1.Text, result1.First().Text); 174 | 175 | var result2 = _db.Query("select * from TestObj2").ToList(); 176 | Assert.AreEqual(numIn2, result2.Count); 177 | } 178 | 179 | [Test] 180 | public void InsertWithExtra() 181 | { 182 | var obj1 = new TestObj2() { Id=1, Text = "GLaDOS loves testing!" }; 183 | var obj2 = new TestObj2() { Id=1, Text = "Keep testing, just keep testing" }; 184 | var obj3 = new TestObj2() { Id=1, Text = "Done testing" }; 185 | 186 | _db.Insert(obj1); 187 | 188 | 189 | try { 190 | _db.Insert(obj2); 191 | Assert.Fail("Expected unique constraint violation"); 192 | } 193 | catch (SQLiteException) { 194 | } 195 | _db.Insert(obj2, "OR REPLACE"); 196 | 197 | 198 | try { 199 | _db.Insert(obj3); 200 | Assert.Fail("Expected unique constraint violation"); 201 | } 202 | catch (SQLiteException) { 203 | } 204 | _db.Insert(obj3, "OR IGNORE"); 205 | 206 | var result = _db.Query("select * from TestObj2").ToList(); 207 | Assert.AreEqual(1, result.Count); 208 | Assert.AreEqual(obj2.Text, result.First().Text); 209 | } 210 | 211 | [Test] 212 | public void InsertIntoOneColumnAutoIncrementTable() 213 | { 214 | var obj = new OneColumnObj(); 215 | _db.Insert(obj); 216 | 217 | var result = _db.Get(1); 218 | Assert.AreEqual(1, result.Id); 219 | } 220 | 221 | [Test] 222 | public void InsertAllSuccessOutsideTransaction() 223 | { 224 | var testObjects = Enumerable.Range(1, 20).Select(i => new UniqueObj { Id = i }).ToList(); 225 | 226 | _db.InsertAll(testObjects); 227 | 228 | Assert.AreEqual(testObjects.Count, _db.Table().Count()); 229 | } 230 | 231 | [Test] 232 | public void InsertAllFailureOutsideTransaction() 233 | { 234 | var testObjects = Enumerable.Range(1, 20).Select(i => new UniqueObj { Id = i }).ToList(); 235 | testObjects[testObjects.Count - 1].Id = 1; // causes the insert to fail because of duplicate key 236 | 237 | ExceptionAssert.Throws(() => _db.InsertAll(testObjects)); 238 | 239 | Assert.AreEqual(0, _db.Table().Count()); 240 | } 241 | 242 | [Test] 243 | public void InsertAllSuccessInsideTransaction() 244 | { 245 | var testObjects = Enumerable.Range(1, 20).Select(i => new UniqueObj { Id = i }).ToList(); 246 | 247 | _db.RunInTransaction(() => { 248 | _db.InsertAll(testObjects); 249 | }); 250 | 251 | Assert.AreEqual(testObjects.Count, _db.Table().Count()); 252 | } 253 | 254 | [Test] 255 | public void InsertAllFailureInsideTransaction() 256 | { 257 | var testObjects = Enumerable.Range(1, 20).Select(i => new UniqueObj { Id = i }).ToList(); 258 | testObjects[testObjects.Count - 1].Id = 1; // causes the insert to fail because of duplicate key 259 | 260 | ExceptionAssert.Throws(() => _db.RunInTransaction(() => { 261 | _db.InsertAll(testObjects); 262 | })); 263 | 264 | Assert.AreEqual(0, _db.Table().Count()); 265 | } 266 | 267 | [Test] 268 | public void InsertOrReplace () 269 | { 270 | _db.Trace = true; 271 | _db.InsertAll (from i in Enumerable.Range(1, 20) select new TestObj { Text = "#" + i }); 272 | 273 | Assert.AreEqual (20, _db.Table ().Count ()); 274 | 275 | var t = new TestObj { Id = 5, Text = "Foo", }; 276 | _db.InsertOrReplace (t); 277 | 278 | var r = (from x in _db.Table () orderby x.Id select x).ToList (); 279 | Assert.AreEqual (20, r.Count); 280 | Assert.AreEqual ("Foo", r[4].Text); 281 | } 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/JoinTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | //using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestTools.UnitTesting; 10 | using SetUp = Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; 11 | using TestFixture = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; 12 | using Test = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; 13 | #else 14 | using NUnit.Framework; 15 | #endif 16 | 17 | using System.Diagnostics; 18 | 19 | namespace SQLite.Tests 20 | { 21 | [TestFixture] 22 | public class JoinTest 23 | { 24 | TestDb _db; 25 | 26 | [SetUp] 27 | public void SetUp () 28 | { 29 | _db = new TestDb (); 30 | _db.CreateTable (); 31 | _db.CreateTable (); 32 | _db.CreateTable (); 33 | 34 | var p1 = new Product { Name = "One", }; 35 | var p2 = new Product { Name = "Two", }; 36 | var p3 = new Product { Name = "Three", }; 37 | _db.InsertAll (new [] { p1, p2, p3 } ); 38 | 39 | var o1 = new Order { PlacedTime = DateTime.Now, }; 40 | var o2 = new Order { PlacedTime = DateTime.Now, }; 41 | _db.InsertAll (new [] { o1, o2 } ); 42 | 43 | _db.InsertAll (new [] { 44 | new OrderLine { 45 | OrderId = o1.Id, 46 | ProductId = p1.Id, 47 | Quantity = 1, 48 | }, 49 | new OrderLine { 50 | OrderId = o1.Id, 51 | ProductId = p2.Id, 52 | Quantity = 2, 53 | }, 54 | new OrderLine { 55 | OrderId = o2.Id, 56 | ProductId = p3.Id, 57 | Quantity = 3, 58 | }, 59 | }); 60 | } 61 | 62 | class R 63 | { 64 | } 65 | 66 | //[Test] 67 | //public void JoinThenWhere () 68 | //{ 69 | // var q = from ol in _db.Table () 70 | // join o in _db.Table () on ol.OrderId equals o.Id 71 | // where o.Id == 1 72 | // select new { o.Id, ol.ProductId, ol.Quantity }; 73 | 74 | // var r = System.Linq.Enumerable.ToList (q); 75 | 76 | // Assert.AreEqual (2, r.Count); 77 | //} 78 | 79 | //[Test] 80 | //public void WhereThenJoin () 81 | //{ 82 | // var q = from ol in _db.Table () 83 | // where ol.OrderId == 1 84 | // join o in _db.Table () on ol.OrderId equals o.Id 85 | // select new { o.Id, ol.ProductId, ol.Quantity }; 86 | 87 | // var r = System.Linq.Enumerable.ToList (q); 88 | 89 | // Assert.AreEqual (2, r.Count); 90 | //} 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/LinqTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class LinqTest 18 | { 19 | TestDb CreateDb () 20 | { 21 | var db = new TestDb (); 22 | db.CreateTable (); 23 | db.CreateTable (); 24 | db.CreateTable (); 25 | db.CreateTable (); 26 | return db; 27 | } 28 | 29 | [Test] 30 | public void FunctionParameter () 31 | { 32 | var db = CreateDb (); 33 | 34 | db.Insert (new Product { 35 | Name = "A", 36 | Price = 20, 37 | }); 38 | 39 | db.Insert (new Product { 40 | Name = "B", 41 | Price = 10, 42 | }); 43 | 44 | Func> GetProductsWithPriceAtLeast = delegate(decimal val) { 45 | return (from p in db.Table () where p.Price > val select p).ToList (); 46 | }; 47 | 48 | var r = GetProductsWithPriceAtLeast (15); 49 | Assert.AreEqual (1, r.Count); 50 | Assert.AreEqual ("A", r [0].Name); 51 | } 52 | 53 | [Test] 54 | public void WhereGreaterThan () 55 | { 56 | var db = CreateDb (); 57 | 58 | db.Insert (new Product { 59 | Name = "A", 60 | Price = 20, 61 | }); 62 | 63 | db.Insert (new Product { 64 | Name = "B", 65 | Price = 10, 66 | }); 67 | 68 | Assert.AreEqual (2, db.Table ().Count ()); 69 | 70 | var r = (from p in db.Table () where p.Price > 15 select p).ToList (); 71 | Assert.AreEqual (1, r.Count); 72 | Assert.AreEqual ("A", r [0].Name); 73 | } 74 | 75 | [Test] 76 | public void GetWithExpression () 77 | { 78 | var db = CreateDb(); 79 | 80 | db.Insert (new Product { 81 | Name = "A", 82 | Price = 20, 83 | }); 84 | 85 | db.Insert (new Product { 86 | Name = "B", 87 | Price = 10, 88 | }); 89 | 90 | db.Insert(new Product 91 | { 92 | Name = "C", 93 | Price = 5, 94 | }); 95 | 96 | Assert.AreEqual (3, db.Table ().Count ()); 97 | 98 | var r = db.Get(x => x.Price == 10); 99 | Assert.IsNotNull(r); 100 | Assert.AreEqual ("B", r.Name); 101 | } 102 | 103 | [Test] 104 | public void FindWithExpression () 105 | { 106 | var db = CreateDb(); 107 | 108 | var r = db.Find (x => x.Price == 10); 109 | Assert.IsNull (r); 110 | } 111 | 112 | [Test] 113 | public void OrderByCast () 114 | { 115 | var db = CreateDb(); 116 | 117 | db.Insert (new Product { 118 | Name = "A", 119 | TotalSales = 1, 120 | }); 121 | db.Insert (new Product { 122 | Name = "B", 123 | TotalSales = 100, 124 | }); 125 | 126 | var nocast = (from p in db.Table () orderby p.TotalSales descending select p).ToList (); 127 | Assert.AreEqual (2, nocast.Count); 128 | Assert.AreEqual ("B", nocast [0].Name); 129 | 130 | var cast = (from p in db.Table () orderby (int)p.TotalSales descending select p).ToList (); 131 | Assert.AreEqual (2, cast.Count); 132 | Assert.AreEqual ("B", cast [0].Name); 133 | } 134 | 135 | public class Issue96_A 136 | { 137 | [ AutoIncrement, PrimaryKey] 138 | public int ID { get; set; } 139 | public string AddressLine { get; set; } 140 | 141 | [Indexed] 142 | public int? ClassB { get; set; } 143 | [Indexed] 144 | public int? ClassC { get; set; } 145 | } 146 | 147 | public class Issue96_B 148 | { 149 | [ AutoIncrement, PrimaryKey] 150 | public int ID { get; set; } 151 | public string CustomerName { get; set; } 152 | } 153 | 154 | public class Issue96_C 155 | { 156 | [ AutoIncrement, PrimaryKey] 157 | public int ID { get; set; } 158 | public string SupplierName { get; set; } 159 | } 160 | 161 | [Test] 162 | public void Issue96_NullabelIntsInQueries () 163 | { 164 | var db = CreateDb(); 165 | db.CreateTable (); 166 | 167 | var id = 42; 168 | 169 | db.Insert (new Issue96_A { 170 | ClassB = id, 171 | }); 172 | db.Insert (new Issue96_A { 173 | ClassB = null, 174 | }); 175 | db.Insert (new Issue96_A { 176 | ClassB = null, 177 | }); 178 | db.Insert (new Issue96_A { 179 | ClassB = null, 180 | }); 181 | 182 | 183 | Assert.AreEqual (1, db.Table().Where(p => p.ClassB == id).Count ()); 184 | Assert.AreEqual (3, db.Table().Where(p => p.ClassB == null).Count ()); 185 | } 186 | 187 | public class Issue303_A 188 | { 189 | [PrimaryKey, NotNull] 190 | public int Id { get; set; } 191 | public string Name { get; set; } 192 | } 193 | 194 | public class Issue303_B 195 | { 196 | [PrimaryKey, NotNull] 197 | public int Id { get; set; } 198 | public bool Flag { get; set; } 199 | } 200 | 201 | [Test] 202 | public void Issue303_WhereNot_A() 203 | { 204 | using (var db = new TestDb()) 205 | { 206 | db.CreateTable(); 207 | db.Insert(new Issue303_A { Id = 1, Name = "aa" }); 208 | db.Insert(new Issue303_A { Id = 2, Name = null }); 209 | db.Insert(new Issue303_A { Id = 3, Name = "test" }); 210 | db.Insert(new Issue303_A { Id = 4, Name = null }); 211 | 212 | var r = (from p in db.Table() where !(p.Name == null) select p).ToList(); 213 | Assert.AreEqual(2, r.Count); 214 | Assert.AreEqual(1, r[0].Id); 215 | Assert.AreEqual(3, r[1].Id); 216 | } 217 | } 218 | 219 | [Test] 220 | public void Issue303_WhereNot_B() 221 | { 222 | using (var db = new TestDb()) 223 | { 224 | db.CreateTable(); 225 | db.Insert(new Issue303_B { Id = 1, Flag = true }); 226 | db.Insert(new Issue303_B { Id = 2, Flag = false }); 227 | db.Insert(new Issue303_B { Id = 3, Flag = true }); 228 | db.Insert(new Issue303_B { Id = 4, Flag = false }); 229 | 230 | var r = (from p in db.Table() where !p.Flag select p).ToList(); 231 | Assert.AreEqual(2, r.Count); 232 | Assert.AreEqual(2, r[0].Id); 233 | Assert.AreEqual(4, r[1].Id); 234 | } 235 | } 236 | 237 | [Test] 238 | public void QuerySelectAverage () 239 | { 240 | var db = CreateDb (); 241 | 242 | db.Insert (new Product { 243 | Name = "A", 244 | Price = 20, 245 | TotalSales = 100, 246 | }); 247 | 248 | db.Insert (new Product { 249 | Name = "B", 250 | Price = 10, 251 | TotalSales = 100, 252 | }); 253 | 254 | db.Insert (new Product { 255 | Name = "C", 256 | Price = 1000, 257 | TotalSales = 1, 258 | }); 259 | 260 | var r = db.Table ().Where (x => x.TotalSales > 50).Select (s => s.Price).Average (); 261 | 262 | Assert.AreEqual (15m, r); 263 | } 264 | 265 | interface IEntity 266 | { 267 | int Id { get; set; } 268 | string Value { get; set; } 269 | } 270 | 271 | class Entity : IEntity 272 | { 273 | [AutoIncrement, PrimaryKey] 274 | public int Id { get; set; } 275 | public string Value { get; set; } 276 | } 277 | 278 | static T GetEntity (TestDb db, int id) where T : IEntity, new () 279 | { 280 | return db.Table ().FirstOrDefault (x => x.Id == id); 281 | } 282 | 283 | [Test] 284 | public void CastedParameters () 285 | { 286 | var db = CreateDb (); 287 | db.CreateTable (); 288 | 289 | db.Insert (new Entity { 290 | Value = "Foo", 291 | }); 292 | 293 | var r = GetEntity (db, 1); 294 | 295 | Assert.AreEqual ("Foo", r.Value); 296 | } 297 | 298 | [Test] 299 | public void Issue460_ReplaceWith2Args () 300 | { 301 | var db = CreateDb (); 302 | db.Trace = true; 303 | //db.Tracer = Console.WriteLine; 304 | 305 | db.Insert (new Product { 306 | Name = "I am not B X B", 307 | }); 308 | db.Insert (new Product { 309 | Name = "I am B O B", 310 | }); 311 | 312 | var cl = (from c in db.Table () 313 | where c.Name.Replace (" ", "").Contains ("BOB") 314 | select c).FirstOrDefault (); 315 | 316 | Assert.AreEqual (2, cl.Id); 317 | Assert.AreEqual ("I am B O B", cl.Name); 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/MappingTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | namespace SQLite.Tests 14 | { 15 | [TestFixture] 16 | public class MappingTest 17 | { 18 | [Table ("AGoodTableName")] 19 | class AFunnyTableName 20 | { 21 | [PrimaryKey] 22 | public int Id { get; set; } 23 | 24 | [Column ("AGoodColumnName")] 25 | public string AFunnyColumnName { get; set; } 26 | } 27 | 28 | 29 | [Test] 30 | public void HasGoodNames () 31 | { 32 | var db = new TestDb (); 33 | 34 | db.CreateTable (); 35 | 36 | var mapping = db.GetMapping (); 37 | 38 | Assert.AreEqual ("AGoodTableName", mapping.TableName); 39 | 40 | Assert.AreEqual ("Id", mapping.Columns[0].Name); 41 | Assert.AreEqual ("AGoodColumnName", mapping.Columns[1].Name); 42 | } 43 | 44 | class OverrideNamesBase 45 | { 46 | [PrimaryKey, AutoIncrement] 47 | public int Id { get; set; } 48 | 49 | public virtual string Name { get; set; } 50 | public virtual string Value { get; set; } 51 | } 52 | 53 | class OverrideNamesClass : OverrideNamesBase 54 | { 55 | [Column ("n")] 56 | public override string Name { get; set; } 57 | [Column ("v")] 58 | public override string Value { get; set; } 59 | } 60 | 61 | [Test] 62 | public void OverrideNames () 63 | { 64 | var db = new TestDb (); 65 | db.CreateTable (); 66 | 67 | var cols = db.GetTableInfo ("OverrideNamesClass"); 68 | Assert.AreEqual (3, cols.Count); 69 | Assert.IsTrue (cols.Exists (x => x.Name == "n")); 70 | Assert.IsTrue (cols.Exists (x => x.Name == "v")); 71 | 72 | var o = new OverrideNamesClass { 73 | Name = "Foo", 74 | Value = "Bar", 75 | }; 76 | 77 | db.Insert (o); 78 | 79 | var oo = db.Table ().First (); 80 | 81 | Assert.AreEqual ("Foo", oo.Name); 82 | Assert.AreEqual ("Bar", oo.Value); 83 | } 84 | 85 | #region Issue #86 86 | 87 | [Table ("foo")] 88 | public class Foo 89 | { 90 | [Column ("baz")] 91 | public int Bar { get; set; } 92 | } 93 | 94 | [Test] 95 | public void Issue86 () 96 | { 97 | var db = new TestDb (); 98 | db.CreateTable (); 99 | 100 | db.Insert (new Foo { Bar = 42 }); 101 | db.Insert (new Foo { Bar = 69 }); 102 | 103 | var found42 = db.Table ().Where (f => f.Bar == 42).FirstOrDefault (); 104 | Assert.IsNotNull (found42); 105 | 106 | var ordered = new List (db.Table ().OrderByDescending (f => f.Bar)); 107 | Assert.AreEqual (2, ordered.Count); 108 | Assert.AreEqual (69, ordered[0].Bar); 109 | Assert.AreEqual (42, ordered[1].Bar); 110 | } 111 | 112 | #endregion 113 | 114 | #region Issue #572 115 | 116 | public class OnlyKeyModel 117 | { 118 | [PrimaryKey] 119 | public string MyModelId { get; set; } 120 | } 121 | 122 | [Test] 123 | public void OnlyKey () 124 | { 125 | var db = new TestDb (); 126 | db.CreateTable (); 127 | 128 | db.InsertOrReplace (new OnlyKeyModel { MyModelId = "Foo" }); 129 | var foo = db.Get ("Foo"); 130 | Assert.AreEqual (foo.MyModelId, "Foo"); 131 | 132 | db.Insert (new OnlyKeyModel { MyModelId = "Bar" }); 133 | var bar = db.Get ("Bar"); 134 | Assert.AreEqual (bar.MyModelId, "Bar"); 135 | 136 | db.Update (new OnlyKeyModel { MyModelId = "Foo" }); 137 | var foo2 = db.Get ("Foo"); 138 | Assert.AreEqual (foo2.MyModelId, "Foo"); 139 | } 140 | 141 | #endregion 142 | 143 | #region Issue #1007 144 | 145 | [Test] 146 | public void TableMapping_MapsValueTypes() 147 | { 148 | var mapping = new TableMapping(typeof( (int a, string b, double? c) )); 149 | 150 | Assert.AreEqual(3, mapping.Columns.Length); 151 | Assert.AreEqual("Item1", mapping.Columns[0].Name); 152 | Assert.AreEqual("Item2", mapping.Columns[1].Name); 153 | Assert.AreEqual("Item3", mapping.Columns[2].Name); 154 | } 155 | 156 | #endregion 157 | } 158 | } 159 | 160 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/MigrationTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text; 3 | using SQLite; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | using System.IO; 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class MigrationTest 20 | { 21 | [Table ("Test")] 22 | class LowerId { 23 | public int Id { get; set; } 24 | } 25 | 26 | [Table ("Test")] 27 | class UpperId { 28 | public int ID { get; set; } 29 | } 30 | 31 | [Test] 32 | public void UpperAndLowerColumnNames () 33 | { 34 | using (var db = new TestDb (true) { Trace = true } ) { 35 | db.CreateTable (); 36 | db.CreateTable (); 37 | 38 | var cols = db.GetTableInfo ("Test").ToList (); 39 | Assert.AreEqual (1, cols.Count); 40 | Assert.AreEqual ("Id", cols[0].Name); 41 | } 42 | } 43 | 44 | [Table ("TestAdd")] 45 | class TestAddBefore 46 | { 47 | [PrimaryKey, AutoIncrement] 48 | public int Id { get; set; } 49 | 50 | public string Name { get; set; } 51 | } 52 | 53 | [Table ("TestAdd")] 54 | class TestAddAfter 55 | { 56 | [PrimaryKey, AutoIncrement] 57 | public int Id { get; set; } 58 | 59 | public string Name { get; set; } 60 | 61 | public int IntValue { get; set; } 62 | public string StringValue { get; set; } 63 | } 64 | 65 | [Test] 66 | public void AddColumns () 67 | { 68 | // 69 | // Init the DB 70 | // 71 | var path = ""; 72 | using (var db = new TestDb (true) { Trace = true }) { 73 | path = db.DatabasePath; 74 | 75 | db.CreateTable (); 76 | 77 | var cols = db.GetTableInfo ("TestAdd"); 78 | Assert.AreEqual (2, cols.Count); 79 | 80 | var o = new TestAddBefore { 81 | Name = "Foo", 82 | }; 83 | 84 | db.Insert (o); 85 | 86 | var oo = db.Table ().First (); 87 | 88 | Assert.AreEqual ("Foo", oo.Name); 89 | } 90 | 91 | // 92 | // Migrate and use it 93 | // 94 | using (var db = new SQLiteConnection (path, true) { Trace = true }) { 95 | 96 | db.CreateTable (); 97 | 98 | var cols = db.GetTableInfo ("TestAdd"); 99 | Assert.AreEqual (4, cols.Count); 100 | 101 | var oo = db.Table ().First (); 102 | 103 | Assert.AreEqual ("Foo", oo.Name); 104 | Assert.AreEqual (0, oo.IntValue); 105 | Assert.AreEqual (null, oo.StringValue); 106 | 107 | var o = new TestAddAfter { 108 | Name = "Bar", 109 | IntValue = 42, 110 | StringValue = "Hello", 111 | }; 112 | db.Insert (o); 113 | 114 | var ooo = db.Get (o.Id); 115 | Assert.AreEqual ("Bar", ooo.Name); 116 | Assert.AreEqual (42, ooo.IntValue); 117 | Assert.AreEqual ("Hello", ooo.StringValue); 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/OpenTests.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text; 3 | using SQLite; 4 | using System.Threading.Tasks; 5 | 6 | #if NETFX_CORE 7 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 8 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 9 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 10 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 11 | #else 12 | using NUnit.Framework; 13 | #endif 14 | 15 | using System.IO; 16 | 17 | namespace SQLite.Tests 18 | { 19 | [TestFixture] 20 | public class OpenTest 21 | { 22 | const string UnicodeText = "\u01F427 \u221E"; 23 | 24 | [Test] 25 | public void UnicodePaths() 26 | { 27 | var path = Path.GetTempFileName () + UnicodeText; 28 | 29 | using (var db = new SQLiteConnection (path, true)) { 30 | db.CreateTable (); 31 | } 32 | 33 | Assert.IsTrue(new FileInfo(path).Length > 0, path); 34 | } 35 | 36 | [Test] 37 | public void UnicodePathsAsync() 38 | { 39 | var path = Path.GetTempFileName () + UnicodeText; 40 | 41 | var db = new SQLiteAsyncConnection (path, true); 42 | db.CreateTableAsync ().Wait (); 43 | 44 | Assert.IsTrue (new FileInfo (path).Length > 0, path); 45 | } 46 | 47 | [Test] 48 | public void OpenTemporaryOnDisk() 49 | { 50 | var path = string.Empty; 51 | 52 | Assert.DoesNotThrow (() => { 53 | using (var db = new SQLiteConnection (path, true)) 54 | { 55 | db.CreateTable (); 56 | } 57 | }); 58 | } 59 | 60 | [Test] 61 | public async Task AsyncWithWalCloses() 62 | { 63 | var path = Path.GetTempFileName (); 64 | 65 | var db = new SQLiteAsyncConnection (path); 66 | await db.CreateTableAsync ().ConfigureAwait (false); 67 | await db.InsertAsync (new OrderLine { }); 68 | var lines = await db.Table ().ToListAsync (); 69 | 70 | Assert.AreEqual (1, lines.Count); 71 | 72 | await db.CloseAsync (); 73 | 74 | File.Delete (path); 75 | } 76 | 77 | [Test] 78 | public async Task AsyncWithNoActionsCloses () 79 | { 80 | var path = Path.GetTempFileName (); 81 | 82 | var db = new SQLiteAsyncConnection (path); 83 | await db.CloseAsync ().ConfigureAwait (false); 84 | } 85 | 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/QueryTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text; 3 | using SQLite; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | 7 | #if NETFX_CORE 8 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 9 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 10 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 11 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 12 | #else 13 | using NUnit.Framework; 14 | #endif 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class QueryTest 20 | { 21 | private readonly SQLiteConnection _db = new SQLiteConnection (Path.GetTempFileName(), true); 22 | private readonly (int Value, double Walue)[] _records = new[] 23 | { 24 | (42, 0.5) 25 | }; 26 | 27 | public QueryTest () 28 | { 29 | _db.Execute ("create table G(Value integer not null, Walue real not null)"); 30 | 31 | for (int i = 0; i < _records.Length; i++) { 32 | _db.Execute ("insert into G(Value, Walue) values (?, ?)", 33 | _records[i].Value, _records[i].Walue); 34 | } 35 | } 36 | 37 | class GenericObject 38 | { 39 | public int Value { get; set; } 40 | public double Walue { get; set; } 41 | } 42 | 43 | [Test] 44 | public void QueryGenericObject () 45 | { 46 | var r = _db.Query ("select * from G"); 47 | 48 | Assert.AreEqual (_records.Length, r.Count); 49 | Assert.AreEqual (_records[0].Value, r[0].Value); 50 | Assert.AreEqual (_records[0].Walue, r[0].Walue); 51 | } 52 | 53 | #region Issue #1007 54 | 55 | [Test] 56 | public void QueryValueTuple() 57 | { 58 | var r = _db.Query<(int Value, double Walue)> ("select * from G"); 59 | 60 | Assert.AreEqual(_records.Length, r.Count); 61 | Assert.AreEqual(_records[0].Value, r[0].Value); 62 | Assert.AreEqual(_records[0].Walue, r[0].Walue); 63 | } 64 | 65 | #endregion 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/ReadmeTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using SQLite; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using System.Collections.Generic; 8 | 9 | #if NETFX_CORE 10 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 11 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 12 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 13 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 14 | #else 15 | using NUnit.Framework; 16 | #endif 17 | 18 | namespace SQLite.Tests 19 | { 20 | public class ReadmeTest 21 | { 22 | public class Stock 23 | { 24 | [PrimaryKey, AutoIncrement] 25 | public int Id { get; set; } 26 | public string Symbol { get; set; } 27 | } 28 | 29 | public class Valuation 30 | { 31 | [PrimaryKey, AutoIncrement] 32 | public int Id { get; set; } 33 | [Indexed] 34 | public int StockId { get; set; } 35 | public DateTime Time { get; set; } 36 | public decimal Price { get; set; } 37 | } 38 | 39 | public static void AddStock (SQLiteConnection db, string symbol) 40 | { 41 | var stock = new Stock () { 42 | Symbol = symbol 43 | }; 44 | db.Insert (stock); // Returns the number of rows added to the table 45 | Console.WriteLine ("{0} == {1}", stock.Symbol, stock.Id); 46 | } 47 | 48 | public static IEnumerable QueryValuations (SQLiteConnection db, Stock stock) 49 | { 50 | return db.Query ("select * from Valuation where StockId = ?", stock.Id); 51 | } 52 | 53 | public class Val 54 | { 55 | public decimal Money { get; set; } 56 | public DateTime Date { get; set; } 57 | } 58 | 59 | public static IEnumerable QueryVals (SQLiteConnection db, Stock stock) 60 | { 61 | return db.Query ("select \"Price\" as \"Money\", \"Time\" as \"Date\" from Valuation where StockId = ?", stock.Id); 62 | } 63 | 64 | [Test] 65 | public void Synchronous () 66 | { 67 | var databasePath = Path.Combine (Path.GetTempPath(), "SynchronousMyData"+ Guid.NewGuid() +".db"); 68 | File.Delete(databasePath); 69 | var db = new SQLiteConnection (databasePath); 70 | try 71 | { 72 | db.CreateTable(); 73 | db.CreateTable(); 74 | 75 | AddStock(db, "A1"); 76 | AddStock(db, "A2"); 77 | AddStock(db, "A3"); 78 | AddStock(db, "B1"); 79 | AddStock(db, "B2"); 80 | AddStock(db, "B3"); 81 | 82 | var query = db.Table().Where(v => v.Symbol.StartsWith("A")); 83 | 84 | foreach (var stock in query) 85 | Console.WriteLine("Stock: " + stock.Symbol); 86 | 87 | Assert.AreEqual(3, query.ToList().Count); 88 | } 89 | finally 90 | { 91 | db.Close(); 92 | File.Delete(databasePath); 93 | } 94 | 95 | 96 | } 97 | 98 | [Test] 99 | public async Task Asynchronous() 100 | { 101 | // Get an absolute path to the database file 102 | var databasePath = Path.Combine(Path.GetTempPath(), "AsynchronousMyData" + Guid.NewGuid() + ".db"); 103 | File.Delete(databasePath); 104 | var db = new SQLiteAsyncConnection(databasePath); 105 | try 106 | { 107 | await db.CreateTableAsync(); 108 | 109 | Console.WriteLine("Table created!"); 110 | 111 | var stock = new Stock() 112 | { 113 | Symbol = "AAPL" 114 | }; 115 | 116 | await db.InsertAsync(stock); 117 | 118 | Console.WriteLine("New sti ID: {0}", stock.Id); 119 | 120 | var query = db.Table().Where(s => s.Symbol.StartsWith("A")); 121 | 122 | var result = await query.ToListAsync(); 123 | 124 | foreach (var s in result) 125 | Console.WriteLine("Stock: " + s.Symbol); 126 | 127 | Assert.AreEqual(1, result.Count); 128 | 129 | var count = await db.ExecuteScalarAsync("select count(*) from Stock"); 130 | 131 | Console.WriteLine(string.Format("Found '{0}' stock items.", count)); 132 | 133 | Assert.AreEqual(1, count); 134 | } 135 | finally 136 | { 137 | await db.CloseAsync(); 138 | File.Delete(databasePath); 139 | } 140 | } 141 | 142 | [Test] 143 | public async Task Cipher() 144 | { 145 | var databasePath = Path.Combine(Path.GetTempPath(), "CipherMyData" + Guid.NewGuid() + ".db"); 146 | File.Delete(databasePath); 147 | 148 | var options = new SQLiteConnectionString(databasePath, true, key: "password"); 149 | var encryptedDb = new SQLiteAsyncConnection(options); 150 | 151 | var options2 = new SQLiteConnectionString(databasePath, true, 152 | key: "password", 153 | preKeyAction: db => db.Execute("PRAGMA cipher_default_use_hmac = OFF;"), 154 | postKeyAction: db => db.Execute("PRAGMA kdf_iter = 128000;")); 155 | SQLiteAsyncConnection encryptedDb2 = null; 156 | try 157 | { 158 | encryptedDb2 = new SQLiteAsyncConnection(options2); 159 | } 160 | finally 161 | { 162 | await encryptedDb2?.CloseAsync(); 163 | File.Delete(databasePath); 164 | } 165 | } 166 | 167 | [Test] 168 | public void Manual() 169 | { 170 | var db = new SQLiteConnection (":memory:"); 171 | try 172 | { 173 | 174 | db.Execute("create table Stock(Symbol varchar(100) not null)"); 175 | db.Execute("insert into Stock(Symbol) values (?)", "MSFT"); 176 | var stocks = db.Query("select * from Stock"); 177 | 178 | Assert.AreEqual(1, stocks.Count); 179 | Assert.AreEqual("MSFT", stocks[0].Symbol); 180 | } 181 | finally 182 | { 183 | db.Close(); 184 | } 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/SQLCipherTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class SQLCipherTest 18 | { 19 | class TestTable 20 | { 21 | [PrimaryKey, AutoIncrement] 22 | public int Id { get; set; } 23 | 24 | public string Value { get; set; } 25 | } 26 | 27 | [SetUp] 28 | public void Setup () 29 | { 30 | // open an in memory connection and reset SQLCipher default pragma settings 31 | using (var c = new SQLiteConnection (":memory:", true)) { 32 | c.Execute ("PRAGMA cipher_default_use_hmac = ON;"); 33 | } 34 | } 35 | 36 | [Test] 37 | public void SetStringKey () 38 | { 39 | string path; 40 | 41 | var key = "SecretPassword"; 42 | 43 | using (var db = new TestDb (key: key)) { 44 | path = db.DatabasePath; 45 | 46 | db.CreateTable (); 47 | db.Insert (new TestTable { Value = "Hello" }); 48 | } 49 | 50 | using (var db = new TestDb (path, key: key)) { 51 | path = db.DatabasePath; 52 | 53 | var r = db.Table ().First (); 54 | 55 | Assert.AreEqual ("Hello", r.Value); 56 | } 57 | } 58 | 59 | [Test] 60 | public void SetBytesKey () 61 | { 62 | string path; 63 | 64 | var rand = new Random (); 65 | var key = new byte[32]; 66 | rand.NextBytes (key); 67 | 68 | using (var db = new TestDb (key: key)) { 69 | path = db.DatabasePath; 70 | 71 | db.CreateTable (); 72 | db.Insert (new TestTable { Value = "Hello" }); 73 | } 74 | 75 | using (var db = new TestDb (path, key: key)) { 76 | path = db.DatabasePath; 77 | 78 | var r = db.Table ().First (); 79 | 80 | Assert.AreEqual ("Hello", r.Value); 81 | } 82 | } 83 | 84 | [Test] 85 | public void SetEmptyStringKey () 86 | { 87 | using (var db = new TestDb (key: "")) { 88 | } 89 | } 90 | 91 | [Test] 92 | public void SetBadTypeKey () 93 | { 94 | try { 95 | using (var db = new TestDb (key: 42)) { 96 | } 97 | Assert.Fail ("Should have thrown"); 98 | } 99 | catch (ArgumentException) { 100 | } 101 | } 102 | 103 | [Test] 104 | public void SetBadBytesKey () 105 | { 106 | try { 107 | using (var db = new TestDb (key: new byte[] { 1, 2, 3, 4 })) { 108 | } 109 | Assert.Fail ("Should have thrown"); 110 | } 111 | catch (ArgumentException) { 112 | } 113 | } 114 | 115 | [Test] 116 | public void SetPreKeyAction () 117 | { 118 | var path = TestPath.GetTempFileName (); 119 | var key = "SecretKey"; 120 | 121 | using (var db = new SQLiteConnection (new SQLiteConnectionString (path, true, key, 122 | preKeyAction: conn => conn.Execute ("PRAGMA page_size = 8192;")))) { 123 | db.CreateTable (); 124 | db.Insert (new TestTable { Value = "Secret Value" }); 125 | Assert.AreEqual ("8192", db.ExecuteScalar ("PRAGMA page_size;")); 126 | } 127 | } 128 | 129 | [Test] 130 | public void SetPostKeyAction () 131 | { 132 | var path = TestPath.GetTempFileName (); 133 | var key = "SecretKey"; 134 | 135 | using (var db = new SQLiteConnection (new SQLiteConnectionString (path, true, key, 136 | postKeyAction: conn => conn.Execute ("PRAGMA page_size = 512;")))) { 137 | db.CreateTable (); 138 | db.Insert (new TestTable { Value = "Secret Value" }); 139 | Assert.AreEqual ("512", db.ExecuteScalar ("PRAGMA page_size;")); 140 | } 141 | } 142 | 143 | [Test] 144 | public void CheckJournalModeForNonKeyed () 145 | { 146 | using (var db = new TestDb ()) { 147 | db.CreateTable (); 148 | Assert.AreEqual ("wal", db.ExecuteScalar ("PRAGMA journal_mode;")); 149 | } 150 | } 151 | 152 | [Test] 153 | public void ResetStringKey () 154 | { 155 | string path; 156 | 157 | var key = "SecretPassword"; 158 | var reKey = "SecretKey"; 159 | 160 | using (var db = new TestDb (key: key)) { 161 | db.ReKey (reKey); 162 | path = db.DatabasePath; 163 | 164 | db.CreateTable (); 165 | db.Insert (new TestTable { Value = "Hello" }); 166 | } 167 | 168 | using (var db = new TestDb (path, key: reKey)) { 169 | var r = db.Table ().First (); 170 | 171 | Assert.AreEqual ("Hello", r.Value); 172 | } 173 | } 174 | 175 | [Test] 176 | public void ResetByteKey () 177 | { 178 | string path; 179 | 180 | var rand = new Random (); 181 | var key = new byte[32]; 182 | rand.NextBytes (key); 183 | var reKey = new byte[32]; 184 | rand.NextBytes (reKey); 185 | 186 | using (var db = new TestDb (key: key)) { 187 | db.ReKey (reKey); 188 | path = db.DatabasePath; 189 | 190 | db.CreateTable (); 191 | db.Insert (new TestTable { Value = "Hello" }); 192 | } 193 | 194 | using (var db = new TestDb (path, key: reKey)) { 195 | var r = db.Table ().First (); 196 | 197 | Assert.AreEqual ("Hello", r.Value); 198 | } 199 | } 200 | 201 | [Test] 202 | public void ResetBadKey () 203 | { 204 | var key = new byte[] { 42 }; 205 | 206 | try 207 | { 208 | using (var db = new TestDb ()) { 209 | db.ReKey (key); 210 | } 211 | 212 | Assert.Fail ("Should have thrown"); 213 | } 214 | catch (ArgumentException) { 215 | } 216 | } 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/SQLite.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | SQLite.cs 20 | 21 | 22 | SQLiteAsync.cs 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/ScalarTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | namespace SQLite.Tests 14 | { 15 | [TestFixture] 16 | public class ScalarTest 17 | { 18 | class TestTable 19 | { 20 | [PrimaryKey, AutoIncrement] 21 | public int Id { get; set; } 22 | public int Two { get; set; } 23 | } 24 | 25 | const int Count = 100; 26 | 27 | SQLiteConnection CreateDb () 28 | { 29 | var db = new TestDb (); 30 | db.CreateTable (); 31 | var items = from i in Enumerable.Range (0, Count) 32 | select new TestTable { Two = 2 }; 33 | db.InsertAll (items); 34 | Assert.AreEqual (Count, db.Table ().Count ()); 35 | return db; 36 | } 37 | 38 | 39 | [Test] 40 | public void Int32 () 41 | { 42 | var db = CreateDb (); 43 | 44 | var r = db.ExecuteScalar ("SELECT SUM(Two) FROM TestTable"); 45 | 46 | Assert.AreEqual (Count * 2, r); 47 | 48 | db.DeleteAll (); 49 | 50 | var r1 = db.ExecuteScalar ("SELECT SUM(Two) FROM TestTable"); 51 | 52 | Assert.AreEqual (0, r1); 53 | } 54 | 55 | [Test] 56 | public void SelectSingleRowValue () 57 | { 58 | var db = CreateDb (); 59 | 60 | var r = db.ExecuteScalar ("SELECT Two FROM TestTable WHERE Id = 1 LIMIT 1"); 61 | 62 | Assert.AreEqual (2, r); 63 | } 64 | 65 | [Test] 66 | public void SelectNullableSingleRowValue () 67 | { 68 | var db = CreateDb (); 69 | 70 | var r = db.ExecuteScalar ("SELECT Two FROM TestTable WHERE Id = 1 LIMIT 1"); 71 | 72 | Assert.AreEqual (true, r.HasValue); 73 | Assert.AreEqual (2, r); 74 | } 75 | 76 | [Test] 77 | public void SelectNoRowValue () 78 | { 79 | var db = CreateDb (); 80 | 81 | var r = db.ExecuteScalar ("SELECT Two FROM TestTable WHERE Id = 999"); 82 | 83 | Assert.AreEqual (false, r.HasValue); 84 | } 85 | 86 | [Test] 87 | public void SelectNullRowValue () 88 | { 89 | var db = CreateDb (); 90 | 91 | var r = db.ExecuteScalar ("SELECT null AS Unknown FROM TestTable WHERE Id = 1 LIMIT 1"); 92 | 93 | Assert.AreEqual (false, r.HasValue); 94 | } 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/SkipTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using SQLite; 7 | 8 | #if NETFX_CORE 9 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 10 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 11 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 12 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 13 | #else 14 | using NUnit.Framework; 15 | #endif 16 | 17 | using System.Diagnostics; 18 | 19 | namespace SQLite.Tests 20 | { 21 | [TestFixture] 22 | public class SkipTest 23 | { 24 | public class TestObj 25 | { 26 | [AutoIncrement, PrimaryKey] 27 | public int Id { get; set; } 28 | public int Order { get; set; } 29 | 30 | public override string ToString () 31 | { 32 | return string.Format("[TestObj: Id={0}, Order={1}]", Id, Order); 33 | } 34 | 35 | } 36 | public class TestDb : SQLiteConnection 37 | { 38 | public TestDb(String path) 39 | : base(path) 40 | { 41 | CreateTable(); 42 | } 43 | } 44 | 45 | [Test] 46 | public void Skip() 47 | { 48 | var n = 100; 49 | 50 | var cq = from i in Enumerable.Range(1, n) 51 | select new TestObj() { 52 | Order = i 53 | }; 54 | var objs = cq.ToArray(); 55 | var db = new TestDb(TestPath.GetTempFileName()); 56 | 57 | var numIn = db.InsertAll(objs); 58 | Assert.AreEqual(numIn, n, "Num inserted must = num objects"); 59 | 60 | var q = from o in db.Table() 61 | orderby o.Order 62 | select o; 63 | 64 | var qs1 = q.Skip(1); 65 | var s1 = qs1.ToList(); 66 | Assert.AreEqual(n - 1, s1.Count); 67 | Assert.AreEqual(2, s1[0].Order); 68 | 69 | var qs5 = q.Skip(5); 70 | var s5 = qs5.ToList(); 71 | Assert.AreEqual(n - 5, s5.Count); 72 | Assert.AreEqual(6, s5[0].Order); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/StringQueryTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class StringQueryTest 18 | { 19 | TestDb db; 20 | 21 | [SetUp] 22 | public void SetUp () 23 | { 24 | db = new TestDb (); 25 | db.CreateTable (); 26 | 27 | var prods = new[] { 28 | new Product { Name = "Foo" }, 29 | new Product { Name = "Bar" }, 30 | new Product { Name = "Foobar" }, 31 | new Product { Name = null, Price=100 }, 32 | new Product { Name = string.Empty,Price=1000 }, 33 | }; 34 | 35 | db.InsertAll (prods); 36 | } 37 | 38 | [Test] 39 | public void StringEquals () 40 | { 41 | // C#: x => x.Name == "Foo" 42 | var fs = db.Table().Where(x => x.Name == "Foo").ToList(); 43 | Assert.AreEqual(1, fs.Count); 44 | 45 | #if !NO_VB 46 | // VB: Function(x) x.Name = "Foo" 47 | var param = System.Linq.Expressions.Expression.Parameter(typeof(Product), "x"); 48 | var expr = System.Linq.Expressions.Expression.Lambda>( 49 | System.Linq.Expressions.Expression.Equal( 50 | System.Linq.Expressions.Expression.Call( 51 | typeof(Microsoft.VisualBasic.CompilerServices.Operators).GetMethod("CompareString"), 52 | System.Linq.Expressions.Expression.MakeMemberAccess(param, typeof(Product).GetMember("Name").First()), 53 | System.Linq.Expressions.Expression.Constant("Foo"), 54 | System.Linq.Expressions.Expression.Constant(false)), // Option Compare Binary (false) or Text (true) 55 | System.Linq.Expressions.Expression.Constant(0)), 56 | param); 57 | var bs = db.Table().Where(expr).ToList(); 58 | Assert.AreEqual(1, bs.Count); 59 | #endif 60 | } 61 | 62 | [Test] 63 | public void StartsWith () 64 | { 65 | var fs = db.Table ().Where (x => x.Name.StartsWith ("F")).ToList (); 66 | Assert.AreEqual (2, fs.Count); 67 | 68 | var lfs = db.Table().Where(x => x.Name.StartsWith("f")).ToList(); 69 | Assert.AreEqual(0, lfs.Count); 70 | 71 | 72 | var lfs2 = db.Table().Where(x => x.Name.StartsWith("f",StringComparison.OrdinalIgnoreCase)).ToList(); 73 | Assert.AreEqual(2, lfs2.Count); 74 | 75 | 76 | var bs = db.Table ().Where (x => x.Name.StartsWith ("B")).ToList (); 77 | Assert.AreEqual (1, bs.Count); 78 | } 79 | 80 | [Test] 81 | public void EndsWith () 82 | { 83 | var fs = db.Table ().Where (x => x.Name.EndsWith ("ar")).ToList (); 84 | Assert.AreEqual (2, fs.Count); 85 | 86 | var lfs = db.Table().Where(x => x.Name.EndsWith("Ar")).ToList(); 87 | Assert.AreEqual(0, lfs.Count); 88 | 89 | var bs = db.Table ().Where (x => x.Name.EndsWith ("o")).ToList (); 90 | Assert.AreEqual (1, bs.Count); 91 | } 92 | 93 | [Test] 94 | public void Contains () 95 | { 96 | var fs = db.Table().Where(x => x.Name.Contains("o")).ToList(); 97 | Assert.AreEqual(2, fs.Count); 98 | 99 | var lfs = db.Table ().Where (x => x.Name.Contains ("O")).ToList (); 100 | Assert.AreEqual (0, lfs.Count); 101 | 102 | var lfsu = db.Table().Where(x => x.Name.ToUpper().Contains("O")).ToList(); 103 | Assert.AreEqual(2, lfsu.Count); 104 | 105 | var bs = db.Table ().Where (x => x.Name.Contains ("a")).ToList (); 106 | Assert.AreEqual (2, bs.Count); 107 | 108 | var zs = db.Table().Where(x => x.Name.Contains("z")).ToList(); 109 | Assert.AreEqual(0, zs.Count); 110 | } 111 | [Test] 112 | public void IsNullOrEmpty () 113 | { 114 | var isnullorempty = db.Table().Where(x => string.IsNullOrEmpty(x.Name)).ToList(); 115 | Assert.AreEqual (2, isnullorempty.Count); 116 | 117 | var isnotnullorempty = db.Table().Where(x => !string.IsNullOrEmpty(x.Name)).ToList(); 118 | Assert.AreEqual(3, isnotnullorempty.Count); 119 | 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/TableChangedTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestTools.UnitTesting; 7 | using SetUp = Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | 15 | 16 | namespace SQLite.Tests 17 | { 18 | [TestFixture] 19 | public class TableChangedTest 20 | { 21 | TestDb db; 22 | int changeCount = 0; 23 | 24 | [SetUp] 25 | public void SetUp () 26 | { 27 | db = new TestDb (); 28 | db.Trace = true; 29 | db.CreateTable (); 30 | db.CreateTable (); 31 | db.InsertAll (from i in Enumerable.Range (0, 22) 32 | select new Product { Name = "Thing" + i, Price = (decimal)Math.Pow (2, i) }); 33 | 34 | changeCount = 0; 35 | 36 | db.TableChanged += (sender, e) => { 37 | 38 | if (e.Table.TableName == "Product") { 39 | changeCount++; 40 | } 41 | }; 42 | } 43 | 44 | [Test] 45 | public void Insert () 46 | { 47 | var query = 48 | from p in db.Table () 49 | select p; 50 | 51 | Assert.AreEqual (0, changeCount); 52 | Assert.AreEqual (22, query.Count ()); 53 | 54 | db.Insert (new Product { Name = "Hello", Price = 1001 }); 55 | 56 | Assert.AreEqual (1, changeCount); 57 | Assert.AreEqual (23, query.Count ()); 58 | } 59 | 60 | [Test] 61 | public void InsertAll () 62 | { 63 | var query = 64 | from p in db.Table () 65 | select p; 66 | 67 | Assert.AreEqual (0, changeCount); 68 | Assert.AreEqual (22, query.Count ()); 69 | 70 | db.InsertAll (from i in Enumerable.Range (0, 22) 71 | select new Product { Name = "Test" + i, Price = (decimal)Math.Pow (3, i) }); 72 | 73 | Assert.AreEqual (22, changeCount); 74 | Assert.AreEqual (44, query.Count ()); 75 | } 76 | 77 | [Test] 78 | public void Update () 79 | { 80 | var query = 81 | from p in db.Table () 82 | select p; 83 | 84 | Assert.AreEqual (0, changeCount); 85 | Assert.AreEqual (22, query.Count ()); 86 | 87 | var pr = query.First (); 88 | pr.Price = 10000000; 89 | db.Update (pr); 90 | 91 | Assert.AreEqual (1, changeCount); 92 | Assert.AreEqual (22, query.Count ()); 93 | } 94 | 95 | [Test] 96 | public void Delete () 97 | { 98 | var query = 99 | from p in db.Table () 100 | select p; 101 | 102 | Assert.AreEqual (0, changeCount); 103 | Assert.AreEqual (22, query.Count ()); 104 | 105 | var pr = query.First (); 106 | pr.Price = 10000000; 107 | db.Delete (pr); 108 | 109 | Assert.AreEqual (1, changeCount); 110 | Assert.AreEqual (21, query.Count ()); 111 | 112 | db.DeleteAll (); 113 | 114 | Assert.AreEqual (2, changeCount); 115 | Assert.AreEqual (0, query.Count ()); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/TestDb.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | #if NETFX_CORE 5 | class DescriptionAttribute : Attribute 6 | { 7 | public DescriptionAttribute (string desc) 8 | { 9 | } 10 | } 11 | #endif 12 | 13 | namespace SQLite.Tests 14 | { 15 | public class Product 16 | { 17 | [AutoIncrement, PrimaryKey] 18 | public int Id { get; set; } 19 | public string Name { get; set; } 20 | public decimal Price { get; set; } 21 | 22 | public uint TotalSales { get; set; } 23 | } 24 | public class Order 25 | { 26 | [AutoIncrement, PrimaryKey] 27 | public int Id { get; set; } 28 | public DateTime PlacedTime { get; set; } 29 | } 30 | public class OrderHistory { 31 | [AutoIncrement, PrimaryKey] 32 | public int Id { get; set; } 33 | public int OrderId { get; set; } 34 | public DateTime Time { get; set; } 35 | public string Comment { get; set; } 36 | } 37 | public class OrderLine 38 | { 39 | [AutoIncrement, PrimaryKey] 40 | public int Id { get; set; } 41 | [Indexed("IX_OrderProduct", 1)] 42 | public int OrderId { get; set; } 43 | [Indexed("IX_OrderProduct", 2)] 44 | public int ProductId { get; set; } 45 | public int Quantity { get; set; } 46 | public decimal UnitPrice { get; set; } 47 | public OrderLineStatus Status { get; set; } 48 | } 49 | public enum OrderLineStatus { 50 | Placed = 1, 51 | Shipped = 100 52 | } 53 | 54 | public class TestDb : SQLiteConnection 55 | { 56 | public TestDb (bool storeDateTimeAsTicks = true, object key = null, bool wal = true) : base (new SQLiteConnectionString (TestPath.GetTempFileName (), storeDateTimeAsTicks, key: key)) 57 | { 58 | Trace = true; 59 | if (wal) 60 | EnableWriteAheadLogging (); 61 | } 62 | 63 | public TestDb (SQLiteConnectionString connectionString, bool wal = true) : base (connectionString) 64 | { 65 | Trace = true; 66 | if (wal) 67 | EnableWriteAheadLogging (); 68 | } 69 | 70 | public TestDb (string path, bool storeDateTimeAsTicks = true, object key = null, bool wal = true) : base (new SQLiteConnectionString (path, storeDateTimeAsTicks, key: key)) 71 | { 72 | Trace = true; 73 | if (wal) 74 | EnableWriteAheadLogging (); 75 | } 76 | } 77 | 78 | public class TestPath 79 | { 80 | public static string GetTempFileName () 81 | { 82 | #if NETFX_CORE 83 | var name = Guid.NewGuid () + ".sqlite"; 84 | return Path.Combine (Windows.Storage.ApplicationData.Current.LocalFolder.Path, name); 85 | #else 86 | return Path.GetTempFileName (); 87 | #endif 88 | } 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/TimeSpanTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | namespace SQLite.Tests 14 | { 15 | [TestFixture] 16 | public class TimeSpanTest 17 | { 18 | class TestObj 19 | { 20 | [PrimaryKey, AutoIncrement] 21 | public int Id { get; set; } 22 | 23 | public string Name { get; set; } 24 | public TimeSpan Duration { get; set; } 25 | } 26 | 27 | [Test] 28 | public void AsTicks () 29 | { 30 | var db = new TestDb (TimeSpanAsTicks (true)); 31 | var span = new TimeSpan (42, 12, 33, 20, 501); 32 | TestTimeSpan (db, span, span.Ticks.ToString ()); 33 | } 34 | 35 | [Test] 36 | public void AsStrings () 37 | { 38 | var db = new TestDb (TimeSpanAsTicks (false)); 39 | var span = new TimeSpan (42, 12, 33, 20, 501); 40 | TestTimeSpan (db, span, span.ToString ()); 41 | } 42 | 43 | [Test] 44 | public void AsyncAsTicks () 45 | { 46 | var db = new SQLiteAsyncConnection (TimeSpanAsTicks (true)); 47 | var span = new TimeSpan (42, 12, 33, 20, 501); 48 | TestAsyncTimeSpan (db, span, span.Ticks.ToString ()); 49 | } 50 | 51 | [Test] 52 | public void AsyncAsStrings () 53 | { 54 | var db = new SQLiteAsyncConnection (TimeSpanAsTicks (false)); 55 | var span = new TimeSpan (42, 12, 33, 20, 501); 56 | TestAsyncTimeSpan (db, span, span.ToString ()); 57 | } 58 | 59 | SQLiteConnectionString TimeSpanAsTicks (bool asTicks = true) => new SQLiteConnectionString (TestPath.GetTempFileName (), SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite, true, storeTimeSpanAsTicks: asTicks); 60 | 61 | void TestAsyncTimeSpan (SQLiteAsyncConnection db, TimeSpan duration, string expected) 62 | { 63 | db.CreateTableAsync ().Wait (); 64 | 65 | TestObj o, o2; 66 | 67 | o = new TestObj { 68 | Duration = duration, 69 | }; 70 | db.InsertAsync (o).Wait (); 71 | o2 = db.GetAsync (o.Id).Result; 72 | Assert.AreEqual (o.Duration, o2.Duration); 73 | 74 | var stored = db.ExecuteScalarAsync ("SELECT Duration FROM TestObj;").Result; 75 | Assert.AreEqual (expected, stored); 76 | } 77 | 78 | void TestTimeSpan (TestDb db, TimeSpan duration, string expected) 79 | { 80 | db.CreateTable (); 81 | 82 | TestObj o, o2; 83 | 84 | o = new TestObj { 85 | Duration = duration, 86 | }; 87 | db.Insert (o); 88 | o2 = db.Get (o.Id); 89 | Assert.AreEqual (o.Duration, o2.Duration); 90 | 91 | var stored = db.ExecuteScalar ("SELECT Duration FROM TestObj;"); 92 | Assert.AreEqual (expected, stored); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/TransactionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TearDown = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestCleanupAttribute; 9 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 10 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 11 | #else 12 | using NUnit.Framework; 13 | #endif 14 | 15 | namespace SQLite.Tests 16 | { 17 | [TestFixture] 18 | public class TransactionTest 19 | { 20 | private TestDb db; 21 | private List testObjects; 22 | 23 | public class TestObj 24 | { 25 | [AutoIncrement, PrimaryKey] 26 | public int Id { get; set; } 27 | 28 | public override string ToString() 29 | { 30 | return string.Format("[TestObj: Id={0}]", Id); 31 | } 32 | } 33 | 34 | public class TransactionTestException : Exception 35 | { 36 | } 37 | 38 | public class TestDb : SQLiteConnection 39 | { 40 | public TestDb(String path) : base(path) 41 | { 42 | CreateTable(); 43 | } 44 | } 45 | 46 | [SetUp] 47 | public void Setup() 48 | { 49 | testObjects = Enumerable.Range(1, 20).Select(i => new TestObj()).ToList(); 50 | 51 | db = new TestDb(TestPath.GetTempFileName()); 52 | db.InsertAll(testObjects); 53 | } 54 | 55 | [TearDown] 56 | public void TearDown() 57 | { 58 | if (db != null) { 59 | db.Close(); 60 | } 61 | } 62 | 63 | [Test] 64 | public void SuccessfulSavepointTransaction() 65 | { 66 | db.RunInTransaction(() => { 67 | db.Delete(testObjects[0]); 68 | db.Delete(testObjects[1]); 69 | db.Insert(new TestObj()); 70 | }); 71 | 72 | Assert.AreEqual(testObjects.Count - 1, db.Table().Count()); 73 | } 74 | 75 | [Test] 76 | public void FailSavepointTransaction() 77 | { 78 | try { 79 | db.RunInTransaction(() => { 80 | db.Delete(testObjects[0]); 81 | 82 | throw new TransactionTestException(); 83 | }); 84 | } catch (TransactionTestException) { 85 | // ignore 86 | } 87 | 88 | Assert.AreEqual(testObjects.Count, db.Table().Count()); 89 | } 90 | 91 | [Test] 92 | public void SuccessfulNestedSavepointTransaction() 93 | { 94 | db.RunInTransaction(() => { 95 | db.Delete(testObjects[0]); 96 | 97 | db.RunInTransaction(() => { 98 | db.Delete(testObjects[1]); 99 | }); 100 | }); 101 | 102 | Assert.AreEqual(testObjects.Count - 2, db.Table().Count()); 103 | } 104 | 105 | [Test] 106 | public void FailNestedSavepointTransaction() 107 | { 108 | try { 109 | db.RunInTransaction(() => { 110 | db.Delete(testObjects[0]); 111 | 112 | db.RunInTransaction(() => { 113 | db.Delete(testObjects[1]); 114 | 115 | throw new TransactionTestException(); 116 | }); 117 | }); 118 | } catch (TransactionTestException) { 119 | // ignore 120 | } 121 | 122 | Assert.AreEqual(testObjects.Count, db.Table().Count()); 123 | } 124 | 125 | [Test] 126 | public void Issue329_AsyncTransactionFailuresShouldRollback () 127 | { 128 | var adb = new SQLiteAsyncConnection (TestPath.GetTempFileName ()); 129 | adb.CreateTableAsync ().Wait (); 130 | var initialCount = adb.Table ().CountAsync ().Result; 131 | var rollbacks = 0; 132 | 133 | // 134 | // Fail a commit 135 | // 136 | adb.Trace = true; 137 | adb.Tracer = m => { 138 | Console.WriteLine (m); 139 | if (m == "Executing: rollback") 140 | rollbacks++; 141 | }; 142 | 143 | try { 144 | adb.RunInTransactionAsync (db => { 145 | db.Insert (new TestObj ()); 146 | throw new Exception ("User exception"); 147 | }).Wait (); 148 | Assert.Fail ("Should have thrown"); 149 | } 150 | catch (AggregateException aex) 151 | when (aex.InnerException.Message == "User exception") { 152 | // Expected 153 | } 154 | 155 | Assert.AreEqual (1, rollbacks); 156 | } 157 | 158 | [Test] 159 | public void Issue604_RunInTransactionAsync () 160 | { 161 | var adb = new SQLiteAsyncConnection (TestPath.GetTempFileName ()); 162 | adb.CreateTableAsync ().Wait (); 163 | var initialCount = adb.Table ().CountAsync ().Result; 164 | 165 | // 166 | // Fail a commit 167 | // 168 | adb.Trace = true; 169 | adb.Tracer = m => { 170 | //Console.WriteLine (m); 171 | if (m.Trim().EndsWith ("commit")) 172 | throw SQLiteException.New (SQLite3.Result.Busy, "Make commit fail"); 173 | }; 174 | 175 | try { 176 | adb.RunInTransactionAsync (db => { 177 | db.Insert (new TestObj ()); 178 | }).Wait (); 179 | Assert.Fail ("Should have thrown"); 180 | } 181 | catch (AggregateException aex) 182 | when (aex.InnerException is SQLiteException ex 183 | && ex.Result == SQLite3.Result.Busy) { 184 | // Expected 185 | } 186 | 187 | // 188 | // Are we stuck? 189 | // 190 | adb.Tracer = null; 191 | adb.RunInTransactionAsync (db => { 192 | db.Insert (new TestObj ()); 193 | }).Wait (); 194 | 195 | Assert.AreEqual (initialCount + 1, adb.Table ().CountAsync ().Result); 196 | } 197 | 198 | [Test] 199 | public void Issue604_RecoversFromFailedCommit () 200 | { 201 | db.Trace = true; 202 | var initialCount = db.Table ().Count (); 203 | 204 | // 205 | // Well this is an issue because there is an internal variable called _transactionDepth 206 | // that tries to track if we are in an active transaction. 207 | // The problem is, _transactionDepth is set to 0 and then commit is executed on the database. 208 | // Well, the commit fails and "When COMMIT fails in this way, the transaction remains active and 209 | // the COMMIT can be retried later after the reader has had a chance to clear" 210 | // 211 | var rollbacks = 0; 212 | db.Tracer = m => { 213 | if (m == "Executing: commit") 214 | throw SQLiteException.New (SQLite3.Result.Busy, "Make commit fail"); 215 | if (m == "Executing: rollback") 216 | rollbacks++; 217 | }; 218 | db.BeginTransaction (); 219 | db.Insert (new TestObj ()); 220 | try { 221 | db.Commit (); 222 | Assert.Fail ("Should have thrown"); 223 | } 224 | catch (SQLiteException ex) when (ex.Result == SQLite3.Result.Busy) { 225 | db.Tracer = null; 226 | } 227 | Assert.False (db.IsInTransaction); 228 | Assert.AreEqual (1, rollbacks); 229 | 230 | // 231 | // The catch statements in the RunInTransaction family of functions catch this and call rollback, 232 | // but since _transactionDepth is 0, the transaction isn't actually rolled back. 233 | // 234 | // So the next time begin transaction is called on the same connection, 235 | // sqlite-net attempts to begin a new transaction (because _transactionDepth is 0), 236 | // which promptly fails because there is still an active transaction on the connection. 237 | // 238 | // Well now we are in big trouble because _transactionDepth got set to 1, 239 | // and when begin transaction fails in this manner, the transaction isn't rolled back 240 | // (which would have set _transactionDepth to 0) 241 | // 242 | db.BeginTransaction (); 243 | db.Insert (new TestObj ()); 244 | db.Commit (); 245 | Assert.AreEqual (initialCount + 1, db.Table ().Count ()); 246 | } 247 | 248 | [Test] 249 | public void Issue604_RecoversFromFailedRelease () 250 | { 251 | db.Trace = true; 252 | var initialCount = db.Table ().Count (); 253 | 254 | var rollbacks = 0; 255 | db.Tracer = m => { 256 | //Console.WriteLine (m); 257 | if (m.StartsWith ("Executing: release")) 258 | throw SQLiteException.New (SQLite3.Result.Busy, "Make release fail"); 259 | if (m == "Executing: rollback") 260 | rollbacks++; 261 | }; 262 | var sp0 = db.SaveTransactionPoint (); 263 | db.Insert (new TestObj ()); 264 | try { 265 | db.Release (sp0); 266 | Assert.Fail ("Should have thrown"); 267 | } 268 | catch (SQLiteException ex) when (ex.Result == SQLite3.Result.Busy) { 269 | db.Tracer = null; 270 | } 271 | Assert.False (db.IsInTransaction); 272 | Assert.AreEqual (1, rollbacks); 273 | 274 | db.BeginTransaction (); 275 | db.Insert (new TestObj ()); 276 | db.Commit (); 277 | Assert.AreEqual (initialCount + 1, db.Table ().Count ()); 278 | } 279 | } 280 | } 281 | 282 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/UnicodeTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | #if NETFX_CORE 5 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 6 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 7 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 8 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 9 | #else 10 | using NUnit.Framework; 11 | #endif 12 | 13 | 14 | namespace SQLite.Tests 15 | { 16 | [TestFixture] 17 | public class UnicodeTest 18 | { 19 | [Test] 20 | public void Insert () 21 | { 22 | var db = new TestDb (); 23 | 24 | db.CreateTable (); 25 | 26 | string testString = "\u2329\u221E\u232A"; 27 | 28 | db.Insert (new Product { 29 | Name = testString, 30 | }); 31 | 32 | var p = db.Get (1); 33 | 34 | Assert.AreEqual (testString, p.Name); 35 | } 36 | 37 | [Test] 38 | public void Query () 39 | { 40 | var db = new TestDb (); 41 | 42 | db.CreateTable (); 43 | 44 | string testString = "\u2329\u221E\u232A"; 45 | 46 | db.Insert (new Product { 47 | Name = testString, 48 | }); 49 | 50 | var ps = (from p in db.Table () where p.Name == testString select p).ToList (); 51 | 52 | Assert.AreEqual (1, ps.Count); 53 | Assert.AreEqual (testString, ps [0].Name); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/SQLite.Tests/UniqueTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | #if NETFX_CORE 6 | using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 7 | using SetUp = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; 8 | using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; 9 | using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; 10 | #else 11 | using NUnit.Framework; 12 | #endif 13 | 14 | 15 | namespace SQLite.Tests 16 | { 17 | [TestFixture] 18 | public class UniqueIndexTest 19 | { 20 | public class TheOne { 21 | [PrimaryKey, AutoIncrement] 22 | public int ID { get; set; } 23 | 24 | [Unique (Name = "UX_Uno")] 25 | public int Uno { get; set;} 26 | 27 | [Unique (Name = "UX_Dos")] 28 | public int Dos { get; set;} 29 | [Unique (Name = "UX_Dos")] 30 | public int Tres { get; set;} 31 | 32 | [Indexed (Name = "UX_Uno_bool", Unique = true)] 33 | public int Cuatro { get; set;} 34 | 35 | [Indexed (Name = "UX_Dos_bool", Unique = true)] 36 | public int Cinco { get; set;} 37 | [Indexed (Name = "UX_Dos_bool", Unique = true)] 38 | public int Seis { get; set;} 39 | } 40 | 41 | public class IndexColumns { 42 | public int seqno { get; set;} 43 | public int cid { get; set;} 44 | public string name { get; set; } 45 | } 46 | 47 | public class IndexInfo { 48 | public int seq { get; set;} 49 | public string name { get; set;} 50 | public bool unique { get; set;} 51 | } 52 | 53 | [Test] 54 | public void CreateUniqueIndexes () 55 | { 56 | using (var db = new TestDb ()) { 57 | db.CreateTable (); 58 | var indexes = db.Query ("PRAGMA INDEX_LIST (\"TheOne\")"); 59 | Assert.AreEqual (4, indexes.Count, "# of indexes"); 60 | CheckIndex (db, indexes, "UX_Uno", true, "Uno"); 61 | CheckIndex (db, indexes, "UX_Dos", true, "Dos", "Tres"); 62 | CheckIndex (db, indexes, "UX_Uno_bool", true, "Cuatro"); 63 | CheckIndex (db, indexes, "UX_Dos_bool", true, "Cinco", "Seis"); 64 | } 65 | } 66 | 67 | static void CheckIndex (TestDb db, List indexes, string iname, bool unique, params string [] columns) 68 | { 69 | if (columns == null) 70 | throw new Exception ("Don't!"); 71 | var idx = indexes.SingleOrDefault (i => i.name == iname); 72 | Assert.IsNotNull (idx, String.Format ("Index {0} not found", iname)); 73 | Assert.AreEqual (idx.unique, unique, String.Format ("Index {0} unique expected {1} but got {2}", iname, unique, idx.unique)); 74 | var idx_columns = db.Query (String.Format ("PRAGMA INDEX_INFO (\"{0}\")", iname)); 75 | Assert.AreEqual (columns.Length, idx_columns.Count, String.Format ("# of columns: expected {0}, got {1}", columns.Length, idx_columns.Count)); 76 | foreach (var col in columns) { 77 | Assert.IsNotNull (idx_columns.SingleOrDefault (c => c.name == col), String.Format ("Column {0} not in index {1}", col, idx.name)); 78 | } 79 | } 80 | } 81 | } 82 | --------------------------------------------------------------------------------