Skip to content

Commit 4eace8e

Browse files
author
Nathan Fallet
authored
Merge pull request #972 from SVKorosteleva/MigrateToNewSQLCipher
2 parents dcbbd35 + c4455ea commit 4eace8e

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

Sources/SQLite/Extensions/Cipher.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ extension Connection {
3131
try _key_v2(db: db, keyPointer: key.bytes, keySize: key.bytes.count)
3232
}
3333

34+
/// Same as `key(_ key: String, db: String = "main")`, running "PRAGMA cipher_migrate;"
35+
/// immediately after calling `sqlite3_key_v2`, which performs the migration of
36+
/// SQLCipher database created by older major version of SQLCipher, to be able to
37+
/// open this database with new major version of SQLCipher
38+
/// (e.g. to open database created by SQLCipher version 3.x.x with SQLCipher version 4.x.x).
39+
/// As "PRAGMA cipher_migrate;" is time-consuming, it is recommended to use this function
40+
/// only after failure of `key(_ key: String, db: String = "main")`, if older versions of
41+
/// your app may ise older version of SQLCipher
42+
/// See https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate
43+
/// and https://discuss.zetetic.net/t/upgrading-to-sqlcipher-4/3283
44+
/// for more details regarding SQLCipher upgrade
45+
public func keyAndMigrate(_ key: String, db: String = "main") throws {
46+
try _key_v2(db: db, keyPointer: key, keySize: key.utf8.count, migrate: true)
47+
}
48+
49+
/// Same as `[`keyAndMigrate(_ key: String, db: String = "main")` accepting byte array as key
50+
public func keyAndMigrate(_ key: Blob, db: String = "main") throws {
51+
try _key_v2(db: db, keyPointer: key.bytes, keySize: key.bytes.count, migrate: true)
52+
}
53+
3454
/// Change the key on an open database. If the current database is not encrypted, this routine
3555
/// will encrypt it.
3656
/// To change the key on an existing encrypted database, it must first be unlocked with the
@@ -45,8 +65,20 @@ extension Connection {
4565
}
4666

4767
// MARK: - private
48-
private func _key_v2(db: String, keyPointer: UnsafePointer<UInt8>, keySize: Int) throws {
68+
private func _key_v2(db: String,
69+
keyPointer: UnsafePointer<UInt8>,
70+
keySize: Int,
71+
migrate: Bool = false) throws {
4972
try check(sqlite3_key_v2(handle, db, keyPointer, Int32(keySize)))
73+
if migrate {
74+
// Run "PRAGMA cipher_migrate;" immediately after `sqlite3_key_v2`
75+
// per recommendation of SQLCipher authors
76+
let migrateResult = try scalar("PRAGMA cipher_migrate;")
77+
if (migrateResult as? String) != "0" {
78+
// "0" is the result of successfull migration
79+
throw Result.error(message: "Error in cipher migration, result \(migrateResult.debugDescription)", code: 1, statement: nil)
80+
}
81+
}
5082
try cipher_key_check()
5183
}
5284

0 commit comments

Comments
 (0)