Full Code of stephencelis/SQLite.swift for AI

master 964c300fb073 cached
115 files
851.7 KB
225.7k tokens
1 requests
Download .txt
Showing preview only (893K chars total). Download the full file or copy to clipboard to get everything.
Repository: stephencelis/SQLite.swift
Branch: master
Commit: 964c300fb073
Files: 115
Total size: 851.7 KB

Directory structure:
gitextract_03naq3tg/

├── .github/
│   ├── FUNDING.yml
│   ├── issue_template.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .swiftlint.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Documentation/
│   ├── Index.md
│   ├── Linux.md
│   ├── Planning.md
│   ├── Release.md
│   └── Upgrading.md
├── Gemfile
├── LICENSE.txt
├── Makefile
├── Package.swift
├── README.md
├── SQLite.playground/
│   ├── Contents.swift
│   ├── contents.xcplayground
│   └── playground.xcworkspace/
│       └── contents.xcworkspacedata
├── SQLite.swift.podspec
├── SQLite.xcodeproj/
│   ├── project.pbxproj
│   ├── project.xcworkspace/
│   │   ├── contents.xcworkspacedata
│   │   └── xcshareddata/
│   │       └── IDEWorkspaceChecks.plist
│   └── xcshareddata/
│       └── xcschemes/
│           ├── SQLite Mac.xcscheme
│           ├── SQLite iOS.xcscheme
│           ├── SQLite tvOS.xcscheme
│           ├── SQLite visionOS.xcscheme
│           └── SQLite watchOS.xcscheme
├── Sources/
│   └── SQLite/
│       ├── Core/
│       │   ├── Backup.swift
│       │   ├── Blob.swift
│       │   ├── Connection+Aggregation.swift
│       │   ├── Connection+Attach.swift
│       │   ├── Connection+Pragmas.swift
│       │   ├── Connection.swift
│       │   ├── Errors.swift
│       │   ├── Result.swift
│       │   ├── SQLiteFeature.swift
│       │   ├── SQLiteVersion.swift
│       │   ├── Statement.swift
│       │   ├── URIQueryParameter.swift
│       │   └── Value.swift
│       ├── Extensions/
│       │   ├── Cipher.swift
│       │   ├── FTS4.swift
│       │   ├── FTS5.swift
│       │   └── RTree.swift
│       ├── Foundation.swift
│       ├── Helpers.swift
│       ├── Info.plist
│       ├── PrivacyInfo.xcprivacy
│       ├── SQLite.h
│       ├── Schema/
│       │   ├── Connection+Schema.swift
│       │   ├── SchemaChanger.swift
│       │   ├── SchemaDefinitions.swift
│       │   └── SchemaReader.swift
│       └── Typed/
│           ├── AggregateFunctions.swift
│           ├── Coding.swift
│           ├── Collation.swift
│           ├── CoreFunctions.swift
│           ├── CustomFunctions.swift
│           ├── DateAndTimeFunctions.swift
│           ├── Expression.swift
│           ├── Operators.swift
│           ├── Query+with.swift
│           ├── Query.swift
│           ├── Schema.swift
│           ├── Setter.swift
│           └── WindowFunctions.swift
├── Tests/
│   ├── .swiftlint.yml
│   ├── SPM/
│   │   ├── .gitignore
│   │   ├── Package.swift
│   │   └── Sources/
│   │       └── test/
│   │           └── main.swift
│   ├── SQLite visionOS.xctestplan
│   ├── SQLiteTests/
│   │   ├── Core/
│   │   │   ├── BlobTests.swift
│   │   │   ├── Connection+AttachTests.swift
│   │   │   ├── Connection+PragmaTests.swift
│   │   │   ├── ConnectionTests.swift
│   │   │   ├── CoreFunctionsTests.swift
│   │   │   ├── ResultTests.swift
│   │   │   ├── StatementTests.swift
│   │   │   └── ValueTests.swift
│   │   ├── Extensions/
│   │   │   ├── CipherTests.swift
│   │   │   ├── FTS4Tests.swift
│   │   │   ├── FTS5IntegrationTests.swift
│   │   │   ├── FTS5Tests.swift
│   │   │   └── RTreeTests.swift
│   │   ├── Fixtures.swift
│   │   ├── FoundationTests.swift
│   │   ├── Info.plist
│   │   ├── Schema/
│   │   │   ├── Connection+SchemaTests.swift
│   │   │   ├── SchemaChangerTests.swift
│   │   │   ├── SchemaDefinitionsTests.swift
│   │   │   ├── SchemaReaderTests.swift
│   │   │   └── SchemaTests.swift
│   │   ├── TestHelpers.swift
│   │   └── Typed/
│   │       ├── AggregateFunctionsTests.swift
│   │       ├── CustomAggregationTests.swift
│   │       ├── CustomFunctionsTests.swift
│   │       ├── DateAndTimeFunctionTests.swift
│   │       ├── ExpressionTests.swift
│   │       ├── OperatorsTests.swift
│   │       ├── QueryIntegrationTests.swift
│   │       ├── QueryTests.swift
│   │       ├── RowTests.swift
│   │       ├── SelectTests.swift
│   │       ├── SetterTests.swift
│   │       └── WindowFunctionsTests.swift
│   └── Tuist/
│       └── SQLite-Test/
│           ├── .gitignore
│           ├── Project.swift
│           ├── SQLite-Test/
│           │   ├── Sources/
│           │   │   └── SQLiteTestApp.swift
│           │   └── Tests/
│           │       └── SQLiteTestTests.swift
│           ├── Tuist/
│           │   └── Package.swift
│           └── Tuist.swift
└── run-tests.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: [stephencelis, jberkel, NathanFallet]


================================================
FILE: .github/issue_template.md
================================================
> Issues are used to track bugs and feature requests.
> Need help or have a general question? Ask on Stack Overflow (tag sqlite.swift).

## Build Information

- Include the SQLite.swift version, commit or branch experiencing the issue.
- Mention Xcode and OS X versions affected.
- How do do you integrate SQLite.swift in your project?
    - manual
    - CocoaPods
    - Carthage
    - Swift Package manager

## General guidelines

- Be as descriptive as possible.
- Provide as much information needed to _reliably reproduce_ the issue.
- Attach screenshots if possible.
- Better yet: attach GIFs or link to video.
- Even better: link to a sample project exhibiting the issue.


================================================
FILE: .github/pull_request_template.md
================================================
Thanks for taking the time to submit a pull request.

Before submitting, please do the following:

- Run `make lint` to check if there are any format errors (install [swiftlint](https://github.com/realm/SwiftLint#installation) first)
- Run `swift test` to see if the tests pass.
- Write new tests for new functionality.
- Update documentation comments where applicable.



================================================
FILE: .github/workflows/build.yml
================================================
name: Build and test
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress:  ${{ github.ref != 'refs/heads/master' }}
jobs:
  build:
    strategy:
      matrix:
        os: [macos-15, macos-26]
    runs-on: ${{ matrix.os }}
    env:
      IOS_SIMULATOR: ${{ matrix.os == 'macos-15' && 'iPhone 16' || 'iPhone 16e' }}
      IOS_VERSION: ${{ matrix.os == 'macos-15' && '18.5' || '26.0.1' }}
    steps:
    - uses: actions/checkout@v4
    - name: "xcrun simctl list"
      run: "xcrun simctl list"
    - name: Update pod repo
      run: pod repo update
    - name: "Lint"
      run: make lint
    - name: "Run tests (PACKAGE_MANAGER_COMMAND: test)"
      env:
        PACKAGE_MANAGER_COMMAND: test -Xswiftc -warnings-as-errors
      run: ./run-tests.sh
    - name: "Run tests (PACKAGE_MANAGER_COMMAND: test --traits SQLiteSwiftCSQLite)"
      env:
        PACKAGE_MANAGER_COMMAND: test -Xswiftc -warnings-as-errors --traits SQLiteSwiftCSQLite
      run: ./run-tests.sh
    - name: "Run tests (PACKAGE_MANAGER_COMMAND: test --traits SQLiteSwiftCSQLite,FTS5)"
      env:
        PACKAGE_MANAGER_COMMAND: test -Xswiftc -warnings-as-errors --traits SQLiteSwiftCSQLite,FTS5
      run: ./run-tests.sh
    - name: "Run tests (PACKAGE_MANAGER_COMMAND: test --traits SQLCipher)"
      env:
        PACKAGE_MANAGER_COMMAND: test -Xswiftc -warnings-as-errors --traits SQLCipher
      run: ./run-tests.sh
    - name: "Run tests (SPM integration test)"
      env:
        SPM: run
      run: ./run-tests.sh
    - name: "Run tests (BUILD_SCHEME: SQLite iOS)"
      env:
        BUILD_SCHEME: SQLite iOS
      run: ./run-tests.sh
    - name: "Run tests (BUILD_SCHEME: SQLite Mac)"
      env:
        BUILD_SCHEME: SQLite Mac
      run: ./run-tests.sh
    - name: "Run tests (VALIDATOR_SUBSPEC: none)"
      env:
        VALIDATOR_SUBSPEC: none
      run: ./run-tests.sh
    - name: "Run tests (VALIDATOR_SUBSPEC: standard)"
      env:
        VALIDATOR_SUBSPEC: standard
      run: ./run-tests.sh
    - name: "Run tests (VALIDATOR_SUBSPEC: standalone)"
      env:
        VALIDATOR_SUBSPEC: standalone
      run: ./run-tests.sh
    - name: "Run tests (VALIDATOR_SUBSPEC: SQLCipher)"
      env:
        VALIDATOR_SUBSPEC: SQLCipher
      run: ./run-tests.sh
    - name: "Run tests (tuist)"
      run: |
        brew install tuist
        cd Tests/Tuist/SQLite-Test
        tuist install
        tuist test
  build-linux:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Install
      run: |
        sudo apt-get update -qq
        sudo apt-get install -y libsqlite3-dev
    - name: Test (default trait)
      run: swift test
    - name: Test (SQLiteSwiftCSQLite)
      run: swift test --traits SQLiteSwiftCSQLite
    - name: "Run tests (SPM integration test)"
      env:
        SPM: run
      run: ./run-tests.sh
  build-android:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Run tests on Android
      uses: skiptools/swift-android-action@v2
      with:
        # Ubuntu runners low on space causes the emulator to fail to install
        free-disk-space: true
        swift-build-flags: --traits SQLiteSwiftCSQLite


================================================
FILE: .gitignore
================================================
# OS X
.DS_Store

# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate

# Carthage
/Carthage/

# Makefile
bin/

# Swift Package Manager
.build
Packages/
.swiftpm/
Package.resolved
Derived/


================================================
FILE: .swiftlint.yml
================================================
opt_in_rules:
  - shorthand_optional_binding
disabled_rules: # rule identifiers to exclude from running
  - todo
  - function_name_whitespace
  - large_tuple
  - closure_parameter_position
  - inclusive_language  # sqlite_master etc.
  - blanket_disable_command
included: # paths to include during linting. `--path` is ignored if present. takes precendence over `excluded`.
  - Sources
  - Tests
  - Package.swift
excluded: # paths to ignore during linting. overridden by `included`.
  - "*/.build/*"

identifier_name:
  excluded:
    - db
    - in
    - to
    - by
    - or
    - eq
    - gt
    - lt
    - fn
    - a
    - b
    - q
    - SQLITE_TRANSIENT

type_body_length:
  warning: 350
  error: 350

function_body_length:
  warning: 60
  error: 60

line_length:
  warning: 150
  error: 150
  ignores_comments: true

file_length:
  warning: 500
  error: 500
  ignore_comment_only_lines: true


================================================
FILE: CHANGELOG.md
================================================
0.16.0 (28-01-2026), [diff][diff-0.16.0]
========================================
* Revert trait changes for Linux
* Remove SwiftToolchainCSQLite (replaced with fork)

0.15.5 (22-01-2026), [diff][diff-0.15.5]
========================================
* Support more package traits ([#1341][]), including FTS5 ([#1343][])
* SQLCipher package manager integration ([#1336][], [#1340][])
* Provide a dynamic library in SPM ([#1342][])
* Added sendability conformance ([#1332][])

0.15.4 (13-06-2025), [diff][diff-0.15.4]
========================================
* Fix cross compilation for linux on macOS fails ([#1317][])
* Support creating tables in schema changer ([#1315][])
* Update oldest supported platform versions ([#1280][])
* Add CustomStringConvertible for Setter ([#1279][])

0.15.3 (19-04-2024), [diff][diff-0.15.3]
========================================
* Update `podspec` to include privacy manifest ([#1265][])

0.15.2 (16-04-2024), [diff][diff-0.15.2]
========================================
* fix: visionos to CocoaPods ([#1260][])

0.15.1 (14-04-2024), [diff][diff-0.15.1]
========================================

* Update CoreFunctions.swift fix typo ([#1249][])
* Fix #1247 support nil case when decoding optionals ([#1248][])
* Change deployment targets for Xcode 15 and add dependency on custom Cocoapods fork ([#1255][])
* Add VisionOS support ([#1237][])

0.15.0 (24-02-2024), [diff][diff-0.15.0]
========================================

* Fix incorrect behavior when preparing `SELECT *` preceded by a `WITH` ([#1179][])
* Adds support for returning extended error codes ([#1178][])
* Fix typos ([#1182][])
* fix Xcode build error ([#1192][])
* Make the IndexDefinition properties public ([#1196][])
* Fix GitHub Actions build badge ([#1200][])
* Run CI on macOS 13 ([#1206][])
* SchemaReader: return the correct column definition for a composite primary key ([#1217][])
* Add optional support for decoding ([#1224][])
* make fromDatatypeValue throw ([#1242][])
* Implements built-in window functions ([#1228][])
* Fix column affinity parsing to match how SQLite determines affinity ([#1218][])
* Handle FK definitions w/o key references ([#1210][])
* Add privacy manifest ([#1245][])
* New minimum deployment targets: iOS/tvOS 11.0, watchOS 4.0

0.14.1 (01-11-2022), [diff][diff-0.14.1]
========================================

* Reverted `Blob` changes (See [#1167][] for rationale).

0.14.0 (27-10-2022), [diff][diff-0.14.0]
========================================
For breaking changes, see [Upgrading.md](Documentation/Upgrading.md).

* Support more complex schema changes and queries ([#1073][], [#1146][] [#1148][])
* Support `ATTACH`/`DETACH` ([#30][], [#1142][])
* Expose connection flags (via `URIQueryParameter`) to open db ([#1074][])
* Support `WITH` clause ([#1139][])
* Add `Value` conformance for `NSURL` ([#1110][], [#1141][])
* Add decoding for `UUID` ([#1137][])
* SQLCipher: improve documentation ([#1098][]), add `sqlcipher_export` ([#1101][])
* Fix `insertMany([Encodable])` ([#1130][], [#1138][])
* Fix incorrect spelling of `remove_diacritics` ([#1128][])
* Fix project build order ([#1131][])
* Blob performance improvements ([#416][], [#1167][])
* Various performance improvements ([#1109][], [#1115][], [#1132][])
* Removed FTS3/4 tokenizer integration (`registerTokenizer`, [#1104][], [#1144][])

0.13.3 (27-03-2022), [diff][diff-0.13.3]
========================================

* UUID Fix ([#1112][])
* Add prepareRowIterator method to an extension of Statement. ([#1119][])
* Adding primary key support to column with references ([#1121][])

0.13.2 (25-01-2022), [diff][diff-0.13.2]
========================================

* Closing bracket position ([#1100][])
* Native user_version support in Connection ([#1105][])

0.13.1 (17-11-2021), [diff][diff-0.13.1]
========================================

* Support for database backup ([#919][])
* Support for custom SQL aggregates ([#881][])
* Restore previous behavior in `FailableIterator` ([#1075][])
* Fix compilation on Linux ([#1077][])
* Align platform versions in SPM manifest and Xcode ([#1094][])
* Revert OSX deployment target back to 10.10 ([#1095][])

0.13.0 (22-08-2021), [diff][diff-0.13.0]
========================================

* Swift 5.3 support
* Xcode 12.5 support
* Bumps minimum deployment versions
* Fixes up Package.swift to build SQLiteObjc module

0.12.1, 0.12.2 (21-06-2019) [diff][diff-0.12.2]
========================================

* CocoaPods modular headers support

0.12.0 (24-04-2019) [diff][diff-0.12.0]
========================================

* Version with Swift 5 Support

0.11.6 (19-04-2019), [diff][diff-0.11.6]
========================================

* Swift 4.2, SQLCipher 4.x ([#866][])

0.11.5 (04-14-2018), [diff][diff-0.11.5]
========================================

* Swift 4.1 ([#797][])

0.11.4 (30-09-2017), [diff][diff-0.11.4]
========================================

* Collate `.nocase` strictly enforces `NOT NULL` even when using Optional ([#697][])
* Fix transactions not being rolled back when committing fails ([#426][])
* Add possibility to have expression on right hand side of like ([#591][])
* Added Date and Time functions ([#142][])
* Add Swift4 Coding support ([#733][])
* Preliminary Linux support ([#315][], [#681][])
* Add `RowIterator` for more safety ([#647][], [#726][])
* Make `Row.get` throw instead of crash ([#649][])
* Fix create/drop index functions ([#666][])
* Revert deployment target to 8.0 ([#625][], [#671][], [#717][])
* Added support for the union query clause ([#723][])
* Add support for `ORDER` and `LIMIT` on `UPDATE` and `DELETE` ([#657][], [#722][])
* Swift 4 support ([#668][])

0.11.3 (30-03-2017), [diff][diff-0.11.3]
========================================

* Fix compilation problems when using Carthage ([#615][])
* Add `WITHOUT ROWID` table option ([#541][])
* Argument count fixed for binary custom functions ([#481][])
* Documentation updates
* Tested with Xcode 8.3 / iOS 10.3

0.11.2 (25-12-2016), [diff][diff-0.11.2]
========================================

* Fixed SQLCipher integration with read-only databases ([#559][])
* Preliminary Swift Package Manager support ([#548][], [#560][])
* Fixed null pointer when fetching an empty BLOB ([#561][])
* Allow `where` as alias for `filter` ([#571][])

0.11.1 (06-12-2016), [diff][diff-0.11.1]
========================================

* Integrate SQLCipher via CocoaPods ([#546][], [#553][])
* Made lastInsertRowid consistent with other SQLite wrappers ([#532][])
* Fix for `~=` operator used with Double ranges
* Various documentation updates

0.11.0 (19-10-2016)
===================

* Swift3 migration ([diff][diff-0.11.0])


[diff-0.11.0]: https://github.com/stephencelis/SQLite.swift/compare/0.10.1...0.11.0
[diff-0.11.1]: https://github.com/stephencelis/SQLite.swift/compare/0.11.0...0.11.1
[diff-0.11.2]: https://github.com/stephencelis/SQLite.swift/compare/0.11.1...0.11.2
[diff-0.11.3]: https://github.com/stephencelis/SQLite.swift/compare/0.11.2...0.11.3
[diff-0.11.4]: https://github.com/stephencelis/SQLite.swift/compare/0.11.3...0.11.4
[diff-0.11.5]: https://github.com/stephencelis/SQLite.swift/compare/0.11.4...0.11.5
[diff-0.11.6]: https://github.com/stephencelis/SQLite.swift/compare/0.11.5...0.11.6
[diff-0.12.0]: https://github.com/stephencelis/SQLite.swift/compare/0.11.6...0.12.0
[diff-0.12.2]: https://github.com/stephencelis/SQLite.swift/compare/0.12.0...0.12.2
[diff-0.13.0]: https://github.com/stephencelis/SQLite.swift/compare/0.12.2...0.13.0
[diff-0.13.1]: https://github.com/stephencelis/SQLite.swift/compare/0.13.0...0.13.1
[diff-0.13.2]: https://github.com/stephencelis/SQLite.swift/compare/0.13.1...0.13.2
[diff-0.13.3]: https://github.com/stephencelis/SQLite.swift/compare/0.13.2...0.13.3
[diff-0.14.0]: https://github.com/stephencelis/SQLite.swift/compare/0.13.3...0.14.0
[diff-0.14.1]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.14.1
[diff-0.15.0]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.15.0
[diff-0.15.1]: https://github.com/stephencelis/SQLite.swift/compare/0.15.0...0.15.1
[diff-0.15.2]: https://github.com/stephencelis/SQLite.swift/compare/0.15.1...0.15.2
[diff-0.15.3]: https://github.com/stephencelis/SQLite.swift/compare/0.15.2...0.15.3
[diff-0.15.4]: https://github.com/stephencelis/SQLite.swift/compare/0.15.3...0.15.4
[diff-0.15.5]: https://github.com/stephencelis/SQLite.swift/compare/0.15.4...0.15.5
[diff-0.16.0]: https://github.com/stephencelis/SQLite.swift/compare/0.15.5...0.16.0

[#30]: https://github.com/stephencelis/SQLite.swift/issues/30
[#142]: https://github.com/stephencelis/SQLite.swift/issues/142
[#315]: https://github.com/stephencelis/SQLite.swift/issues/315
[#416]: https://github.com/stephencelis/SQLite.swift/pull/416
[#426]: https://github.com/stephencelis/SQLite.swift/pull/426
[#481]: https://github.com/stephencelis/SQLite.swift/pull/481
[#532]: https://github.com/stephencelis/SQLite.swift/issues/532
[#541]: https://github.com/stephencelis/SQLite.swift/issues/541
[#546]: https://github.com/stephencelis/SQLite.swift/issues/546
[#548]: https://github.com/stephencelis/SQLite.swift/pull/548
[#553]: https://github.com/stephencelis/SQLite.swift/pull/553
[#559]: https://github.com/stephencelis/SQLite.swift/pull/559
[#560]: https://github.com/stephencelis/SQLite.swift/pull/560
[#561]: https://github.com/stephencelis/SQLite.swift/issues/561
[#571]: https://github.com/stephencelis/SQLite.swift/issues/571
[#591]: https://github.com/stephencelis/SQLite.swift/pull/591
[#615]: https://github.com/stephencelis/SQLite.swift/pull/615
[#625]: https://github.com/stephencelis/SQLite.swift/issues/625
[#647]: https://github.com/stephencelis/SQLite.swift/pull/647
[#649]: https://github.com/stephencelis/SQLite.swift/pull/649
[#657]: https://github.com/stephencelis/SQLite.swift/issues/657
[#666]: https://github.com/stephencelis/SQLite.swift/pull/666
[#668]: https://github.com/stephencelis/SQLite.swift/pull/668
[#671]: https://github.com/stephencelis/SQLite.swift/issues/671
[#681]: https://github.com/stephencelis/SQLite.swift/issues/681
[#697]: https://github.com/stephencelis/SQLite.swift/issues/697
[#717]: https://github.com/stephencelis/SQLite.swift/issues/717
[#722]: https://github.com/stephencelis/SQLite.swift/pull/722
[#723]: https://github.com/stephencelis/SQLite.swift/pull/723
[#733]: https://github.com/stephencelis/SQLite.swift/pull/733
[#726]: https://github.com/stephencelis/SQLite.swift/pull/726
[#797]: https://github.com/stephencelis/SQLite.swift/pull/797
[#866]: https://github.com/stephencelis/SQLite.swift/pull/866
[#881]: https://github.com/stephencelis/SQLite.swift/pull/881
[#919]: https://github.com/stephencelis/SQLite.swift/pull/919
[#1073]: https://github.com/stephencelis/SQLite.swift/issues/1073
[#1074]: https://github.com/stephencelis/SQLite.swift/issues/1074
[#1075]: https://github.com/stephencelis/SQLite.swift/pull/1075
[#1077]: https://github.com/stephencelis/SQLite.swift/issues/1077
[#1094]: https://github.com/stephencelis/SQLite.swift/pull/1094
[#1095]: https://github.com/stephencelis/SQLite.swift/pull/1095
[#1098]: https://github.com/stephencelis/SQLite.swift/issues/1098
[#1100]: https://github.com/stephencelis/SQLite.swift/pull/1100
[#1101]: https://github.com/stephencelis/SQLite.swift/issues/1101
[#1104]: https://github.com/stephencelis/SQLite.swift/issues/1104
[#1105]: https://github.com/stephencelis/SQLite.swift/pull/1105
[#1109]: https://github.com/stephencelis/SQLite.swift/issues/1109
[#1110]: https://github.com/stephencelis/SQLite.swift/pull/1110
[#1112]: https://github.com/stephencelis/SQLite.swift/pull/1112
[#1115]: https://github.com/stephencelis/SQLite.swift/pull/1115
[#1119]: https://github.com/stephencelis/SQLite.swift/pull/1119
[#1121]: https://github.com/stephencelis/SQLite.swift/pull/1121
[#1128]: https://github.com/stephencelis/SQLite.swift/issues/1128
[#1130]: https://github.com/stephencelis/SQLite.swift/issues/1130
[#1131]: https://github.com/stephencelis/SQLite.swift/pull/1131
[#1132]: https://github.com/stephencelis/SQLite.swift/pull/1132
[#1137]: https://github.com/stephencelis/SQLite.swift/pull/1137
[#1138]: https://github.com/stephencelis/SQLite.swift/pull/1138
[#1139]: https://github.com/stephencelis/SQLite.swift/pull/1139
[#1141]: https://github.com/stephencelis/SQLite.swift/pull/1141
[#1142]: https://github.com/stephencelis/SQLite.swift/pull/1142
[#1144]: https://github.com/stephencelis/SQLite.swift/pull/1144
[#1146]: https://github.com/stephencelis/SQLite.swift/pull/1146
[#1148]: https://github.com/stephencelis/SQLite.swift/pull/1148
[#1167]: https://github.com/stephencelis/SQLite.swift/pull/1167
[#1179]: https://github.com/stephencelis/SQLite.swift/pull/1179
[#1178]: https://github.com/stephencelis/SQLite.swift/pull/1178
[#1182]: https://github.com/stephencelis/SQLite.swift/pull/1182
[#1192]: https://github.com/stephencelis/SQLite.swift/pull/1192
[#1196]: https://github.com/stephencelis/SQLite.swift/pull/1196
[#1200]: https://github.com/stephencelis/SQLite.swift/pull/1200
[#1206]: https://github.com/stephencelis/SQLite.swift/pull/1206
[#1217]: https://github.com/stephencelis/SQLite.swift/pull/1217
[#1224]: https://github.com/stephencelis/SQLite.swift/pull/1224
[#1242]: https://github.com/stephencelis/SQLite.swift/pull/1242
[#1228]: https://github.com/stephencelis/SQLite.swift/pull/1228
[#1218]: https://github.com/stephencelis/SQLite.swift/pull/1218
[#1210]: https://github.com/stephencelis/SQLite.swift/pull/1210
[#1245]: https://github.com/stephencelis/SQLite.swift/pull/1245
[#1249]: https://github.com/stephencelis/SQLite.swift/pull/1249
[#1248]: https://github.com/stephencelis/SQLite.swift/pull/1248
[#1255]: https://github.com/stephencelis/SQLite.swift/pull/1255
[#1237]: https://github.com/stephencelis/SQLite.swift/pull/1237
[#1260]: https://github.com/stephencelis/SQLite.swift/pull/1260
[#1265]: https://github.com/stephencelis/SQLite.swift/pull/1265
[#1279]: https://github.com/stephencelis/SQLite.swift/pull/1279
[#1280]: https://github.com/stephencelis/SQLite.swift/pull/1280
[#1315]: https://github.com/stephencelis/SQLite.swift/pull/1315
[#1317]: https://github.com/stephencelis/SQLite.swift/pull/1317
[#1332]: https://github.com/stephencelis/SQLite.swift/pull/1332
[#1336]: https://github.com/stephencelis/SQLite.swift/pull/1336
[#1340]: https://github.com/stephencelis/SQLite.swift/pull/1340
[#1341]: https://github.com/stephencelis/SQLite.swift/pull/1341
[#1342]: https://github.com/stephencelis/SQLite.swift/pull/1342
[#1343]: https://github.com/stephencelis/SQLite.swift/pull/1343


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

The where and when to open an [issue](#issues) or [pull
request](#pull-requests).


## Issues

Issues are used to track **bugs** and **feature requests**. Need **help** or
have a **general question**? [Ask on Stack Overflow][] (tag `sqlite.swift`).

Before reporting a bug or requesting a feature, [run a few searches][Search] to
see if a similar issue has already been opened and ensure you’re not submitting
a duplicate.

If you find a similar issue, read the existing conversation and see if it
addresses everything. If it doesn’t, continue the conversation there.

If your searches return empty, see the [bug](#bugs) or [feature
request](#feature-requests) guidelines below.

[Ask on Stack Overflow]: https://stackoverflow.com/questions/tagged/sqlite.swift
[Search]: https://github.com/stephencelis/SQLite.swift/search?type=Issues


### Bugs

Think you’ve discovered a new **bug**? Let’s try troubleshooting a few things
first.

  - **Is it an installation issue?** <a name='bugs-1'/>

    If this is your first time building SQLite.swift in your project, you may
    encounter a build error, _e.g._:

        No such module 'SQLite'

    Please carefully re-read the [installation instructions][] to make sure
    everything is in order.

  - **Have you read the documentation?** <a name='bugs-2'/>

    If you can’t seem to get something working, check
    [the documentation][See Documentation] to see if the solution is there.

  - **Are you up-to-date?** <a name='bugs-3'/>

    If you’re perusing [the documentation][See Documentation] online and find
    that an example is just not working, please upgrade to the latest version
    of SQLite.swift and try again before continuing.

  - **Is it an unhelpful build error?** <a name='bugs-4'/>

    While Swift error messaging is improving with each release, complex
    expressions still lend themselves to misleading errors. If you encounter an
    error on a complex line, breaking it down into smaller pieces generally
    yields a more understandable error.

  - **Is it an _even more_ unhelpful build error?** <a name='bugs-5'/>

    Have you updated Xcode recently? Did your project stop building out of the
    blue?

    Hold down the **option** key and select **Clean Build Folder…** from the
    **Product** menu (⌥⇧⌘K).

Made it through everything above and still having trouble? Sorry!
[Open an issue][]! And _please_:

  - Be as descriptive as possible.
  - Provide as much information needed to _reliably reproduce_ the issue.
  - Attach screenshots if possible.
  - Better yet: attach GIFs or link to video.
  - Even better: link to a sample project exhibiting the issue.
  - Include the SQLite.swift commit or branch experiencing the issue.
  - Include devices and operating systems affected.
  - Include build information: the Xcode and macOS versions affected.

[installation instructions]: Documentation/Index.md#installation
[See Documentation]: Documentation/Index.md#sqliteswift-documentation
[Open an issue]: https://github.com/stephencelis/SQLite.swift/issues/new


### Feature Requests

Have an innovative **feature request**? [Open an issue][]! Be thorough! Provide
context and examples. Be open to discussion.


## Pull Requests

Interested in contributing but don’t know where to start? Try the [`help
wanted`][help wanted] label.

Ready to submit a fix or a feature? [Submit a pull request][]! And _please_:

  - If code changes, run the tests and make sure everything still works.
  - Write new tests for new functionality.
  - Update documentation comments where applicable.
  - Maintain the existing style.
  - Don’t forget to have fun.

While we cannot guarantee a merge to every pull request, we do read each one
and love your input.


[help wanted]: https://github.com/stephencelis/SQLite.swift/labels/help%20wanted
[Submit a pull request]: https://github.com/stephencelis/SQLite.swift/fork


================================================
FILE: Documentation/Index.md
================================================
# SQLite.swift Documentation

- [SQLite.swift Documentation](#sqliteswift-documentation)
  - [Installation](#installation)
    - [Swift Package Manager](#swift-package-manager)
        - [Using SQLite.swift with SQLCipher](#using-sqliteswift-with-sqlcipher)
    - [Carthage](#carthage)
    - [CocoaPods](#cocoapods)
      - [Requiring a specific version of SQLite](#requiring-a-specific-version-of-sqlite)
    - [Manual](#manual)
  - [Getting Started](#getting-started)
    - [Connecting to a Database](#connecting-to-a-database)
      - [Read-Write Databases](#read-write-databases)
      - [Read-Only Databases](#read-only-databases)
      - [In a shared group container](#in-a-shared-group-container)
      - [In-Memory Databases](#in-memory-databases)
      - [URI parameters](#uri-parameters)
      - [Thread-Safety](#thread-safety)
  - [Building Type-Safe SQL](#building-type-safe-sql)
    - [Expressions](#expressions)
    - [Compound Expressions](#compound-expressions)
    - [Queries](#queries)
  - [Creating a Table](#creating-a-table)
    - [Create Table Options](#create-table-options)
    - [Column Constraints](#column-constraints)
    - [Table Constraints](#table-constraints)
  - [Inserting Rows](#inserting-rows)
    - [Handling SQLite errors](#handling-sqlite-errors)
    - [Setters](#setters)
          - [Infix Setters](#infix-setters)
          - [Postfix Setters](#postfix-setters)
  - [Selecting Rows](#selecting-rows)
    - [Iterating and Accessing Values](#iterating-and-accessing-values)
      - [Failable iteration](#failable-iteration)
    - [Plucking Rows](#plucking-rows)
    - [Building Complex Queries](#building-complex-queries)
      - [Selecting Columns](#selecting-columns)
      - [Joining Other Tables](#joining-other-tables)
        - [Column Namespacing](#column-namespacing)
        - [Table Aliasing](#table-aliasing)
      - [Filtering Rows](#filtering-rows)
        - [Filter Operators and Functions](#filter-operators-and-functions)
          - [Infix Filter Operators](#infix-filter-operators)
          - [Prefix Filter Operators](#prefix-filter-operators)
          - [Filtering Functions](#filtering-functions)
      - [Sorting Rows](#sorting-rows)
      - [Limiting and Paging Results](#limiting-and-paging-results)
      - [Recursive and Hierarchical Queries](#recursive-and-hierarchical-queries)
      - [Aggregation](#aggregation)
  - [Upserting Rows](#upserting-rows)
  - [Updating Rows](#updating-rows)
  - [Deleting Rows](#deleting-rows)
  - [Transactions and Savepoints](#transactions-and-savepoints)
  - [Querying the Schema](#querying-the-schema)
    - [Indexes and Columns](#indexes-and-columns)
  - [Altering the Schema](#altering-the-schema)
    - [Renaming Tables](#renaming-tables)
    - [Dropping Tables](#dropping-tables)
    - [Adding Columns](#adding-columns)
      - [Added Column Constraints](#added-column-constraints)
    - [SchemaChanger](#schemachanger)
      - [Adding Columns](#adding-columns-1)
      - [Renaming Columns](#renaming-columns)
      - [Dropping Columns](#dropping-columns)
      - [Renaming/Dropping Tables](#renamingdropping-tables)
      - [Creating Tables](#creating-tables)      
    - [Indexes](#indexes)
      - [Creating Indexes](#creating-indexes)
      - [Dropping Indexes](#dropping-indexes)
    - [Migrations and Schema Versioning](#migrations-and-schema-versioning)
  - [Custom Types](#custom-types)
    - [Date-Time Values](#date-time-values)
    - [Binary Data](#binary-data)
  - [Codable Types](#codable-types)
    - [Inserting Codable Types](#inserting-codable-types)
    - [Updating Codable Types](#updating-codable-types)
    - [Retrieving Codable Types](#retrieving-codable-types)
    - [Restrictions](#restrictions)
  - [Other Operators](#other-operators)
          - [Other Infix Operators](#other-infix-operators)
          - [Other Prefix Operators](#other-prefix-operators)
  - [Core SQLite Functions](#core-sqlite-functions)
  - [Aggregate SQLite Functions](#aggregate-sqlite-functions)
  - [Window SQLite Functions](#window-sqlite-functions)
  - [Date and Time functions](#date-and-time-functions)
  - [Custom SQL Functions](#custom-sql-functions)
  - [Custom Aggregations](#custom-aggregations)
  - [Custom Collations](#custom-collations)
  - [Full-text Search](#full-text-search)
    - [FTS5](#fts5)
  - [Executing Arbitrary SQL](#executing-arbitrary-sql)
  - [Online Database Backup](#online-database-backup)
  - [Attaching and detaching databases](#attaching-and-detaching-databases)
  - [Logging](#logging)
  - [Vacuum](#vacuum)

[↩]: #sqliteswift-documentation


## Installation

### Swift Package Manager

The [Swift Package Manager][] is a tool for managing the distribution of
Swift code. It’s integrated with the Swift build system to automate the
process of downloading, compiling, and linking dependencies.

 1. Add the following to your `Package.swift` file:

  ```swift
  dependencies: [
    .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.16.0")
  ]
  ```

 2. Build your project:

  ```sh
  $ swift build
  ```

#### Available traits

The Swift package manager now supports [traits][], which can be used to configure
SQLite.swift for different use cases.

  ```swift
  dependencies: [
    .package(url: "https://github.com/stephencelis/SQLite.swift.git", 
             from: "0.16.0",
             traits: ["XXX"])
  ]
  ```

| Trait                    | Description                                             | SQLite version                       |
|--------------------------|---------------------------------------------------------|--------------------------------------|
| `SystemSQLite` (default) | Uses the system SQLite (provided by Apple)              | macOS 15.7.x: `3.43.2`, 26: `3.50.2` |
| `SQLiteSwiftCSQLite`     | Embeds a [custom SQLite][] based on [swift-toolchain][] | `3.50.4`                             |
| `StandaloneSQLite`       | Only used by CocoaPods                                  |                                      |
| `SQLCipher`              | Embeds [SQLCipher][] (see below)                        | 4.13.0: `3.51.2`                     |
| `FTS5`                   | Enables FTS5, only works with `SQLiteSwiftCSQLite`      |                                      |

[traits]: https://docs.swift.org/swiftpm/documentation/packagemanagerdocs/packagetraits/
[custom SQLite]: https://github.com/stephencelis/CSQLite/tree/SQLite.swift
[swift-toolchain]: https://github.com/swiftlang/swift-toolchain-sqlite 

#### Using SQLite.swift with SQLCipher

If you want to use [SQLCipher][] with SQLite.swift you can specify the `SQLCipher` trait when consuming SQLite.swift.

```swift
depdencies: [
  .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.16.0", traits: ["SQLCipher"])
]
```

As of Xcode 26.2 (17C52), there's no direct way in the Xcode UI to select trait variations so you'll need to use a local wrapper package to pull in the SQLite.swift dependency with the `SQLCipher` trait enabled:

```swift
// swift-tools-version: 6.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "AppDependencies",
    platforms: [
        .macOS(.v10_14),
        .iOS(.v13),
        .macCatalyst(.v13),
        .watchOS(.v8),
        .tvOS(.v15),
        .visionOS(.v1)
    ],
    products: [
        .library(
            name: "AppDependencies",
            targets: ["AppDependencies"]),
    ],
    dependencies: [
        .package(
            url: "https://github.com/stephencelis/SQLite.swift.git",
            from: "0.16.0",
            traits: ["SQLCipher"])
    ],
    targets: [
        .target(
            name: "AppDependencies",
            dependencies: [
                .product(
                    name: "SQLite",
                    package: "SQLite.swift")
            ],
            // necessary if you have other Package dependencies which explicitly link sqlite3
            linkerSettings: [
              .linkedFramework("SQLCipher")
            ]
        )
    ]
)
```

_Note: It's important to include the linkerSettings to link SQLCipher framework first if you have any other Package dependencies in your wrapper package which explicitly link standard sqlite3. This ensures SQLCipher is linked first and properly used._

Within Xcode add your local `AppDependencies` wrapper package as a package dependency and SQLite.swift with SQLCipher functionality will be accessible.

Using the `SQLCipher` trait will cause SQLite.swift to include a dependency on SQLCipher.swift and enable `Connection` methods to set and change the database key:

```swift
import SQLite

let db = try Connection("path/to/encrypted.sqlite3")
try db.key("secret")
try db.rekey("new secret") // changes encryption key on already encrypted db
```

To encrypt an existing database:

```swift
let db = try Connection("path/to/unencrypted.sqlite3")
try db.sqlcipher_export(.uri("encrypted.sqlite3"), key: "secret")
```

[Swift Package Manager]: https://swift.org/package-manager
[SQLCipher]: https://www.zetetic.net/sqlcipher/

### Carthage

[Carthage][] is a simple, decentralized dependency manager for Cocoa. To
install SQLite.swift with Carthage:
 1. Make sure Carthage is [installed][Carthage Installation].

 2. Update your Cartfile to include the following:

    ```ruby
    github "stephencelis/SQLite.swift" ~> 0.16.0
    ```

 3. Run `carthage update` and [add the appropriate framework][Carthage Usage].


[Carthage]: https://github.com/Carthage/Carthage
[Carthage Installation]: https://github.com/Carthage/Carthage#installing-carthage
[Carthage Usage]: https://github.com/Carthage/Carthage#adding-frameworks-to-an-application


### CocoaPods

[CocoaPods][] is a dependency manager for Cocoa projects. To install SQLite.swift with CocoaPods:

 1. Make sure CocoaPods is [installed][CocoaPods Installation] (SQLite.swift
    requires version 1.6.1 or greater).

    ```sh
    # Using the default Ruby install will require you to use sudo when
    # installing and updating gems.
    [sudo] gem install cocoapods
    ```

 2. Update your Podfile to include the following:

    ```ruby
    use_frameworks!

    target 'YourAppTargetName' do
        pod 'SQLite.swift', '~> 0.16.0'
    end
    ```

 3. Run `pod install --repo-update`.


#### Requiring a specific version of SQLite

If you want to use a more recent version of SQLite than what is provided
with the OS you can require the `standalone` subspec:

```ruby
target 'YourAppTargetName' do
  pod 'SQLite.swift/standalone', '~> 0.16.0'
end
```

By default this will use the most recent version of SQLite without any
extras. If you want you can further customize this by adding another
dependency to sqlite3 or one of its subspecs:

```ruby
target 'YourAppTargetName' do
  pod 'SQLite.swift/standalone', '~> 0.16.0'
  pod 'sqlite3/fts5', '= 3.15.0'  # SQLite 3.15.0 with FTS5 enabled
end
```

See the [sqlite3 podspec][sqlite3pod] for more details.

[CocoaPods]: https://cocoapods.org
[CocoaPods Installation]: https://guides.cocoapods.org/using/getting-started.html#getting-started
[sqlite3pod]: https://github.com/clemensg/sqlite3pod

### Manual

To install SQLite.swift as an Xcode sub-project:

 1. Drag the **SQLite.xcodeproj** file into your own project.
    ([Submodule](http://git-scm.com/book/en/Git-Tools-Submodules), clone, or
    [download](https://github.com/stephencelis/SQLite.swift/archive/master.zip)
    the project first.)

    ![Installation Screen Shot](Resources/installation@2x.png)

 2. In your target’s **General** tab, click the **+** button under **Linked
    Frameworks and Libraries**.

 3. Select the appropriate **SQLite.framework** for your platform.

 4. **Add**.

You should now be able to `import SQLite` from any of your target’s source
files and begin using SQLite.swift.

Some additional steps are required to install the application on an actual
device:

 5. In the **General** tab, click the **+** button under **Embedded
    Binaries**.

 6. Select the appropriate **SQLite.framework** for your platform.

 7. **Add**.

## Getting Started

To use SQLite.swift classes or structures in your target’s source file, first
import the `SQLite` module.

```swift
import SQLite
```


### Connecting to a Database

Database connections are established using the `Connection` class. A
connection is initialized with a path to a database. SQLite will attempt to
create the database file if it does not already exist.

```swift
let db = try Connection("path/to/db.sqlite3")
```


#### Read-Write Databases

On iOS, you can create a writable database in your app’s **Documents**
directory.

```swift
let path = NSSearchPathForDirectoriesInDomains(
    .documentDirectory, .userDomainMask, true
).first!

let db = try Connection("\(path)/db.sqlite3")
```

If you have bundled it in your application, you can use FileManager to copy it to the Documents directory:

```swift
func copyDatabaseIfNeeded(sourcePath: String) -> Bool {
    let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    let destinationPath = documents + "/db.sqlite3"
    let exists = FileManager.default.fileExists(atPath: destinationPath)
    guard !exists else { return false }
    do {
        try FileManager.default.copyItem(atPath: sourcePath, toPath: destinationPath)
        return true
    } catch {
      print("error during file copy: \(error)")
	    return false
    }
}
```

On macOS, you can use your app’s **Application Support** directory:


```swift
// set the path corresponding to application support
var path = NSSearchPathForDirectoriesInDomains(
    .applicationSupportDirectory, .userDomainMask, true
).first! + "/" + Bundle.main.bundleIdentifier!

// create parent directory inside application support if it doesn’t exist
try FileManager.default.createDirectory(
atPath: path, withIntermediateDirectories: true, attributes: nil
)

let db = try Connection("\(path)/db.sqlite3")
```

#### Read-Only Databases

If you bundle a database with your app (_i.e._, you’ve copied a database file
into your Xcode project and added it to your application target), you can
establish a _read-only_ connection to it.

```swift
let path = Bundle.main.path(forResource: "db", ofType: "sqlite3")!

let db = try Connection(path, readonly: true)
```

> _Note:_ Signed applications cannot modify their bundle resources. If you
> bundle a database file with your app for the purpose of bootstrapping, copy
> it to a writable location _before_ establishing a connection (see
> [Read-Write Databases](#read-write-databases), above, for typical, writable
> locations).
>
> See these two Stack Overflow questions for more information about iOS apps
> with SQLite databases: [1](https://stackoverflow.com/questions/34609746/what-different-between-store-database-in-different-locations-in-ios),
> [2](https://stackoverflow.com/questions/34614968/ios-how-to-copy-pre-seeded-database-at-the-first-running-app-with-sqlite-swift).
> We welcome changes to the above sample code to show how to successfully copy and use a bundled "seed"
> database for writing in an app.

#### In a shared group container

It is not recommend to store databases in a [shared group container],
some users have reported crashes ([#1042](https://github.com/stephencelis/SQLite.swift/issues/1042)).

[shared group container]: https://developer.apple.com/documentation/foundation/filemanager/1412643-containerurl#

#### In-Memory Databases

If you omit the path, SQLite.swift will provision an [in-memory
database](https://www.sqlite.org/inmemorydb.html).

```swift
let db = try Connection() // equivalent to `Connection(.inMemory)`
```

To create a temporary, disk-backed database, pass an empty file name.

```swift
let db = try Connection(.temporary)
```

In-memory databases are automatically deleted when the database connection is
closed.

#### URI parameters

We can pass `.uri` to the `Connection` initializer to control more aspects of
the database connection with the help of `URIQueryParameter`s:

```swift
let db = try Connection(.uri("file.sqlite", parameters: [.cache(.private), .noLock(true)]))
```

See [Uniform Resource Identifiers](https://www.sqlite.org/uri.html#recognized_query_parameters) for more details.

#### Thread-Safety

Every Connection comes equipped with its own serial queue for statement
execution and can be safely accessed across threads. Threads that open
transactions and savepoints will block other threads from executing
statements while the transaction is open.

If you maintain multiple connections for a single database, consider setting a timeout
(in seconds) *or* a busy handler. There can only be one active at a time, so setting a busy
handler will effectively override `busyTimeout`.

```swift
db.busyTimeout = 5 // error after 5 seconds (does multiple retries)

db.busyHandler({ tries in
    tries < 3  // error after 3 tries
})
```

> _Note:_ The default timeout is 0, so if you see `database is locked`
> errors, you may be trying to access the same database simultaneously from
> multiple connections.


## Building Type-Safe SQL

SQLite.swift comes with a typed expression layer that directly maps
[Swift types](https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/SwiftStandardLibraryReference/)
to their [SQLite counterparts](https://www.sqlite.org/datatype3.html).

| Swift Type      | SQLite Type |
| --------------- | ----------- |
| `Int64`*        | `INTEGER`   |
| `Double`        | `REAL`      |
| `String`        | `TEXT`      |
| `nil`           | `NULL`      |
| `SQLite.Blob`†  | `BLOB`      |
| `URL`           | `TEXT`      |
| `UUID`          | `TEXT`      |
| `Date`          | `TEXT`      |

> *While `Int64` is the basic, raw type (to preserve 64-bit integers on
> 32-bit platforms), `Int` and `Bool` work transparently.
>
> †SQLite.swift defines its own `Blob` structure, which safely wraps the
> underlying bytes.
>
> See [Custom Types](#custom-types) for more information about extending
> other classes and structures to work with SQLite.swift.
>
> See [Executing Arbitrary SQL](#executing-arbitrary-sql) to forego the typed
> layer and execute raw SQL, instead.

These expressions (in the form of the structure,
[`Expression`](#expressions)) build on one another and, with a query
([`QueryType`](#queries)), can create and execute SQL statements.


### Expressions

Expressions are generic structures associated with a type ([built-in
](#building-type-safe-sql) or [custom](#custom-types)), raw SQL, and
(optionally) values to bind to that SQL. Typically, you will only explicitly
create expressions to describe your columns, and typically only once per
column.

```swift
let id = Expression<Int64>("id")
let email = Expression<String>("email")
let balance = Expression<Double>("balance")
let verified = Expression<Bool>("verified")
```

Use optional generics for expressions that can evaluate to `NULL`.

```swift
let name = Expression<String?>("name")
```

> _Note:_ The default `Expression` initializer is for [quoted
> identifiers](https://www.sqlite.org/lang_keywords.html) (_i.e._, column
> names). To build a literal SQL expression, use `init(literal:)`.
> <!-- FIXME -->


### Compound Expressions

Expressions can be combined with other expressions and types using
[filter operators and functions](#filter-operators-and-functions)
(as well as other [non-filter operators](#other-operators) and
[functions](#core-sqlite-functions)). These building blocks can create complex SQLite statements.


### Queries

Queries are structures that reference a database and table name, and can be
used to build a variety of statements using expressions. We can create a
query by initializing a `Table`, `View`, or `VirtualTable`.

```swift
let users = Table("users")
```

Assuming [the table exists](#creating-a-table), we can immediately [insert
](#inserting-rows), [select](#selecting-rows), [update](#updating-rows), and
[delete](#deleting-rows) rows.


## Creating a Table

We can build [`CREATE TABLE`
statements](https://www.sqlite.org/lang_createtable.html) by calling the
`create` function on a `Table`. The following is a basic example of
SQLite.swift code (using the [expressions](#expressions) and
[query](#queries) above) and the corresponding SQL it generates.

```swift
try db.run(users.create { t in     // CREATE TABLE "users" (
    t.column(id, primaryKey: true) //     "id" INTEGER PRIMARY KEY NOT NULL,
    t.column(email, unique: true)  //     "email" TEXT UNIQUE NOT NULL,
    t.column(name)                 //     "name" TEXT
})                                 // )
```

> _Note:_ `Expression<T>` structures (in this case, the `id` and `email`
> columns), generate `NOT NULL` constraints automatically, while
> `Expression<T?>` structures (`name`) do not.


### Create Table Options

The `Table.create` function has several default parameters we can override.

  - `temporary` adds a `TEMPORARY` clause to the `CREATE TABLE` statement (to
    create a temporary table that will automatically drop when the database
    connection closes). Default: `false`.

    ```swift
    try db.run(users.create(temporary: true) { t in /* ... */ })
    // CREATE TEMPORARY TABLE "users" -- ...
    ```

  - `ifNotExists` adds an `IF NOT EXISTS` clause to the `CREATE TABLE`
    statement (which will bail out gracefully if the table already exists).
    Default: `false`.

    ```swift
    try db.run(users.create(ifNotExists: true) { t in /* ... */ })
    // CREATE TABLE "users" IF NOT EXISTS -- ...
    ```

### Column Constraints

The `column` function is used for a single column definition. It takes an
[expression](#expressions) describing the column name and type, and accepts
several parameters that map to various column constraints and clauses.

  - `primaryKey` adds a `PRIMARY KEY` constraint to a single column.

    ```swift
    t.column(id, primaryKey: true)
    // "id" INTEGER PRIMARY KEY NOT NULL

    t.column(id, primaryKey: .autoincrement)
    // "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
    ```

    > _Note:_ The `primaryKey` parameter cannot be used alongside
    > `references`. If you need to create a column that has a default value
    > and is also a primary and/or foreign key, use the `primaryKey` and
    > `foreignKey` functions mentioned under
    > [Table Constraints](#table-constraints).
    >
    > Primary keys cannot be optional (_e.g._, `Expression<Int64?>`).
    >
    > Only an `INTEGER PRIMARY KEY` can take `.autoincrement`.

  - `unique` adds a `UNIQUE` constraint to the column. (See the `unique`
    function under [Table Constraints](#table-constraints) for uniqueness
    over multiple columns).

    ```swift
    t.column(email, unique: true)
    // "email" TEXT UNIQUE NOT NULL
    ```

  - `check` attaches a `CHECK` constraint to a column definition in the form
    of a boolean expression (`Expression<Bool>`). Boolean expressions can be
    easily built using
    [filter operators and functions](#filter-operators-and-functions).
    (See also the `check` function under
    [Table Constraints](#table-constraints).)

    ```swift
    t.column(email, check: email.like("%@%"))
    // "email" TEXT NOT NULL CHECK ("email" LIKE '%@%')
    ```

  - `defaultValue` adds a `DEFAULT` clause to a column definition and _only_
    accepts a value (or expression) matching the column’s type. This value is
    used if none is explicitly provided during
    [an `INSERT`](#inserting-rows).

    ```swift
    t.column(name, defaultValue: "Anonymous")
    // "name" TEXT DEFAULT 'Anonymous'
    ```

    > _Note:_ The `defaultValue` parameter cannot be used alongside
    > `primaryKey` and `references`. If you need to create a column that has
    > a default value and is also a primary and/or foreign key, use the
    > `primaryKey` and `foreignKey` functions mentioned under
    > [Table Constraints](#table-constraints).

  - `collate` adds a `COLLATE` clause to `Expression<String>` (and
    `Expression<String?>`) column definitions with
    [a collating sequence](https://www.sqlite.org/datatype3.html#collation)
    defined in the `Collation` enumeration.

    ```swift
    t.column(email, collate: .nocase)
    // "email" TEXT NOT NULL COLLATE "NOCASE"

    t.column(name, collate: .rtrim)
    // "name" TEXT COLLATE "RTRIM"
    ```

  - `references` adds a `REFERENCES` clause to `Expression<Int64>` (and
    `Expression<Int64?>`) column definitions and accepts a table
    (`SchemaType`) or namespaced column expression. (See the `foreignKey`
    function under [Table Constraints](#table-constraints) for non-integer
    foreign key support.)

    ```swift
    t.column(user_id, references: users, id)
    // "user_id" INTEGER REFERENCES "users" ("id")
    ```

    > _Note:_ The `references` parameter cannot be used alongside
    > `primaryKey` and `defaultValue`. If you need to create a column that
    > has a default value and is also a primary and/or foreign key, use the
    > `primaryKey` and `foreignKey` functions mentioned under
    > [Table Constraints](#table-constraints).


### Table Constraints

Additional constraints may be provided outside the scope of a single column
using the following functions.

  - `primaryKey` adds a `PRIMARY KEY` constraint to the table. Unlike [the
    column constraint, above](#column-constraints), it supports all SQLite
    types, [ascending and descending orders](#sorting-rows), and composite
    (multiple column) keys.

    ```swift
    t.primaryKey(email.asc, name)
    // PRIMARY KEY("email" ASC, "name")
    ```

  - `unique` adds a `UNIQUE` constraint to the table. Unlike
    [the column constraint, above](#column-constraints), it
    supports composite (multiplecolumn) constraints.

    ```swift
    t.unique(local, domain)
    // UNIQUE("local", "domain")
    ```

  - `check` adds a `CHECK` constraint to the table in the form of a boolean
    expression (`Expression<Bool>`). Boolean expressions can be easily built
    using [filter operators and functions](#filter-operators-and-functions).
    (See also the `check` parameter under
    [Column Constraints](#column-constraints).)

    ```swift
    t.check(balance >= 0)
    // CHECK ("balance" >= 0.0)
    ```

  - `foreignKey` adds a `FOREIGN KEY` constraint to the table. Unlike [the
    `references` constraint, above](#column-constraints), it supports all
    SQLite types, both [`ON UPDATE` and `ON DELETE`
    actions](https://www.sqlite.org/foreignkeys.html#fk_actions), and
    composite (multiple column) keys.

    ```swift
    t.foreignKey(user_id, references: users, id, delete: .setNull)
    // FOREIGN KEY("user_id") REFERENCES "users"("id") ON DELETE SET NULL
    ```

<!-- TODO
### Creating a Table from a Select Statement
-->


## Inserting Rows

We can insert rows into a table by calling a [query’s](#queries) `insert`
function with a list of [setters](#setters)—typically [typed column
expressions](#expressions) and values (which can also be expressions)—each
joined by the `<-` operator.

```swift
try db.run(users.insert(email <- "alice@mac.com", name <- "Alice"))
// INSERT INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice')

try db.run(users.insert(or: .replace, email <- "alice@mac.com", name <- "Alice B."))
// INSERT OR REPLACE INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice B.')
```

The `insert` function, when run successfully, returns an `Int64` representing
the inserted row’s [`ROWID`][ROWID].

```swift
do {
    let rowid = try db.run(users.insert(email <- "alice@mac.com"))
    print("inserted id: \(rowid)")
} catch {
    print("insertion failed: \(error)")
}
```

Multiple rows can be inserted at once by similarly calling `insertMany` with an array of
per-row [setters](#setters).

```swift
do {
    let lastRowid = try db.run(users.insertMany([mail <- "alice@mac.com"], [email <- "geoff@mac.com"]))
    print("last inserted id: \(lastRowid)")
} catch {
    print("insertion failed: \(error)")
}
```


The [`update`](#updating-rows) and [`delete`](#deleting-rows) functions
follow similar patterns.

> _Note:_ If `insert` is called without any arguments, the statement will run
> with a `DEFAULT VALUES` clause. The table must not have any constraints
> that aren’t fulfilled by default values.
>
> ```swift
> try db.run(timestamps.insert())
> // INSERT INTO "timestamps" DEFAULT VALUES
> ```

### Handling SQLite errors

You can pattern match on the error to selectively catch SQLite errors. For example, to
specifically handle constraint errors ([SQLITE_CONSTRAINT](https://sqlite.org/rescode.html#constraint)):

```swift
do {
    try db.run(users.insert(email <- "alice@mac.com"))
    try db.run(users.insert(email <- "alice@mac.com"))
} catch let Result.error(message, code, statement) where code == SQLITE_CONSTRAINT {
    print("constraint failed: \(message), in \(statement)")
} catch let error {
    print("insertion failed: \(error)")
}
```

The `Result.error` type contains the English-language text that describes the error (`message`),
the error `code` (see [SQLite result code list](https://sqlite.org/rescode.html#primary_result_code_list)
for details) and a optional reference to the `statement` which produced the error.

### Setters

SQLite.swift typically uses the `<-` operator to set values during [inserts
](#inserting-rows) and [updates](#updating-rows).

```swift
try db.run(counter.update(count <- 0))
// UPDATE "counters" SET "count" = 0 WHERE ("id" = 1)
```

There are also a number of convenience setters that take the existing value
into account using native Swift operators.

For example, to atomically increment a column, we can use `++`:

```swift
try db.run(counter.update(count++)) // equivalent to `counter.update(count -> count + 1)`
// UPDATE "counters" SET "count" = "count" + 1 WHERE ("id" = 1)
```

To take an amount and “move” it via transaction, we can use `-=` and `+=`:

```swift
let amount = 100.0
try db.transaction {
    try db.run(alice.update(balance -= amount))
    try db.run(betty.update(balance += amount))
}
// BEGIN DEFERRED TRANSACTION
// UPDATE "users" SET "balance" = "balance" - 100.0 WHERE ("id" = 1)
// UPDATE "users" SET "balance" = "balance" + 100.0 WHERE ("id" = 2)
// COMMIT TRANSACTION
```


###### Infix Setters

| Operator | Types              |
| -------- | ------------------ |
| `<-`     | `Value -> Value`   |
| `+=`     | `Number -> Number` |
| `-=`     | `Number -> Number` |
| `*=`     | `Number -> Number` |
| `/=`     | `Number -> Number` |
| `%=`     | `Int -> Int`       |
| `<<=`    | `Int -> Int`       |
| `>>=`    | `Int -> Int`       |
| `&=`     | `Int -> Int`       |
| `\|\|=`  | `Int -> Int`       |
| `^=`     | `Int -> Int`       |
| `+=`     | `String -> String` |


###### Postfix Setters

| Operator | Types        |
| -------- | ------------ |
| `++`     | `Int -> Int` |
| `--`     | `Int -> Int` |


## Selecting Rows

[Query structures](#queries) are `SELECT` statements waiting to happen. They
execute via [iteration](#iterating-and-accessing-values) and [other means
](#plucking-values) of sequence access.


### Iterating and Accessing Values

Prepared [queries](#queries) execute lazily upon iteration. Each row is
returned as a `Row` object, which can be subscripted with a [column
expression](#expressions) matching one of the columns returned.

```swift
for user in try db.prepare(users) {
    print("id: \(user[id]), email: \(user[email]), name: \(user[name])")
    // id: 1, email: alice@mac.com, name: Optional("Alice")
}
// SELECT * FROM "users"
```

`Expression<T>` column values are _automatically unwrapped_ (we’ve made a
promise to the compiler that they’ll never be `NULL`), while `Expression<T?>`
values remain wrapped.

⚠ Column subscripts on `Row` will force try and abort execution in error cases.
If you want to handle this yourself, use `Row.get(_ column: Expression<V>)`:

```swift
for user in try db.prepare(users) {
    do {
        print("name: \(try user.get(name))")
    } catch {
        // handle
    }
}
```

Note that the iterator can throw *undeclared* database errors at any point during
iteration:

```swift
let query = try db.prepare(users)
for user in query {
    // 💥 can throw an error here
}
```

#### Failable iteration

It is therefore recommended using the `RowIterator` API instead,
which has explicit error handling:

```swift
// option 1: convert results into an Array of rows
let rowIterator = try db.prepareRowIterator(users)
for user in try Array(rowIterator) {
    print("id: \(user[id]), email: \(user[email])")
}

/// option 2: transform results using `map()`
let mapRowIterator = try db.prepareRowIterator(users)
let userIds = try mapRowIterator.map { $0[id] }

/// option 3: handle each row individually with `failableNext()`
do {
    while let row = try rowIterator.failableNext() {
        // Handle row
    }
} catch {
    // Handle error
}
```

### Plucking Rows

We can pluck the first row by passing a query to the `pluck` function on a
database connection.

```swift
if let user = try db.pluck(users) { /* ... */ } // Row
// SELECT * FROM "users" LIMIT 1
```

To collect all rows into an array, we can simply wrap the sequence (though
this is not always the most memory-efficient idea).

```swift
let all = Array(try db.prepare(users))
// SELECT * FROM "users"
```


### Building Complex Queries

[Queries](#queries) have a number of chainable functions that can be used
(with [expressions](#expressions)) to add and modify [a number of
clauses](https://www.sqlite.org/lang_select.html) to the underlying
statement.

```swift
let query = users.select(email)           // SELECT "email" FROM "users"
                 .filter(name != nil)     // WHERE "name" IS NOT NULL
                 .order(email.desc, name) // ORDER BY "email" DESC, "name"
                 .limit(5, offset: 1)     // LIMIT 5 OFFSET 1
```


#### Selecting Columns

By default, [queries](#queries) select every column of the result set (using
`SELECT *`). We can use the `select` function with a list of
[expressions](#expressions) to return specific columns instead.

```swift
for user in try db.prepare(users.select(id, email)) {
    print("id: \(user[id]), email: \(user[email])")
    // id: 1, email: alice@mac.com
}
// SELECT "id", "email" FROM "users"
```

We can access the results of more complex expressions by holding onto a
reference of the expression itself.

```swift
let sentence = name + " is " + cast(age) as Expression<String?> + " years old!"
for user in users.select(sentence) {
    print(user[sentence])
    // Optional("Alice is 30 years old!")
}
// SELECT ((("name" || ' is ') || CAST ("age" AS TEXT)) || ' years old!') FROM "users"
```


#### Joining Other Tables

We can join tables using a [query’s](#queries) `join` function.

```swift
users.join(posts, on: user_id == users[id])
// SELECT * FROM "users" INNER JOIN "posts" ON ("user_id" = "users"."id")
```

The `join` function takes a [query](#queries) object (for the table being
joined on), a join condition (`on`), and is prefixed with an optional join
type (default: `.inner`). Join conditions can be built using [filter
operators and functions](#filter-operators-and-functions), generally require
[namespacing](#column-namespacing), and sometimes require
[aliasing](#table-aliasing).


##### Column Namespacing

When joining tables, column names can become ambiguous. _E.g._, both tables
may have an `id` column.

```swift
let query = users.join(posts, on: user_id == id)
// assertion failure: ambiguous column 'id'
```

We can disambiguate by namespacing `id`.

```swift
let query = users.join(posts, on: user_id == users[id])
// SELECT * FROM "users" INNER JOIN "posts" ON ("user_id" = "users"."id")
```

Namespacing is achieved by subscripting a [query](#queries) with a [column
expression](#expressions) (_e.g._, `users[id]` above becomes `users.id`).

> _Note:_ We can namespace all of a table’s columns using `*`.
>
> ```swift
> let query = users.select(users[*])
> // SELECT "users".* FROM "users"
> ```


##### Table Aliasing

Occasionally, we need to join a table to itself, in which case we must alias
the table with another name. We can achieve this using the
[query’s](#queries) `alias` function.

```swift
let managers = users.alias("managers")

let query = users.join(managers, on: managers[id] == users[managerId])
// SELECT * FROM "users"
// INNER JOIN ("users") AS "managers" ON ("managers"."id" = "users"."manager_id")
```

If query results can have ambiguous column names, row values should be
accessed with namespaced [column expressions](#expressions). In the above
case, `SELECT *` immediately namespaces all columns of the result set.

```swift
let user = try db.pluck(query)
user[id]           // fatal error: ambiguous column 'id'
                   // (please disambiguate: ["users"."id", "managers"."id"])

user[users[id]]    // returns "users"."id"
user[managers[id]] // returns "managers"."id"
```


#### Filtering Rows

SQLite.swift filters rows using a [query’s](#queries) `filter` function with
a boolean [expression](#expressions) (`Expression<Bool>`).

```swift
users.filter(id == 1)
// SELECT * FROM "users" WHERE ("id" = 1)

users.filter([1, 2, 3, 4, 5].contains(id))
// SELECT * FROM "users" WHERE ("id" IN (1, 2, 3, 4, 5))

users.filter(email.like("%@mac.com"))
// SELECT * FROM "users" WHERE ("email" LIKE '%@mac.com')

users.filter(verified && name.lowercaseString == "alice")
// SELECT * FROM "users" WHERE ("verified" AND (lower("name") == 'alice'))

users.filter(verified || balance >= 10_000)
// SELECT * FROM "users" WHERE ("verified" OR ("balance" >= 10000.0))
```

We can build our own boolean expressions by using one of the many [filter
operators and functions](#filter-operators-and-functions).

Instead of `filter` we can also use the `where` function which is an alias:

```swift
users.where(id == 1)
// SELECT * FROM "users" WHERE ("id" = 1)
```

##### Filter Operators and Functions

SQLite.swift defines a number of operators for building filtering predicates.
Operators and functions work together in a type-safe manner, so attempting to
equate or compare different types will prevent compilation.


###### Infix Filter Operators

| Swift | Types                            | SQLite         |
| ----- | -------------------------------- | -------------- |
| `==`  | `Equatable -> Bool`              | `=`/`IS`*      |
| `!=`  | `Equatable -> Bool`              | `!=`/`IS NOT`* |
| `>`   | `Comparable -> Bool`             | `>`            |
| `>=`  | `Comparable -> Bool`             | `>=`           |
| `<`   | `Comparable -> Bool`             | `<`            |
| `<=`  | `Comparable -> Bool`             | `<=`           |
| `~=`  | `(Interval, Comparable) -> Bool` | `BETWEEN`      |
| `&&`  | `Bool -> Bool`                   | `AND`          |
| `\|\|`| `Bool -> Bool`                   | `OR`           |
| `===` | `Equatable -> Bool`              | `IS`           |
| `!==` | `Equatable -> Bool`              | `IS NOT`       |

> * When comparing against `nil`, SQLite.swift will use `IS` and `IS NOT`
> accordingly.


###### Prefix Filter Operators

| Swift | Types              | SQLite |
| ----- | ------------------ | ------ |
| `!`   | `Bool -> Bool`     | `NOT`  |


###### Filtering Functions

| Swift      | Types                   | SQLite  |
| ---------- | ----------------------- | ------- |
| `like`     | `String -> Bool`        | `LIKE`  |
| `glob`     | `String -> Bool`        | `GLOB`  |
| `match`    | `String -> Bool`        | `MATCH` |
| `contains` | `(Array<T>, T) -> Bool` | `IN`    |


<!-- TODO
#### Grouping Results
-->


#### Sorting Rows

We can pre-sort returned rows using the [query’s](#queries) `order` function.

_E.g._, to return users sorted by `email`, then `name`, in ascending order:

```swift
users.order(email, name)
// SELECT * FROM "users" ORDER BY "email", "name"
```

The `order` function takes a list of [column expressions](#expressions).

`Expression` objects have two computed properties to assist sorting: `asc`
and `desc`. These properties append the expression with `ASC` and `DESC` to
mark ascending and descending order respectively.

```swift
users.order(email.desc, name.asc)
// SELECT * FROM "users" ORDER BY "email" DESC, "name" ASC
```


#### Limiting and Paging Results

We can limit and skip returned rows using a [query’s](#queries) `limit`
function (and its optional `offset` parameter).

```swift
users.limit(5)
// SELECT * FROM "users" LIMIT 5

users.limit(5, offset: 5)
// SELECT * FROM "users" LIMIT 5 OFFSET 5
```


#### Recursive and Hierarchical Queries

We can perform a recursive or hierarchical query using a [query's](#queries)
[`WITH`](https://sqlite.org/lang_with.html) function.

```swift
// Get the management chain for the manager with id == 8

let chain = Table("chain")
let id = Expression<Int64>("id")
let managerId = Expression<Int64>("manager_id")

let query = managers
    .where(id == 8)
    .union(chain.join(managers, on: chain[managerId] == managers[id])

chain.with(chain, recursive: true, as: query)
// WITH RECURSIVE
//   "chain" AS (
//     SELECT * FROM "managers" WHERE "id" = 8
//     UNION
//     SELECT * from "chain"
//     JOIN "managers" ON "chain"."manager_id" = "managers"."id"
//   )
// SELECT * FROM "chain"
```

Column names and a materialization hint can optionally be provided.

```swift
// Add a "level" column to the query representing manager's position in the chain
let level = Expression<Int64>("level")

let queryWithLevel =
    managers
        .select(id, managerId, 0)
        .where(id == 8)
        .union(
            chain
                .select(managers[id], managers[manager_id], level + 1)
                .join(managers, on: chain[managerId] == managers[id])
        )

chain.with(chain,
           columns: [id, managerId, level],
           recursive: true,
           hint: .materialize,
           as: queryWithLevel)
// WITH RECURSIVE
//   "chain" ("id", "manager_id", "level") AS MATERIALIZED (
//     SELECT ("id", "manager_id", 0) FROM "managers" WHERE "id" = 8
//     UNION
//     SELECT ("manager"."id", "manager"."manager_id", "level" + 1) FROM "chain"
//     JOIN "managers" ON "chain"."manager_id" = "managers"."id"
//   )
// SELECT * FROM "chain"
```


#### Aggregation

[Queries](#queries) come with a number of functions that quickly return
aggregate scalar values from the table. These mirror the [core aggregate
functions](#aggregate-sqlite-functions) and are executed immediately against
the query.

```swift
let count = try db.scalar(users.count)
// SELECT count(*) FROM "users"
```

Filtered queries will appropriately filter aggregate values.

```swift
let count = try db.scalar(users.filter(name != nil).count)
// SELECT count(*) FROM "users" WHERE "name" IS NOT NULL
```

  - `count` as a computed property on a query (see examples above) returns
    the total number of rows matching the query.

    `count` as a computed property on a column expression returns the total
    number of rows where that column is not `NULL`.

    ```swift
    let count = try db.scalar(users.select(name.count)) // -> Int
    // SELECT count("name") FROM "users"
    ```

  - `max` takes a comparable column expression and returns the largest value
    if any exists.

    ```swift
    let max = try db.scalar(users.select(id.max)) // -> Int64?
    // SELECT max("id") FROM "users"
    ```

  - `min` takes a comparable column expression and returns the smallest value
    if any exists.

    ```swift
    let min = try db.scalar(users.select(id.min)) // -> Int64?
    // SELECT min("id") FROM "users"
    ```

  - `average` takes a numeric column expression and returns the average row
    value (as a `Double`) if any exists.

    ```swift
    let average = try db.scalar(users.select(balance.average)) // -> Double?
    // SELECT avg("balance") FROM "users"
    ```

  - `sum` takes a numeric column expression and returns the sum total of all
    rows if any exist.

    ```swift
    let sum = try db.scalar(users.select(balance.sum)) // -> Double?
    // SELECT sum("balance") FROM "users"
    ```

  - `total`, like `sum`, takes a numeric column expression and returns the
    sum total of all rows, but in this case always returns a `Double`, and
    returns `0.0` for an empty query.

    ```swift
    let total = try db.scalar(users.select(balance.total)) // -> Double
    // SELECT total("balance") FROM "users"
    ```

> _Note:_ Expressions can be prefixed with a `DISTINCT` clause by calling the
> `distinct` computed property.
>
> ```swift
> let count = try db.scalar(users.select(name.distinct.count) // -> Int
> // SELECT count(DISTINCT "name") FROM "users"
> ```

## Upserting Rows

We can upsert rows into a table by calling a [query’s](#queries) `upsert`
function with a list of [setters](#setters)—typically [typed column
expressions](#expressions) and values (which can also be expressions)—each
joined by the `<-` operator. Upserting is like inserting, except if there is a
conflict on the specified column value, SQLite will perform an update on the row instead.

```swift
try db.run(users.upsert(email <- "alice@mac.com", name <- "Alice", onConflictOf: email))
// INSERT INTO "users" ("email", "name") VALUES ('alice@mac.com', 'Alice') ON CONFLICT (\"email\") DO UPDATE SET \"name\" = \"excluded\".\"name\"
```

The `upsert` function, when run successfully, returns an `Int64` representing
the inserted row’s [`ROWID`][ROWID].

```swift
do {
    let rowid = try db.run(users.upsert(email <- "alice@mac.com", name <- "Alice", onConflictOf: email))
    print("inserted id: \(rowid)")
} catch {
    print("insertion failed: \(error)")
}
```

The [`insert`](#inserting-rows), [`update`](#updating-rows), and [`delete`](#deleting-rows) functions
follow similar patterns.

## Updating Rows

We can update a table’s rows by calling a [query’s](#queries) `update`
function with a list of [setters](#setters)—typically [typed column
expressions](#expressions) and values (which can also be expressions)—each
joined by the `<-` operator.

When an unscoped query calls `update`, it will update _every_ row in the
table.

```swift
try db.run(users.update(email <- "alice@me.com"))
// UPDATE "users" SET "email" = 'alice@me.com'
```

Be sure to scope `UPDATE` statements beforehand using [the `filter` function
](#filtering-rows).

```swift
let alice = users.filter(id == 1)
try db.run(alice.update(email <- "alice@me.com"))
// UPDATE "users" SET "email" = 'alice@me.com' WHERE ("id" = 1)
```

The `update` function returns an `Int` representing the number of updated
rows.

```swift
do {
    if try db.run(alice.update(email <- "alice@me.com")) > 0 {
        print("updated alice")
    } else {
        print("alice not found")
    }
} catch {
    print("update failed: \(error)")
}
```


## Deleting Rows

We can delete rows from a table by calling a [query’s](#queries) `delete`
function.

When an unscoped query calls `delete`, it will delete _every_ row in the
table.

```swift
try db.run(users.delete())
// DELETE FROM "users"
```

Be sure to scope `DELETE` statements beforehand using
[the `filter` function](#filtering-rows).

```swift
let alice = users.filter(id == 1)
try db.run(alice.delete())
// DELETE FROM "users" WHERE ("id" = 1)
```

The `delete` function returns an `Int` representing the number of deleted
rows.

```swift
do {
    if try db.run(alice.delete()) > 0 {
        print("deleted alice")
    } else {
        print("alice not found")
    }
} catch {
    print("delete failed: \(error)")
}
```


## Transactions and Savepoints

Using the `transaction` and `savepoint` functions, we can run a series of
statements in a transaction. If a single statement fails or the block throws
an error, the changes will be rolled back.

```swift
try db.transaction {
    let rowid = try db.run(users.insert(email <- "betty@icloud.com"))
    try db.run(users.insert(email <- "cathy@icloud.com", managerId <- rowid))
}
// BEGIN DEFERRED TRANSACTION
// INSERT INTO "users" ("email") VALUES ('betty@icloud.com')
// INSERT INTO "users" ("email", "manager_id") VALUES ('cathy@icloud.com', 2)
// COMMIT TRANSACTION
```

> _Note:_ Transactions run in a serial queue.

## Querying the Schema

We can obtain generic information about objects in the current schema with a `SchemaReader`:

```swift
let schema = db.schema
```

To query the data:

```swift
let indexes = try schema.objectDefinitions(type: .index)
let tables = try schema.objectDefinitions(type: .table)
let triggers = try schema.objectDefinitions(type: .trigger)
```

### Indexes and Columns

Specialized methods are available to get more detailed information:

```swift
let indexes = try schema.indexDefinitions("users")
let columns = try schema.columnDefinitions("users")

for index in indexes {
    print("\(index.name) columns:\(index.columns))")
}
for column in columns {
    print("\(column.name) pk:\(column.primaryKey) nullable: \(column.nullable)")
}
```

## Altering the Schema

SQLite.swift comes with several functions (in addition to `Table.create`) for
altering a database schema in a type-safe manner.

### Renaming Tables

We can build an `ALTER TABLE … RENAME TO` statement by calling the `rename`
function on a `Table` or `VirtualTable`.

```swift
try db.run(users.rename(Table("users_old")))
// ALTER TABLE "users" RENAME TO "users_old"
```

### Dropping Tables

We can build
[`DROP TABLE` statements](https://www.sqlite.org/lang_droptable.html)
by calling the `dropTable` function on a `SchemaType`.

```swift
try db.run(users.drop())
// DROP TABLE "users"
```

The `drop` function has one additional parameter, `ifExists`, which (when
`true`) adds an `IF EXISTS` clause to the statement.

```swift
try db.run(users.drop(ifExists: true))
// DROP TABLE IF EXISTS "users"
```

### Adding Columns

We can add columns to a table by calling `addColumn` function on a `Table`.
SQLite.swift enforces
[the same limited subset](https://www.sqlite.org/lang_altertable.html) of
`ALTER TABLE` that SQLite supports.

```swift
try db.run(users.addColumn(suffix))
// ALTER TABLE "users" ADD COLUMN "suffix" TEXT
```

#### Added Column Constraints

The `addColumn` function shares several of the same [`column` function
parameters](#column-constraints) used when [creating
tables](#creating-a-table).

  - `check` attaches a `CHECK` constraint to a column definition in the form
    of a boolean expression (`Expression<Bool>`). (See also the `check`
    function under [Table Constraints](#table-constraints).)

    ```swift
    try db.run(users.addColumn(suffix, check: ["JR", "SR"].contains(suffix)))
    // ALTER TABLE "users" ADD COLUMN "suffix" TEXT CHECK ("suffix" IN ('JR', 'SR'))
    ```

  - `defaultValue` adds a `DEFAULT` clause to a column definition and _only_
    accepts a value matching the column’s type. This value is used if none is
    explicitly provided during [an `INSERT`](#inserting-rows).

    ```swift
    try db.run(users.addColumn(suffix, defaultValue: "SR"))
    // ALTER TABLE "users" ADD COLUMN "suffix" TEXT DEFAULT 'SR'
    ```

    > _Note:_ Unlike the [`CREATE TABLE` constraint](#table-constraints),
    > default values may not be expression structures (including
    > `CURRENT_TIME`, `CURRENT_DATE`, or `CURRENT_TIMESTAMP`).

  - `collate` adds a `COLLATE` clause to `Expression<String>` (and
    `Expression<String?>`) column definitions with [a collating
    sequence](https://www.sqlite.org/datatype3.html#collation) defined in the
    `Collation` enumeration.

    ```swift
    try db.run(users.addColumn(email, collate: .nocase))
    // ALTER TABLE "users" ADD COLUMN "email" TEXT NOT NULL COLLATE "NOCASE"

    try db.run(users.addColumn(name, collate: .rtrim))
    // ALTER TABLE "users" ADD COLUMN "name" TEXT COLLATE "RTRIM"
    ```

  - `references` adds a `REFERENCES` clause to `Int64` (and `Int64?`) column
    definitions and accepts a table or namespaced column expression. (See the
    `foreignKey` function under [Table Constraints](#table-constraints) for
    non-integer foreign key support.)

    ```swift
    try db.run(posts.addColumn(userId, references: users, id)
    // ALTER TABLE "posts" ADD COLUMN "user_id" INTEGER REFERENCES "users" ("id")
    ```

### SchemaChanger

Version 0.14.0 introduces `SchemaChanger`, an alternative API to perform more complex
migrations such as renaming columns. These operations work with all versions of
SQLite but use SQL statements such as `ALTER TABLE RENAME COLUMN` when available.

#### Adding Columns

```swift
let newColumn = ColumnDefinition(
    name: "new_text_column",
    type: .TEXT,
    nullable: true,
    defaultValue: .stringLiteral("foo")
)

let schemaChanger = SchemaChanger(connection: db)

try schemaChanger.alter(table: "users") { table in
    table.add(column: newColumn)
}
```

#### Renaming Columns

```swift
let schemaChanger = SchemaChanger(connection: db)
try schemaChanger.alter(table: "users") { table in
    table.rename(column: "old_name", to: "new_name")
}
```

#### Dropping Columns

```swift
let schemaChanger = SchemaChanger(connection: db)
try schemaChanger.alter(table: "users") { table in
    table.drop(column: "email")
}
```

#### Renaming/Dropping Tables

```swift
let schemaChanger = SchemaChanger(connection: db)

try schemaChanger.rename(table: "users", to: "users_new")
try schemaChanger.drop(table: "emails", ifExists: false)
```

#### Creating Tables

```swift
let schemaChanger = SchemaChanger(connection: db)

try schemaChanger.create(table: "users") { table in 
    table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER))
    table.add(column: .init(name: "name", type: .TEXT, nullable: false))            
}
``` 

### Indexes


#### Creating Indexes

We can build
[`CREATE INDEX` statements](https://www.sqlite.org/lang_createindex.html)
by calling the `createIndex` function on a `SchemaType`.

```swift
try db.run(users.createIndex(email))
// CREATE INDEX "index_users_on_email" ON "users" ("email")
```

The index name is generated automatically based on the table and column
names.

The `createIndex` function has a couple default parameters we can override.

  - `unique` adds a `UNIQUE` constraint to the index. Default: `false`.

    ```swift
    try db.run(users.createIndex(email, unique: true))
    // CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email")
    ```

  - `ifNotExists` adds an `IF NOT EXISTS` clause to the `CREATE TABLE`
    statement (which will bail out gracefully if the table already exists).
    Default: `false`.

    ```swift
    try db.run(users.createIndex(email, ifNotExists: true))
    // CREATE INDEX IF NOT EXISTS "index_users_on_email" ON "users" ("email")
    ```


#### Dropping Indexes

We can build
[`DROP INDEX` statements](https://www.sqlite.org/lang_dropindex.html) by
calling the `dropIndex` function on a `SchemaType`.

```swift
try db.run(users.dropIndex(email))
// DROP INDEX "index_users_on_email"
```

The `dropIndex` function has one additional parameter, `ifExists`, which
(when `true`) adds an `IF EXISTS` clause to the statement.

```swift
try db.run(users.dropIndex(email, ifExists: true))
// DROP INDEX IF EXISTS "index_users_on_email"
```

### Migrations and Schema Versioning

You can use the convenience property on `Connection` to query and set the
[`PRAGMA user_version`](https://sqlite.org/pragma.html#pragma_user_version).

This is a great way to manage your schema’s version over migrations.
You can conditionally run your migrations along the lines of:

```swift
if db.userVersion == 0 {
    // handle first migration
    db.userVersion = 1
}
if db.userVersion == 1 {
    // handle second migration
    db.userVersion = 2
}
```

For more complex migration requirements check out the schema management
system [SQLiteMigrationManager.swift][].

## Custom Types

SQLite.swift supports serializing and deserializing any custom type as long
as it conforms to the `Value` protocol.

```swift
protocol Value {
    typealias Datatype: Binding
    class var declaredDatatype: String { get }
    class func fromDatatypeValue(datatypeValue: Datatype) -> Self
    var datatypeValue: Datatype { get }
}
```

The `Datatype` must be one of the basic Swift types that values are bridged
through before serialization and deserialization (see [Building Type-Safe SQL
](#building-type-safe-sql) for a list of types).

> ⚠ _Note:_ `Binding` is a protocol that SQLite.swift uses internally to
> directly map SQLite types to Swift types. **Do _not_** conform custom types
> to the `Binding` protocol.


### Date-Time Values

In SQLite, `DATETIME` columns can be treated as strings or numbers, so we can
transparently bridge `Date` objects through Swift’s `String` types.

We can use these types directly in SQLite statements.

```swift
let published_at = Expression<Date>("published_at")

let published = posts.filter(published_at <= Date())
// SELECT * FROM "posts" WHERE "published_at" <= '2014-11-18T12:45:30.000'

let startDate = Date(timeIntervalSince1970: 0)
let published = posts.filter(startDate...Date() ~= published_at)
// SELECT * FROM "posts" WHERE "published_at" BETWEEN '1970-01-01T00:00:00.000' AND '2014-11-18T12:45:30.000'
```


### Binary Data

We can bridge any type that can be initialized from and encoded to `Data`.

```swift
extension UIImage: Value {
    public class var declaredDatatype: String {
        return Blob.declaredDatatype
    }
    public class func fromDatatypeValue(blobValue: Blob) -> UIImage {
        return UIImage(data: Data.fromDatatypeValue(blobValue))!
    }
    public var datatypeValue: Blob {
        return UIImagePNGRepresentation(self)!.datatypeValue
    }

}
```

> _Note:_ See the [Archives and Serializations Programming Guide][] for more
> information on encoding and decoding custom types.


[Archives and Serializations Programming Guide]: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Archiving/Archiving.html

## Codable Types

[Codable types][Encoding and Decoding Custom Types] were introduced as a part
of Swift 4 to  allow serializing and deserializing types. SQLite.swift supports
the insertion, updating, and retrieval of basic Codable types.

[Encoding and Decoding Custom Types]: https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

### Inserting Codable Types

Queries have a method to allow inserting an [Encodable][] type.

```swift
struct User: Encodable {
    let name: String
}
try db.run(users.insert(User(name: "test")))

```

There are two other parameters also available to this method:

- `userInfo` is a dictionary that is passed to the encoder and made available
  to encodable types to allow customizing their behavior.

- `otherSetters` allows you to specify additional setters on top of those
  that are generated from the encodable types themselves.

[Encodable]: https://developer.apple.com/documentation/swift/encodable

### Updating Codable Types

Queries have a method to allow updating an Encodable type.

```swift
try db.run(users.filter(id == userId).update(user))

```

> ⚠ Unless filtered, using the update method on an instance of a Codable
> type updates all table rows.

There are two other parameters also available to this method:

- `userInfo` is a dictionary that is passed to the encoder and made available
  to encodable types to allow customizing their behavior.

- `otherSetters` allows you to specify additional setters on top of those
  that are generated from the encodable types themselves.

### Retrieving Codable Types

Rows have a method to decode a [Decodable][] type.

```swift
let loadedUsers: [User] = try db.prepare(users).map { row in
    return try row.decode()
}
```

You can also create a decoder to use manually yourself. This can be useful
for example if you are using the
[Facade pattern](https://en.wikipedia.org/wiki/Facade_pattern) to hide
subclasses behind a super class. For example, you may want to encode an Image
type that can be multiple different formats such as PNGImage, JPGImage, or
HEIFImage. You will need to determine the correct subclass before you know
which type to decode.

```swift
enum ImageCodingKeys: String, CodingKey {
    case kind
}

enum ImageKind: Int, Codable {
    case png, jpg, heif
}

let loadedImages: [Image] = try db.prepare(images).map { row in
    let decoder = row.decoder()
    let container = try decoder.container(keyedBy: ImageCodingKeys.self)
    switch try container.decode(ImageKind.self, forKey: .kind) {
    case .png:
        return try PNGImage(from: decoder)
    case .jpg:
        return try JPGImage(from: decoder)
    case .heif:
        return try HEIFImage(from: decoder)
    }
}
```

Both of the above methods also have the following optional parameter:

- `userInfo` is a dictionary that is passed to the decoder and made available
  to decodable types to allow customizing their behavior.

[Decodable]: https://developer.apple.com/documentation/swift/decodable

### Restrictions

There are a few restrictions on using Codable types:

- The encodable and decodable objects can only use the following types:
    - Int, Bool, Float, Double, String, Date
    - Nested Codable types that will be encoded as JSON to a single column
- These methods will not handle object relationships for you. You must write
  your own Codable and Decodable implementations if you wish to support this.
- The Codable types may not try to access nested containers or nested unkeyed
  containers
- The Codable types may not access single value containers or unkeyed
  containers
- The Codable types may not access super decoders or encoders

## Other Operators

In addition to [filter operators](#filtering-infix-operators), SQLite.swift
defines a number of operators that can modify expression values with
arithmetic, bitwise operations, and concatenation.


###### Other Infix Operators

| Swift | Types                            | SQLite   |
| ----- | -------------------------------- | -------- |
| `+`   | `Number -> Number`               | `+`      |
| `-`   | `Number -> Number`               | `-`      |
| `*`   | `Number -> Number`               | `*`      |
| `/`   | `Number -> Number`               | `/`      |
| `%`   | `Int -> Int`                     | `%`      |
| `<<`  | `Int -> Int`                     | `<<`     |
| `>>`  | `Int -> Int`                     | `>>`     |
| `&`   | `Int -> Int`                     | `&`      |
| `\|`  | `Int -> Int`                     | `\|`     |
| `+`   | `String -> String`               | `\|\|`   |

> _Note:_ SQLite.swift also defines a bitwise XOR operator, `^`, which
> expands the expression `lhs ^ rhs` to `~(lhs & rhs) & (lhs | rhs)`.


###### Other Prefix Operators

| Swift | Types              | SQLite |
| ----- | ------------------ | ------ |
| `~`   | `Int -> Int`       | `~`    |
| `-`   | `Number -> Number` | `-`    |


## Core SQLite Functions

Many of SQLite’s [core functions](https://www.sqlite.org/lang_corefunc.html)
have been surfaced in and type-audited for SQLite.swift.

> _Note:_ SQLite.swift aliases the `??` operator to the `ifnull` function.
>
> ```swift
> name ?? email // ifnull("name", "email")
> ```


## Aggregate SQLite Functions

Most of SQLite’s
[aggregate functions](https://www.sqlite.org/lang_aggfunc.html) have been
surfaced in and type-audited for SQLite.swift.

## Window SQLite Functions

Most of SQLite's [window functions](https://www.sqlite.org/windowfunctions.html) have been
surfaced in and type-audited for SQLite.swift. Currently only `OVER (ORDER BY ...)` windowing is possible. 

## Date and Time functions

SQLite's [date and time](https://www.sqlite.org/lang_datefunc.html)
functions are available:

```swift
DateFunctions.date("now")
// date('now')
Date().date
// date('2007-01-09T09:41:00.000')
Expression<Date>("date").date
// date("date")
```

## Custom SQL Functions

We can create custom SQL functions by calling `createFunction` on a database
connection.

For example, to give queries access to
[`MobileCoreServices.UTTypeConformsTo`][UTTypeConformsTo], we can
write the following:

```swift
import MobileCoreServices

let typeConformsTo: (Expression<String>, Expression<String>) -> Expression<Bool> = (
    try db.createFunction("typeConformsTo", deterministic: true) { UTI, conformsToUTI in
        return UTTypeConformsTo(UTI, conformsToUTI)
    }
)
```

> _Note:_ The optional `deterministic` parameter is an optimization that
> causes the function to be created with
> [`SQLITE_DETERMINISTIC`](https://www.sqlite.org/c3ref/c_deterministic.html).

Note `typeConformsTo`’s signature:

```swift
(Expression<String>, Expression<String>) -> Expression<Bool>
```

Because of this, `createFunction` expects a block with the following
signature:

```swift
(String, String) -> Bool
```

Once assigned, the closure can be called wherever boolean expressions are
accepted.

```swift
let attachments = Table("attachments")
let UTI = Expression<String>("UTI")

let images = attachments.filter(typeConformsTo(UTI, kUTTypeImage))
// SELECT * FROM "attachments" WHERE "typeConformsTo"("UTI", 'public.image')
```

> _Note:_ The return type of a function must be
> [a core SQL type](#building-type-safe-sql) or [conform to `Value`](#custom-types).

We can create loosely-typed functions by handling an array of raw arguments,
instead.

```swift
db.createFunction("typeConformsTo", deterministic: true) { args in
    guard let UTI = args[0] as? String, conformsToUTI = args[1] as? String else { return nil }
    return UTTypeConformsTo(UTI, conformsToUTI)
}
```

Creating a loosely-typed function cannot return a closure and instead must be
wrapped manually or executed [using raw SQL](#executing-arbitrary-sql).

```swift
let stmt = try db.prepare("SELECT * FROM attachments WHERE typeConformsTo(UTI, ?)")
for row in stmt.bind(kUTTypeImage) { /* ... */ }
```

> _Note:_ Prepared queries can be reused, and long lived prepared queries should be `reset()` after each use. Otherwise, the transaction (either [implicit or explicit](https://www.sqlite.org/lang_transaction.html#implicit_versus_explicit_transactions)) will be held open until the query is reset or finalized. This can affect performance. Statements are reset automatically during `deinit`.
>
> ```swift
> someObj.statement = try db.prepare("SELECT * FROM attachments WHERE typeConformsTo(UTI, ?)")
> for row in someObj.statement.bind(kUTTypeImage) { /* ... */ }
> someObj.statement.reset()
> ```

[UTTypeConformsTo]: https://developer.apple.com/documentation/coreservices/1444079-uttypeconformsto

## Custom Aggregations

We can create custom aggregation functions by calling `createAggregation`:

```swift
let reduce: (String, [Binding?]) -> String = { (last, bindings) in
    last + " " + (bindings.first as? String ?? "")
}

db.createAggregation("customConcat", initialValue: "", reduce: reduce, result: { $0 })
let result = db.prepare("SELECT customConcat(email) FROM users").scalar() as! String
```

## Custom Collations

We can create custom collating sequences by calling `createCollation` on a
database connection.

```swift
try db.createCollation("NODIACRITIC") { lhs, rhs in
    return lhs.compare(rhs, options: .diacriticInsensitiveSearch)
}
```

We can reference a custom collation using the `Custom` member of the
`Collation` enumeration.

```swift
restaurants.order(collate(.custom("NODIACRITIC"), name))
// SELECT * FROM "restaurants" ORDER BY "name" COLLATE "NODIACRITIC"
```


## Full-text Search

We can create a virtual table using the [FTS4
module](http://www.sqlite.org/fts3.html) by calling `create` on a
`VirtualTable`.

```swift
let emails = VirtualTable("emails")
let subject = Expression<String>("subject")
let body = Expression<String>("body")

try db.run(emails.create(.FTS4(subject, body)))
// CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body")
```

We can specify a [tokenizer](http://www.sqlite.org/fts3.html#tokenizer) using the `tokenize` parameter.

```swift
try db.run(emails.create(.FTS4([subject, body], tokenize: .Porter)))
// CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body", tokenize=porter)
```

We can set the full range of parameters by creating a `FTS4Config` object.

```swift
let emails = VirtualTable("emails")
let subject = Expression<String>("subject")
let body = Expression<String>("body")
let config = FTS4Config()
    .column(subject)
    .column(body, [.unindexed])
    .languageId("lid")
    .order(.desc)

try db.run(emails.create(.FTS4(config))
// CREATE VIRTUAL TABLE "emails" USING fts4("subject", "body", notindexed="body", languageid="lid", order="desc")
```

Once we insert a few rows, we can search using the `match` function, which
takes a table or column as its first argument and a query string as its
second.

```swift
try db.run(emails.insert(
    subject <- "Just Checking In",
    body <- "Hey, I was just wondering...did you get my last email?"
))

let wonderfulEmails: QueryType = emails.match("wonder*")
// SELECT * FROM "emails" WHERE "emails" MATCH 'wonder*'

let replies = emails.filter(subject.match("Re:*"))
// SELECT * FROM "emails" WHERE "subject" MATCH 'Re:*'
```

### FTS5

When linking against a version of SQLite with
[FTS5](http://www.sqlite.org/fts5.html) enabled we can create the virtual
table in a similar fashion.

```swift
let emails = VirtualTable("emails")
let subject = Expression<String>("subject")
let body = Expression<String>("body")
let config = FTS5Config()
    .column(subject)
    .column(body, [.unindexed])

try db.run(emails.create(.FTS5(config)))
// CREATE VIRTUAL TABLE "emails" USING fts5("subject", "body" UNINDEXED)

// Note that FTS5 uses a different syntax to select columns, so we need to rewrite
// the last FTS4 query above as:
let replies = emails.filter(emails.match("subject:\"Re:\"*"))
// SELECT * FROM "emails" WHERE "emails" MATCH 'subject:"Re:"*'
```

## Executing Arbitrary SQL

Though we recommend you stick with SQLite.swift’s
[type-safe system](#building-type-safe-sql) whenever possible, it is possible
to simply and safely prepare and execute raw SQL statements via a `Database` connection
using the following functions.

  - `execute` runs an arbitrary number of SQL statements as a convenience.

    ```swift
    try db.execute("""
        BEGIN TRANSACTION;
        CREATE TABLE users (
            id INTEGER PRIMARY KEY NOT NULL,
            email TEXT UNIQUE NOT NULL,
            name TEXT
        );
        CREATE TABLE posts (
            id INTEGER PRIMARY KEY NOT NULL,
            title TEXT NOT NULL,
            body TEXT NOT NULL,
            published_at DATETIME
        );
        PRAGMA user_version = 1;
        COMMIT TRANSACTION;
        """
    )
    ```

  - `prepare` prepares a single `Statement` object from a SQL string,
      optionally binds values to it (using the statement’s `bind` function),
      and returns the statement for deferred execution.

    ```swift
    let stmt = try db.prepare("INSERT INTO users (email) VALUES (?)")
    ```

    Once prepared, statements may be executed using `run`, binding any
    unbound parameters.

    ```swift
    try stmt.run("alice@mac.com")
    db.changes // -> {Some 1}
    ```

    Statements with results may be iterated over, using the columnNames if
    useful.

    ```swift
    let stmt = try db.prepare("SELECT id, email FROM users")
    for row in stmt {
        for (index, name) in stmt.columnNames.enumerated() {
            print ("\(name):\(row[index]!)")
            // id: Optional(1), email: Optional("alice@mac.com")
        }
    }
    ```

  - `run` prepares a single `Statement` object from a SQL string, optionally
    binds values to it (using the statement’s `bind` function), executes,
    and returns the statement.

    ```swift
    try db.run("INSERT INTO users (email) VALUES (?)", "alice@mac.com")
    ```

  - `scalar` prepares a single `Statement` object from a SQL string,
      optionally binds values to it (using the statement’s `bind` function),
      executes, and returns the first value of the first row.

    ```swift
    let count = try db.scalar("SELECT count(*) FROM users") as! Int64
    ```

    Statements also have a `scalar` function, which can optionally re-bind
    values at execution.

    ```swift
    let stmt = try db.prepare("SELECT count (*) FROM users")
    let count = try stmt.scalar() as! Int64
    ```

## Online Database Backup

To copy a database to another using the
[SQLite Online Backup API](https://sqlite.org/backup.html):

```swift
// creates an in-memory copy of db.sqlite
let db = try Connection("db.sqlite")
let target = try Connection(.inMemory)

let backup = try db.backup(usingConnection: target)
try backup.step()
```

## Attaching and detaching databases

We can [ATTACH](https://www3.sqlite.org/lang_attach.html) and [DETACH](https://www3.sqlite.org/lang_detach.html)
databases to an existing connection:

```swift
let db = try Connection("db.sqlite")

try db.attach(.uri("external.sqlite", parameters: [.mode(.readOnly)]), as: "external")
// ATTACH DATABASE 'file:external.sqlite?mode=ro' AS 'external'

let table = Table("table", database: "external")
let count = try db.scalar(table.count)
// SELECT count(*) FROM 'external.table'

try db.detach("external")
// DETACH DATABASE 'external'
```

When compiled for SQLCipher, we can additionally pass a `key` parameter to `attach`:

```swift
try db.attach(.uri("encrypted.sqlite"), as: "encrypted", key: "secret")
// ATTACH DATABASE 'encrypted.sqlite' AS 'encrypted' KEY 'secret'
```

## Logging

We can log SQL using the database’s `trace` function.

```swift
#if DEBUG
    db.trace { print($0) }
#endif
```

## Vacuum

To run the [vacuum](https://www.sqlite.org/lang_vacuum.html) command:

```swift
try db.vacuum()
```


[ROWID]: https://sqlite.org/lang_createtable.html#rowid
[SQLiteMigrationManager.swift]: https://github.com/garriguv/SQLiteMigrationManager.swift


================================================
FILE: Documentation/Linux.md
================================================
# Linux

## Limitations

* Custom functions/aggregations are currently not supported and crash, caused by a bug in Swift.
See [#1071](https://github.com/stephencelis/SQLite.swift/issues/1071).

## Installation

On Linux you should enable the `SQLiteSwiftCSQLite` trait to automatically
embed SQLite:

  ```swift
  dependencies: [
    .package(url: "https://github.com/stephencelis/SQLite.swift.git", 
             from: "0.16.0",
             traits: ["SQLiteSwiftCSQLite"])
  ]
  ```

See the [main documentation](Index.md#available-traits) for a list of all available traits.

## Debugging

### Create and launch docker container

```shell
$ docker container create swift:focal
$ docker run --cap-add=SYS_PTRACE \
  --security-opt seccomp=unconfined \
  --security-opt apparmor=unconfined \
  -i -t swift:focal bash
```

### Compile and run tests in debugger

```shell
$ apt-get update && apt-get install libsqlite3-dev
$ git clone https://github.com/stephencelis/SQLite.swift.git
$ swift test
$ lldb .build/x86_64-unknown-linux-gnu/debug/SQLite.swiftPackageTests.xctest
(lldb) target create ".build/x86_64-unknown-linux-gnu/debug/SQLite.swiftPackageTests.xctest"
(lldb) run
```


================================================
FILE: Documentation/Planning.md
================================================
# SQLite.swift Planning

This document captures both near term steps (aka Roadmap) and feature
requests. The goal is to add some visibility and guidance for future
additions and Pull Requests, as well as to keep the Issues list clear of
enhancement requests so that bugs are more visible.

> ⚠ This document is currently not actively maintained. See
> the [0.14.1 milestone](https://github.com/stephencelis/SQLite.swift/issues?q=is%3Aopen+is%3Aissue+milestone%3A0.14.1)
> on Github for additional information about planned features for the next release.

## Roadmap

_Lists agreed upon next steps in approximate priority order._

## Feature Requests

_A gathering point for ideas for new features. In general, the corresponding
issue will be closed once it is added here, with the assumption that it will
be referred to when it comes time to add the corresponding feature._

### Features

 * provide separate threads for update vs read, so updates don't block reads,
   per [#236](https://github.com/stephencelis/SQLite.swift/issues/236)
 * expose triggers, per
   [#164](https://github.com/stephencelis/SQLite.swift/issues/164)

## Suspended Feature Requests

_Features that are not actively being considered, perhaps because of no clean
type-safe way to implement them with the current Swift, or bugs, or just
general uncertainty._


================================================
FILE: Documentation/Release.md
================================================
# SQLite.swift Release checklist

* [ ] Make sure current master branch has a green build
* [ ] Make sure `SQLite.playground` runs without errors
* [ ] Make sure `CHANGELOG.md` is up-to-date
* [ ] Add content to `Documentation/Upgrading.md` if needed
* [ ] Update the version number in `SQLite.swift.podspec`
* [ ] Run `pod lib lint` locally
* [ ] Update the version numbers mentioned in `README.md`, `Documentation/Index.md`
* [ ] Update `MARKETING_VERSION` in `SQLite.xcodeproj/project.pbxproj`
* [ ] Create a tag with the version number (`x.y.z`)
* [ ] Publish to CocoaPods: `pod trunk push`
* [ ] Update the release information on GitHub


================================================
FILE: Documentation/Upgrading.md
================================================
# Upgrading

## 0.13 → 0.14

- `Expression.asSQL()` is no longer available. Expressions now implement `CustomStringConvertible`,
  where `description` returns the SQL.
- `Statement.prepareRowIterator()` is no longer available. Instead, use the methods
  of the same name on `Connection`.
- `Connection.registerTokenizer` is no longer available to register custom FTS4 tokenizers.
- `Setter.asSQL()` is no longer available. Instead, Setter now implement `CustomStringConvertible`,
  where `description` returns the SQL.


================================================
FILE: Gemfile
================================================
source "https://rubygems.org"

# https://github.com/CocoaPods/CocoaPods/pull/12816
gem 'cocoapods', :git => 'https://github.com/jberkel/CocoaPods.git', branch: 'watchos-fourflusher'


================================================
FILE: LICENSE.txt
================================================
(The MIT License)

Copyright (c) 2014-2015 Stephen Celis (<stephen@stephencelis.com>)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
XCODEBUILD = xcodebuild
BUILD_SCHEME = SQLite Mac
IOS_SIMULATOR = iPhone 14
IOS_VERSION = 16.4

# tool settings
SWIFTLINT_VERSION=0.63.1
SWIFTLINT=bin/swiftlint-$(SWIFTLINT_VERSION)
SWIFTLINT_URL=https://github.com/realm/SwiftLint/releases/download/$(SWIFTLINT_VERSION)/portable_swiftlint.zip
XCBEAUTIFY_VERSION=3.1.2
XCBEAUTIFY=bin/xcbeautify-$(XCBEAUTIFY_VERSION)
ifeq ($(shell uname), Linux)
	XCBEAUTIFY_PLATFORM=x86_64-unknown-linux-gnu.tar.xz
else
	XCBEAUTIFY_PLATFORM=universal-apple-macosx.zip
endif
XCBEAUTIFY_URL=https://github.com/cpisciotta/xcbeautify/releases/download/$(XCBEAUTIFY_VERSION)/xcbeautify-$(XCBEAUTIFY_VERSION)-$(XCBEAUTIFY_PLATFORM)
CURL_OPTS=--fail --silent -L --retry 3

ifeq ($(BUILD_SCHEME),SQLite iOS)
	BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)" -destination "platform=iOS Simulator,name=$(IOS_SIMULATOR),OS=$(IOS_VERSION)"
else
	BUILD_ARGUMENTS = -scheme "$(BUILD_SCHEME)"
endif

test: $(XCBEAUTIFY)
	set -o pipefail; \
	$(XCODEBUILD) $(BUILD_ARGUMENTS) test | $(XCBEAUTIFY)

build: $(XCBEAUTIFY)
	set -o pipefail; \
	$(XCODEBUILD) $(BUILD_ARGUMENTS) | $(XCBEAUTIFY)

lint: $(SWIFTLINT)
	$< --strict

lint-fix: $(SWIFTLINT)
	$< --fix

clean:
	$(XCODEBUILD) $(BUILD_ARGUMENTS) clean

repl:
	@$(XCODEBUILD) $(BUILD_ARGUMENTS) -derivedDataPath $(TMPDIR)/SQLite.swift > /dev/null && \
		swift repl -F '$(TMPDIR)/SQLite.swift/Build/Products/Debug'

sloc:
	@zsh -c "grep -vE '^ *//|^$$' Sources/**/*.{swift,h} | wc -l"

$(SWIFTLINT):
	set -e ; \
	curl $(CURL_OPTS) $(SWIFTLINT_URL) -o swiftlint.zip; \
	unzip -o swiftlint.zip swiftlint; \
	mkdir -p bin; \
	mv swiftlint $@ && rm -f swiftlint.zip

$(XCBEAUTIFY):
	set -e; \
	FILE=$(XCBEAUTIFY_PLATFORM); \
	curl $(CURL_OPTS) $(XCBEAUTIFY_URL) -o $$FILE; \
	case "$${FILE#*.}" in \
	  "zip") \
		unzip -o $$FILE release/xcbeautify; \
		;; \
	  "tar.xz") \
	  	tar -xvf $$FILE release/xcbeautify; \
		;; \
	  *) \
		echo "unknown extension $${FILE#*.}!"; \
		exit 1; \
		;; \
	esac; \
	mkdir -p bin; \
	mv release/xcbeautify $@ && rm -f $$FILE;

.PHONY: test clean repl sloc


================================================
FILE: Package.swift
================================================
// swift-tools-version: 6.1
import PackageDescription
let applePlatforms: [PackageDescription.Platform] = [.iOS, .macOS, .watchOS, .tvOS, .visionOS]

let target: Target = .target(
    name: "SQLite",
    dependencies: [
        .product(name: "SQLiteSwiftCSQLite",
                 package: "CSQLite",
                 condition: .when(traits: ["SQLiteSwiftCSQLite"])),
        .product(name: "SQLCipher",
                 package: "SQLCipher.swift",
                 condition: .when(platforms: applePlatforms, traits: ["SQLCipher"]))
    ],
    exclude: ["Info.plist"],
    resources: [.copy("PrivacyInfo.xcprivacy")],
    cSettings: [
        .define("SQLITE_HAS_CODEC", .when(platforms: applePlatforms, traits: ["SQLCipher"]))
    ]
)

let testTarget: Target = .testTarget(
    name: "SQLiteTests",
    dependencies: ["SQLite"],
    exclude: ["Info.plist"],
    resources: [.copy("Resources")]
)

let defaultTraits: Set<String>
#if os(Linux)
defaultTraits = ["SQLiteSwiftCSQLite"]
#else
defaultTraits = ["SystemSQLite"]
#endif

let package = Package(
    name: "SQLite.swift",
    platforms: [
        .iOS(.v12),
        .macOS(.v10_13),
        .watchOS(.v4),
        .tvOS(.v12),
        .visionOS(.v1)
    ],
    products: [
        .library(name: "SQLite", targets: ["SQLite"]),
        .library(name: "SQLite-Dynamic", type: .dynamic, targets: ["SQLite"])
    ],
    traits: [
        .trait(name: "SystemSQLite",
              description: "Uses the system-provided SQLite (on Apple platforms)"),
        .trait(name: "SQLiteSwiftCSQLite",
               description: "Include SQLite from SQLite.swift, based on the toolchain version"),
        // this will note compile, just included for sake of completeness
        .trait(name: "StandaloneSQLite",
               description: "Assumes SQLite to be already available as 'sqlite3'"),
        .trait(name: "SQLCipher",
               description: "Enables SQLCipher encryption when a key is supplied to Connection"),
        .trait(name: "FTS5",
              description: "Enables FTS5 in the embedded SQLite (only supported by SQLiteSwiftCSQLite)"),
        .default(enabledTraits: defaultTraits)
    ],
    dependencies: [
        .package(url: "https://github.com/stephencelis/CSQLite", from: "3.50.4", traits: [.trait(name: "FTS5", condition: .when(traits: ["FTS5"]))]),
        .package(url: "https://github.com/sqlcipher/SQLCipher.swift", from: "4.11.0")
    ],
    targets: [target, testTarget],
    swiftLanguageModes: [.v5],
)


================================================
FILE: README.md
================================================
# SQLite.swift

![Build Status][GitHubActionBadge] [![CocoaPods Version][CocoaPodsVersionBadge]][CocoaPodsVersionLink] [![Swift5 compatible][Swift5Badge]][Swift5Link] [![Platform][PlatformBadge]][PlatformLink] [![Carthage compatible][CartagheBadge]][CarthageLink] [![Join the chat at https://gitter.im/stephencelis/SQLite.swift][GitterBadge]][GitterLink]

A type-safe, [Swift][]-language layer over [SQLite3][].

[SQLite.swift][] provides compile-time confidence in SQL statement
syntax _and_ intent.

## Features

 - A pure-Swift interface
 - A type-safe, optional-aware SQL expression builder
 - A flexible, chainable, lazy-executing query layer
 - Automatically-typed data access
 - A lightweight, uncomplicated query and parameter binding interface
 - Developer-friendly error handling and debugging
 - [Full-text search][] support
 - [Well-documented][See Documentation]
 - Extensively tested
 - [SQLCipher][] support via Swift Package Manager
 - [Schema query/migration][]
 - Works on [Linux](Documentation/Linux.md) (with some limitations)
 - Active support at
   [StackOverflow](https://stackoverflow.com/questions/tagged/sqlite.swift),
   and [Gitter Chat Room](https://gitter.im/stephencelis/SQLite.swift)
   (_experimental_)

[SQLCipher]: https://www.zetetic.net/sqlcipher/
[Full-text search]: Documentation/Index.md#full-text-search
[Schema query/migration]: Documentation/Index.md#querying-the-schema
[See Documentation]: Documentation/Index.md#sqliteswift-documentation


## Usage

```swift
import SQLite

// Wrap everything in a do...catch to handle errors
do {
    let db = try Connection("path/to/db.sqlite3")

    let users = Table("users")
    let id = SQLite.Expression<Int64>("id")
    let name = SQLite.Expression<String?>("name")
    let email = SQLite.Expression<String>("email")

    try db.run(users.create { t in
        t.column(id, primaryKey: true)
        t.column(name)
        t.column(email, unique: true)
    })
    // CREATE TABLE "users" (
    //     "id" INTEGER PRIMARY KEY NOT NULL,
    //     "name" TEXT,
    //     "email" TEXT NOT NULL UNIQUE
    // )

    let insert = users.insert(name <- "Alice", email <- "alice@mac.com")
    let rowid = try db.run(insert)
    // INSERT INTO "users" ("name", "email") VALUES ('Alice', 'alice@mac.com')

    for user in try db.prepare(users) {
        print("id: \(user[id]), name: \(user[name]), email: \(user[email])")
        // id: 1, name: Optional("Alice"), email: alice@mac.com
    }
    // SELECT * FROM "users"

    let alice = users.filter(id == rowid)

    try db.run(alice.update(email <- email.replace("mac.com", with: "me.com")))
    // UPDATE "users" SET "email" = replace("email", 'mac.com', 'me.com')
    // WHERE ("id" = 1)

    try db.run(alice.delete())
    // DELETE FROM "users" WHERE ("id" = 1)

    try db.scalar(users.count) // 0
    // SELECT count(*) FROM "users"
} catch {
    print (error)
}
```

Note that `Expression` should be written as `SQLite.Expression` to avoid
conflicts with the `SwiftUI.Expression` if you are using SwiftUI too.

SQLite.swift also works as a lightweight, Swift-friendly wrapper over the C
API.

```swift
// Wrap everything in a do...catch to handle errors
do {
    // ...

    let stmt = try db.prepare("INSERT INTO users (email) VALUES (?)")
    for email in ["betty@icloud.com", "cathy@icloud.com"] {
        try stmt.run(email)
    }

    db.totalChanges    // 3
    db.changes         // 1
    db.lastInsertRowid // 3

    for row in try db.prepare("SELECT id, email FROM users") {
        print("id: \(row[0]), email: \(row[1])")
        // id: Optional(2), email: Optional("betty@icloud.com")
        // id: Optional(3), email: Optional("cathy@icloud.com")
    }

    try db.scalar("SELECT count(*) FROM users") // 2
} catch {
    print (error)
}
```

[Read the documentation][See Documentation] or explore more,
interactively, from the Xcode project’s playground.

![SQLite.playground Screen Shot](Documentation/Resources/playground@2x.png)

## Installation

### Swift Package Manager

The [Swift Package Manager][] is a tool for managing the distribution of
Swift code.

1. Add the following to your `Package.swift` file:

  ```swift
  dependencies: [
      .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.16.0")
  ]
  ```

2. Build your project:

  ```sh
  $ swift build
  ```

See the [Tests/SPM](https://github.com/stephencelis/SQLite.swift/tree/master/Tests/SPM) folder for a small demo project which uses SPM.

[Swift Package Manager]: https://swift.org/package-manager

### Carthage

[Carthage][] is a simple, decentralized dependency manager for Cocoa. To
install SQLite.swift with Carthage:

 1. Make sure Carthage is [installed][Carthage Installation].

 2. Update your Cartfile to include the following:

    ```ruby
    github "stephencelis/SQLite.swift" ~> 0.16.0
    ```

 3. Run `carthage update` and
    [add the appropriate framework][Carthage Usage].


[Carthage]: https://github.com/Carthage/Carthage
[Carthage Installation]: https://github.com/Carthage/Carthage#installing-carthage
[Carthage Usage]: https://github.com/Carthage/Carthage#adding-frameworks-to-an-application


### CocoaPods

[CocoaPods][] is a dependency manager for Cocoa projects. To install
SQLite.swift with CocoaPods:

 1. Make sure CocoaPods is [installed][CocoaPods Installation].

    ```sh
    # Using the default Ruby install will require you to use sudo when
    # installing and updating gems.
    [sudo] gem install cocoapods
    ```

 2. Update your Podfile to include the following:

    ```ruby
    use_frameworks!

    target 'YourAppTargetName' do
        pod 'SQLite.swift', '~> 0.15.0'
    end
    ```

 3. Run `pod install --repo-update`.

[CocoaPods]: https://cocoapods.org
[CocoaPods Installation]: https://guides.cocoapods.org/using/getting-started.html#getting-started

### Manual

To install SQLite.swift as an Xcode sub-project:

 1. Drag the **SQLite.xcodeproj** file into your own project.
    ([Submodule][], clone, or [download][] the project first.)

    ![Installation Screen Shot](Documentation/Resources/installation@2x.png)

 2. In your target’s **General** tab, click the **+** button under **Linked
    Frameworks and Libraries**.

 3. Select the appropriate **SQLite.framework** for your platform.

 4. **Add**.

Some additional steps are required to install the application on an actual
device:

 5. In the **General** tab, click the **+** button under **Embedded
    Binaries**.

 6. Select the appropriate **SQLite.framework** for your platform.

 7. **Add**.


[Xcode]: https://developer.apple.com/xcode/downloads/
[Submodule]: https://git-scm.com/book/en/Git-Tools-Submodules
[download]: https://github.com/stephencelis/SQLite.swift/archive/master.zip


## Communication

[Read the contributing guidelines][]. The _TL;DR_ (but please; _R_):

 - Need **help** or have a **general question**? [Ask on Stack
   Overflow][] (tag `sqlite.swift`).
 - Found a **bug** or have a **feature request**? [Open an issue][].
 - Want to **contribute**? [Submit a pull request][].

[Read the contributing guidelines]: ./CONTRIBUTING.md#contributing
[Ask on Stack Overflow]: https://stackoverflow.com/questions/tagged/sqlite.swift
[Open an issue]: https://github.com/stephencelis/SQLite.swift/issues/new
[Submit a pull request]: https://github.com/stephencelis/SQLite.swift/fork


## Original author

 - [Stephen Celis](mailto:stephen@stephencelis.com)
   ([@stephencelis](https://twitter.com/stephencelis))


## License

SQLite.swift is available under the MIT license. See [the LICENSE
file](./LICENSE.txt) for more information.

## Related

These projects enhance or use SQLite.swift:

 - [SQLiteMigrationManager.swift][] (inspired by
   [FMDBMigrationManager][])

## Alternatives

Looking for something else? Try another Swift wrapper (or [FMDB][]):

 - [GRDB](https://github.com/groue/GRDB.swift)
 - [SQLiteDB](https://github.com/FahimF/SQLiteDB)

[Swift]: https://swift.org/
[SQLite3]: https://www.sqlite.org
[SQLite.swift]: https://github.com/stephencelis/SQLite.swift

[GitHubActionBadge]: https://img.shields.io/github/actions/workflow/status/stephencelis/SQLite.swift/build.yml?branch=master

[CocoaPodsVersionBadge]: https://img.shields.io/cocoapods/v/SQLite.swift.svg?style=flat
[CocoaPodsVersionLink]: https://cocoapods.org/pods/SQLite.swift

[PlatformBadge]: https://img.shields.io/cocoapods/p/SQLite.swift.svg?style=flat
[PlatformLink]: https://cocoapods.org/pods/SQLite.swift

[CartagheBadge]: https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat
[CarthageLink]: https://github.com/Carthage/Carthage

[GitterBadge]: https://badges.gitter.im/stephencelis/SQLite.swift.svg
[GitterLink]: https://gitter.im/stephencelis/SQLite.swift

[Swift5Badge]: https://img.shields.io/badge/swift-5-orange.svg?style=flat
[Swift5Link]: https://developer.apple.com/swift/

[SQLiteMigrationManager.swift]: https://github.com/garriguv/SQLiteMigrationManager.swift
[FMDB]: https://github.com/ccgus/fmdb
[FMDBMigrationManager]: https://github.com/layerhq/FMDBMigrationManager


================================================
FILE: SQLite.playground/Contents.swift
================================================
import SQLite

/// Create an in-memory database
let db = try Connection(.inMemory)

/// enable statement logging
db.trace { print($0) }

/// define a "users" table with some fields
let users = Table("users")

let id = Expression<Int64>("id")
let email = Expression<String>("email") // non-null
let name = Expression<String?>("name")  // nullable

/// prepare the query
let statement = users.create { t in
    t.column(id, primaryKey: true)
    t.column(email, unique: true, check: email.like("%@%"))
    t.column(name)
}

/// …and run it
try db.run(statement)

/// insert "alice"
let rowid = try db.run(users.insert(email <- "alice@mac.com"))

/// insert multiple rows using `insertMany`
let lastRowid = try db.run(users.insertMany([
  [email <- "bob@mac.com"],
  [email <- "mallory@evil.com"]
]))


let query = try db.prepare(users)
for user in query {
    print("id: \(user[id]), email: \(user[email])")
}

// re-requery just rowid of Alice
let alice = try db.prepare(users.filter(id == rowid))
for user in alice {
    print("id: \(user[id]), email: \(user[email])")
}

/// using the `RowIterator` API
let rowIterator = try db.prepareRowIterator(users)
for user in try Array(rowIterator) {
    print("id: \(user[id]), email: \(user[email])")
}

/// also with `map()`
let mapRowIterator = try db.prepareRowIterator(users)

let userIds = try mapRowIterator.map { $0[id] }

/// using `failableNext()` on `RowIterator`
let iterator = try db.prepareRowIterator(users)
do {
    while let row = try rowIterator.failableNext() {
        print(row)
    }
} catch {
    // Handle error
}

/// define a virtual table for the FTS index
let emails = VirtualTable("emails")

let subject = Expression<String>("subject")
let body = Expression<String?>("body")

/// create the index
try db.run(emails.create(.FTS5(
    FTS5Config()
      .column(subject)
      .column(body)
)))

/// populate with data
try db.run(emails.insert(
    subject <- "Hello, world!",
    body <- "This is a hello world message."
))

/// run a query
let ftsQuery = try db.prepare(emails.match("hello"))

for row in ftsQuery {
    print(row[subject])
}

/// custom aggregations
let reduce: (String, [Binding?]) -> String = { (last, bindings) in
    last + " " + (bindings.first as? String ?? "")
}

db.createAggregation("customConcat",
                     initialValue: "users:",
                     reduce: reduce,
                     result: { $0 })
let result = try db.prepare("SELECT customConcat(email) FROM users").scalar() as! String
print(result)

/// schema queries
let schema = db.schema
let objects = try schema.objectDefinitions()
print(objects)

let columns = try schema.columnDefinitions(table: "users")
print(columns)

/// schema alteration

let schemaChanger = SchemaChanger(connection: db)
try schemaChanger.alter(table: "users") { table in
    table.add(column: ColumnDefinition(name: "age", type: .INTEGER))
    table.rename(column: "email", to: "electronic_mail")
    table.drop(column: "name")
}

let changedColumns = try schema.columnDefinitions(table: "users")
print(changedColumns)

let age = Expression<Int?>("age")
let electronicMail = Expression<String>("electronic_mail")

let newRowid = try db.run(users.insert(
    electronicMail <- "carol@mac.com",
    age <- 33
))


================================================
FILE: SQLite.playground/contents.xcplayground
================================================
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos' display-mode='rendered' buildActiveScheme='true' importAppTypes='true'>
    <timeline fileName='timeline.xctimeline'/>
</playground>

================================================
FILE: SQLite.playground/playground.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:">
   </FileRef>
</Workspace>


================================================
FILE: SQLite.swift.podspec
================================================
Pod::Spec.new do |s|
  s.name             = "SQLite.swift"
  s.version          = "0.16.0"
  s.summary          = "A type-safe, Swift-language layer over SQLite3."

  s.description      = <<-DESC
    SQLite.swift provides compile-time confidence in SQL statement syntax and
    intent.
                       DESC

  s.homepage         = "https://github.com/stephencelis/SQLite.swift"
  s.license          = 'MIT'
  s.author           = { "Stephen Celis" => "stephen@stephencelis.com" }
  s.source           = { :git => "https://github.com/stephencelis/SQLite.swift.git", :tag => s.version.to_s }
  s.social_media_url = 'https://twitter.com/stephencelis'

  s.module_name      = 'SQLite'
  s.default_subspec  = 'standard'
  s.swift_versions = ['5']

  s.ios.deployment_target = '12.0'
  s.tvos.deployment_target = '12.0'
  s.osx.deployment_target = '10.13'
  s.watchos.deployment_target = '4.0'
  s.visionos.deployment_target = '1.0'

  # uses the built-in sqlite3 library
  s.subspec 'standard' do |ss|
    ss.library = 'sqlite3'
    ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}'
    ss.exclude_files = 'Sources/**/Cipher.swift'
    ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' }
    ss.xcconfig = {
      'OTHER_SWIFT_FLAGS' => '$(inherited) -DSystemSQLite'
    }
    ss.test_spec 'tests' do |test_spec|
      test_spec.resources = 'Tests/SQLiteTests/Resources/*'
      test_spec.source_files = 'Tests/SQLiteTests/**/*.swift'
    end
  end

  # uses SQLite from https://github.com/clemensg/sqlite3pod
  s.subspec 'standalone' do |ss|
    ss.dependency 'sqlite3'
    ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}'
    ss.exclude_files = 'Sources/**/Cipher.swift'
    ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' }
    ss.xcconfig = {
      'OTHER_SWIFT_FLAGS' => '$(inherited) -DStandaloneSQLite'
    }
    ss.test_spec 'tests' do |test_spec|
      test_spec.resources = 'Tests/SQLiteTests/Resources/*'
      test_spec.source_files = 'Tests/SQLiteTests/**/*.swift'
    end
  end

  # uses SQLCipher from https://github.com/sqlcipher/sqlcipher
  s.subspec 'SQLCipher' do |ss|
    ss.dependency 'SQLCipher', '>= 4.0.0'
    # Disable unsupported visionOS
    # https://github.com/sqlcipher/sqlcipher/issues/483
    ss.ios.deployment_target = s.deployment_target(:ios)
    ss.tvos.deployment_target = s.deployment_target(:tvos)
    ss.osx.deployment_target = s.deployment_target(:osx)
    ss.watchos.deployment_target = s.deployment_target(:watchos)
    ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}'
    ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' }
    ss.xcconfig = {
      'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLCipher',
      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_HAS_CODEC=1'
    }
    ss.test_spec 'tests' do |test_spec|
      test_spec.resources = 'Tests/SQLiteTests/Resources/*'
      test_spec.source_files = 'Tests/SQLiteTests/**/*.swift'
    end
  end
end


================================================
FILE: SQLite.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		02A43A9822738CF100FEC494 /* Backup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A43A9722738CF100FEC494 /* Backup.swift */; };
		02A43A9922738CF100FEC494 /* Backup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A43A9722738CF100FEC494 /* Backup.swift */; };
		02A43A9A22738CF100FEC494 /* Backup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A43A9722738CF100FEC494 /* Backup.swift */; };
		02A43A9B22738CF100FEC494 /* Backup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A43A9722738CF100FEC494 /* Backup.swift */; };
		03A65E641C6BB0F60062603F /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E5A1C6BB0F50062603F /* SQLite.framework */; };
		03A65E721C6BB2D30062603F /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
		03A65E731C6BB2D80062603F /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; };
		03A65E741C6BB2DA0062603F /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; };
		03A65E761C6BB2E60062603F /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
		03A65E771C6BB2E60062603F /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; };
		03A65E7A1C6BB2F70062603F /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; };
		03A65E7B1C6BB2F70062603F /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; };
		03A65E7C1C6BB2F70062603F /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; };
		03A65E7D1C6BB2F70062603F /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; };
		03A65E7E1C6BB2FB0062603F /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; };
		03A65E7F1C6BB2FB0062603F /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; };
		03A65E801C6BB2FB0062603F /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; };
		03A65E811C6BB2FB0062603F /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; };
		03A65E821C6BB2FB0062603F /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; };
		03A65E831C6BB2FB0062603F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; };
		03A65E841C6BB2FB0062603F /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; };
		03A65E851C6BB2FB0062603F /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; };
		03A65E861C6BB2FB0062603F /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; };
		03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; };
		03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E961C6BB3210062603F /* libsqlite3.tbd */; };
		19A17018F250343BD0F9F4B0 /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
		19A17021286A4D8D6C2EF12D /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17855BD524FF888265B3C /* ConnectionTests.swift */; };
		19A17026DCDCDA405B09A229 /* Connection+AttachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */; };
		19A17073552293CA063BEA66 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; };
		19A1708D3D58D7BC1168E55F /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1787E16C8562C09C076F5 /* CipherTests.swift */; };
		19A1709C3E7A406E62293B2A /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; };
		19A170ACC97B19730FB7BA4D /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
		19A170AEBAA56DC3355A73B3 /* DateAndTimeFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178AEF32ABC8BF2993FB5 /* DateAndTimeFunctionTests.swift */; };
		19A170C56745F9D722A73D77 /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17613F00A3F4D4A257A04 /* AggregateFunctionsTests.swift */; };
		19A170D938343E30119EDFB3 /* RowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A174FE5B47A97937A27276 /* RowTests.swift */; };
		19A1714F7CF964D568AB14E0 /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A2ED4E2640F197F48C /* BlobTests.swift */; };
		19A17152E32A9585831E3FE0 /* DateAndTimeFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */; };
		19A1716BF8E15F91A6B5CB7A /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F2B5959B212A33C383F /* CustomFunctionsTests.swift */; };
		19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
		19A17188B4D96636F9C0C209 /* Connection+SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */; };
		19A171F12AB8B07F2FD7201A /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
		19A171F243A589C5EBC47937 /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17475DCA068453F787613 /* OperatorsTests.swift */; };
		19A1725658E480B9B378F28B /* Connection+SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */; };
		19A1726002D24C14F876C8FE /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17AE284BB1DF31D1B753E /* ValueTests.swift */; };
		19A172F71EFD65342072D8D2 /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A7714C6524093255C5 /* SchemaTests.swift */; };
		19A173088B85A7E18E8582A7 /* FTS5IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BE1CC4AD4036BAB8EE0 /* FTS5IntegrationTests.swift */; };
		19A173389E53CB24DFA8CEDD /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CAE60446607E99C22A6 /* QueryIntegrationTests.swift */; };
		19A173465F23C64DF3DF469B /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17855BD524FF888265B3C /* ConnectionTests.swift */; };
		19A173668D948AD4DF1F5352 /* DateAndTimeFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */; };
		19A1737286A74F3CF7412906 /* DateAndTimeFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */; };
		19A173EFEF0B3BD0B3ED406C /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; };
		19A173F25449876761347072 /* Connection+AttachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */; };
		19A173F429D7E46289EB2167 /* ResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1745BE8623D8C6808DB3C /* ResultTests.swift */; };
		19A17408007B182F884E3A53 /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; };
		19A1740EACD47904AA24B8DC /* SchemaDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */; };
		19A17411403D60640467209E /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170F141BF21946D159083 /* ExpressionTests.swift */; };
		19A174118D11B93DA5DAAF79 /* DateAndTimeFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178AEF32ABC8BF2993FB5 /* DateAndTimeFunctionTests.swift */; };
		19A17437659BD7FD787D94A6 /* CustomAggregationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */; };
		19A17444861E1443143DEB44 /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1715904F7B6851FCB5EF6 /* FTS4Tests.swift */; };
		19A174506543905D71BF0518 /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; };
		19A17457B0461F484AF6BE40 /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F2B5959B212A33C383F /* CustomFunctionsTests.swift */; };
		19A17482E6FC5E563F3E6A47 /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17475DCA068453F787613 /* OperatorsTests.swift */; };
		19A17490543609FCED53CACC /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; };
		19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
		19A1750EF4A5F92954A451FF /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; };
		19A1755C49154C87304C9146 /* FTS5IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BE1CC4AD4036BAB8EE0 /* FTS5IntegrationTests.swift */; };
		19A1760CE25615CA015E2E5F /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
		19A176376CB6A94759F7980A /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
		19A1766135CE9786B1878603 /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17AE284BB1DF31D1B753E /* ValueTests.swift */; };
		19A1766AC10D13C4EFF349AD /* SchemaChangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */; };
		19A176B3316281F004F92276 /* RowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A174FE5B47A97937A27276 /* RowTests.swift */; };
		19A177290558991BCC60E4E3 /* SchemaChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171B262DDE8718513CFDA /* SchemaChanger.swift */; };
		19A1772EBE65173EDFB1AFCA /* CustomAggregationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */; };
		19A1773155AC2BF2CA86A473 /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1709D5BDD2691BA160012 /* SetterTests.swift */; };
		19A1773A335CAB9D0AE14E8E /* SchemaChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171B262DDE8718513CFDA /* SchemaChanger.swift */; };
		19A17746150A815944A6820B /* SelectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17EC0C43015063945D32E /* SelectTests.swift */; };
		19A1776BD5127DFDF847FF1F /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B96EBD42C878E609CDC /* FTS5Tests.swift */; };
		19A177909023B7B940C5805E /* FTS5IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BE1CC4AD4036BAB8EE0 /* FTS5IntegrationTests.swift */; };
		19A177AA5922527BBDC77CF9 /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CAE60446607E99C22A6 /* QueryIntegrationTests.swift */; };
		19A177C25834473FAB32CF3B /* SchemaChangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */; };
		19A177D5C6542E2D572162E5 /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CAE60446607E99C22A6 /* QueryIntegrationTests.swift */; };
		19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
		19A1781CBA8968ABD3E00877 /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170F141BF21946D159083 /* ExpressionTests.swift */; };
		19A1782444437C7FC6B75CBC /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A2ED4E2640F197F48C /* BlobTests.swift */; };
		19A17835FD5886FDC5A3228F /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
		19A178767223229E61C5066F /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1715904F7B6851FCB5EF6 /* FTS4Tests.swift */; };
		19A17885B646CB0201BE4BD5 /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171ED017645C8B04DF9F2 /* QueryTests.swift */; };
		19A178A8B2A34FB6B565DEDA /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
		19A178C041DDCF80B533AD13 /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A2ED4E2640F197F48C /* BlobTests.swift */; };
		19A178DA2BB5970778CCAF13 /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B96EBD42C878E609CDC /* FTS5Tests.swift */; };
		19A178DF5A96CFEFF1E271F6 /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17613F00A3F4D4A257A04 /* AggregateFunctionsTests.swift */; };
		19A178F9008614B8A8425635 /* Connection+PragmaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */; };
		19A17900387FDCF578B31E3E /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17475DCA068453F787613 /* OperatorsTests.swift */; };
		19A17912DB9D3AC8FECF948B /* ResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1745BE8623D8C6808DB3C /* ResultTests.swift */; };
		19A17923494236793893BF72 /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1756EB81E9F7F45B12A78 /* StatementTests.swift */; };
		19A1792C0520D4E83C2EB075 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; };
		19A1793972BDDDB027C113BB /* CustomAggregationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */; };
		19A179786A6826D58A70F8BC /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17613F00A3F4D4A257A04 /* AggregateFunctionsTests.swift */; };
		19A17986405D9A875698408F /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
		19A1799AF6643CF5081BFA15 /* DateAndTimeFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178AEF32ABC8BF2993FB5 /* DateAndTimeFunctionTests.swift */; };
		19A179B59450FE7C4811AB8A /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
		19A179BB9A6665B2B99DA546 /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */; };
		19A179BCD483DEA21661FD37 /* Connection+AttachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */; };
		19A179CCF9671E345E5A9811 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
		19A179E76EA6207669B60C1B /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
		19A17A33EA026C2E2CEBAF36 /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; };
		19A17A391BF056E3D729E70A /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A7714C6524093255C5 /* SchemaTests.swift */; };
		19A17A52BF29D27C9AA229E7 /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171ED017645C8B04DF9F2 /* QueryTests.swift */; };
		19A17A7B3E3B7E76364A2AEE /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1787E16C8562C09C076F5 /* CipherTests.swift */; };
		19A17A7DF99B0379FD3396B1 /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F2B5959B212A33C383F /* CustomFunctionsTests.swift */; };
		19A17A9520802ACF45907970 /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17162C9861E5C4900455D /* RTreeTests.swift */; };
		19A17ABCF0EB4808BDC5B5FF /* RowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A174FE5B47A97937A27276 /* RowTests.swift */; };
		19A17B0DF1DDB6BBC9C95D64 /* SchemaDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */; };
		19A17B1D9B5CEBE9CE09280C /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17162C9861E5C4900455D /* RTreeTests.swift */; };
		19A17B36ABC6006AB80F693C /* Connection+SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */; };
		19A17B62A4125AF4F6014CF5 /* SchemaDefinitionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */; };
		19A17BA13FD35F058787B7D3 /* SchemaDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */; };
		19A17BACF4C032513DE1F879 /* Connection+PragmaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */; };
		19A17C74233AFC2EDAFA23DC /* ResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1745BE8623D8C6808DB3C /* ResultTests.swift */; };
		19A17CA4D7B63D845428A9C5 /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1756EB81E9F7F45B12A78 /* StatementTests.swift */; };
		19A17CA6ADB78A2E545BF836 /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1787E16C8562C09C076F5 /* CipherTests.swift */; };
		19A17CF65C0196E03BC64519 /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17855BD524FF888265B3C /* ConnectionTests.swift */; };
		19A17D1BEABA610ABF003D67 /* SchemaDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */; };
		19A17D6EC40BC35A5DC81BA8 /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1756EB81E9F7F45B12A78 /* StatementTests.swift */; };
		19A17D993398B8215B73E1EA /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */; };
		19A17DAD5975D9367EAA46E2 /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17162C9861E5C4900455D /* RTreeTests.swift */; };
		19A17DC282E36C4F41AA440B /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; };
		19A17DD33C2E43DD6EE05A60 /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170F141BF21946D159083 /* ExpressionTests.swift */; };
		19A17DE1FCDB5695702AD24D /* SelectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17EC0C43015063945D32E /* SelectTests.swift */; };
		19A17DE34C477232592A8F6B /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */; };
		19A17DF8D4F13A20F5D2269E /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; };
		19A17DFE05ED8B1F7C45F7EE /* SchemaChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171B262DDE8718513CFDA /* SchemaChanger.swift */; };
		19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
		19A17E0ABA6C415F014CD51C /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1709D5BDD2691BA160012 /* SetterTests.swift */; };
		19A17E1DD976D5CE80018749 /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1715904F7B6851FCB5EF6 /* FTS4Tests.swift */; };
		19A17E29278A12BC4F542506 /* DateAndTimeFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */; };
		19A17E3F47DA087E2B76D087 /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171ED017645C8B04DF9F2 /* QueryTests.swift */; };
		19A17E80F736EEE8EE2AA4CE /* SchemaDefinitionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */; };
		19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
		19A17F0BF02896E1664F4090 /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; };
		19A17F1B3F0A3C96B5ED6D64 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; };
		19A17F2096E83A3181E03317 /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A7714C6524093255C5 /* SchemaTests.swift */; };
		19A17F60B685636D1F83C2DD /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; };
		19A17F7977364EC8CD33C3C3 /* SelectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17EC0C43015063945D32E /* SelectTests.swift */; };
		19A17F907258E524B3CA2FAE /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1709D5BDD2691BA160012 /* SetterTests.swift */; };
		19A17FACE8E4D54A50BA934E /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B96EBD42C878E609CDC /* FTS5Tests.swift */; };
		19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
		19A17FBAA26953EB854E790D /* Connection+PragmaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */; };
		19A17FC04708C6ED637DDFD4 /* SchemaChangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */; };
		19A17FC07731779C1B8506FA /* SchemaChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171B262DDE8718513CFDA /* SchemaChanger.swift */; };
		19A17FD22EF43DF428DD93BA /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17AE284BB1DF31D1B753E /* ValueTests.swift */; };
		19A17FE78A39E86F330420EC /* SchemaDefinitionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */; };
		19A17FF4A10B44D3937C8CAC /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; };
		3D67B3E61DB2469200A4F4C6 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 3D67B3E51DB2469200A4F4C6 /* libsqlite3.tbd */; };
		3D67B3E71DB246BA00A4F4C6 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
		3D67B3E81DB246BA00A4F4C6 /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; };
		3D67B3E91DB246D100A4F4C6 /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; };
		3D67B3EA1DB246D100A4F4C6 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; };
		3D67B3EB1DB246D100A4F4C6 /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; };
		3D67B3EC1DB246D100A4F4C6 /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; };
		3D67B3ED1DB246D100A4F4C6 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
		3D67B3EE1DB246D100A4F4C6 /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; };
		3D67B3EF1DB246D100A4F4C6 /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; };
		3D67B3F01DB246D100A4F4C6 /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; };
		3D67B3F11DB246D100A4F4C6 /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; };
		3D67B3F21DB246D100A4F4C6 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; };
		3D67B3F31DB246D100A4F4C6 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; };
		3D67B3F41DB246D100A4F4C6 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; };
		3D67B3F51DB246D100A4F4C6 /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; };
		3D67B3F61DB246D100A4F4C6 /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; };
		3D67B3F71DB246D700A4F4C6 /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; };
		3D67B3F81DB246D700A4F4C6 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; };
		3D67B3FC1DB2471B00A4F4C6 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
		3DF7B78828842972005DD8CA /* Connection+Attach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B78728842972005DD8CA /* Connection+Attach.swift */; };
		3DF7B78928842972005DD8CA /* Connection+Attach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B78728842972005DD8CA /* Connection+Attach.swift */; };
		3DF7B78A28842972005DD8CA /* Connection+Attach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B78728842972005DD8CA /* Connection+Attach.swift */; };
		3DF7B78B28842972005DD8CA /* Connection+Attach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B78728842972005DD8CA /* Connection+Attach.swift */; };
		3DF7B791288449BA005DD8CA /* URIQueryParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */; };
		3DF7B792288449BA005DD8CA /* URIQueryParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */; };
		3DF7B793288449BA005DD8CA /* URIQueryParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */; };
		3DF7B794288449BA005DD8CA /* URIQueryParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */; };
		3DF7B79628846FCC005DD8CA /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 3DF7B79528846FCC005DD8CA /* Resources */; };
		3DF7B79828846FED005DD8CA /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 3DF7B79528846FCC005DD8CA /* Resources */; };
		3DF7B79928847055005DD8CA /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 3DF7B79528846FCC005DD8CA /* Resources */; };
		49EB68C41F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
		49EB68C51F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
		49EB68C61F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
		49EB68C71F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
		64A8EE432B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; };
		64A8EE442B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; };
		64A8EE452B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; };
		64A8EE462B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; };
		64B8E1702B09748000545AFB /* WindowFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */; };
		64B8E1712B09748000545AFB /* WindowFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */; };
		64B8E1722B09748000545AFB /* WindowFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */; };
		997DF2AE287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; };
		997DF2AF287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; };
		997DF2B0287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; };
		997DF2B1287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; };
		DB58B21128FB864300F8EEA4 /* SchemaReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21028FB864300F8EEA4 /* SchemaReader.swift */; };
		DB58B21228FB864300F8EEA4 /* SchemaReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21028FB864300F8EEA4 /* SchemaReader.swift */; };
		DB58B21328FB864300F8EEA4 /* SchemaReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21028FB864300F8EEA4 /* SchemaReader.swift */; };
		DB58B21428FB864300F8EEA4 /* SchemaReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21028FB864300F8EEA4 /* SchemaReader.swift */; };
		DB58B21628FC7C4600F8EEA4 /* SQLiteFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */; };
		DB58B21728FC7C4600F8EEA4 /* SQLiteFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */; };
		DB58B21828FC7C4600F8EEA4 /* SQLiteFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */; };
		DB58B21928FC7C4600F8EEA4 /* SQLiteFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */; };
		DB7C5DA628D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
		DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
		DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
		DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
		DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; };
		DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; };
		DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; };
		DEB306BA2B61CEF500F9D46B /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
		DEB306BC2B61CEF500F9D46B /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; };
		DEB306BD2B61CEF500F9D46B /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
		DEB306BE2B61CEF500F9D46B /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; };
		DEB306BF2B61CEF500F9D46B /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
		DEB306C02B61CEF500F9D46B /* URIQueryParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */; };
		DEB306C12B61CEF500F9D46B /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; };
		DEB306C22B61CEF500F9D46B /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; };
		DEB306C32B61CEF500F9D46B /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; };
		DEB306C42B61CEF500F9D46B /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; };
		DEB306C52B61CEF500F9D46B /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; };
		DEB306C62B61CEF500F9D46B /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; };
		DEB306C72B61CEF500F9D46B /* Connection+Attach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B78728842972005DD8CA /* Connection+Attach.swift */; };
		DEB306C82B61CEF500F9D46B /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; };
		DEB306C92B61CEF500F9D46B /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; };
		DEB306CA2B61CEF500F9D46B /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; };
		DEB306CB2B61CEF500F9D46B /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; };
		DEB306CC2B61CEF500F9D46B /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; };
		DEB306CD2B61CEF500F9D46B /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; };
		DEB306CE2B61CEF500F9D46B /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; };
		DEB306CF2B61CEF500F9D46B /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; };
		DEB306D02B61CEF500F9D46B /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
		DEB306D12B61CEF500F9D46B /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
		DEB306D22B61CEF500F9D46B /* Backup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A43A9722738CF100FEC494 /* Backup.swift */; };
		DEB306D32B61CEF500F9D46B /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; };
		DEB306D42B61CEF500F9D46B /* DateAndTimeFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */; };
		DEB306D52B61CEF500F9D46B /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; };
		DEB306D62B61CEF500F9D46B /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; };
		DEB306D72B61CEF500F9D46B /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; };
		DEB306D82B61CEF500F9D46B /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
		DEB306D92B61CEF500F9D46B /* SQLiteFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */; };
		DEB306DA2B61CEF500F9D46B /* SchemaChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171B262DDE8718513CFDA /* SchemaChanger.swift */; };
		DEB306DB2B61CEF500F9D46B /* SchemaDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */; };
		DEB306DC2B61CEF500F9D46B /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; };
		DEB306DD2B61CEF500F9D46B /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
		DEB306DE2B61CEF500F9D46B /* SchemaReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21028FB864300F8EEA4 /* SchemaReader.swift */; };
		DEB306E02B61CEF500F9D46B /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EE9180931C46EA210038162A /* libsqlite3.tbd */; };
		DEB306EB2B61CF9500F9D46B /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; };
		DEB306EC2B61CF9500F9D46B /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
		DEB306ED2B61CF9500F9D46B /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; };
		DEB306EE2B61CF9500F9D46B /* SchemaDefinitionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */; };
		DEB306EF2B61CF9500F9D46B /* SchemaChangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */; };
		DEB306F02B61CF9500F9D46B /* Connection+SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */; };
		DEB306F12B61CF9500F9D46B /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B96EBD42C878E609CDC /* FTS5Tests.swift */; };
		DEB306F22B61CF9500F9D46B /* FTS5IntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BE1CC4AD4036BAB8EE0 /* FTS5IntegrationTests.swift */; };
		DEB306F32B61CF9500F9D46B /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1715904F7B6851FCB5EF6 /* FTS4Tests.swift */; };
		DEB306F42B61CF9500F9D46B /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170F141BF21946D159083 /* ExpressionTests.swift */; };
		DEB306F52B61CF9500F9D46B /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1756EB81E9F7F45B12A78 /* StatementTests.swift */; };
		DEB306F62B61CF9500F9D46B /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171ED017645C8B04DF9F2 /* QueryTests.swift */; };
		DEB306F72B61CF9500F9D46B /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1787E16C8562C09C076F5 /* CipherTests.swift */; };
		DEB306F82B61CF9500F9D46B /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A2ED4E2640F197F48C /* BlobTests.swift */; };
		DEB306F92B61CF9500F9D46B /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17855BD524FF888265B3C /* ConnectionTests.swift */; };
		DEB306FA2B61CF9500F9D46B /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */; };
		DEB306FB2B61CF9500F9D46B /* DateAndTimeFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178AEF32ABC8BF2993FB5 /* DateAndTimeFunctionTests.swift */; };
		DEB306FC2B61CF9500F9D46B /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F2B5959B212A33C383F /* CustomFunctionsTests.swift */; };
		DEB306FD2B61CF9500F9D46B /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17475DCA068453F787613 /* OperatorsTests.swift */; };
		DEB306FE2B61CF9500F9D46B /* ResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1745BE8623D8C6808DB3C /* ResultTests.swift */; };
		DEB306FF2B61CF9500F9D46B /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17162C9861E5C4900455D /* RTreeTests.swift */; };
		DEB307002B61CF9500F9D46B /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A7714C6524093255C5 /* SchemaTests.swift */; };
		DEB307012B61CF9500F9D46B /* SelectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17EC0C43015063945D32E /* SelectTests.swift */; };
		DEB307022B61CF9500F9D46B /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17AE284BB1DF31D1B753E /* ValueTests.swift */; };
		DEB307032B61CF9500F9D46B /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CAE60446607E99C22A6 /* QueryIntegrationTests.swift */; };
		DEB307042B61CF9500F9D46B /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17613F00A3F4D4A257A04 /* AggregateFunctionsTests.swift */; };
		DEB307052B61CF9500F9D46B /* CustomAggregationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */; };
		DEB307062B61CF9500F9D46B /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1709D5BDD2691BA160012 /* SetterTests.swift */; };
		DEB307072B61CF9500F9D46B /* RowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A174FE5B47A97937A27276 /* RowTests.swift */; };
		DEB307082B61CF9500F9D46B /* Connection+PragmaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */; };
		DEB307092B61CF9500F9D46B /* Connection+AttachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */; };
		DEB3070B2B61CF9500F9D46B /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E5A1C6BB0F50062603F /* SQLite.framework */; };
		DEB3070D2B61CF9500F9D46B /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 3DF7B79528846FCC005DD8CA /* Resources */; };
		EAE5A0372B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; };
		EAE5A0382B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; };
		EAE5A0392B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; };
		EAE5A03A2B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; };
		EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
		EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; };
		EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
		EE247B041C3F06E900AE3E12 /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; };
		EE247B071C3F06E900AE3E12 /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; };
		EE247B081C3F06E900AE3E12 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; };
		EE247B091C3F06E900AE3E12 /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; };
		EE247B0A1C3F06E900AE3E12 /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; };
		EE247B0B1C3F06E900AE3E12 /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; };
		EE247B0C1C3F06E900AE3E12 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; };
		EE247B0D1C3F06E900AE3E12 /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; };
		EE247B0E1C3F06E900AE3E12 /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; };
		EE247B0F1C3F06E900AE3E12 /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; };
		EE247B101C3F06E900AE3E12 /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; };
		EE247B111C3F06E900AE3E12 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; };
		EE247B121C3F06E900AE3E12 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; };
		EE247B131C3F06E900AE3E12 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; };
		EE247B141C3F06E900AE3E12 /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; };
		EE247B151C3F06E900AE3E12 /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; };
		EE247B171C3F127200AE3E12 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; };
		EE247B461C3F3ED000AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247B3C1C3F3ED000AE3E12 /* SQLite.framework */; };
		EE247B611C3F3FC700AE3E12 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; };
		EE247B621C3F3FDB00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
		EE247B631C3F3FDB00AE3E12 /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; };
		EE247B641C3F3FDB00AE3E12 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; };
		EE247B651C3F3FEC00AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
		EE247B661C3F3FEC00AE3E12 /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; };
		EE247B691C3F3FEC00AE3E12 /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; };
		EE247B6A1C3F3FEC00AE3E12 /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; };
		EE247B6B1C3F3FEC00AE3E12 /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; };
		EE247B6C1C3F3FEC00AE3E12 /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; };
		EE247B6D1C3F3FEC00AE3E12 /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; };
		EE247B6E1C3F3FEC00AE3E12 /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; };
		EE247B6F1C3F3FEC00AE3E12 /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; };
		EE247B701C3F3FEC00AE3E12 /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; };
		EE247B711C3F3FEC00AE3E12 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; };
		EE247B721C3F3FEC00AE3E12 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; };
		EE247B731C3F3FEC00AE3E12 /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; };
		EE247B741C3F3FEC00AE3E12 /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; };
		EE247B751C3F3FEC00AE3E12 /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; };
		EE9180941C46EA210038162A /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EE9180931C46EA210038162A /* libsqlite3.tbd */; };
		EE9180951C46EBCC0038162A /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EE9180911C46E9D30038162A /* libsqlite3.tbd */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
		03A65E651C6BB0F60062603F /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 03A65E591C6BB0F50062603F;
			remoteInfo = "SQLite tvOS";
		};
		DEB307142B61D07F00F9D46B /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = DEB306B82B61CEF500F9D46B;
			remoteInfo = "SQLite visionOS";
		};
		EE247ADF1C3F04ED00AE3E12 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = EE247AD21C3F04ED00AE3E12;
			remoteInfo = SQLite;
		};
		EE247B471C3F3ED000AE3E12 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = EE247B3B1C3F3ED000AE3E12;
			remoteInfo = SQLite;
		};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
		02A43A9722738CF100FEC494 /* Backup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backup.swift; sourceTree = "<group>"; };
		03A65E5A1C6BB0F50062603F /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		03A65E631C6BB0F60062603F /* SQLiteTests tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests tvOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
		03A65E961C6BB3210062603F /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; };
		19A1709D5BDD2691BA160012 /* SetterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetterTests.swift; sourceTree = "<group>"; };
		19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+Schema.swift"; sourceTree = "<group>"; };
		19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+AttachTests.swift"; sourceTree = "<group>"; };
		19A170F141BF21946D159083 /* ExpressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpressionTests.swift; sourceTree = "<group>"; };
		19A1710E73A46D5AC721CDA9 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
		19A1715904F7B6851FCB5EF6 /* FTS4Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4Tests.swift; sourceTree = "<group>"; };
		19A17162C9861E5C4900455D /* RTreeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTreeTests.swift; sourceTree = "<group>"; };
		19A171A2ED4E2640F197F48C /* BlobTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlobTests.swift; sourceTree = "<group>"; };
		19A171A7714C6524093255C5 /* SchemaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaTests.swift; sourceTree = "<group>"; };
		19A171B262DDE8718513CFDA /* SchemaChanger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaChanger.swift; sourceTree = "<group>"; };
		19A171ED017645C8B04DF9F2 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
		19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaDefinitions.swift; sourceTree = "<group>"; };
		19A1730E4390C775C25677D1 /* FTS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5.swift; sourceTree = "<group>"; };
		19A1745BE8623D8C6808DB3C /* ResultTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResultTests.swift; sourceTree = "<group>"; };
		19A17475DCA068453F787613 /* OperatorsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorsTests.swift; sourceTree = "<group>"; };
		19A174FE5B47A97937A27276 /* RowTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowTests.swift; sourceTree = "<group>"; };
		19A1756EB81E9F7F45B12A78 /* StatementTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatementTests.swift; sourceTree = "<group>"; };
		19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+Aggregation.swift"; sourceTree = "<group>"; };
		19A17613F00A3F4D4A257A04 /* AggregateFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctionsTests.swift; sourceTree = "<group>"; };
		19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaDefinitionsTests.swift; sourceTree = "<group>"; };
		19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomAggregationTests.swift; sourceTree = "<group>"; };
		19A17855BD524FF888265B3C /* ConnectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionTests.swift; sourceTree = "<group>"; };
		19A1787E16C8562C09C076F5 /* CipherTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CipherTests.swift; sourceTree = "<group>"; };
		19A178A39ACA9667A62663CC /* Cipher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cipher.swift; sourceTree = "<group>"; };
		19A178AEF32ABC8BF2993FB5 /* DateAndTimeFunctionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateAndTimeFunctionTests.swift; sourceTree = "<group>"; };
		19A1794B7972D14330A65BBD /* Linux.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Linux.md; sourceTree = "<group>"; };
		19A1794CC4D7827E997E32A7 /* FoundationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationTests.swift; sourceTree = "<group>"; };
		19A17AE284BB1DF31D1B753E /* ValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValueTests.swift; sourceTree = "<group>"; };
		19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreFunctionsTests.swift; sourceTree = "<group>"; };
		19A17B93B48B5560E6E51791 /* Fixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fixtures.swift; sourceTree = "<group>"; };
		19A17B96EBD42C878E609CDC /* FTS5Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5Tests.swift; sourceTree = "<group>"; };
		19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateAndTimeFunctions.swift; sourceTree = "<group>"; };
		19A17BE1CC4AD4036BAB8EE0 /* FTS5IntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5IntegrationTests.swift; sourceTree = "<group>"; };
		19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+PragmaTests.swift"; sourceTree = "<group>"; };
		19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+SchemaTests.swift"; sourceTree = "<group>"; };
		19A17CAE60446607E99C22A6 /* QueryIntegrationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryIntegrationTests.swift; sourceTree = "<group>"; };
		19A17E723300E5ED3771DCB5 /* Result.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
		19A17EA3A313F129011B3FA0 /* Release.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Release.md; sourceTree = "<group>"; };
		19A17EC0C43015063945D32E /* SelectTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectTests.swift; sourceTree = "<group>"; };
		19A17F285B767BFACD96714B /* Connection+Pragmas.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+Pragmas.swift"; sourceTree = "<group>"; };
		19A17F2B5959B212A33C383F /* CustomFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFunctionsTests.swift; sourceTree = "<group>"; };
		19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaChangerTests.swift; sourceTree = "<group>"; };
		3D3C3CCB26E5568800759140 /* SQLite.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = SQLite.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
		3D67B3E51DB2469200A4F4C6 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS3.0.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; };
		3DF7B78728842972005DD8CA /* Connection+Attach.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Connection+Attach.swift"; sourceTree = "<group>"; };
		3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URIQueryParameter.swift; sourceTree = "<group>"; };
		3DF7B79528846FCC005DD8CA /* Resources */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resources; sourceTree = "<group>"; };
		3DF7B79A2884C353005DD8CA /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
		3DF7B79B2884C901005DD8CA /* Planning.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Planning.md; sourceTree = "<group>"; };
		3DFC0B862886C239001C8FC9 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
		49EB68C31F7B3CB400D89D40 /* Coding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coding.swift; sourceTree = "<group>"; };
		64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowFunctions.swift; sourceTree = "<group>"; };
		64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowFunctionsTests.swift; sourceTree = "<group>"; };
		997DF2AD287FC06D00F8DF95 /* Query+with.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Query+with.swift"; sourceTree = "<group>"; };
		A121AC451CA35C79005A31D1 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = "<group>"; };
		DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = "<group>"; };
		DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = "<group>"; };
		DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReaderTests.swift; sourceTree = "<group>"; };
		DEB306E52B61CEF500F9D46B /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		DEB307112B61CF9500F9D46B /* SQLiteTests visionOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests visionOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
		DEB307132B61D04500F9D46B /* SQLite visionOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = "SQLite visionOS.xctestplan"; path = "Tests/SQLite visionOS.xctestplan"; sourceTree = "<group>"; };
		EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
		EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = "<group>"; };
		EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		EE247ADD1C3F04ED00AE3E12 /* SQLiteTests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
		EE247AE41C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		EE247AEE1C3F06E900AE3E12 /* Blob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Blob.swift; sourceTree = "<group>"; };
		EE247AEF1C3F06E900AE3E12 /* Connection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Connection.swift; sourceTree = "<group>"; };
		EE247AF21C3F06E900AE3E12 /* Statement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Statement.swift; sourceTree = "<group>"; };
		EE247AF31C3F06E900AE3E12 /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = "<group>"; };
		EE247AF51C3F06E900AE3E12 /* FTS4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4.swift; sourceTree = "<group>"; };
		EE247AF61C3F06E900AE3E12 /* RTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = "<group>"; };
		EE247AF71C3F06E900AE3E12 /* Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Foundation.swift; sourceTree = "<group>"; };
		EE247AF81C3F06E900AE3E12 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
		EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctions.swift; sourceTree = "<group>"; };
		EE247AFB1C3F06E900AE3E12 /* Collation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Collation.swift; sourceTree = "<group>"; };
		EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreFunctions.swift; sourceTree = "<group>"; };
		EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFunctions.swift; sourceTree = "<group>"; };
		EE247AFE1C3F06E900AE3E12 /* Expression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expression.swift; sourceTree = "<group>"; };
		EE247AFF1C3F06E900AE3E12 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = "<group>"; };
		EE247B001C3F06E900AE3E12 /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = "<group>"; };
		EE247B011C3F06E900AE3E12 /* Schema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Schema.swift; sourceTree = "<group>"; };
		EE247B021C3F06E900AE3E12 /* Setter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Setter.swift; sourceTree = "<group>"; };
		EE247B161C3F127200AE3E12 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = "<group>"; };
		EE247B3C1C3F3ED000AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
		EE247B451C3F3ED000AE3E12 /* SQLiteTests Mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests Mac.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
		EE247B771C3F40D700AE3E12 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
		EE247B8B1C3F820300AE3E12 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = "<group>"; };
		EE247B8D1C3F821200AE3E12 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
		EE247B8F1C3F822500AE3E12 /* Index.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Index.md; sourceTree = "<group>"; };
		EE247B911C3F822500AE3E12 /* installation@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "installation@2x.png"; sourceTree = "<group>"; };
		EE247B921C3F822600AE3E12 /* playground@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "playground@2x.png"; sourceTree = "<group>"; };
		EE247B931C3F826100AE3E12 /* SQLite.swift.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = SQLite.swift.podspec; sourceTree = "<group>"; };
		EE9180911C46E9D30038162A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; };
		EE9180931C46EA210038162A /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		03A65E561C6BB0F50062603F /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		03A65E601C6BB0F60062603F /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				03A65E641C6BB0F60062603F /* SQLite.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		A121AC411CA35C79005A31D1 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				3D67B3E61DB2469200A4F4C6 /* libsqlite3.tbd in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		DEB306DF2B61CEF500F9D46B /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				DEB306E02B61CEF500F9D46B /* libsqlite3.tbd in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		DEB3070A2B61CF9500F9D46B /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				DEB3070B2B61CF9500F9D46B /* SQLite.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		EE247ACF1C3F04ED00AE3E12 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				EE9180941C46EA210038162A /* libsqlite3.tbd in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		EE247ADA1C3F04ED00AE3E12 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		EE247B381C3F3ED000AE3E12 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				EE9180951C46EBCC0038162A /* libsqlite3.tbd in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		EE247B421C3F3ED000AE3E12 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				EE247B461C3F3ED000AE3E12 /* SQLite.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		19A1792D261C689FC988A90A /* Schema */ = {
			isa = PBXGroup;
			children = (
				DB58B21028FB864300F8EEA4 /* SchemaReader.swift */,
				19A171B262DDE8718513CFDA /* SchemaChanger.swift */,
				19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */,
				19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */,
			);
			path = Schema;
			sourceTree = "<group>";
		};
		19A1798E3459573BEE50FA34 /* Core */ = {
			isa = PBXGroup;
			children = (
				19A1756EB81E9F7F45B12A78 /* StatementTests.swift */,
				19A171A2ED4E2640F197F48C /* BlobTests.swift */,
				19A17855BD524FF888265B3C /* ConnectionTests.swift */,
				19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */,
				19A1745BE8623D8C6808DB3C /* ResultTests.swift */,
				19A17AE284BB1DF31D1B753E /* ValueTests.swift */,
				19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */,
				19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */,
			);
			path = Core;
			sourceTree = "<group>";
		};
		19A17AECBF878B1DAE0AE3DD /* Typed */ = {
			isa = PBXGr
Download .txt
gitextract_03naq3tg/

├── .github/
│   ├── FUNDING.yml
│   ├── issue_template.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .swiftlint.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Documentation/
│   ├── Index.md
│   ├── Linux.md
│   ├── Planning.md
│   ├── Release.md
│   └── Upgrading.md
├── Gemfile
├── LICENSE.txt
├── Makefile
├── Package.swift
├── README.md
├── SQLite.playground/
│   ├── Contents.swift
│   ├── contents.xcplayground
│   └── playground.xcworkspace/
│       └── contents.xcworkspacedata
├── SQLite.swift.podspec
├── SQLite.xcodeproj/
│   ├── project.pbxproj
│   ├── project.xcworkspace/
│   │   ├── contents.xcworkspacedata
│   │   └── xcshareddata/
│   │       └── IDEWorkspaceChecks.plist
│   └── xcshareddata/
│       └── xcschemes/
│           ├── SQLite Mac.xcscheme
│           ├── SQLite iOS.xcscheme
│           ├── SQLite tvOS.xcscheme
│           ├── SQLite visionOS.xcscheme
│           └── SQLite watchOS.xcscheme
├── Sources/
│   └── SQLite/
│       ├── Core/
│       │   ├── Backup.swift
│       │   ├── Blob.swift
│       │   ├── Connection+Aggregation.swift
│       │   ├── Connection+Attach.swift
│       │   ├── Connection+Pragmas.swift
│       │   ├── Connection.swift
│       │   ├── Errors.swift
│       │   ├── Result.swift
│       │   ├── SQLiteFeature.swift
│       │   ├── SQLiteVersion.swift
│       │   ├── Statement.swift
│       │   ├── URIQueryParameter.swift
│       │   └── Value.swift
│       ├── Extensions/
│       │   ├── Cipher.swift
│       │   ├── FTS4.swift
│       │   ├── FTS5.swift
│       │   └── RTree.swift
│       ├── Foundation.swift
│       ├── Helpers.swift
│       ├── Info.plist
│       ├── PrivacyInfo.xcprivacy
│       ├── SQLite.h
│       ├── Schema/
│       │   ├── Connection+Schema.swift
│       │   ├── SchemaChanger.swift
│       │   ├── SchemaDefinitions.swift
│       │   └── SchemaReader.swift
│       └── Typed/
│           ├── AggregateFunctions.swift
│           ├── Coding.swift
│           ├── Collation.swift
│           ├── CoreFunctions.swift
│           ├── CustomFunctions.swift
│           ├── DateAndTimeFunctions.swift
│           ├── Expression.swift
│           ├── Operators.swift
│           ├── Query+with.swift
│           ├── Query.swift
│           ├── Schema.swift
│           ├── Setter.swift
│           └── WindowFunctions.swift
├── Tests/
│   ├── .swiftlint.yml
│   ├── SPM/
│   │   ├── .gitignore
│   │   ├── Package.swift
│   │   └── Sources/
│   │       └── test/
│   │           └── main.swift
│   ├── SQLite visionOS.xctestplan
│   ├── SQLiteTests/
│   │   ├── Core/
│   │   │   ├── BlobTests.swift
│   │   │   ├── Connection+AttachTests.swift
│   │   │   ├── Connection+PragmaTests.swift
│   │   │   ├── ConnectionTests.swift
│   │   │   ├── CoreFunctionsTests.swift
│   │   │   ├── ResultTests.swift
│   │   │   ├── StatementTests.swift
│   │   │   └── ValueTests.swift
│   │   ├── Extensions/
│   │   │   ├── CipherTests.swift
│   │   │   ├── FTS4Tests.swift
│   │   │   ├── FTS5IntegrationTests.swift
│   │   │   ├── FTS5Tests.swift
│   │   │   └── RTreeTests.swift
│   │   ├── Fixtures.swift
│   │   ├── FoundationTests.swift
│   │   ├── Info.plist
│   │   ├── Schema/
│   │   │   ├── Connection+SchemaTests.swift
│   │   │   ├── SchemaChangerTests.swift
│   │   │   ├── SchemaDefinitionsTests.swift
│   │   │   ├── SchemaReaderTests.swift
│   │   │   └── SchemaTests.swift
│   │   ├── TestHelpers.swift
│   │   └── Typed/
│   │       ├── AggregateFunctionsTests.swift
│   │       ├── CustomAggregationTests.swift
│   │       ├── CustomFunctionsTests.swift
│   │       ├── DateAndTimeFunctionTests.swift
│   │       ├── ExpressionTests.swift
│   │       ├── OperatorsTests.swift
│   │       ├── QueryIntegrationTests.swift
│   │       ├── QueryTests.swift
│   │       ├── RowTests.swift
│   │       ├── SelectTests.swift
│   │       ├── SetterTests.swift
│   │       └── WindowFunctionsTests.swift
│   └── Tuist/
│       └── SQLite-Test/
│           ├── .gitignore
│           ├── Project.swift
│           ├── SQLite-Test/
│           │   ├── Sources/
│           │   │   └── SQLiteTestApp.swift
│           │   └── Tests/
│           │       └── SQLiteTestTests.swift
│           ├── Tuist/
│           │   └── Package.swift
│           └── Tuist.swift
└── run-tests.sh
Condensed preview — 115 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (924K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 46,
    "preview": "github: [stephencelis, jberkel, NathanFallet]\n"
  },
  {
    "path": ".github/issue_template.md",
    "chars": 677,
    "preview": "> Issues are used to track bugs and feature requests.\n> Need help or have a general question? Ask on Stack Overflow (tag"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 371,
    "preview": "Thanks for taking the time to submit a pull request.\n\nBefore submitting, please do the following:\n\n- Run `make lint` to "
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 3263,
    "preview": "name: Build and test\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\nconcurrency:\n"
  },
  {
    "path": ".gitignore",
    "chars": 348,
    "preview": "# OS X\n.DS_Store\n\n# Xcode\nbuild/\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.pers"
  },
  {
    "path": ".swiftlint.yml",
    "chars": 898,
    "preview": "opt_in_rules:\n  - shorthand_optional_binding\ndisabled_rules: # rule identifiers to exclude from running\n  - todo\n  - fun"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 14604,
    "preview": "0.16.0 (28-01-2026), [diff][diff-0.16.0]\n========================================\n* Revert trait changes for Linux\n* Rem"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3902,
    "preview": "# Contributing\n\nThe where and when to open an [issue](#issues) or [pull\nrequest](#pull-requests).\n\n\n## Issues\n\nIssues ar"
  },
  {
    "path": "Documentation/Index.md",
    "chars": 73939,
    "preview": "# SQLite.swift Documentation\n\n- [SQLite.swift Documentation](#sqliteswift-documentation)\n  - [Installation](#installatio"
  },
  {
    "path": "Documentation/Linux.md",
    "chars": 1181,
    "preview": "# Linux\n\n## Limitations\n\n* Custom functions/aggregations are currently not supported and crash, caused by a bug in Swift"
  },
  {
    "path": "Documentation/Planning.md",
    "chars": 1334,
    "preview": "# SQLite.swift Planning\n\nThis document captures both near term steps (aka Roadmap) and feature\nrequests. The goal is to "
  },
  {
    "path": "Documentation/Release.md",
    "chars": 642,
    "preview": "# SQLite.swift Release checklist\n\n* [ ] Make sure current master branch has a green build\n* [ ] Make sure `SQLite.playgr"
  },
  {
    "path": "Documentation/Upgrading.md",
    "chars": 519,
    "preview": "# Upgrading\n\n## 0.13 → 0.14\n\n- `Expression.asSQL()` is no longer available. Expressions now implement `CustomStringConve"
  },
  {
    "path": "Gemfile",
    "chars": 182,
    "preview": "source \"https://rubygems.org\"\n\n# https://github.com/CocoaPods/CocoaPods/pull/12816\ngem 'cocoapods', :git => 'https://git"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1110,
    "preview": "(The MIT License)\n\nCopyright (c) 2014-2015 Stephen Celis (<stephen@stephencelis.com>)\n\nPermission is hereby granted, fre"
  },
  {
    "path": "Makefile",
    "chars": 2049,
    "preview": "XCODEBUILD = xcodebuild\nBUILD_SCHEME = SQLite Mac\nIOS_SIMULATOR = iPhone 14\nIOS_VERSION = 16.4\n\n# tool settings\nSWIFTLIN"
  },
  {
    "path": "Package.swift",
    "chars": 2499,
    "preview": "// swift-tools-version: 6.1\nimport PackageDescription\nlet applePlatforms: [PackageDescription.Platform] = [.iOS, .macOS,"
  },
  {
    "path": "README.md",
    "chars": 9071,
    "preview": "# SQLite.swift\n\n![Build Status][GitHubActionBadge] [![CocoaPods Version][CocoaPodsVersionBadge]][CocoaPodsVersionLink] ["
  },
  {
    "path": "SQLite.playground/Contents.swift",
    "chars": 3260,
    "preview": "import SQLite\n\n/// Create an in-memory database\nlet db = try Connection(.inMemory)\n\n/// enable statement logging\ndb.trac"
  },
  {
    "path": "SQLite.playground/contents.xcplayground",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='macos' display-mode='"
  },
  {
    "path": "SQLite.playground/playground.xcworkspace/contents.xcworkspacedata",
    "chars": 135,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef"
  },
  {
    "path": "SQLite.swift.podspec",
    "chars": 3013,
    "preview": "Pod::Spec.new do |s|\n  s.name             = \"SQLite.swift\"\n  s.version          = \"0.16.0\"\n  s.summary          = \"A typ"
  },
  {
    "path": "SQLite.xcodeproj/project.pbxproj",
    "chars": 136535,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "SQLite.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 151,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:SQLite.xcodepro"
  },
  {
    "path": "SQLite.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "SQLite.xcodeproj/xcshareddata/xcschemes/SQLite Mac.xcscheme",
    "chars": 3546,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "SQLite.xcodeproj/xcshareddata/xcschemes/SQLite iOS.xcscheme",
    "chars": 3546,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "SQLite.xcodeproj/xcshareddata/xcschemes/SQLite tvOS.xcscheme",
    "chars": 3552,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme",
    "chars": 2549,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1520\"\n   version = \"1.7\">\n   <BuildAction\n      "
  },
  {
    "path": "SQLite.xcodeproj/xcshareddata/xcschemes/SQLite watchOS.xcscheme",
    "chars": 2759,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1250\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "Sources/SQLite/Core/Backup.swift",
    "chars": 5430,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Core/Blob.swift",
    "chars": 1922,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Core/Connection+Aggregation.swift",
    "chars": 6271,
    "preview": "import Foundation\n#if StandaloneSQLite\nimport sqlite3\n#elseif SQLCipher\nimport SQLCipher\n#elseif SQLiteSwiftCSQLite\nimpo"
  },
  {
    "path": "Sources/SQLite/Core/Connection+Attach.swift",
    "chars": 849,
    "preview": "import Foundation\n\nextension Connection {\n    #if SQLCipher\n    /// See https://www.zetetic.net/sqlcipher/sqlcipher-api/"
  },
  {
    "path": "Sources/SQLite/Core/Connection+Pragmas.swift",
    "chars": 1908,
    "preview": "import Foundation\n\npublic typealias UserVersion = Int32\n\npublic extension Connection {\n    /// The user version of the d"
  },
  {
    "path": "Sources/SQLite/Core/Connection.swift",
    "chars": 28593,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Core/Errors.swift",
    "chars": 800,
    "preview": "import Foundation\n\npublic enum QueryError: Error, CustomStringConvertible, Sendable {\n    case noSuchTable(name: String)"
  },
  {
    "path": "Sources/SQLite/Core/Result.swift",
    "chars": 2418,
    "preview": "#if StandaloneSQLite\nimport sqlite3\n#elseif SQLCipher\nimport SQLCipher\n#elseif SQLiteSwiftCSQLite\nimport SQLiteSwiftCSQL"
  },
  {
    "path": "Sources/SQLite/Core/SQLiteFeature.swift",
    "chars": 829,
    "preview": "import Foundation\n\nenum SQLiteFeature {\n    case partialIntegrityCheck      // PRAGMA integrity_check(table)\n    case sq"
  },
  {
    "path": "Sources/SQLite/Core/SQLiteVersion.swift",
    "chars": 623,
    "preview": "import Foundation\n\npublic struct SQLiteVersion: Comparable, CustomStringConvertible, Sendable {\n    public let major: In"
  },
  {
    "path": "Sources/SQLite/Core/Statement.swift",
    "chars": 10521,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Core/URIQueryParameter.swift",
    "chars": 2449,
    "preview": "import Foundation\n\n/// See https://www.sqlite.org/uri.html\npublic enum URIQueryParameter: CustomStringConvertible {\n    "
  },
  {
    "path": "Sources/SQLite/Core/Value.swift",
    "chars": 3388,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Extensions/Cipher.swift",
    "chars": 9127,
    "preview": "#if SQLCipher\nimport SQLCipher\n\n/// Extension methods for [SQLCipher](https://www.zetetic.net/sqlcipher/).\n/// @see [sql"
  },
  {
    "path": "Sources/SQLite/Extensions/FTS4.swift",
    "chars": 11069,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Extensions/FTS5.swift",
    "chars": 3297,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Extensions/RTree.swift",
    "chars": 1691,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Foundation.swift",
    "chars": 3016,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Helpers.swift",
    "chars": 4122,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Info.plist",
    "chars": 823,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "Sources/SQLite/PrivacyInfo.xcprivacy",
    "chars": 373,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "Sources/SQLite/SQLite.h",
    "chars": 128,
    "preview": "@import Foundation;\n\nFOUNDATION_EXPORT double SQLiteVersionNumber;\nFOUNDATION_EXPORT const unsigned char SQLiteVersionSt"
  },
  {
    "path": "Sources/SQLite/Schema/Connection+Schema.swift",
    "chars": 1655,
    "preview": "import Foundation\n\npublic extension Connection {\n    var schema: SchemaReader { SchemaReader(connection: self) }\n\n    //"
  },
  {
    "path": "Sources/SQLite/Schema/SchemaChanger.swift",
    "chars": 15170,
    "preview": "import Foundation\n\n/*\n    https://www.sqlite.org/lang_altertable.html\n\n   The only schema altering commands directly sup"
  },
  {
    "path": "Sources/SQLite/Schema/SchemaDefinitions.swift",
    "chars": 15589,
    "preview": "import Foundation\n\nstruct TableDefinition: Equatable {\n    let name: String\n    let columns: [ColumnDefinition]\n    let "
  },
  {
    "path": "Sources/SQLite/Schema/SchemaReader.swift",
    "chars": 10034,
    "preview": "import Foundation\n\npublic class SchemaReader {\n    private let connection: Connection\n\n    init(connection: Connection) "
  },
  {
    "path": "Sources/SQLite/Typed/AggregateFunctions.swift",
    "chars": 8248,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Coding.swift",
    "chars": 26064,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Collation.swift",
    "chars": 2208,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/CoreFunctions.swift",
    "chars": 28167,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/CustomFunctions.swift",
    "chars": 8236,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/DateAndTimeFunctions.swift",
    "chars": 4489,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Expression.swift",
    "chars": 4245,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Operators.swift",
    "chars": 29675,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Query+with.swift",
    "chars": 4315,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Query.swift",
    "chars": 41899,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Schema.swift",
    "chars": 26501,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/Setter.swift",
    "chars": 11002,
    "preview": "//\n// SQLite.swift\n// https://github.com/stephencelis/SQLite.swift\n// Copyright © 2014-2015 Stephen Celis.\n//\n// Permiss"
  },
  {
    "path": "Sources/SQLite/Typed/WindowFunctions.swift",
    "chars": 6494,
    "preview": "import Foundation\n\n// see https://www.sqlite.org/windowfunctions.html#builtins\nprivate enum WindowFunction: String, Send"
  },
  {
    "path": "Tests/.swiftlint.yml",
    "chars": 211,
    "preview": "disabled_rules:\n  - force_cast\n  - force_try\n  - identifier_name\n\ntype_body_length:\n  warning: 1000\n  error: 1000\n\nfunct"
  },
  {
    "path": "Tests/SPM/.gitignore",
    "chars": 126,
    "preview": ".DS_Store\n/.build\n/Packages\n/*.xcodeproj\nxcuserdata/\nDerivedData/\n.swiftpm/xcode/package.xcworkspace/contents.xcworkspac"
  },
  {
    "path": "Tests/SPM/Package.swift",
    "chars": 666,
    "preview": "// swift-tools-version:6.1\n// The swift-tools-version declares the minimum version of Swift required to build this packa"
  },
  {
    "path": "Tests/SPM/Sources/test/main.swift",
    "chars": 192,
    "preview": "import SQLite\n\nlet table = Table(\"test\")\nlet name = Expression<String>(\"name\")\n\nlet db = try Connection(\"db.sqlite\", rea"
  },
  {
    "path": "Tests/SQLite visionOS.xctestplan",
    "chars": 416,
    "preview": "{\n  \"configurations\" : [\n    {\n      \"id\" : \"72B91FD4-441C-4C06-9E92-CAEDCB7325AB\",\n      \"name\" : \"Configuration 1\",\n  "
  },
  {
    "path": "Tests/SQLiteTests/Core/BlobTests.swift",
    "chars": 1405,
    "preview": "import XCTest\nimport SQLite\n\nclass BlobTests: XCTestCase {\n\n    func test_toHex() {\n        let blob = Blob(bytes: [0, 1"
  },
  {
    "path": "Tests/SQLiteTests/Core/Connection+AttachTests.swift",
    "chars": 1841,
    "preview": "import XCTest\nimport Foundation\n@testable import SQLite\n\n#if StandaloneSQLite\nimport sqlite3\n#elseif SQLCipher\nimport SQ"
  },
  {
    "path": "Tests/SQLiteTests/Core/Connection+PragmaTests.swift",
    "chars": 767,
    "preview": "import XCTest\nimport Foundation\n@testable import SQLite\n\nclass ConnectionPragmaTests: SQLiteTestCase {\n    func test_use"
  },
  {
    "path": "Tests/SQLiteTests/Core/ConnectionTests.swift",
    "chars": 16971,
    "preview": "import XCTest\nimport Foundation\nimport Dispatch\n@testable import SQLite\n\n#if StandaloneSQLite\nimport sqlite3\n#elseif SQL"
  },
  {
    "path": "Tests/SQLiteTests/Core/CoreFunctionsTests.swift",
    "chars": 7073,
    "preview": "import XCTest\n@testable import SQLite\n\nclass CoreFunctionsTests: XCTestCase {\n\n    func test_round_wrapsDoubleExpression"
  },
  {
    "path": "Tests/SQLiteTests/Core/ResultTests.swift",
    "chars": 2371,
    "preview": "import XCTest\nimport Foundation\n@testable import SQLite\n\n#if StandaloneSQLite\nimport sqlite3\n#elseif SQLCipher\nimport SQ"
  },
  {
    "path": "Tests/SQLiteTests/Core/StatementTests.swift",
    "chars": 2623,
    "preview": "import XCTest\n@testable import SQLite\n\n#if StandaloneSQLite\nimport sqlite3\n#elseif SQLCipher\nimport SQLCipher\n#elseif SQ"
  },
  {
    "path": "Tests/SQLiteTests/Core/ValueTests.swift",
    "chars": 63,
    "preview": "import XCTest\nimport SQLite\n\nclass ValueTests: XCTestCase {\n\n}\n"
  },
  {
    "path": "Tests/SQLiteTests/Extensions/CipherTests.swift",
    "chars": 4348,
    "preview": "#if SQLCipher\nimport XCTest\nimport SQLite\nimport SQLCipher\n\nclass CipherTests: XCTestCase {\n    var db1: Connection!\n   "
  },
  {
    "path": "Tests/SQLiteTests/Extensions/FTS4Tests.swift",
    "chars": 7051,
    "preview": "import XCTest\nimport SQLite\n\nclass FTS4Tests: XCTestCase {\n\n    func test_create_onVirtualTable_withFTS4_compilesCreateV"
  },
  {
    "path": "Tests/SQLiteTests/Extensions/FTS5IntegrationTests.swift",
    "chars": 2040,
    "preview": "import XCTest\n@testable import SQLite\n\n// Note: these tests are only run when the FTS5 trait has been enabled.\nclass FTS"
  },
  {
    "path": "Tests/SQLiteTests/Extensions/FTS5Tests.swift",
    "chars": 4491,
    "preview": "import XCTest\nimport SQLite\n\nclass FTS5Tests: XCTestCase {\n    var config: FTS5Config!\n\n    override func setUp() {\n    "
  },
  {
    "path": "Tests/SQLiteTests/Extensions/RTreeTests.swift",
    "chars": 591,
    "preview": "import XCTest\nimport SQLite\n\nclass RTreeTests: XCTestCase {\n\n    func test_create_onVirtualTable_withRTree_createVirtual"
  },
  {
    "path": "Tests/SQLiteTests/Fixtures.swift",
    "chars": 622,
    "preview": "import Foundation\n\nfunc fixture(_ name: String, withExtension: String?) -> String {\n    #if SWIFT_PACKAGE\n    let testBu"
  },
  {
    "path": "Tests/SQLiteTests/FoundationTests.swift",
    "chars": 1204,
    "preview": "import XCTest\nimport SQLite\n\nclass FoundationTests: XCTestCase {\n    func testDataFromBlob() {\n        let data = Data(["
  },
  {
    "path": "Tests/SQLiteTests/Info.plist",
    "chars": 733,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "Tests/SQLiteTests/Schema/Connection+SchemaTests.swift",
    "chars": 1650,
    "preview": "import XCTest\n@testable import SQLite\n\nclass ConnectionSchemaTests: SQLiteTestCase {\n\n    override func setUpWithError()"
  },
  {
    "path": "Tests/SQLiteTests/Schema/SchemaChangerTests.swift",
    "chars": 14983,
    "preview": "import XCTest\n@testable import SQLite\n\nclass SchemaChangerTests: SQLiteTestCase {\n    var schemaChanger: SchemaChanger!\n"
  },
  {
    "path": "Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift",
    "chars": 15758,
    "preview": "import XCTest\n@testable import SQLite\n\nclass ColumnDefinitionTests: XCTestCase {\n    var definition: ColumnDefinition!\n "
  },
  {
    "path": "Tests/SQLiteTests/Schema/SchemaReaderTests.swift",
    "chars": 11374,
    "preview": "import XCTest\n@testable import SQLite\n\nclass SchemaReaderTests: SQLiteTestCase {\n    private var schemaReader: SchemaRea"
  },
  {
    "path": "Tests/SQLiteTests/Schema/SchemaTests.swift",
    "chars": 46199,
    "preview": "import XCTest\nimport SQLite\n\nclass SchemaTests: XCTestCase {\n\n    func test_drop_compilesDropTableExpression() {\n       "
  },
  {
    "path": "Tests/SQLiteTests/TestHelpers.swift",
    "chars": 5716,
    "preview": "import XCTest\n@testable import SQLite\n\nclass SQLiteTestCase: XCTestCase {\n    private var trace: [String: Int]!\n    var "
  },
  {
    "path": "Tests/SQLiteTests/Typed/AggregateFunctionsTests.swift",
    "chars": 2820,
    "preview": "import XCTest\nimport SQLite\n\nclass AggregateFunctionsTests: XCTestCase {\n\n    func test_distinct_prependsExpressionsWith"
  },
  {
    "path": "Tests/SQLiteTests/Typed/CustomAggregationTests.swift",
    "chars": 5797,
    "preview": "import XCTest\nimport Foundation\nimport Dispatch\n@testable import SQLite\n\n// https://github.com/stephencelis/SQLite.swift"
  },
  {
    "path": "Tests/SQLiteTests/Typed/CustomFunctionsTests.swift",
    "chars": 6548,
    "preview": "import XCTest\nimport SQLite\n\n// https://github.com/stephencelis/SQLite.swift/issues/1071\n#if !(os(Linux) || os(Android))"
  },
  {
    "path": "Tests/SQLiteTests/Typed/DateAndTimeFunctionTests.swift",
    "chars": 2005,
    "preview": "import XCTest\n@testable import SQLite\n\nclass DateAndTimeFunctionsTests: XCTestCase {\n\n    func test_date() {\n        ass"
  },
  {
    "path": "Tests/SQLiteTests/Typed/ExpressionTests.swift",
    "chars": 1146,
    "preview": "import XCTest\n@testable import SQLite\n\nclass ExpressionTests: XCTestCase {\n\n    func test_asSQL_expression_bindings() {\n"
  },
  {
    "path": "Tests/SQLiteTests/Typed/OperatorsTests.swift",
    "chars": 20571,
    "preview": "import XCTest\nimport SQLite\n\nclass OperatorsTests: XCTestCase {\n\n    func test_stringExpressionPlusStringExpression_buil"
  },
  {
    "path": "Tests/SQLiteTests/Typed/QueryIntegrationTests.swift",
    "chars": 17458,
    "preview": "import XCTest\n#if StandaloneSQLite\nimport sqlite3\n#elseif SQLCipher\nimport SQLCipher\n#elseif SQLiteSwiftCSQLite\nimport S"
  },
  {
    "path": "Tests/SQLiteTests/Typed/QueryTests.swift",
    "chars": 24312,
    "preview": "import XCTest\n@testable import SQLite\n\nclass QueryTests: XCTestCase {\n\n    let users = Table(\"users\")\n    let id = SQLit"
  },
  {
    "path": "Tests/SQLiteTests/Typed/RowTests.swift",
    "chars": 3867,
    "preview": "import XCTest\n@testable import SQLite\n\nclass RowTests: XCTestCase {\n\n    public func test_get_value() throws {\n        l"
  },
  {
    "path": "Tests/SQLiteTests/Typed/SelectTests.swift",
    "chars": 1219,
    "preview": "import XCTest\n@testable import SQLite\n\nclass SelectTests: SQLiteTestCase {\n\n    override func setUpWithError() throws {\n"
  },
  {
    "path": "Tests/SQLiteTests/Typed/SetterTests.swift",
    "chars": 8185,
    "preview": "import XCTest\nimport SQLite\n\nclass SetterTests: XCTestCase {\n\n    func test_setterAssignmentOperator_buildsSetter() {\n  "
  },
  {
    "path": "Tests/SQLiteTests/Typed/WindowFunctionsTests.swift",
    "chars": 2664,
    "preview": "import XCTest\nimport SQLite\n\nclass WindowFunctionsTests: XCTestCase {\n\n    func test_ntile_wrapsExpressionWithOverClause"
  },
  {
    "path": "Tests/Tuist/SQLite-Test/.gitignore",
    "chars": 1206,
    "preview": "### macOS ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two\nIcon\n\n# Thumbnails\n._*\n\n# Files tha"
  },
  {
    "path": "Tests/Tuist/SQLite-Test/Project.swift",
    "chars": 1005,
    "preview": "import ProjectDescription\n\nlet project = Project(\n    name: \"SQLite-Test\",\n    targets: [\n        .target(\n            n"
  },
  {
    "path": "Tests/Tuist/SQLite-Test/SQLite-Test/Sources/SQLiteTestApp.swift",
    "chars": 262,
    "preview": "import SwiftUI\nimport SQLite\n\nlet connection = try! SQLite.Connection(.inMemory)\n\n@main\nstruct SQLiteTestApp: App {\n    "
  },
  {
    "path": "Tests/Tuist/SQLite-Test/SQLite-Test/Tests/SQLiteTestTests.swift",
    "chars": 255,
    "preview": "import Testing\nimport SQLite\n\nstruct SQLiteTestTests {\n\n    @Test func test_connection() async throws {\n        let conn"
  },
  {
    "path": "Tests/Tuist/SQLite-Test/Tuist/Package.swift",
    "chars": 627,
    "preview": "// swift-tools-version: 6.0\nimport PackageDescription\n\n#if TUIST\n    import struct ProjectDescription.PackageSettings\n\n "
  },
  {
    "path": "Tests/Tuist/SQLite-Test/Tuist.swift",
    "chars": 64,
    "preview": "import ProjectDescription\n\nlet tuist = Tuist(project: .tuist())\n"
  },
  {
    "path": "run-tests.sh",
    "chars": 799,
    "preview": "#!/bin/bash\nset -ev\nif [ -n \"$BUILD_SCHEME\" ]; then\n    if [ -n \"$IOS_SIMULATOR\" ]; then\n        make test BUILD_SCHEME="
  }
]

About this extraction

This page contains the full source code of the stephencelis/SQLite.swift GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 115 files (851.7 KB), approximately 225.7k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!