Skip to content

Commit a1ac6ba

Browse files
authored
Update to sqlcipher 4.8.0 (#7)
* Update to sqlcipher 4.8.0 * Update README with sqlcipher 4.8.0 and mention of using package traits for database middleware packages * Update README * Update README * Update README with licenses * Update README with licenses
1 parent f008b2b commit a1ac6ba

File tree

2 files changed

+273
-124
lines changed

2 files changed

+273
-124
lines changed

README.md

Lines changed: 105 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ library (e.g., Android, Windows).
1414
## Features
1515

1616
- 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
1818
- Works on iOS, macOS, Android, Windows, and Linux
1919
- A type-safe, optional-aware SQL expression builder
2020
- A flexible, chainable, lazy-executing query layer
@@ -120,7 +120,8 @@ library (e.g., Android, Windows).
120120
- [Online Database Backup](#online-database-backup)
121121
- [Attaching and detaching databases](#attaching-and-detaching-databases)
122122
- [Logging](#logging)
123-
- [Vacuum](#vacuum)
123+
- [Database Middleware Packages](#database-middleware-packages)
124+
- [Communication](#communication)
124125

125126
[]: #sqliteswift-documentation
126127

@@ -136,7 +137,7 @@ process of downloading, compiling, and linking dependencies.
136137

137138
```swift
138139
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")
140141
]
141142
```
142143

@@ -150,22 +151,41 @@ process of downloading, compiling, and linking dependencies.
150151

151152
## Getting Started
152153

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+
153174
To use SQLiteDB classes or structures in your target’s source file, first
154175
import the `SQLiteDB` module.
155176

156177
```swift
157178
import SQLiteDB
158179
```
159180

160-
161181
### Connecting to a Database
162182

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

167187
```swift
168-
let db = try Connection("path/to/db.sqlite3")
188+
let db = try Connection("path/to/database.db")
169189
```
170190

171191

@@ -178,7 +198,7 @@ directory.
178198
let path = URL.applicationSupportDirectory
179199
// create parent directory inside application support if it doesn’t exist
180200
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)
182202
```
183203

184204
#### Read-Only Databases
@@ -193,7 +213,7 @@ let path = Bundle.main.path(forResource: "db", ofType: "sqlite3")!
193213
let db = try Connection(path, readonly: true)
194214
```
195215

196-
> [!NOTE]
216+
> [!WARNING]
197217
> Signed applications cannot modify their bundle resources. If you
198218
> bundle a database file with your app for the purpose of bootstrapping, copy
199219
> it to a writable location _before_ establishing a connection (see
@@ -2112,15 +2132,90 @@ try db.vacuum()
21122132
[ROWID]: https://sqlite.org/lang_createtable.html#rowid
21132133
[SQLiteMigrationManager.swift]: https://github.com/garriguv/SQLiteMigrationManager.swift
21142134

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.
21152207

21162208
## Communication
21172209

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)
21202213

21212214
## License
21222215

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).
21242219

21252220
## Alternatives
21262221

0 commit comments

Comments
 (0)