Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-add support for SQLcipher via CocoaPods #553

Merged
merged 13 commits into from
Dec 6, 2016
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ matrix:
- env: VALIDATOR_SUBSPEC="none"
- env: VALIDATOR_SUBSPEC="standard"
- env: VALIDATOR_SUBSPEC="standalone"
- env: VALIDATOR_SUBSPEC="SQLCipher"
before_install:
- gem update bundler
- gem install xcpretty --no-document
Expand Down
14 changes: 10 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
0.11.1 (unreleased, [diff][diff-0.11.1])

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

* Made lastInsertRowid consistent with other SQLite wrappers (#532)
* 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)
0.11.0 (10-19-2016)
===================

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


[diff-0.11.1]: https://github.com/stephencelis/SQLite.swift/compare/0.11.1...0.11.0
[diff-0.11.1]: https://github.com/stephencelis/SQLite.swift/compare/0.11.0...0.11.1
[diff-0.11.0]: https://github.com/stephencelis/SQLite.swift/compare/0.10.1...0.11.0

[#532]: https://github.com/stephencelis/SQLite.swift/issues/532
[#546]: https://github.com/stephencelis/SQLite.swift/issues/546
[#553]: https://github.com/stephencelis/SQLite.swift/pull/553
24 changes: 22 additions & 2 deletions Documentation/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ install SQLite.swift with Carthage:
4. Run `pod install --repo-update`.


#### Requiring a specific version of SQLite
#### 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:

Expand All @@ -131,10 +131,30 @@ By default this will use the most recent version of SQLite without any extras. I

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

#### Using SQLite.swift with SQLCipher

If you want to use [SQLCipher][] with SQLite.swift you can require the `SQLCipher`
subspec in your Podfile:

``` ruby
pod 'SQLite.swift/SQLCipher', '~> 0.11.1'
```

This will automatically add a dependency to the SQLCipher pod as well as extend
`Connection` with methods to change the database key:

``` swift
import SQLite

let db = try Connection("path/to/db.sqlite3")
try db.key("secret")
try db.rekey("another secret")
```

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

[SQLCipher]: https://www.zetetic.net/sqlcipher/

### Manual

Expand Down
9 changes: 2 additions & 7 deletions Documentation/Planning.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
# SQLite.swift Planning

This document captures both near term steps (aka Roadmap) and feature requests.
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.

## Roadmap

_Lists agreed upon next steps in approximate priority order._

* ~~publish to the CocoaPods directory at https://cocoapods.org/, per [#257](https://github.com/stephencelis/SQLite.swift/issues/257)~~ _jan 7, 2016_)
* add SQLCipher back into the product as a separate repo, per [#311](https://github.com/stephencelis/SQLite.swift/issues/311), _in progress jan 6, 2016_


## 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._

### Packaging

* add TV OS support, per [#272](https://github.com/stephencelis/SQLite.swift/issues/272) - currently pending SQLiteCipher merge and/or adding ability for user to pick their preferred [SQLCipher](https://github.com/sqlcipher/sqlcipher) branch
* linux support via Swift Package Manager, per [#315](https://github.com/stephencelis/SQLite.swift/issues/315)
* linux support via Swift Package Manager, per [#315](https://github.com/stephencelis/SQLite.swift/issues/315), _in progress_: [#548](https://github.com/stephencelis/SQLite.swift/pull/548)

### Features

Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ syntax _and_ intent.
- [Full-text search][] support
- [Well-documented][See Documentation]
- Extensively tested
- Companion project has [SQLCipher support](https://github.com/stephencelis/SQLiteCipher.swift)
- SQLCipher support via CocoaPods
- Active support at [StackOverflow](http://stackoverflow.com/questions/tagged/sqlite.swift), and [Gitter Chat Room](https://gitter.im/stephencelis/SQLite.swift) (_experimental_)

[Full-text search]: Documentation/Index.md#full-text-search
Expand Down Expand Up @@ -224,7 +224,6 @@ file](./LICENSE.txt) for more information.

These projects enhance or use SQLite.swift:

- [SQLiteCipher.swift](https://github.com/stephencelis/SQLiteCipher.swift)
- [SQLiteMigrationManager.swift](https://github.com/garriguv/SQLiteMigrationManager.swift) (inspired by [FMDBMigrationManager](https://github.com/layerhq/FMDBMigrationManager))


Expand Down
19 changes: 17 additions & 2 deletions SQLite.swift.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Pod::Spec.new do |s|

s.subspec 'standard' do |ss|
ss.source_files = 'SQLite/**/*.{c,h,m,swift}'
ss.exclude_files = 'SQLite/Extensions/Cipher.swift'
ss.private_header_files = 'SQLite/Core/fts3_tokenizer.h'

ss.library = 'sqlite3'
Expand All @@ -47,9 +48,23 @@ Pod::Spec.new do |s|

s.subspec 'standalone' do |ss|
ss.source_files = 'SQLite/**/*.{c,h,m,swift}'
ss.exclude_files = 'SQLite/Extensions/Cipher.swift'
ss.private_header_files = 'SQLite/Core/fts3_tokenizer.h'
ss.xcconfig = { 'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_STANDALONE' }
ss.xcconfig = {
'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_STANDALONE'
}

ss.dependency 'sqlite3', '>= 3.14.0'
end

s.subspec 'SQLCipher' do |ss|
ss.source_files = 'SQLite/**/*.{c,h,m,swift}'
ss.private_header_files = 'SQLite/Core/fts3_tokenizer.h'
ss.xcconfig = {
'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_SQLCIPHER',
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_HAS_CODEC=1'
}

ss.dependency 'sqlite3'
ss.dependency 'SQLCipher', '>= 3.4.0'
end
end
18 changes: 18 additions & 0 deletions SQLite.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,17 @@
03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E961C6BB3210062603F /* libsqlite3.tbd */; };
19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
19A171E6FA242F72A308C594 /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; };
19A171F12AB8B07F2FD7201A /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; };
19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; };
19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
19A177CC33F2E6A24AF90B02 /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; };
19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
19A17835FD5886FDC5A3228F /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
19A179A0C45377CB09BB358C /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; };
19A179CCF9671E345E5A9811 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
19A179E76EA6207669B60C1B /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
19A17C4B951CB054EE48AB1C /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; };
19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
Expand Down Expand Up @@ -189,6 +196,8 @@
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; };
19A1721B8984686B9963B45D /* FTS5Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5Tests.swift; sourceTree = "<group>"; };
19A1730E4390C775C25677D1 /* FTS5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS5.swift; sourceTree = "<group>"; };
19A17399EA9E61235D5D77BF /* 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>"; };
19A1794CC4D7827E997E32A7 /* FoundationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationTests.swift; sourceTree = "<group>"; };
39548A631CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
39548A651CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
Expand Down Expand Up @@ -455,6 +464,7 @@
EE247AE41C3F04ED00AE3E12 /* Info.plist */,
19A1721B8984686B9963B45D /* FTS5Tests.swift */,
19A1794CC4D7827E997E32A7 /* FoundationTests.swift */,
19A17399EA9E61235D5D77BF /* CipherTests.swift */,
);
path = SQLiteTests;
sourceTree = "<group>";
Expand All @@ -479,6 +489,7 @@
EE247AF51C3F06E900AE3E12 /* FTS4.swift */,
EE247AF61C3F06E900AE3E12 /* RTree.swift */,
19A1730E4390C775C25677D1 /* FTS5.swift */,
19A178A39ACA9667A62663CC /* Cipher.swift */,
);
path = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -845,6 +856,7 @@
03A65E771C6BB2E60062603F /* Connection.swift in Sources */,
03A65E7E1C6BB2FB0062603F /* AggregateFunctions.swift in Sources */,
19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */,
19A179E76EA6207669B60C1B /* Cipher.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -869,6 +881,7 @@
03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */,
19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */,
19A17E04C4C0956715C5676A /* FoundationTests.swift in Sources */,
19A179A0C45377CB09BB358C /* CipherTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -895,6 +908,7 @@
3D67B3F61DB246D100A4F4C6 /* Setter.swift in Sources */,
3D67B3E71DB246BA00A4F4C6 /* Blob.swift in Sources */,
3D67B3E81DB246BA00A4F4C6 /* Connection.swift in Sources */,
19A179CCF9671E345E5A9811 /* Cipher.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -921,6 +935,7 @@
EE247B071C3F06E900AE3E12 /* Statement.swift in Sources */,
EE247B0D1C3F06E900AE3E12 /* AggregateFunctions.swift in Sources */,
19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */,
19A171F12AB8B07F2FD7201A /* Cipher.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -945,6 +960,7 @@
EE247B251C3F137700AE3E12 /* ConnectionTests.swift in Sources */,
19A171E6FA242F72A308C594 /* FTS5Tests.swift in Sources */,
19A17FB80B94E882050AA908 /* FoundationTests.swift in Sources */,
19A177CC33F2E6A24AF90B02 /* CipherTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -971,6 +987,7 @@
EE247B661C3F3FEC00AE3E12 /* Connection.swift in Sources */,
EE247B6D1C3F3FEC00AE3E12 /* AggregateFunctions.swift in Sources */,
19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */,
19A17835FD5886FDC5A3228F /* Cipher.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -995,6 +1012,7 @@
EE247B5B1C3F3FC700AE3E12 /* QueryTests.swift in Sources */,
19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */,
19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */,
19A17C4B951CB054EE48AB1C /* CipherTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
83 changes: 48 additions & 35 deletions SQLite/Core/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import Foundation.NSUUID
import Dispatch
#if SQLITE_SWIFT_STANDALONE
import sqlite3
#elseif SQLITE_SWIFT_SQLCIPHER
import SQLCipher
#elseif COCOAPODS
import CSQLite
#endif
Expand Down Expand Up @@ -411,11 +413,15 @@ public final class Connection {
///
/// db.trace { SQL in print(SQL) }
public func trace(_ callback: ((String) -> Void)?) {
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
trace_v2(callback)
} else {
#if SQLITE_SWIFT_SQLCIPHER
trace_v1(callback)
}
#else
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
trace_v2(callback)
} else {
trace_v1(callback)
}
#endif
}

fileprivate func trace_v1(_ callback: ((String) -> Void)?) {
Expand All @@ -439,37 +445,8 @@ public final class Connection {
trace = box
}

@available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *)
fileprivate func trace_v2(_ callback: ((String) -> Void)?) {
guard let callback = callback else {
// If the X callback is NULL or if the M mask is zero, then tracing is disabled.
sqlite3_trace_v2(handle, 0 /* mask */, nil /* xCallback */, nil /* pCtx */)
trace = nil
return
}

let box: Trace = { (pointer: UnsafeRawPointer) in
callback(String(cString: pointer.assumingMemoryBound(to: UInt8.self)))
}
sqlite3_trace_v2(handle,
UInt32(SQLITE_TRACE_STMT) /* mask */,
{
// A trace callback is invoked with four arguments: callback(T,C,P,X).
// The T argument is one of the SQLITE_TRACE constants to indicate why the
// callback was invoked. The C argument is a copy of the context pointer.
// The P and X arguments are pointers whose meanings depend on T.
(T: UInt32, C: UnsafeMutableRawPointer?, P: UnsafeMutableRawPointer?, X: UnsafeMutableRawPointer?) in
if let P = P,
let expandedSQL = sqlite3_expanded_sql(OpaquePointer(P)) {
unsafeBitCast(C, to: Trace.self)(expandedSQL)
sqlite3_free(expandedSQL)
}
return Int32(0) // currently ignored
},
unsafeBitCast(box, to: UnsafeMutableRawPointer.self) /* pCtx */
)
trace = box
}


fileprivate typealias Trace = @convention(block) (UnsafeRawPointer) -> Void
fileprivate var trace: Trace?
Expand Down Expand Up @@ -674,7 +651,7 @@ public final class Connection {
return success!
}

@discardableResult public func check(_ resultCode: Int32, statement: Statement? = nil) throws -> Int32 {
@discardableResult func check(_ resultCode: Int32, statement: Statement? = nil) throws -> Int32 {
guard let error = Result(errorCode: resultCode, connection: self, statement: statement) else {
return resultCode
}
Expand Down Expand Up @@ -740,3 +717,39 @@ extension Result : CustomStringConvertible {
}

}

#if !SQLITE_SWIFT_SQLCIPHER
@available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *)
extension Connection {
fileprivate func trace_v2(_ callback: ((String) -> Void)?) {
guard let callback = callback else {
// If the X callback is NULL or if the M mask is zero, then tracing is disabled.
sqlite3_trace_v2(handle, 0 /* mask */, nil /* xCallback */, nil /* pCtx */)
trace = nil
return
}

let box: Trace = { (pointer: UnsafeRawPointer) in
callback(String(cString: pointer.assumingMemoryBound(to: UInt8.self)))
}
sqlite3_trace_v2(handle,
UInt32(SQLITE_TRACE_STMT) /* mask */,
{
// A trace callback is invoked with four arguments: callback(T,C,P,X).
// The T argument is one of the SQLITE_TRACE constants to indicate why the
// callback was invoked. The C argument is a copy of the context pointer.
// The P and X arguments are pointers whose meanings depend on T.
(T: UInt32, C: UnsafeMutableRawPointer?, P: UnsafeMutableRawPointer?, X: UnsafeMutableRawPointer?) in
if let P = P,
let expandedSQL = sqlite3_expanded_sql(OpaquePointer(P)) {
unsafeBitCast(C, to: Trace.self)(expandedSQL)
sqlite3_free(expandedSQL)
}
return Int32(0) // currently ignored
},
unsafeBitCast(box, to: UnsafeMutableRawPointer.self) /* pCtx */
)
trace = box
}
}
#endif
2 changes: 2 additions & 0 deletions SQLite/Core/Statement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

#if SQLITE_SWIFT_STANDALONE
import sqlite3
#elseif SQLITE_SWIFT_SQLCIPHER
import SQLCipher
#elseif COCOAPODS
import CSQLite
#endif
Expand Down
Loading