@@ -14,7 +14,7 @@ library (e.g., Android, Windows).
14
14
## Features
15
15
16
16
- A pure-Swift interface
17
- - Embeds a modern and consistent sqlite ([ 3.49.1] ( https://www.sqlite.org/releaselog/3_49_1.html ) ) and sqlcipher ([ 4.7 .0] ( https://github.com/sqlcipher/sqlcipher/releases/tag/v4.7 .0 ) ) build in the library
17
+ - Embeds a modern and consistent sqlite ([ 3.49.1] ( https://www.sqlite.org/releaselog/3_49_1.html ) ) and sqlcipher ([ 4.8 .0] ( https://github.com/sqlcipher/sqlcipher/releases/tag/v4.8 .0 ) ) build in the library
18
18
- Works on iOS, macOS, Android, Windows, and Linux
19
19
- A type-safe, optional-aware SQL expression builder
20
20
- A flexible, chainable, lazy-executing query layer
@@ -120,7 +120,8 @@ library (e.g., Android, Windows).
120
120
- [ Online Database Backup] ( #online-database-backup )
121
121
- [ Attaching and detaching databases] ( #attaching-and-detaching-databases )
122
122
- [ Logging] ( #logging )
123
- - [ Vacuum] ( #vacuum )
123
+ - [ Database Middleware Packages] ( #database-middleware-packages )
124
+ - [ Communication] ( #communication )
124
125
125
126
[ ↩ ] : #sqliteswift-documentation
126
127
@@ -136,7 +137,7 @@ process of downloading, compiling, and linking dependencies.
136
137
137
138
``` swift
138
139
dependencies: [
139
- .package (url : " https://github.com/skiptools/swift-sqlcipher.git" , from : " 1.3 .0" )
140
+ .package (url : " https://github.com/skiptools/swift-sqlcipher.git" , from : " 1.4 .0" )
140
141
]
141
142
```
142
143
@@ -150,22 +151,41 @@ process of downloading, compiling, and linking dependencies.
150
151
151
152
## Getting Started
152
153
154
+ If you just want to use the low-level SQLCipher functions instead of SQLite3,
155
+ you can conditionally import the package:
156
+
157
+ ``` swift
158
+ #if canImport (SQLCipher )
159
+ import SQLCipher
160
+ #else
161
+ import SQLite3
162
+ #endif
163
+ ```
164
+
165
+ SQLCipher is API-compatible with the SQLite3 framework that is included on many platforms,
166
+ including iOS and Android.
167
+
168
+ The remainder of this document assumes you want to use the higher-level SQLiteDB
169
+ interface atop the SQLCipher package. This interface is based on the
170
+ [ SQLite.swift] ( https://github.com/stephencelis/SQLite.swift ) package, but
171
+ uses SQLCipher rather than SQLite3 and enables various features like encryption,
172
+ FTS5, and JSON support.
173
+
153
174
To use SQLiteDB classes or structures in your target’s source file, first
154
175
import the ` SQLiteDB ` module.
155
176
156
177
``` swift
157
178
import SQLiteDB
158
179
```
159
180
160
-
161
181
### Connecting to a Database
162
182
163
183
Database connections are established using the ` Connection ` class. A
164
184
connection is initialized with a path to a database. SQLite will attempt to
165
185
create the database file if it does not already exist.
166
186
167
187
``` swift
168
- let db = try Connection (" path/to/db.sqlite3 " )
188
+ let db = try Connection (" path/to/database.db " )
169
189
```
170
190
171
191
@@ -178,7 +198,7 @@ directory.
178
198
let path = URL.applicationSupportDirectory
179
199
// create parent directory inside application support if it doesn’t exist
180
200
try FileManager.default .createDirectory (atPath : path, withIntermediateDirectories : true , attributes : nil )
181
- let db = try Connection (dbURL.appendingPathComponent (" db.sqlite3 " ).path )
201
+ let db = try Connection (dbURL.appendingPathComponent (" database.db " ).path )
182
202
```
183
203
184
204
#### Read-Only Databases
@@ -193,7 +213,7 @@ let path = Bundle.main.path(forResource: "db", ofType: "sqlite3")!
193
213
let db = try Connection (path, readonly : true )
194
214
```
195
215
196
- > [ !NOTE ]
216
+ > [ !WARNING ]
197
217
> Signed applications cannot modify their bundle resources. If you
198
218
> bundle a database file with your app for the purpose of bootstrapping, copy
199
219
> it to a writable location _ before_ establishing a connection (see
@@ -2112,15 +2132,90 @@ try db.vacuum()
2112
2132
[ROWID]: https: // sqlite.org/lang_createtable.html#rowid
2113
2133
[SQLiteMigrationManager.swift ]: https: // github.com/garriguv/SQLiteMigrationManager.swift
2114
2134
2135
+ ## Database Middleware Packages
2136
+
2137
+ If you have a Swift package that acts as database middleware, such as an ORM
2138
+ or other database access layer, that uses the SQLite3 C API directly, you can expose a
2139
+ [SwiftPM 6.1 trait](https :// github.com/swiftlang/swift-evolution/blob/main/proposals/0450-swiftpm-package-traits.md)
2140
+ in your `Package.swift ` to enable dependent packages to enable using SQLCipher rather than SQLite3.
2141
+
2142
+ ```swift
2143
+ // swift-tools-version:6.1
2144
+ import PackageDescription
2145
+
2146
+ let package = Package (name : " your-middleware" ,
2147
+ products : [
2148
+ .library (name : " NeatORM" , targets : [" NeatORM" ])
2149
+ ],
2150
+ traits : [
2151
+ .trait (name : " SQLCipher" , description : " Use the SQLCipher library rather than the vendored SQLite" )
2152
+ ],
2153
+ depedencies : [
2154
+ .package (url : " https://github.com/skiptools/swift-sqlcipher.git" , from : " 1.4.0" )
2155
+ ],
2156
+ targets : [
2157
+ .target (name : " NeatORM" , dependencies : [
2158
+ // target only depends on SQLCipher when the "SQLCipher" trait is activated by a dependent package
2159
+ // otherwise it will default to using the system "SQLite3" framework
2160
+ .product (name : " SQLCipher" , package : " swift-sqlcipher" , condition : .when (traits : [" SQLCipher" ]))
2161
+ ])
2162
+ ]
2163
+ )
2164
+ ```
2165
+
2166
+ Then throughout your package 's code, wherever you `import SQLite3`,
2167
+ you would change this to conditionally `import SQLCipher` if it is available
2168
+ (i.e ., if the trait is activated by the client package ):
2169
+
2170
+ ```swift
2171
+ #if canImport (SQLCipher)
2172
+ import SQLCipher
2173
+ #else
2174
+ import SQLite3
2175
+ #endif
2176
+ ```
2177
+
2178
+ Since the C API surface of the SQLCipher package is a superset of the SQLite3 framework,
2179
+ all the same `sqlite3_* ` functions will behave identically. However, you may want to also
2180
+ create additional conditionally- enabled functionality in your own package , such as
2181
+ for key management or FTS5 search index handling. For example:
2182
+
2183
+ ```swift
2184
+ #if canImport (SQLCipher)
2185
+ import SQLCipher
2186
+
2187
+ extension Connection {
2188
+ func updateEncryptionKey (newKey : String ) throws {
2189
+ try checkError (sqlite3_rekey_v2 (dbHandle, newKey, Int32 (newKey.utf8 .count )))
2190
+ }
2191
+ }
2192
+ ```
2193
+
2194
+ Clients of your package would then enable the SQLCipher trait in their
2195
+ Package.swift 's dependencies:
2196
+
2197
+ ```swift
2198
+ dependencies: [
2199
+ // turn on SQLCipher support for NeatORM
2200
+ .package (url : " https://github.com/your-middleware/NeatORM.git" , from : " 1.2.3" , traits : [" SQLCipher" ])
2201
+ ]
2202
+ ```
2203
+
2204
+ In this way, your package can be parameterized to work with either the
2205
+ built- in vendored SQLite3 package or with the SQLCipher package
2206
+ depending on the needs of the developer.
2115
2207
2116
2208
## Communication
2117
2209
2118
- [Open an issue]: https: // github.com/skiptools/swift-sqlcipher/issues/new
2119
- [Submit a pull request]: https: // github.com/skiptools/swift-sqlcipher/pulls
2210
+ - [Browse discussions](https :// github.com/skiptools/swift-sqlcipher/discussions)
2211
+ - [Open an issue](https :// github.com/skiptools/swift-sqlcipher/issues/new)
2212
+ - [Submit a pull request](https :// github.com/skiptools/swift-sqlcipher/pulls)
2120
2213
2121
2214
## License
2122
2215
2123
- MIT license. See [the LICENSE file](./ LICENSE.txt ) for more information.
2216
+ - This swift- sqlcipher package uses the MIT license. See [the LICENSE file](./ LICENSE.txt ) for more information.
2217
+ - The BSD- style sqlcipher license is available at [https :// www.zetetic.net/sqlcipher/license/](https://www.zetetic.net/sqlcipher/license/).
2218
+ - SQLite3 itself is in the public domain. Its license is available at [https :// sqlite.org/purchase/license](https://sqlite.org/purchase/license).
2124
2219
2125
2220
## Alternatives
2126
2221
0 commit comments