From b26c42c83a8bb94f1a236004704c0c8f8a025353 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 26 Jan 2025 12:40:17 -0500 Subject: [PATCH 1/8] Rework import order for SQLCipher; add test conditionals for Android --- GRDB/Core/Configuration.swift | 6 +++--- GRDB/Core/Database+Schema.swift | 6 +++--- GRDB/Core/Database+Statements.swift | 6 +++--- GRDB/Core/Database.swift | 6 +++--- GRDB/Core/DatabaseCollation.swift | 6 +++--- GRDB/Core/DatabaseError.swift | 6 +++--- GRDB/Core/DatabaseFunction.swift | 6 +++--- GRDB/Core/DatabaseSnapshotPool.swift | 6 +++--- GRDB/Core/DatabaseValue.swift | 6 +++--- GRDB/Core/Row.swift | 6 +++--- GRDB/Core/RowDecodingError.swift | 6 +++--- GRDB/Core/Statement.swift | 6 +++--- GRDB/Core/StatementAuthorizer.swift | 8 +++++--- GRDB/Core/StatementColumnConvertible.swift | 6 +++--- GRDB/Core/Support/Foundation/Data.swift | 6 +++--- .../Foundation/DatabaseDateComponents.swift | 6 +++--- GRDB/Core/Support/Foundation/Date.swift | 6 +++--- GRDB/Core/Support/Foundation/Decimal.swift | 6 +++--- GRDB/Core/Support/Foundation/NSNumber.swift | 2 +- GRDB/Core/Support/Foundation/URL.swift | 2 +- GRDB/Core/Support/Foundation/UUID.swift | 8 ++++---- .../Support/StandardLibrary/Optional.swift | 6 +++--- .../StandardLibrary/StandardLibrary.swift | 6 +++--- GRDB/Core/TransactionObserver.swift | 6 +++--- GRDB/Core/WALSnapshot.swift | 6 +++--- GRDB/Dump/Database+Dump.swift | 3 +++ GRDB/Dump/DumpFormats/DebugDumpFormat.swift | 6 +++--- GRDB/Dump/DumpFormats/JSONDumpFormat.swift | 6 +++--- GRDB/Dump/DumpFormats/LineDumpFormat.swift | 6 +++--- GRDB/Dump/DumpFormats/ListDumpFormat.swift | 6 +++--- GRDB/Dump/DumpFormats/QuoteDumpFormat.swift | 6 +++--- GRDB/FTS/FTS5.swift | 6 +++--- GRDB/FTS/FTS5CustomTokenizer.swift | 6 +++--- GRDB/FTS/FTS5Tokenizer.swift | 6 +++--- GRDB/FTS/FTS5WrapperTokenizer.swift | 6 +++--- GRDB/Record/FetchableRecord+Decodable.swift | 6 +++--- Package.swift | 20 ++++++++++++++++++- .../AssociationPrefetchingRowTests.swift | 6 +++--- Tests/GRDBTests/CGFloatTests.swift | 2 ++ Tests/GRDBTests/DataMemoryTests.swift | 6 +++--- .../DatabaseConfigurationTests.swift | 6 +++--- Tests/GRDBTests/DatabaseDumpTests.swift | 6 +++--- Tests/GRDBTests/DatabaseMigratorTests.swift | 2 ++ .../DatabasePoolConcurrencyTests.swift | 2 ++ .../DatabasePoolReleaseMemoryTests.swift | 6 +++--- Tests/GRDBTests/DatabasePoolTests.swift | 6 +++--- Tests/GRDBTests/DatabaseQueueTests.swift | 2 ++ .../DatabaseRegionObservationTests.swift | 4 +++- Tests/GRDBTests/DatabaseRegionTests.swift | 6 +++--- Tests/GRDBTests/DatabaseSnapshotTests.swift | 2 ++ Tests/GRDBTests/DatabaseWriterTests.swift | 6 +++--- Tests/GRDBTests/FTS5TableBuilderTests.swift | 3 +++ Tests/GRDBTests/FTS5TokenizerTests.swift | 6 +++--- Tests/GRDBTests/FailureTestCase.swift | 2 ++ .../FoundationNSDecimalNumberTests.swift | 2 ++ Tests/GRDBTests/FoundationNSNumberTests.swift | 2 ++ Tests/GRDBTests/FoundationNSURLTests.swift | 2 ++ Tests/GRDBTests/FoundationNSUUIDTests.swift | 2 ++ Tests/GRDBTests/FoundationUUIDTests.swift | 2 ++ Tests/GRDBTests/GRDBTestCase.swift | 6 +++--- Tests/GRDBTests/JSONColumnTests.swift | 3 +++ Tests/GRDBTests/JSONExpressionsTests.swift | 3 +++ .../MutablePersistableRecordTests.swift | 3 +++ Tests/GRDBTests/PersistableRecordTests.swift | 3 +++ .../QueryInterfaceExpressionsTests.swift | 3 +++ Tests/GRDBTests/SingletonRecordTest.swift | 3 +++ ...StatementColumnConvertibleFetchTests.swift | 6 +++--- Tests/GRDBTests/TableDefinitionTests.swift | 6 +++--- Tests/GRDBTests/TableRecordDeleteTests.swift | 3 +++ Tests/GRDBTests/TableRecordUpdateTests.swift | 3 +++ Tests/GRDBTests/UpdateStatementTests.swift | 6 +++--- .../ValueObservationRecorderTests.swift | 2 ++ Tests/GRDBTests/ValueObservationTests.swift | 5 +++++ 73 files changed, 224 insertions(+), 143 deletions(-) diff --git a/GRDB/Core/Configuration.swift b/GRDB/Core/Configuration.swift index 9e4e165010..2f8216f09e 100644 --- a/GRDB/Core/Configuration.swift +++ b/GRDB/Core/Configuration.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Database+Schema.swift b/GRDB/Core/Database+Schema.swift index ff8f9bf1d8..8a83be2fd7 100644 --- a/GRDB/Core/Database+Schema.swift +++ b/GRDB/Core/Database+Schema.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Database+Statements.swift b/GRDB/Core/Database+Statements.swift index 46038a83b5..4862cc9551 100644 --- a/GRDB/Core/Database+Statements.swift +++ b/GRDB/Core/Database+Statements.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Database.swift b/GRDB/Core/Database.swift index 61354847b1..4384d5c719 100644 --- a/GRDB/Core/Database.swift +++ b/GRDB/Core/Database.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/DatabaseCollation.swift b/GRDB/Core/DatabaseCollation.swift index 6748874c8b..47abb79c82 100644 --- a/GRDB/Core/DatabaseCollation.swift +++ b/GRDB/Core/DatabaseCollation.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/DatabaseError.swift b/GRDB/Core/DatabaseError.swift index bf808dbaa5..8609ee6a4f 100644 --- a/GRDB/Core/DatabaseError.swift +++ b/GRDB/Core/DatabaseError.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/DatabaseFunction.swift b/GRDB/Core/DatabaseFunction.swift index 9e2c03ed2f..f32e7cbb4a 100644 --- a/GRDB/Core/DatabaseFunction.swift +++ b/GRDB/Core/DatabaseFunction.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/DatabaseSnapshotPool.swift b/GRDB/Core/DatabaseSnapshotPool.swift index 20398c5562..b5cc8c668d 100644 --- a/GRDB/Core/DatabaseSnapshotPool.swift +++ b/GRDB/Core/DatabaseSnapshotPool.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER) // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/DatabaseValue.swift b/GRDB/Core/DatabaseValue.swift index 1c8e721f98..df7009e699 100644 --- a/GRDB/Core/DatabaseValue.swift +++ b/GRDB/Core/DatabaseValue.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Row.swift b/GRDB/Core/Row.swift index 8d39236bdc..aefda132fb 100644 --- a/GRDB/Core/Row.swift +++ b/GRDB/Core/Row.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/RowDecodingError.swift b/GRDB/Core/RowDecodingError.swift index ed82c1f891..7c9d5e37ba 100644 --- a/GRDB/Core/RowDecodingError.swift +++ b/GRDB/Core/RowDecodingError.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Statement.swift b/GRDB/Core/Statement.swift index f2792af315..86e3008eb0 100644 --- a/GRDB/Core/Statement.swift +++ b/GRDB/Core/Statement.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/StatementAuthorizer.swift b/GRDB/Core/StatementAuthorizer.swift index 169b5dc5f9..518d4f6bf5 100644 --- a/GRDB/Core/StatementAuthorizer.swift +++ b/GRDB/Core/StatementAuthorizer.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif @@ -11,6 +11,8 @@ import SQLite3 import string_h #elseif os(Linux) import Glibc +#elseif canImport(Android) +import Android #elseif os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || os(visionOS) import Darwin #elseif os(Windows) diff --git a/GRDB/Core/StatementColumnConvertible.swift b/GRDB/Core/StatementColumnConvertible.swift index d16c038429..46ab569702 100644 --- a/GRDB/Core/StatementColumnConvertible.swift +++ b/GRDB/Core/StatementColumnConvertible.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Support/Foundation/Data.swift b/GRDB/Core/Support/Foundation/Data.swift index 55d6bdb20f..cf11f5d8ce 100644 --- a/GRDB/Core/Support/Foundation/Data.swift +++ b/GRDB/Core/Support/Foundation/Data.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Support/Foundation/DatabaseDateComponents.swift b/GRDB/Core/Support/Foundation/DatabaseDateComponents.swift index fb861feb8a..56f675bd47 100644 --- a/GRDB/Core/Support/Foundation/DatabaseDateComponents.swift +++ b/GRDB/Core/Support/Foundation/DatabaseDateComponents.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Support/Foundation/Date.swift b/GRDB/Core/Support/Foundation/Date.swift index 6676c065ae..247dd2e1ee 100644 --- a/GRDB/Core/Support/Foundation/Date.swift +++ b/GRDB/Core/Support/Foundation/Date.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Support/Foundation/Decimal.swift b/GRDB/Core/Support/Foundation/Decimal.swift index e200c6c596..e9a60d7e39 100644 --- a/GRDB/Core/Support/Foundation/Decimal.swift +++ b/GRDB/Core/Support/Foundation/Decimal.swift @@ -1,9 +1,9 @@ #if !os(Linux) // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Support/Foundation/NSNumber.swift b/GRDB/Core/Support/Foundation/NSNumber.swift index 1c5778c19e..5c2846a169 100644 --- a/GRDB/Core/Support/Foundation/NSNumber.swift +++ b/GRDB/Core/Support/Foundation/NSNumber.swift @@ -1,4 +1,4 @@ -#if !os(Linux) && !os(Windows) +#if !os(Linux) && !os(Windows) && !os(Android) import Foundation private let integerRoundingBehavior = NSDecimalNumberHandler( diff --git a/GRDB/Core/Support/Foundation/URL.swift b/GRDB/Core/Support/Foundation/URL.swift index 6db66ec3b8..145f2046ea 100644 --- a/GRDB/Core/Support/Foundation/URL.swift +++ b/GRDB/Core/Support/Foundation/URL.swift @@ -1,6 +1,6 @@ import Foundation -#if !os(Linux) && !os(Windows) +#if !os(Linux) && !os(Windows) && !os(Android) /// NSURL stores its absoluteString in the database. extension NSURL: DatabaseValueConvertible { diff --git a/GRDB/Core/Support/Foundation/UUID.swift b/GRDB/Core/Support/Foundation/UUID.swift index 7595b53ef6..7bf62de67a 100644 --- a/GRDB/Core/Support/Foundation/UUID.swift +++ b/GRDB/Core/Support/Foundation/UUID.swift @@ -1,15 +1,15 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif import Foundation -#if !os(Linux) && !os(Windows) +#if !os(Linux) && !os(Windows) && !os(Android) /// NSUUID adopts DatabaseValueConvertible extension NSUUID: DatabaseValueConvertible { /// Returns a BLOB database value containing the uuid bytes. diff --git a/GRDB/Core/Support/StandardLibrary/Optional.swift b/GRDB/Core/Support/StandardLibrary/Optional.swift index 0902097d9a..6628ba4f2e 100644 --- a/GRDB/Core/Support/StandardLibrary/Optional.swift +++ b/GRDB/Core/Support/StandardLibrary/Optional.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/Support/StandardLibrary/StandardLibrary.swift b/GRDB/Core/Support/StandardLibrary/StandardLibrary.swift index 8a4c5a7d83..6ee5ede586 100644 --- a/GRDB/Core/Support/StandardLibrary/StandardLibrary.swift +++ b/GRDB/Core/Support/StandardLibrary/StandardLibrary.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/TransactionObserver.swift b/GRDB/Core/TransactionObserver.swift index 5c7593916c..3bfd7e3e20 100644 --- a/GRDB/Core/TransactionObserver.swift +++ b/GRDB/Core/TransactionObserver.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Core/WALSnapshot.swift b/GRDB/Core/WALSnapshot.swift index a8c0168a73..1a5206e214 100644 --- a/GRDB/Core/WALSnapshot.swift +++ b/GRDB/Core/WALSnapshot.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER) // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Dump/Database+Dump.swift b/GRDB/Dump/Database+Dump.swift index bb5aed2641..2d89c78e36 100644 --- a/GRDB/Dump/Database+Dump.swift +++ b/GRDB/Dump/Database+Dump.swift @@ -1,4 +1,7 @@ import Foundation +#if GRDBCIPHER +import SQLCipher +#endif // MARK: - Dump diff --git a/GRDB/Dump/DumpFormats/DebugDumpFormat.swift b/GRDB/Dump/DumpFormats/DebugDumpFormat.swift index b3ae312485..631ac7b282 100644 --- a/GRDB/Dump/DumpFormats/DebugDumpFormat.swift +++ b/GRDB/Dump/DumpFormats/DebugDumpFormat.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Dump/DumpFormats/JSONDumpFormat.swift b/GRDB/Dump/DumpFormats/JSONDumpFormat.swift index d5bc8cb10b..5f15c310a3 100644 --- a/GRDB/Dump/DumpFormats/JSONDumpFormat.swift +++ b/GRDB/Dump/DumpFormats/JSONDumpFormat.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Dump/DumpFormats/LineDumpFormat.swift b/GRDB/Dump/DumpFormats/LineDumpFormat.swift index a71b05ca69..355677471d 100644 --- a/GRDB/Dump/DumpFormats/LineDumpFormat.swift +++ b/GRDB/Dump/DumpFormats/LineDumpFormat.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Dump/DumpFormats/ListDumpFormat.swift b/GRDB/Dump/DumpFormats/ListDumpFormat.swift index dc7bfdb6c3..a2c62412b3 100644 --- a/GRDB/Dump/DumpFormats/ListDumpFormat.swift +++ b/GRDB/Dump/DumpFormats/ListDumpFormat.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Dump/DumpFormats/QuoteDumpFormat.swift b/GRDB/Dump/DumpFormats/QuoteDumpFormat.swift index 3818c7c17e..8f350780bb 100644 --- a/GRDB/Dump/DumpFormats/QuoteDumpFormat.swift +++ b/GRDB/Dump/DumpFormats/QuoteDumpFormat.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/FTS/FTS5.swift b/GRDB/FTS/FTS5.swift index a87b184b1d..68233598b8 100644 --- a/GRDB/FTS/FTS5.swift +++ b/GRDB/FTS/FTS5.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_FTS5 // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/FTS/FTS5CustomTokenizer.swift b/GRDB/FTS/FTS5CustomTokenizer.swift index 370f1256c5..c0efe9aae2 100644 --- a/GRDB/FTS/FTS5CustomTokenizer.swift +++ b/GRDB/FTS/FTS5CustomTokenizer.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_FTS5 // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/FTS/FTS5Tokenizer.swift b/GRDB/FTS/FTS5Tokenizer.swift index e4aecc36f5..a2a58b7713 100644 --- a/GRDB/FTS/FTS5Tokenizer.swift +++ b/GRDB/FTS/FTS5Tokenizer.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_FTS5 // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/FTS/FTS5WrapperTokenizer.swift b/GRDB/FTS/FTS5WrapperTokenizer.swift index 5851866be7..9d892d23e3 100644 --- a/GRDB/FTS/FTS5WrapperTokenizer.swift +++ b/GRDB/FTS/FTS5WrapperTokenizer.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_FTS5 // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/GRDB/Record/FetchableRecord+Decodable.swift b/GRDB/Record/FetchableRecord+Decodable.swift index a4c6e423b2..23b7591997 100644 --- a/GRDB/Record/FetchableRecord+Decodable.swift +++ b/GRDB/Record/FetchableRecord+Decodable.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Package.swift b/Package.swift index 36937d039a..d3537a510f 100644 --- a/Package.swift +++ b/Package.swift @@ -27,6 +27,24 @@ if ProcessInfo.processInfo.environment["SPI_BUILDER"] == "1" { dependencies.append(.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")) } +var targetDependencies: [Target.Dependency] = ["GRDBSQLite"] + + +var GRDBCIPHER = ProcessInfo.processInfo.environment["GRDBCIPHER"] +// e.g.: +//GRDBCIPHER="https://github.com/skiptools/swift-sqlcipher.git#1.2.1" +if let SQLCipherRepo = GRDBCIPHER?.split(separator: "#").first, + let SQLCipherVersion = GRDBCIPHER?.split(separator: "#").last, + let SQLCipherRepoURL = URL(string: SQLCipherRepo.description) { + swiftSettings.append(.define("GRDBCIPHER")) + targetDependencies = [.product(name: "SQLCipher", package: SQLCipherRepoURL.deletingPathExtension().lastPathComponent)] + if let version = Version(SQLCipherVersion.description) { // numeric version + dependencies.append(.package(url: SQLCipherRepoURL.absoluteString, from: version)) + } else { // branch + dependencies.append(.package(url: SQLCipherRepoURL.absoluteString, branch: SQLCipherVersion.description)) + } +} + let package = Package( name: "GRDB", defaultLocalization: "en", // for tests @@ -48,7 +66,7 @@ let package = Package( providers: [.apt(["libsqlite3-dev"])]), .target( name: "GRDB", - dependencies: ["GRDBSQLite"], + dependencies: targetDependencies, path: "GRDB", resources: [.copy("PrivacyInfo.xcprivacy")], cSettings: cSettings, diff --git a/Tests/GRDBTests/AssociationPrefetchingRowTests.swift b/Tests/GRDBTests/AssociationPrefetchingRowTests.swift index ead7d89b92..69aeb09ed4 100644 --- a/Tests/GRDBTests/AssociationPrefetchingRowTests.swift +++ b/Tests/GRDBTests/AssociationPrefetchingRowTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/CGFloatTests.swift b/Tests/GRDBTests/CGFloatTests.swift index 1bcfaaa582..c21267e74e 100644 --- a/Tests/GRDBTests/CGFloatTests.swift +++ b/Tests/GRDBTests/CGFloatTests.swift @@ -1,3 +1,4 @@ +#if canImport(CoreGraphics) import XCTest import CoreGraphics import GRDB @@ -21,3 +22,4 @@ class CGFloatTests: GRDBTestCase { } } } +#endif diff --git a/Tests/GRDBTests/DataMemoryTests.swift b/Tests/GRDBTests/DataMemoryTests.swift index 3f572fc304..5b4e9aaf76 100644 --- a/Tests/GRDBTests/DataMemoryTests.swift +++ b/Tests/GRDBTests/DataMemoryTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/DatabaseConfigurationTests.swift b/Tests/GRDBTests/DatabaseConfigurationTests.swift index 7c64c91e5f..0955efb395 100644 --- a/Tests/GRDBTests/DatabaseConfigurationTests.swift +++ b/Tests/GRDBTests/DatabaseConfigurationTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/DatabaseDumpTests.swift b/Tests/GRDBTests/DatabaseDumpTests.swift index 29d59caa72..b27be4bd5d 100644 --- a/Tests/GRDBTests/DatabaseDumpTests.swift +++ b/Tests/GRDBTests/DatabaseDumpTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/DatabaseMigratorTests.swift b/Tests/GRDBTests/DatabaseMigratorTests.swift index b82d221d03..1d49d013e8 100644 --- a/Tests/GRDBTests/DatabaseMigratorTests.swift +++ b/Tests/GRDBTests/DatabaseMigratorTests.swift @@ -1,6 +1,7 @@ import XCTest import GRDB +#if !os(Android) class DatabaseMigratorTests : GRDBTestCase { // Test passes if it compiles. // See @@ -1110,3 +1111,4 @@ class DatabaseMigratorTests : GRDBTestCase { } catch DatabaseError.SQLITE_CONSTRAINT_FOREIGNKEY { } } } +#endif diff --git a/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift b/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift index 7d2478545b..eefd3d0023 100644 --- a/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift +++ b/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift @@ -3,6 +3,7 @@ import Dispatch import Foundation @testable import GRDB +#if canImport(Darwin) // needs NSFileCoordinator class DatabasePoolConcurrencyTests: GRDBTestCase { func testDatabasePoolFundamental1() throws { @@ -1348,3 +1349,4 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { } } } +#endif diff --git a/Tests/GRDBTests/DatabasePoolReleaseMemoryTests.swift b/Tests/GRDBTests/DatabasePoolReleaseMemoryTests.swift index afa8bd32a5..5ee6dc28dd 100644 --- a/Tests/GRDBTests/DatabasePoolReleaseMemoryTests.swift +++ b/Tests/GRDBTests/DatabasePoolReleaseMemoryTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/DatabasePoolTests.swift b/Tests/GRDBTests/DatabasePoolTests.swift index e1ab57bbd5..1da50d7277 100644 --- a/Tests/GRDBTests/DatabasePoolTests.swift +++ b/Tests/GRDBTests/DatabasePoolTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/DatabaseQueueTests.swift b/Tests/GRDBTests/DatabaseQueueTests.swift index c22be83261..01e8b5455c 100644 --- a/Tests/GRDBTests/DatabaseQueueTests.swift +++ b/Tests/GRDBTests/DatabaseQueueTests.swift @@ -2,6 +2,7 @@ import XCTest import Dispatch import GRDB +#if canImport(Darwin) // needed for __dispatch_get_global_queue class DatabaseQueueTests: GRDBTestCase { func testJournalModeConfiguration() throws { do { @@ -473,3 +474,4 @@ class DatabaseQueueTests: GRDBTestCase { dbQueue.releaseMemory() } } +#endif diff --git a/Tests/GRDBTests/DatabaseRegionObservationTests.swift b/Tests/GRDBTests/DatabaseRegionObservationTests.swift index 3ffdfc39eb..7574c6a0b3 100644 --- a/Tests/GRDBTests/DatabaseRegionObservationTests.swift +++ b/Tests/GRDBTests/DatabaseRegionObservationTests.swift @@ -2,6 +2,7 @@ import XCTest import GRDB class DatabaseRegionObservationTests: GRDBTestCase { + #if canImport(Combine) // Test passes if it compiles. // See func testAnyDatabaseWriter(writer: any DatabaseWriter) throws { @@ -10,7 +11,8 @@ class DatabaseRegionObservationTests: GRDBTestCase { _ = observation.start(in: writer, onError: { _ in }, onChange: { _ in }) _ = observation.publisher(in: writer) } - + #endif + func testDatabaseRegionObservation_FullDatabase() throws { let dbQueue = try makeDatabaseQueue() try dbQueue.write { diff --git a/Tests/GRDBTests/DatabaseRegionTests.swift b/Tests/GRDBTests/DatabaseRegionTests.swift index 848187ed0f..b0608ad533 100644 --- a/Tests/GRDBTests/DatabaseRegionTests.swift +++ b/Tests/GRDBTests/DatabaseRegionTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/DatabaseSnapshotTests.swift b/Tests/GRDBTests/DatabaseSnapshotTests.swift index 1cb422ecdd..f27e0dceeb 100644 --- a/Tests/GRDBTests/DatabaseSnapshotTests.swift +++ b/Tests/GRDBTests/DatabaseSnapshotTests.swift @@ -1,6 +1,7 @@ import XCTest @testable import GRDB +#if !os(Android) class DatabaseSnapshotTests: GRDBTestCase { /// A helper type private struct Counter { @@ -432,3 +433,4 @@ class DatabaseSnapshotTests: GRDBTestCase { } } } +#endif diff --git a/Tests/GRDBTests/DatabaseWriterTests.swift b/Tests/GRDBTests/DatabaseWriterTests.swift index 221f01063e..29bc2a61fb 100644 --- a/Tests/GRDBTests/DatabaseWriterTests.swift +++ b/Tests/GRDBTests/DatabaseWriterTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/FTS5TableBuilderTests.swift b/Tests/GRDBTests/FTS5TableBuilderTests.swift index fe63cfc427..c14f7148ee 100644 --- a/Tests/GRDBTests/FTS5TableBuilderTests.swift +++ b/Tests/GRDBTests/FTS5TableBuilderTests.swift @@ -1,6 +1,9 @@ #if SQLITE_ENABLE_FTS5 import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif class FTS5TableBuilderTests: GRDBTestCase { func testWithoutBody() throws { diff --git a/Tests/GRDBTests/FTS5TokenizerTests.swift b/Tests/GRDBTests/FTS5TokenizerTests.swift index d7efff5c07..c9ecd780af 100644 --- a/Tests/GRDBTests/FTS5TokenizerTests.swift +++ b/Tests/GRDBTests/FTS5TokenizerTests.swift @@ -1,9 +1,9 @@ #if SQLITE_ENABLE_FTS5 // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/FailureTestCase.swift b/Tests/GRDBTests/FailureTestCase.swift index 9dfb9770ba..9c47bb6d16 100644 --- a/Tests/GRDBTests/FailureTestCase.swift +++ b/Tests/GRDBTests/FailureTestCase.swift @@ -1,6 +1,7 @@ // Inspired by https://github.com/groue/CombineExpectations import XCTest +#if canImport(Darwin) // needed for XCTIssue /// A XCTestCase subclass that can test its own failures. class FailureTestCase: XCTestCase { private struct Failure: Hashable { @@ -207,3 +208,4 @@ class FailureTestCaseTests: FailureTestCase { } } } +#endif diff --git a/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift b/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift index 0013a7056b..10dcc4983b 100644 --- a/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift +++ b/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift @@ -1,6 +1,7 @@ import XCTest import GRDB +#if canImport(Darwin) // needed for NSDecimalNumber class FoundationNSDecimalNumberTests: GRDBTestCase { func testNSDecimalNumberPreservesIntegerValues() { @@ -157,3 +158,4 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { try test("18446744073709551615", isDecodedAs: NSDecimalNumber(string: "18446744073709551615")) } } +#endif diff --git a/Tests/GRDBTests/FoundationNSNumberTests.swift b/Tests/GRDBTests/FoundationNSNumberTests.swift index ff5d3df350..f8eb620dca 100644 --- a/Tests/GRDBTests/FoundationNSNumberTests.swift +++ b/Tests/GRDBTests/FoundationNSNumberTests.swift @@ -1,6 +1,7 @@ import XCTest import GRDB +#if canImport(Darwin) // needed for NSDecimalNumber class FoundationNSNumberTests: GRDBTestCase { func testNSNumberDatabaseValueToSwiftType() { @@ -192,3 +193,4 @@ class FoundationNSNumberTests: GRDBTestCase { try test("18446744073709551615", isDecodedAs: NSDecimalNumber(value: UInt64(18446744073709551615))) } } +#endif diff --git a/Tests/GRDBTests/FoundationNSURLTests.swift b/Tests/GRDBTests/FoundationNSURLTests.swift index 180698a42c..7272c9e89f 100644 --- a/Tests/GRDBTests/FoundationNSURLTests.swift +++ b/Tests/GRDBTests/FoundationNSURLTests.swift @@ -1,6 +1,7 @@ import XCTest import GRDB +#if canImport(Darwin) // needed for NSURL class FoundationNSURLTests: GRDBTestCase { func testNSURLDatabaseRoundTrip() throws { @@ -46,3 +47,4 @@ class FoundationNSURLTests: GRDBTestCase { } } +#endif diff --git a/Tests/GRDBTests/FoundationNSUUIDTests.swift b/Tests/GRDBTests/FoundationNSUUIDTests.swift index cc7243ce86..c955743bc8 100644 --- a/Tests/GRDBTests/FoundationNSUUIDTests.swift +++ b/Tests/GRDBTests/FoundationNSUUIDTests.swift @@ -1,6 +1,7 @@ import XCTest import GRDB +#if canImport(Darwin) // needed for NSUUID class FoundationNSUUIDTests: GRDBTestCase { private func assert(_ value: (any DatabaseValueConvertible)?, isDecodedAs expectedUUID: NSUUID?) throws { try makeDatabaseQueue().read { db in @@ -50,3 +51,4 @@ class FoundationNSUUIDTests: GRDBTestCase { try assert("abcdefghijklmnopq".data(using: .utf8)!, isDecodedAs: nil) } } +#endif diff --git a/Tests/GRDBTests/FoundationUUIDTests.swift b/Tests/GRDBTests/FoundationUUIDTests.swift index 9adfc228a4..29ba77e955 100644 --- a/Tests/GRDBTests/FoundationUUIDTests.swift +++ b/Tests/GRDBTests/FoundationUUIDTests.swift @@ -28,7 +28,9 @@ class FoundationUUIDTests: GRDBTestCase { try assert(string.lowercased(), isDecodedAs: uuid) try assert(string.uppercased(), isDecodedAs: uuid) try assert(uuid, isDecodedAs: uuid) + #if canImport(Darwin) // needed for NSUUID try assert(uuid as NSUUID, isDecodedAs: uuid) + #endif try assert(data, isDecodedAs: uuid) } diff --git a/Tests/GRDBTests/GRDBTestCase.swift b/Tests/GRDBTests/GRDBTestCase.swift index ffb1f1a0b8..e19f4fc3c0 100644 --- a/Tests/GRDBTests/GRDBTestCase.swift +++ b/Tests/GRDBTests/GRDBTestCase.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/JSONColumnTests.swift b/Tests/GRDBTests/JSONColumnTests.swift index e544fd148f..3677a2e358 100644 --- a/Tests/GRDBTests/JSONColumnTests.swift +++ b/Tests/GRDBTests/JSONColumnTests.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif final class JSONColumnTests: GRDBTestCase { func test_JSONColumn_derived_from_CodingKey() throws { diff --git a/Tests/GRDBTests/JSONExpressionsTests.swift b/Tests/GRDBTests/JSONExpressionsTests.swift index 465fc06923..94bb24bb68 100644 --- a/Tests/GRDBTests/JSONExpressionsTests.swift +++ b/Tests/GRDBTests/JSONExpressionsTests.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif final class JSONExpressionsTests: GRDBTestCase { func test_Database_json() throws { diff --git a/Tests/GRDBTests/MutablePersistableRecordTests.swift b/Tests/GRDBTests/MutablePersistableRecordTests.swift index d18bfc8b4a..15ba52539c 100644 --- a/Tests/GRDBTests/MutablePersistableRecordTests.swift +++ b/Tests/GRDBTests/MutablePersistableRecordTests.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif private struct MutablePersistableRecordPerson : MutablePersistableRecord { var id: Int64? diff --git a/Tests/GRDBTests/PersistableRecordTests.swift b/Tests/GRDBTests/PersistableRecordTests.swift index a6577efb14..1533a24d39 100644 --- a/Tests/GRDBTests/PersistableRecordTests.swift +++ b/Tests/GRDBTests/PersistableRecordTests.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif private struct PersistableRecordPerson : PersistableRecord { var name: String? diff --git a/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift b/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift index f2a6d4b59f..c0e30c8911 100644 --- a/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift +++ b/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift @@ -1,5 +1,8 @@ import XCTest @testable import GRDB +#if GRDBCIPHER +import SQLCipher +#endif private struct Col { static let id = Column("id") diff --git a/Tests/GRDBTests/SingletonRecordTest.swift b/Tests/GRDBTests/SingletonRecordTest.swift index a3fb0766ee..b5f05d6677 100644 --- a/Tests/GRDBTests/SingletonRecordTest.swift +++ b/Tests/GRDBTests/SingletonRecordTest.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif private struct AppConfiguration: Codable { // Support for the single row guarantee diff --git a/Tests/GRDBTests/StatementColumnConvertibleFetchTests.swift b/Tests/GRDBTests/StatementColumnConvertibleFetchTests.swift index cee0f6e954..21b19a5c92 100644 --- a/Tests/GRDBTests/StatementColumnConvertibleFetchTests.swift +++ b/Tests/GRDBTests/StatementColumnConvertibleFetchTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/TableDefinitionTests.swift b/Tests/GRDBTests/TableDefinitionTests.swift index 12b666ca1a..cc247f59ec 100644 --- a/Tests/GRDBTests/TableDefinitionTests.swift +++ b/Tests/GRDBTests/TableDefinitionTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/TableRecordDeleteTests.swift b/Tests/GRDBTests/TableRecordDeleteTests.swift index 264daac7aa..1764c9faaf 100644 --- a/Tests/GRDBTests/TableRecordDeleteTests.swift +++ b/Tests/GRDBTests/TableRecordDeleteTests.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif private struct Hacker : TableRecord { static let databaseTableName = "hackers" diff --git a/Tests/GRDBTests/TableRecordUpdateTests.swift b/Tests/GRDBTests/TableRecordUpdateTests.swift index ce2d9d2ed9..71e631afae 100644 --- a/Tests/GRDBTests/TableRecordUpdateTests.swift +++ b/Tests/GRDBTests/TableRecordUpdateTests.swift @@ -1,5 +1,8 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#endif private struct Player: Codable, PersistableRecord, FetchableRecord, Hashable { var id: Int64 diff --git a/Tests/GRDBTests/UpdateStatementTests.swift b/Tests/GRDBTests/UpdateStatementTests.swift index 6a3233fdc8..ba7f6bc2da 100644 --- a/Tests/GRDBTests/UpdateStatementTests.swift +++ b/Tests/GRDBTests/UpdateStatementTests.swift @@ -1,8 +1,8 @@ // Import C SQLite functions -#if SWIFT_PACKAGE -import GRDBSQLite -#elseif GRDBCIPHER +#if GRDBCIPHER import SQLCipher +#elseif SWIFT_PACKAGE +import GRDBSQLite #elseif !GRDBCUSTOMSQLITE && !GRDBCIPHER import SQLite3 #endif diff --git a/Tests/GRDBTests/ValueObservationRecorderTests.swift b/Tests/GRDBTests/ValueObservationRecorderTests.swift index 4b8e8a2ae0..d59550d02d 100644 --- a/Tests/GRDBTests/ValueObservationRecorderTests.swift +++ b/Tests/GRDBTests/ValueObservationRecorderTests.swift @@ -1,6 +1,7 @@ import Dispatch import XCTest +#if canImport(Darwin) // needed for FailureTestCase class ValueObservationRecorderTests: FailureTestCase { // MARK: - NextOne @@ -781,3 +782,4 @@ class ValueObservationRecorderTests: FailureTestCase { } } } +#endif diff --git a/Tests/GRDBTests/ValueObservationTests.swift b/Tests/GRDBTests/ValueObservationTests.swift index ba59108d1e..610554dfee 100644 --- a/Tests/GRDBTests/ValueObservationTests.swift +++ b/Tests/GRDBTests/ValueObservationTests.swift @@ -1,7 +1,11 @@ import XCTest import Dispatch @testable import GRDB +#if GRDBCIPHER +import SQLCipher +#endif +#if canImport(Darwin) class ValueObservationTests: GRDBTestCase { // Test passes if it compiles. // See @@ -1353,3 +1357,4 @@ class ValueObservationTests: GRDBTestCase { }) } } +#endif From c4b027922bc9d4aa81347f9871fb20fedc32c292 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 26 Jan 2025 12:58:30 -0500 Subject: [PATCH 2/8] Add SPMSQLCipher workflow action --- .github/workflows/CI.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ef5e3da7e6..8c080ccc4d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -73,6 +73,23 @@ jobs: - uses: actions/checkout@v4 - name: ${{ matrix.name }} run: make test_SPM test_install_SPM + SPMSQLCipher: + name: SPM + runs-on: ${{ matrix.runsOn }} + env: + DEVELOPER_DIR: "/Applications/${{ matrix.xcode }}/Contents/Developer" + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - xcode: "Xcode_16.1.app" + runsOn: macOS-14 + name: "Xcode 16.1" + steps: + - uses: actions/checkout@v4 + - name: ${{ matrix.name }} + run: GRDBCIPHER="https://github.com/skiptools/swift-sqlcipher.git#1.2.1" swift test SQLCipher3: name: SQLCipher3 runs-on: ${{ matrix.runsOn }} @@ -141,4 +158,4 @@ jobs: - uses: actions/checkout@v4 - name: ${{ matrix.name }} run: make test_universal_xcframework - \ No newline at end of file + From 81b647ffd48325c8a5ae7fbd13841069faa84cfb Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Mon, 27 Jan 2025 08:21:58 -0500 Subject: [PATCH 3/8] Add optional performance testing to Package.swift --- Package.swift | 20 +++++++++++++++++++ .../FetchPositionalValuesTests.swift | 4 ++++ .../FetchRecordStructTests.swift | 4 ++++ .../InsertPositionalValuesTests.swift | 4 ++++ 4 files changed, 32 insertions(+) diff --git a/Package.swift b/Package.swift index d3537a510f..8609d84d2a 100644 --- a/Package.swift +++ b/Package.swift @@ -103,3 +103,23 @@ let package = Package( ], swiftLanguageModes: [.v6] ) + +// The GRDB_PERFORMANCE_TESTS environment variable enables +// the performance tests to be included in the package, which can be run with: +// GRDB_PERFORMANCE_TESTS=1 swift test --filter GRDBPerformanceTests +if ProcessInfo.processInfo.environment["GRDB_PERFORMANCE_TESTS"] == "1" { + package.targets.append( + Target.testTarget( + name: "GRDBPerformanceTests", + dependencies: ["GRDB"], + path: "Tests/Performance/GRDBPerformance", + cSettings: cSettings, + swiftSettings: swiftSettings + [ + // Tests still use the Swift 5 language mode. + .swiftLanguageMode(.v5), + .enableUpcomingFeature("InferSendableFromCaptures"), + .enableUpcomingFeature("GlobalActorIsolatedTypesUsability"), + ]) + ) +} + diff --git a/Tests/Performance/GRDBPerformance/FetchPositionalValuesTests.swift b/Tests/Performance/GRDBPerformance/FetchPositionalValuesTests.swift index 72b41d0e04..47b6557ccd 100644 --- a/Tests/Performance/GRDBPerformance/FetchPositionalValuesTests.swift +++ b/Tests/Performance/GRDBPerformance/FetchPositionalValuesTests.swift @@ -1,6 +1,10 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#else import SQLite3 +#endif #if GRDB_COMPARE import SQLite #endif diff --git a/Tests/Performance/GRDBPerformance/FetchRecordStructTests.swift b/Tests/Performance/GRDBPerformance/FetchRecordStructTests.swift index 13387d5e1d..446a18e6b5 100644 --- a/Tests/Performance/GRDBPerformance/FetchRecordStructTests.swift +++ b/Tests/Performance/GRDBPerformance/FetchRecordStructTests.swift @@ -1,6 +1,10 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#else import SQLite3 +#endif #if GRDB_COMPARE import SQLite #endif diff --git a/Tests/Performance/GRDBPerformance/InsertPositionalValuesTests.swift b/Tests/Performance/GRDBPerformance/InsertPositionalValuesTests.swift index ec6edb99b1..9ba3449121 100644 --- a/Tests/Performance/GRDBPerformance/InsertPositionalValuesTests.swift +++ b/Tests/Performance/GRDBPerformance/InsertPositionalValuesTests.swift @@ -1,6 +1,10 @@ import XCTest import GRDB +#if GRDBCIPHER +import SQLCipher +#else import SQLite3 +#endif #if GRDB_COMPARE import SQLite #endif From 65db92f512c1b077b8958f226158ed1a3ae3a4b3 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 6 Feb 2025 12:39:56 -0500 Subject: [PATCH 4/8] Remove import of SQLCipher due to availability of Database.sqliteLibVersionNumber --- GRDB/Dump/Database+Dump.swift | 3 --- Tests/GRDBTests/FTS5TableBuilderTests.swift | 3 --- Tests/GRDBTests/JSONColumnTests.swift | 3 --- Tests/GRDBTests/JSONExpressionsTests.swift | 3 --- Tests/GRDBTests/MutablePersistableRecordTests.swift | 3 --- Tests/GRDBTests/PersistableRecordTests.swift | 3 --- 6 files changed, 18 deletions(-) diff --git a/GRDB/Dump/Database+Dump.swift b/GRDB/Dump/Database+Dump.swift index 0a458dfcae..8876b8cb72 100644 --- a/GRDB/Dump/Database+Dump.swift +++ b/GRDB/Dump/Database+Dump.swift @@ -1,7 +1,4 @@ import Foundation -#if GRDBCIPHER -import SQLCipher -#endif // MARK: - Dump diff --git a/Tests/GRDBTests/FTS5TableBuilderTests.swift b/Tests/GRDBTests/FTS5TableBuilderTests.swift index 95f1305953..b273c538c2 100644 --- a/Tests/GRDBTests/FTS5TableBuilderTests.swift +++ b/Tests/GRDBTests/FTS5TableBuilderTests.swift @@ -1,9 +1,6 @@ #if SQLITE_ENABLE_FTS5 import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif class FTS5TableBuilderTests: GRDBTestCase { func testWithoutBody() throws { diff --git a/Tests/GRDBTests/JSONColumnTests.swift b/Tests/GRDBTests/JSONColumnTests.swift index a287246c75..763eed4aed 100644 --- a/Tests/GRDBTests/JSONColumnTests.swift +++ b/Tests/GRDBTests/JSONColumnTests.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif final class JSONColumnTests: GRDBTestCase { func test_JSONColumn_derived_from_CodingKey() throws { diff --git a/Tests/GRDBTests/JSONExpressionsTests.swift b/Tests/GRDBTests/JSONExpressionsTests.swift index d8f824bd6a..0e9ed40e9b 100644 --- a/Tests/GRDBTests/JSONExpressionsTests.swift +++ b/Tests/GRDBTests/JSONExpressionsTests.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif final class JSONExpressionsTests: GRDBTestCase { /// The SQL function used to build JSON expressions diff --git a/Tests/GRDBTests/MutablePersistableRecordTests.swift b/Tests/GRDBTests/MutablePersistableRecordTests.swift index 1030178737..6084338044 100644 --- a/Tests/GRDBTests/MutablePersistableRecordTests.swift +++ b/Tests/GRDBTests/MutablePersistableRecordTests.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif private struct MutablePersistableRecordPerson : MutablePersistableRecord { var id: Int64? diff --git a/Tests/GRDBTests/PersistableRecordTests.swift b/Tests/GRDBTests/PersistableRecordTests.swift index 62bfba0995..08e67c4b38 100644 --- a/Tests/GRDBTests/PersistableRecordTests.swift +++ b/Tests/GRDBTests/PersistableRecordTests.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif private struct PersistableRecordPerson : PersistableRecord { var name: String? From 15e308950c1f47adcedf4ad80a303b95e022c0f9 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 6 Feb 2025 16:09:38 -0500 Subject: [PATCH 5/8] Re-enable ValueObservationTests and FailureTestCase with degraded capabilites on non-Dawin platforms missing XCTIssue --- Tests/GRDBCombineTests/Support.swift | 2 + Tests/GRDBTests/FailureTestCase.swift | 74 ++++++++++--------- Tests/GRDBTests/FoundationURLTests.swift | 2 +- .../ValueObservationRecorderTests.swift | 2 - Tests/GRDBTests/ValueObservationTests.swift | 9 +-- 5 files changed, 46 insertions(+), 43 deletions(-) diff --git a/Tests/GRDBCombineTests/Support.swift b/Tests/GRDBCombineTests/Support.swift index 6d35dd7718..e386e4f065 100644 --- a/Tests/GRDBCombineTests/Support.swift +++ b/Tests/GRDBCombineTests/Support.swift @@ -1,5 +1,6 @@ #if canImport(Combine) import Combine +#endif import Foundation import XCTest @@ -99,6 +100,7 @@ final class AsyncTest { } } +#if canImport(Combine) public func assertNoFailure( _ completion: Subscribers.Completion, file: StaticString = #file, diff --git a/Tests/GRDBTests/FailureTestCase.swift b/Tests/GRDBTests/FailureTestCase.swift index 9c47bb6d16..18fd24ae4a 100644 --- a/Tests/GRDBTests/FailureTestCase.swift +++ b/Tests/GRDBTests/FailureTestCase.swift @@ -1,12 +1,12 @@ // Inspired by https://github.com/groue/CombineExpectations import XCTest -#if canImport(Darwin) // needed for XCTIssue /// A XCTestCase subclass that can test its own failures. class FailureTestCase: XCTestCase { private struct Failure: Hashable { + #if canImport(Darwin) let issue: XCTIssue - + func issue(prefix: String = "") -> XCTIssue { if prefix.isEmpty { return issue @@ -20,11 +20,11 @@ class FailureTestCase: XCTestCase { attachments: issue.attachments) } } - + private var description: String { return issue.compactDescription } - + func hash(into hasher: inout Hasher) { hasher.combine(0) } @@ -32,12 +32,16 @@ class FailureTestCase: XCTestCase { static func == (lhs: Failure, rhs: Failure) -> Bool { lhs.description.hasPrefix(rhs.description) || rhs.description.hasPrefix(lhs.description) } + #endif } private var recordedFailures: [Failure] = [] private var isRecordingFailures = false - func assertFailure(_ prefixes: String..., file: StaticString = #file, line: UInt = #line, _ execute: () throws -> Void) rethrows { + func assertFailure(_ prefixes: String..., file: StaticString = #file, line: UInt = #line, _ execute: () throws -> Void) throws { + #if !canImport(Darwin) + throw XCTSkip("XCTIssue unavailable on non-Darwin platforms") + #else let recordedFailures = try recordingFailures(execute) if prefixes.isEmpty { if recordedFailures.isEmpty { @@ -69,6 +73,7 @@ class FailureTestCase: XCTestCase { recordedFailures: recordedFailures, expectedFailures: expectedFailures) } + #endif } override func setUp() { @@ -76,7 +81,8 @@ class FailureTestCase: XCTestCase { isRecordingFailures = false recordedFailures = [] } - + + #if canImport(Darwin) override func record(_ issue: XCTIssue) { if isRecordingFailures { recordedFailures.append(Failure(issue: issue)) @@ -84,7 +90,7 @@ class FailureTestCase: XCTestCase { super.record(issue) } } - + private func recordingFailures(_ execute: () throws -> Void) rethrows -> [Failure] { let oldRecordingFailures = isRecordingFailures let oldRecordedFailures = recordedFailures @@ -121,6 +127,7 @@ class FailureTestCase: XCTestCase { } } } + #endif } // MARK: - Tests @@ -129,62 +136,62 @@ class FailureTestCaseTests: FailureTestCase { func testEmptyTest() { } - func testExpectedAnyFailure() { - assertFailure { + func testExpectedAnyFailure() throws { + try assertFailure { XCTFail("foo") } - assertFailure { + try assertFailure { XCTFail("foo") XCTFail("bar") } } - func testMissingAnyFailure() { - assertFailure("No failure did happen") { - assertFailure { + func testMissingAnyFailure() throws { + try assertFailure("No failure did happen") { + try assertFailure { } } } - func testExpectedFailure() { - assertFailure("failed - foo") { + func testExpectedFailure() throws { + try assertFailure("failed - foo") { XCTFail("foo") } } - func testExpectedFailureMatchesOnPrefix() { - assertFailure("failed - foo") { + func testExpectedFailureMatchesOnPrefix() throws { + try assertFailure("failed - foo") { XCTFail("foobarbaz") } } - func testOrderOfExpectedFailureIsIgnored() { - assertFailure("failed - foo", "failed - bar") { + func testOrderOfExpectedFailureIsIgnored() throws { + try assertFailure("failed - foo", "failed - bar") { XCTFail("foo") XCTFail("bar") } - assertFailure("failed - bar", "failed - foo") { + try assertFailure("failed - bar", "failed - foo") { XCTFail("foo") XCTFail("bar") } } - func testExpectedFailureCanBeRepeated() { - assertFailure("failed - foo", "failed - foo", "failed - bar") { + func testExpectedFailureCanBeRepeated() throws { + try assertFailure("failed - foo", "failed - foo", "failed - bar") { XCTFail("foo") XCTFail("bar") XCTFail("foo") } } - func testExactNumberOfRepetitionIsRequired() { - assertFailure("Failure did not happen: failed - foo") { - assertFailure("failed - foo", "failed - foo") { + func testExactNumberOfRepetitionIsRequired() throws { + try assertFailure("Failure did not happen: failed - foo") { + try assertFailure("failed - foo", "failed - foo") { XCTFail("foo") } } - assertFailure("failed - foo") { - assertFailure("failed - foo", "failed - foo") { + try assertFailure("failed - foo") { + try assertFailure("failed - foo", "failed - foo") { XCTFail("foo") XCTFail("foo") XCTFail("foo") @@ -192,20 +199,19 @@ class FailureTestCaseTests: FailureTestCase { } } - func testUnexpectedFailure() { - assertFailure("Failure did not happen: failed - foo") { - assertFailure("failed - foo") { + func testUnexpectedFailure() throws { + try assertFailure("Failure did not happen: failed - foo") { + try assertFailure("failed - foo") { } } } - func testMissedFailure() { - assertFailure("failed - bar") { - assertFailure("failed - foo") { + func testMissedFailure() throws { + try assertFailure("failed - bar") { + try assertFailure("failed - foo") { XCTFail("foo") XCTFail("bar") } } } } -#endif diff --git a/Tests/GRDBTests/FoundationURLTests.swift b/Tests/GRDBTests/FoundationURLTests.swift index 3a042653c6..6dbe5f6142 100644 --- a/Tests/GRDBTests/FoundationURLTests.swift +++ b/Tests/GRDBTests/FoundationURLTests.swift @@ -42,7 +42,7 @@ class FoundationURLTests: GRDBTestCase { XCTAssertNil(URL.fromDatabaseValue(databaseValue_Null)) XCTAssertNil(URL.fromDatabaseValue(databaseValue_Int64)) XCTAssertNil(URL.fromDatabaseValue(databaseValue_Double)) - XCTAssertEqual(URL.fromDatabaseValue(databaseValue_Blob)!.absoluteString, "bar") + XCTAssertEqual(URL.fromDatabaseValue(databaseValue_Blob)?.absoluteString, "bar") } } diff --git a/Tests/GRDBTests/ValueObservationRecorderTests.swift b/Tests/GRDBTests/ValueObservationRecorderTests.swift index d59550d02d..4b8e8a2ae0 100644 --- a/Tests/GRDBTests/ValueObservationRecorderTests.swift +++ b/Tests/GRDBTests/ValueObservationRecorderTests.swift @@ -1,7 +1,6 @@ import Dispatch import XCTest -#if canImport(Darwin) // needed for FailureTestCase class ValueObservationRecorderTests: FailureTestCase { // MARK: - NextOne @@ -782,4 +781,3 @@ class ValueObservationRecorderTests: FailureTestCase { } } } -#endif diff --git a/Tests/GRDBTests/ValueObservationTests.swift b/Tests/GRDBTests/ValueObservationTests.swift index 3909f7ee4a..b929afbd7a 100644 --- a/Tests/GRDBTests/ValueObservationTests.swift +++ b/Tests/GRDBTests/ValueObservationTests.swift @@ -1,11 +1,7 @@ import XCTest import Dispatch @testable import GRDB -#if GRDBCIPHER -import SQLCipher -#endif -#if canImport(Darwin) class ValueObservationTests: GRDBTestCase { // Test passes if it compiles. // See @@ -894,7 +890,8 @@ class ValueObservationTests: GRDBTestCase { try test(makeDatabaseQueue()) try test(makeDatabasePool()) } - + + #if canImport(Darwin) // @MainActor test cases don't compile non-Darwin platforms: "call to main actor-isolated instance method 'test_mainActor_observation()' in a synchronous nonisolated(unsafe) context" // MARK: - Main Actor @MainActor func test_mainActor_observation() throws { let dbQueue = try makeDatabaseQueue() @@ -928,6 +925,7 @@ class ValueObservationTests: GRDBTestCase { wait(for: [expectation], timeout: 2) } } + #endif // MARK: - Async Await @@ -1357,4 +1355,3 @@ class ValueObservationTests: GRDBTestCase { }) } } -#endif From 289f9fd6c9b1c3ce78e5873021533d4b09f67e58 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 6 Feb 2025 16:33:52 -0500 Subject: [PATCH 6/8] Update tests to throw XCTSkip when required frameworks are unvailable rather than disabiling them altogether --- Tests/GRDBTests/DatabaseMigratorTests.swift | 34 +++++++++++++++-- .../DatabasePoolConcurrencyTests.swift | 34 +++++++++++++++-- Tests/GRDBTests/DatabaseQueueTests.swift | 10 ++++- Tests/GRDBTests/DatabaseSnapshotTests.swift | 10 ++++- .../FoundationNSDecimalNumberTests.swift | 37 ++++++++++++++++--- Tests/GRDBTests/FoundationNSNumberTests.swift | 28 +++++++++++--- Tests/GRDBTests/FoundationNSURLTests.swift | 18 +++++++-- Tests/GRDBTests/FoundationNSUUIDTests.swift | 18 +++++++-- Tests/GRDBTests/FoundationUUIDTests.swift | 2 +- 9 files changed, 160 insertions(+), 31 deletions(-) diff --git a/Tests/GRDBTests/DatabaseMigratorTests.swift b/Tests/GRDBTests/DatabaseMigratorTests.swift index 1d49d013e8..6a05c5517f 100644 --- a/Tests/GRDBTests/DatabaseMigratorTests.swift +++ b/Tests/GRDBTests/DatabaseMigratorTests.swift @@ -1,7 +1,6 @@ import XCTest import GRDB -#if !os(Android) class DatabaseMigratorTests : GRDBTestCase { // Test passes if it compiles. // See @@ -44,9 +43,13 @@ class DatabaseMigratorTests : GRDBTestCase { func testEmptyMigratorPublisher() throws { func test(writer: some DatabaseWriter) throws { let migrator = DatabaseMigrator() + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let publisher = migrator.migratePublisher(writer) let recorder = publisher.record() try wait(for: recorder.single, timeout: 1) + #endif } try Test(test).run { try DatabaseQueue() } @@ -176,6 +179,9 @@ class DatabaseMigratorTests : GRDBTestCase { } do { + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let publisher = migrator.migratePublisher(writer) let recorder = publisher.record() try wait(for: recorder.single, timeout: 1) @@ -183,9 +189,13 @@ class DatabaseMigratorTests : GRDBTestCase { XCTAssertTrue(try db.tableExists("persons")) XCTAssertTrue(try db.tableExists("pets")) } + #endif } do { + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let publisher = migrator2.migratePublisher(writer) let recorder = publisher.record() try wait(for: recorder.single, timeout: 1) @@ -193,6 +203,7 @@ class DatabaseMigratorTests : GRDBTestCase { XCTAssertTrue(try db.tableExists("persons")) XCTAssertFalse(try db.tableExists("pets")) } + #endif } } @@ -206,6 +217,9 @@ class DatabaseMigratorTests : GRDBTestCase { let migrator = DatabaseMigrator() let expectation = self.expectation(description: "") let semaphore = DispatchSemaphore(value: 0) + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let cancellable = migrator.migratePublisher(writer).sink( receiveCompletion: { _ in }, receiveValue: { _ in @@ -216,6 +230,7 @@ class DatabaseMigratorTests : GRDBTestCase { semaphore.signal() waitForExpectations(timeout: 5, handler: nil) cancellable.cancel() + #endif } try Test(test).run { try DatabaseQueue() } @@ -229,6 +244,9 @@ class DatabaseMigratorTests : GRDBTestCase { migrator.registerMigration("first", migrate: { _ in }) let expectation = self.expectation(description: "") let semaphore = DispatchSemaphore(value: 0) + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let cancellable = migrator.migratePublisher(writer).sink( receiveCompletion: { _ in }, receiveValue: { _ in @@ -239,6 +257,7 @@ class DatabaseMigratorTests : GRDBTestCase { semaphore.signal() waitForExpectations(timeout: 5, handler: nil) cancellable.cancel() + #endif } try Test(test).run { try DatabaseQueue() } @@ -247,11 +266,14 @@ class DatabaseMigratorTests : GRDBTestCase { } func testMigratorPublisherDefaultScheduler() throws { - func test(writer: Writer) { + func test(writer: Writer) throws { var migrator = DatabaseMigrator() migrator.registerMigration("first", migrate: { _ in }) let expectation = self.expectation(description: "") expectation.expectedFulfillmentCount = 2 // value + completion + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let cancellable = migrator.migratePublisher(writer).sink( receiveCompletion: { completion in dispatchPrecondition(condition: .onQueue(.main)) @@ -264,6 +286,7 @@ class DatabaseMigratorTests : GRDBTestCase { waitForExpectations(timeout: 5, handler: nil) cancellable.cancel() + #endif } try Test(test).run { try DatabaseQueue() } @@ -272,12 +295,15 @@ class DatabaseMigratorTests : GRDBTestCase { } func testMigratorPublisherCustomScheduler() throws { - func test(writer: Writer) { + func test(writer: Writer) throws { var migrator = DatabaseMigrator() migrator.registerMigration("first", migrate: { _ in }) let queue = DispatchQueue(label: "test") let expectation = self.expectation(description: "") expectation.expectedFulfillmentCount = 2 // value + completion + #if !canImport(Combine) + throw XCTSkip("Combine not supported on platform") + #else let cancellable = migrator.migratePublisher(writer, receiveOn: queue).sink( receiveCompletion: { completion in dispatchPrecondition(condition: .onQueue(queue)) @@ -290,6 +316,7 @@ class DatabaseMigratorTests : GRDBTestCase { waitForExpectations(timeout: 5, handler: nil) cancellable.cancel() + #endif } try Test(test).run { try DatabaseQueue() } @@ -1111,4 +1138,3 @@ class DatabaseMigratorTests : GRDBTestCase { } catch DatabaseError.SQLITE_CONSTRAINT_FOREIGNKEY { } } } -#endif diff --git a/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift b/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift index eefd3d0023..9af17aa562 100644 --- a/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift +++ b/Tests/GRDBTests/DatabasePoolConcurrencyTests.swift @@ -3,7 +3,6 @@ import Dispatch import Foundation @testable import GRDB -#if canImport(Darwin) // needs NSFileCoordinator class DatabasePoolConcurrencyTests: GRDBTestCase { func testDatabasePoolFundamental1() throws { @@ -880,8 +879,10 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "GRDB.DatabasePool.writer") + #endif } let s1 = DispatchSemaphore(value: 0) @@ -893,9 +894,11 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "GRDB.DatabasePool.reader.1") - + #endif + _ = s1.signal() _ = s2.wait(timeout: .distantFuture) } @@ -909,8 +912,10 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "GRDB.DatabasePool.reader.2") + #endif } } let blocks = [block1, block2] @@ -928,8 +933,10 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "Toreador.writer") + #endif } let s1 = DispatchSemaphore(value: 0) @@ -941,9 +948,11 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "Toreador.reader.1") - + #endif + _ = s1.signal() _ = s2.wait(timeout: .distantFuture) } @@ -957,8 +966,10 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "Toreador.reader.2") + #endif } } let blocks = [block1, block2] @@ -1056,6 +1067,9 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // > because DISPATCH_QUEUE_OVERCOMMIT is not a public API. I don't // > know of a way to get a reference to the overcommit queue using // > only public APIs. + #if !canImport(Darwin) + throw XCTSkip("__dispatch_get_global_queue unavailable") + #else let DISPATCH_QUEUE_OVERCOMMIT: UInt = 2 let targetQueue = __dispatch_get_global_queue( Int(qos.qosClass.rawValue.rawValue), @@ -1069,6 +1083,7 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { try dbPool.read { _ in dispatchPrecondition(condition: .onQueue(targetQueue)) } + #endif } try test(qos: .background) @@ -1255,6 +1270,9 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // MARK: - Concurrent opening func testConcurrentOpening() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSFileCoordinator unavailable") + #else for _ in 0..<50 { let dbDirectoryName = "DatabasePoolConcurrencyTests-\(ProcessInfo.processInfo.globallyUniqueString)" let directoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) @@ -1278,6 +1296,7 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { XCTAssert(poolError ?? coordinatorError == nil) } } + #endif } // MARK: - NSFileCoordinator sample code tests @@ -1285,6 +1304,9 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // Test for sample code in Documentation.docc/DatabaseSharing.md. // This test passes if this method compiles private func openSharedDatabase(at databaseURL: URL) throws -> DatabasePool { + #if !canImport(ObjectiveC) + throw XCTSkip("NSFileCoordinator unavailable") + #else let coordinator = NSFileCoordinator(filePresenter: nil) var coordinatorError: NSError? var dbPool: DatabasePool? @@ -1300,6 +1322,7 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { throw error } return dbPool! + #endif } // Test for sample code in Documentation.docc/DatabaseSharing.md. @@ -1314,6 +1337,9 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { // Test for sample code in Documentation.docc/DatabaseSharing.md. // This test passes if this method compiles private func openSharedReadOnlyDatabase(at databaseURL: URL) throws -> DatabasePool? { + #if !canImport(ObjectiveC) + throw XCTSkip("NSFileCoordinator unavailable") + #else let coordinator = NSFileCoordinator(filePresenter: nil) var coordinatorError: NSError? var dbPool: DatabasePool? @@ -1329,6 +1355,7 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { throw error } return dbPool + #endif } // Test for sample code in Documentation.docc/DatabaseSharing.md. @@ -1349,4 +1376,3 @@ class DatabasePoolConcurrencyTests: GRDBTestCase { } } } -#endif diff --git a/Tests/GRDBTests/DatabaseQueueTests.swift b/Tests/GRDBTests/DatabaseQueueTests.swift index 01e8b5455c..094491d8a8 100644 --- a/Tests/GRDBTests/DatabaseQueueTests.swift +++ b/Tests/GRDBTests/DatabaseQueueTests.swift @@ -2,7 +2,6 @@ import XCTest import Dispatch import GRDB -#if canImport(Darwin) // needed for __dispatch_get_global_queue class DatabaseQueueTests: GRDBTestCase { func testJournalModeConfiguration() throws { do { @@ -132,8 +131,10 @@ class DatabaseQueueTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "GRDB.DatabaseQueue") + #endif } } @@ -147,8 +148,10 @@ class DatabaseQueueTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "Toreador") + #endif } } @@ -240,6 +243,9 @@ class DatabaseQueueTests: GRDBTestCase { // > because DISPATCH_QUEUE_OVERCOMMIT is not a public API. I don't // > know of a way to get a reference to the overcommit queue using // > only public APIs. + #if !canImport(Darwin) + throw XCTSkip("__dispatch_get_global_queue unavailable") + #else let DISPATCH_QUEUE_OVERCOMMIT: UInt = 2 let targetQueue = __dispatch_get_global_queue( Int(qos.qosClass.rawValue.rawValue), @@ -253,6 +259,7 @@ class DatabaseQueueTests: GRDBTestCase { try dbQueue.read { _ in dispatchPrecondition(condition: .onQueue(targetQueue)) } + #endif } try test(qos: .background) @@ -474,4 +481,3 @@ class DatabaseQueueTests: GRDBTestCase { dbQueue.releaseMemory() } } -#endif diff --git a/Tests/GRDBTests/DatabaseSnapshotTests.swift b/Tests/GRDBTests/DatabaseSnapshotTests.swift index f27e0dceeb..39b6ff9a7a 100644 --- a/Tests/GRDBTests/DatabaseSnapshotTests.swift +++ b/Tests/GRDBTests/DatabaseSnapshotTests.swift @@ -1,7 +1,6 @@ import XCTest @testable import GRDB -#if !os(Android) class DatabaseSnapshotTests: GRDBTestCase { /// A helper type private struct Counter { @@ -233,8 +232,10 @@ class DatabaseSnapshotTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "GRDB.DatabasePool.snapshot.1") + #endif } let snapshot2 = try dbPool.makeSnapshot() @@ -244,8 +245,10 @@ class DatabaseSnapshotTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "GRDB.DatabasePool.snapshot.2") + #endif } } @@ -260,8 +263,10 @@ class DatabaseSnapshotTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "Toreador.snapshot.1") + #endif } let snapshot2 = try dbPool.makeSnapshot() @@ -271,8 +276,10 @@ class DatabaseSnapshotTests: GRDBTestCase { // This test CAN break in future releases: the dispatch queue labels // are documented to be a debug-only tool. + #if canImport(Darwin) // __dispatch_queue_get_label unavailable on non-Darwin platforms let label = String(utf8String: __dispatch_queue_get_label(nil)) XCTAssertEqual(label, "Toreador.snapshot.2") + #endif } } @@ -433,4 +440,3 @@ class DatabaseSnapshotTests: GRDBTestCase { } } } -#endif diff --git a/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift b/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift index 10dcc4983b..681a0af1fb 100644 --- a/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift +++ b/Tests/GRDBTests/FoundationNSDecimalNumberTests.swift @@ -1,11 +1,12 @@ import XCTest import GRDB -#if canImport(Darwin) // needed for NSDecimalNumber class FoundationNSDecimalNumberTests: GRDBTestCase { - func testNSDecimalNumberPreservesIntegerValues() { - + func testNSDecimalNumberPreservesIntegerValues() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else enum Storage { case integer case double @@ -55,9 +56,13 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { // Int64.min - 1 XCTAssertEqual(storage(NSDecimalNumber(string: "-9223372036854775809")), .double) + #endif } func testNSDecimalNumberDatabaseRoundTrip() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else let dbQueue = try makeDatabaseQueue() func roundTrip(_ value: NSDecimalNumber) throws -> Bool { guard let back = try dbQueue.inDatabase({ try NSDecimalNumber.fetchOne($0, sql: "SELECT ?", arguments: [value]) }) else { @@ -69,9 +74,13 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { XCTAssertTrue(try roundTrip(NSDecimalNumber(value: Int32.min + 1))) XCTAssertTrue(try roundTrip(NSDecimalNumber(value: Double(10000000.01)))) + #endif } - func testNSDecimalNumberDatabaseValueRoundTrip() { + func testNSDecimalNumberDatabaseValueRoundTrip() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else func roundTrip(_ value: NSDecimalNumber) -> Bool { let dbValue = value.databaseValue @@ -85,18 +94,26 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { XCTAssertTrue(roundTrip(NSDecimalNumber(value: Int32.min + 1))) XCTAssertTrue(roundTrip(NSDecimalNumber(value: Double(10000000.01)))) + #endif } - func testNSDecimalNumberFromDatabaseValueFailure() { + func testNSDecimalNumberFromDatabaseValueFailure() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else let databaseValue_Null = DatabaseValue.null let databaseValue_String = "foo".databaseValue let databaseValue_Blob = "bar".data(using: .utf8)!.databaseValue XCTAssertNil(NSDecimalNumber.fromDatabaseValue(databaseValue_Null)) XCTAssertNil(NSDecimalNumber.fromDatabaseValue(databaseValue_String)) XCTAssertNil(NSDecimalNumber.fromDatabaseValue(databaseValue_Blob)) + #endif } func testNSDecimalNumberDecodingFromInt64() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else func test(_ value: Int64, isDecodedAs number: NSDecimalNumber) throws { XCTAssertEqual(NSDecimalNumber(value: value), number) @@ -115,9 +132,13 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { try test(9223372036854775806, isDecodedAs: NSDecimalNumber(string: "9223372036854775806")) try test(-9223372036854775807, isDecodedAs: NSDecimalNumber(string: "-9223372036854775807")) try test(-9223372036854775808, isDecodedAs: NSDecimalNumber(string: "-9223372036854775808")) + #endif } func testNSDecimalNumberDecodingFromDouble() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else func test(_ value: Double, isDecodedAs number: NSDecimalNumber) throws { XCTAssertEqual(NSDecimalNumber(value: value), number) @@ -133,9 +154,13 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { try test(0.25, isDecodedAs: NSDecimalNumber(string: "0.25")) try test(1, isDecodedAs: NSDecimalNumber(string: "1")) try test(-1, isDecodedAs: NSDecimalNumber(string: "-1")) + #endif } func testNSDecimalNumberDecodingFromText() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSDecimalNumber unavailable") + #else func test(_ value: String, isDecodedAs number: NSDecimalNumber) throws { XCTAssertEqual(NSDecimalNumber(string: value), number) @@ -156,6 +181,6 @@ class FoundationNSDecimalNumberTests: GRDBTestCase { try test("-9223372036854775807", isDecodedAs: NSDecimalNumber(string: "-9223372036854775807")) try test("-9223372036854775808", isDecodedAs: NSDecimalNumber(string: "-9223372036854775808")) try test("18446744073709551615", isDecodedAs: NSDecimalNumber(string: "18446744073709551615")) + #endif } } -#endif diff --git a/Tests/GRDBTests/FoundationNSNumberTests.swift b/Tests/GRDBTests/FoundationNSNumberTests.swift index f8eb620dca..298f781a8f 100644 --- a/Tests/GRDBTests/FoundationNSNumberTests.swift +++ b/Tests/GRDBTests/FoundationNSNumberTests.swift @@ -1,10 +1,12 @@ import XCTest import GRDB -#if canImport(Darwin) // needed for NSDecimalNumber class FoundationNSNumberTests: GRDBTestCase { - func testNSNumberDatabaseValueToSwiftType() { + func testNSNumberDatabaseValueToSwiftType() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSNumber unavailable") + #else enum Storage { case integer case double @@ -131,9 +133,13 @@ class FoundationNSNumberTests: GRDBTestCase { XCTAssertEqual(storage(number), .integer) XCTAssertEqual(Bool.fromDatabaseValue(number.databaseValue), false) } + #endif } func testNSNumberDatabaseRoundTrip() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSNumber unavailable") + #else let dbQueue = try makeDatabaseQueue() func roundTrip(_ value: NSNumber) throws -> Bool { guard let back = try dbQueue.inDatabase({ try NSNumber.fetchOne($0, sql: "SELECT ?", arguments: [value]) }) else { @@ -145,9 +151,13 @@ class FoundationNSNumberTests: GRDBTestCase { XCTAssertTrue(try roundTrip(NSNumber(value: Int32.min + 1))) XCTAssertTrue(try roundTrip(NSNumber(value: Double(10000000.01)))) + #endif } - func testNSNumberDatabaseValueRoundTrip() { + func testNSNumberDatabaseValueRoundTrip() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSNumber unavailable") + #else func roundTrip(_ value: NSNumber) -> Bool { let dbValue = value.databaseValue @@ -161,18 +171,26 @@ class FoundationNSNumberTests: GRDBTestCase { XCTAssertTrue(roundTrip(NSNumber(value: Int32.min + 1))) XCTAssertTrue(roundTrip(NSNumber(value: Double(10000000.01)))) + #endif } - func testNSNumberFromDatabaseValueFailure() { + func testNSNumberFromDatabaseValueFailure() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSNumber unavailable") + #else let databaseValue_Null = DatabaseValue.null let databaseValue_String = "foo".databaseValue let databaseValue_Blob = "bar".data(using: .utf8)!.databaseValue XCTAssertNil(NSNumber.fromDatabaseValue(databaseValue_Null)) XCTAssertNil(NSNumber.fromDatabaseValue(databaseValue_String)) XCTAssertNil(NSNumber.fromDatabaseValue(databaseValue_Blob)) + #endif } func testNSNumberDecodingFromText() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSNumber unavailable") + #else func test(_ value: String, isDecodedAs number: NSDecimalNumber) throws { let decodedFromDatabaseValue = NSNumber.fromDatabaseValue(value.databaseValue) as? NSDecimalNumber XCTAssertEqual(decodedFromDatabaseValue, number) @@ -191,6 +209,6 @@ class FoundationNSNumberTests: GRDBTestCase { try test("-9223372036854775807", isDecodedAs: NSDecimalNumber(value: -9223372036854775807)) try test("-9223372036854775808", isDecodedAs: NSDecimalNumber(value: -9223372036854775808)) try test("18446744073709551615", isDecodedAs: NSDecimalNumber(value: UInt64(18446744073709551615))) + #endif } } -#endif diff --git a/Tests/GRDBTests/FoundationNSURLTests.swift b/Tests/GRDBTests/FoundationNSURLTests.swift index 7272c9e89f..52f7d2cd96 100644 --- a/Tests/GRDBTests/FoundationNSURLTests.swift +++ b/Tests/GRDBTests/FoundationNSURLTests.swift @@ -1,10 +1,12 @@ import XCTest import GRDB -#if canImport(Darwin) // needed for NSURL class FoundationNSURLTests: GRDBTestCase { func testNSURLDatabaseRoundTrip() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSURL unavailable") + #else let dbQueue = try makeDatabaseQueue() func roundTrip(_ value: NSURL) throws -> Bool { guard let back = try dbQueue.inDatabase({ try NSURL.fetchOne($0, sql: "SELECT ?", arguments: [value]) }) else { @@ -16,9 +18,13 @@ class FoundationNSURLTests: GRDBTestCase { XCTAssertTrue(try roundTrip(NSURL(string: "https://github.com/groue/GRDB.swift")!)) XCTAssertTrue(try roundTrip(NSURL(fileURLWithPath: NSTemporaryDirectory()))) + #endif } - func testNSURLDatabaseValueRoundTrip() { + func testNSURLDatabaseValueRoundTrip() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSURL unavailable") + #else func roundTrip(_ value: NSURL) -> Bool { @@ -33,9 +39,13 @@ class FoundationNSURLTests: GRDBTestCase { XCTAssertTrue(roundTrip(NSURL(string: "https://github.com/groue/GRDB.swift")!)) XCTAssertTrue(roundTrip(NSURL(fileURLWithPath: NSTemporaryDirectory()))) + #endif } - func testNSURLFromDatabaseValueFailure() { + func testNSURLFromDatabaseValueFailure() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSURL unavailable") + #else let databaseValue_Null = DatabaseValue.null let databaseValue_Int64 = Int64(1).databaseValue let databaseValue_Double = Double(100000.1).databaseValue @@ -44,7 +54,7 @@ class FoundationNSURLTests: GRDBTestCase { XCTAssertNil(NSURL.fromDatabaseValue(databaseValue_Int64)) XCTAssertNil(NSURL.fromDatabaseValue(databaseValue_Double)) XCTAssertEqual(NSURL.fromDatabaseValue(databaseValue_Blob)!.absoluteString, "bar") + #endif } } -#endif diff --git a/Tests/GRDBTests/FoundationNSUUIDTests.swift b/Tests/GRDBTests/FoundationNSUUIDTests.swift index c955743bc8..c87606f9e2 100644 --- a/Tests/GRDBTests/FoundationNSUUIDTests.swift +++ b/Tests/GRDBTests/FoundationNSUUIDTests.swift @@ -1,8 +1,8 @@ import XCTest import GRDB -#if canImport(Darwin) // needed for NSUUID class FoundationNSUUIDTests: GRDBTestCase { + #if canImport(ObjectiveC) private func assert(_ value: (any DatabaseValueConvertible)?, isDecodedAs expectedUUID: NSUUID?) throws { try makeDatabaseQueue().read { db in if let expectedUUID { @@ -17,8 +17,12 @@ class FoundationNSUUIDTests: GRDBTestCase { let decodedUUID = NSUUID.fromDatabaseValue(value?.databaseValue ?? .null) XCTAssertEqual(decodedUUID, expectedUUID) } - + #endif + private func assertRoundTrip(_ uuid: UUID) throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSUUID unavailable") + #else let string = uuid.uuidString var uuid_t = uuid.uuid let data = withUnsafeBytes(of: &uuid_t) { @@ -30,15 +34,23 @@ class FoundationNSUUIDTests: GRDBTestCase { try assert(uuid, isDecodedAs: uuid as NSUUID) try assert(uuid as NSUUID, isDecodedAs: uuid as NSUUID) try assert(data, isDecodedAs: uuid as NSUUID) + #endif } func testSuccess() throws { try assertRoundTrip(UUID(uuidString: "56e7d8d3-e9e4-48b6-968e-8d102833af00")!) try assertRoundTrip(UUID()) + #if !canImport(ObjectiveC) + throw XCTSkip("NSUUID unavailable") + #else try assert("abcdefghijklmnop".data(using: .utf8)!, isDecodedAs: NSUUID(uuidString: "61626364-6566-6768-696A-6B6C6D6E6F70")) + #endif } func testFailure() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSUUID unavailable") + #else try assert(nil, isDecodedAs: nil) try assert(DatabaseValue.null, isDecodedAs: nil) try assert(1, isDecodedAs: nil) @@ -49,6 +61,6 @@ class FoundationNSUUIDTests: GRDBTestCase { try assert("bar".data(using: .utf8)!, isDecodedAs: nil) try assert("abcdefghijklmno".data(using: .utf8)!, isDecodedAs: nil) try assert("abcdefghijklmnopq".data(using: .utf8)!, isDecodedAs: nil) + #endif } } -#endif diff --git a/Tests/GRDBTests/FoundationUUIDTests.swift b/Tests/GRDBTests/FoundationUUIDTests.swift index 29ba77e955..8ecb921ad8 100644 --- a/Tests/GRDBTests/FoundationUUIDTests.swift +++ b/Tests/GRDBTests/FoundationUUIDTests.swift @@ -28,7 +28,7 @@ class FoundationUUIDTests: GRDBTestCase { try assert(string.lowercased(), isDecodedAs: uuid) try assert(string.uppercased(), isDecodedAs: uuid) try assert(uuid, isDecodedAs: uuid) - #if canImport(Darwin) // needed for NSUUID + #if canImport(ObjectiveC) try assert(uuid as NSUUID, isDecodedAs: uuid) #endif try assert(data, isDecodedAs: uuid) From 8b974afd27ad071fea699da6d37b591a7ddce528 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Thu, 6 Feb 2025 17:20:38 -0500 Subject: [PATCH 7/8] Remove some more unnecessary conditional imports --- Tests/GRDBTests/DatabaseAggregateTests.swift | 4 ++++ Tests/GRDBTests/DatabaseErrorTests.swift | 4 ++++ Tests/GRDBTests/DatabaseFunctionTests.swift | 2 ++ Tests/GRDBTests/QueryInterfaceExpressionsTests.swift | 3 --- Tests/GRDBTests/SingletonRecordTest.swift | 3 --- Tests/GRDBTests/TableRecordDeleteTests.swift | 3 --- Tests/GRDBTests/TableRecordUpdateTests.swift | 3 --- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Tests/GRDBTests/DatabaseAggregateTests.swift b/Tests/GRDBTests/DatabaseAggregateTests.swift index 3a881b90ed..5dfeac238f 100644 --- a/Tests/GRDBTests/DatabaseAggregateTests.swift +++ b/Tests/GRDBTests/DatabaseAggregateTests.swift @@ -382,9 +382,11 @@ class DatabaseAggregateTests: GRDBTestCase { XCTFail("Expected DatabaseError") } catch let error as DatabaseError { XCTAssertEqual(error.resultCode, .SQLITE_ERROR) + #if canImport(ObjectiveC) // non-Darwin platforms bridge NSError differently and do not set the message the same XCTAssertTrue(error.message!.contains("CustomErrorDomain")) XCTAssertTrue(error.message!.contains("123")) XCTAssertTrue(error.message!.contains("custom error message")) + #endif } } } @@ -470,9 +472,11 @@ class DatabaseAggregateTests: GRDBTestCase { XCTFail("Expected DatabaseError") } catch let error as DatabaseError { XCTAssertEqual(error.resultCode, .SQLITE_ERROR) + #if canImport(ObjectiveC) // non-Darwin platforms bridge NSError differently and do not set the message the same XCTAssertTrue(error.message!.contains("CustomErrorDomain")) XCTAssertTrue(error.message!.contains("123")) XCTAssertTrue(error.message!.contains("custom error message")) + #endif } } } diff --git a/Tests/GRDBTests/DatabaseErrorTests.swift b/Tests/GRDBTests/DatabaseErrorTests.swift index e968b44074..1d1a1460ee 100644 --- a/Tests/GRDBTests/DatabaseErrorTests.swift +++ b/Tests/GRDBTests/DatabaseErrorTests.swift @@ -216,6 +216,9 @@ class DatabaseErrorTests: GRDBTestCase { } func testNSErrorBridging() throws { + #if !canImport(ObjectiveC) + throw XCTSkip("NSError bridging works differently on non-Darwin platforms") + #else let dbQueue = try makeDatabaseQueue() try dbQueue.inDatabase { db in try db.create(table: "parents") { $0.column("id", .integer).primaryKey() } @@ -229,5 +232,6 @@ class DatabaseErrorTests: GRDBTestCase { XCTAssertNotNil(error.localizedFailureReason) } } + #endif } } diff --git a/Tests/GRDBTests/DatabaseFunctionTests.swift b/Tests/GRDBTests/DatabaseFunctionTests.swift index 4c670bbd8a..f614ef660a 100644 --- a/Tests/GRDBTests/DatabaseFunctionTests.swift +++ b/Tests/GRDBTests/DatabaseFunctionTests.swift @@ -336,9 +336,11 @@ class DatabaseFunctionTests: GRDBTestCase { XCTFail("Expected DatabaseError") } catch let error as DatabaseError { XCTAssertEqual(error.resultCode, .SQLITE_ERROR) + #if canImport(ObjectiveC) // non-Darwin platforms bridge NSError differently and do not set the message the same XCTAssertTrue(error.message!.contains("CustomErrorDomain")) XCTAssertTrue(error.message!.contains("123")) XCTAssertTrue(error.message!.contains("custom error message")) + #endif } } } diff --git a/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift b/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift index a22a2b0e61..c5855e2322 100644 --- a/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift +++ b/Tests/GRDBTests/QueryInterfaceExpressionsTests.swift @@ -1,8 +1,5 @@ import XCTest @testable import GRDB -#if GRDBCIPHER -import SQLCipher -#endif private struct Col { static let id = Column("id") diff --git a/Tests/GRDBTests/SingletonRecordTest.swift b/Tests/GRDBTests/SingletonRecordTest.swift index 337c87a615..0be0c8f097 100644 --- a/Tests/GRDBTests/SingletonRecordTest.swift +++ b/Tests/GRDBTests/SingletonRecordTest.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif private struct AppConfiguration: Codable { // Support for the single row guarantee diff --git a/Tests/GRDBTests/TableRecordDeleteTests.swift b/Tests/GRDBTests/TableRecordDeleteTests.swift index ffe39e5e86..8c598b63d9 100644 --- a/Tests/GRDBTests/TableRecordDeleteTests.swift +++ b/Tests/GRDBTests/TableRecordDeleteTests.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif private struct Hacker : TableRecord { static let databaseTableName = "hackers" diff --git a/Tests/GRDBTests/TableRecordUpdateTests.swift b/Tests/GRDBTests/TableRecordUpdateTests.swift index 76022016bf..d52fcf6b76 100644 --- a/Tests/GRDBTests/TableRecordUpdateTests.swift +++ b/Tests/GRDBTests/TableRecordUpdateTests.swift @@ -1,8 +1,5 @@ import XCTest import GRDB -#if GRDBCIPHER -import SQLCipher -#endif private struct Player: Codable, PersistableRecord, FetchableRecord, Hashable { var id: Int64 From 91092ba030b3a7aac15f11d75fae4cd91e4e4eb2 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Tue, 22 Apr 2025 19:50:45 -0400 Subject: [PATCH 8/8] Update to use package traits to control whether SQLCipher is used --- .github/workflows/CI.yml | 8 ++++---- Package.swift | 30 +++++++++++------------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 510d3d163b..8f4c7a4319 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -83,13 +83,13 @@ jobs: fail-fast: false matrix: include: - - xcode: "Xcode_16.1.app" - runsOn: macOS-14 - name: "Xcode 16.1" + - xcode: "Xcode_16.3.app" + runsOn: macOS-15 + name: "Xcode 16.3" steps: - uses: actions/checkout@v4 - name: ${{ matrix.name }} - run: GRDBCIPHER="https://github.com/skiptools/swift-sqlcipher.git#1.2.1" swift test + run: GRDBCIPHER=1 swift test SQLCipher3: name: SQLCipher3 runs-on: ${{ matrix.runsOn }} diff --git a/Package.swift b/Package.swift index 8609d84d2a..b27e6b0790 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:6.0 +// swift-tools-version:6.1 // The swift-tools-version declares the minimum version of Swift required to build this package. import Foundation @@ -27,23 +27,11 @@ if ProcessInfo.processInfo.environment["SPI_BUILDER"] == "1" { dependencies.append(.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")) } -var targetDependencies: [Target.Dependency] = ["GRDBSQLite"] - - -var GRDBCIPHER = ProcessInfo.processInfo.environment["GRDBCIPHER"] -// e.g.: -//GRDBCIPHER="https://github.com/skiptools/swift-sqlcipher.git#1.2.1" -if let SQLCipherRepo = GRDBCIPHER?.split(separator: "#").first, - let SQLCipherVersion = GRDBCIPHER?.split(separator: "#").last, - let SQLCipherRepoURL = URL(string: SQLCipherRepo.description) { - swiftSettings.append(.define("GRDBCIPHER")) - targetDependencies = [.product(name: "SQLCipher", package: SQLCipherRepoURL.deletingPathExtension().lastPathComponent)] - if let version = Version(SQLCipherVersion.description) { // numeric version - dependencies.append(.package(url: SQLCipherRepoURL.absoluteString, from: version)) - } else { // branch - dependencies.append(.package(url: SQLCipherRepoURL.absoluteString, branch: SQLCipherVersion.description)) - } -} +// whether the "GRDBCIPHER" should be enabled by default; used for testing +var GRDBCIPHERENV = (ProcessInfo.processInfo.environment["GRDBCIPHER"] ?? "0") != "0" +var GRDBDependencies: [Target.Dependency] = ["GRDBSQLite"] +GRDBDependencies += [.product(name: "SQLCipher", package: "swift-sqlcipher", condition: .when(traits: ["GRDBCIPHER"]))] +dependencies.append(.package(url: "https://github.com/skiptools/swift-sqlcipher.git", from: "1.3.0")) let package = Package( name: "GRDB", @@ -59,6 +47,10 @@ let package = Package( .library(name: "GRDB", targets: ["GRDB"]), .library(name: "GRDB-dynamic", type: .dynamic, targets: ["GRDB"]), ], + traits: [ + .trait(name: "GRDBCIPHER", description: "Use the SQLCipher library rather than the vendored SQLite"), + .default(enabledTraits: GRDBCIPHERENV ? ["GRDBCIPHER"] : []) // GRDBCIPHER is not enabled by default + ], dependencies: dependencies, targets: [ .systemLibrary( @@ -66,7 +58,7 @@ let package = Package( providers: [.apt(["libsqlite3-dev"])]), .target( name: "GRDB", - dependencies: targetDependencies, + dependencies: GRDBDependencies, path: "GRDB", resources: [.copy("PrivacyInfo.xcprivacy")], cSettings: cSettings,