diff --git a/CHANGELOG.md b/CHANGELOG.md index bfb8382353..68f846842e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception: #### 6.x Releases -- `6.29.x` Releases - [6.29.0](#6290) - [6.29.1](#6291) - [6.29.2](#6292) +- `6.29.x` Releases - [6.29.0](#6290) - [6.29.1](#6291) - [6.29.2](#6292) - [6.29.3](#6293) - `6.28.x` Releases - [6.28.0](#6280) - `6.27.x` Releases - [6.27.0](#6270) - `6.26.x` Releases - [6.26.0](#6260) @@ -127,6 +127,12 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception: --- +## 6.29.3 + +Released September 7, 2024 + +- **Fixed**: [#1613](https://github.com/groue/GRDB.swift/pull/1613) by [@groue](https://github.com/groue): Avoid SQLite misuse when releasing memory on a closed database connection + ## 6.29.2 Released August 24, 2024 diff --git a/GRDB.swift.podspec b/GRDB.swift.podspec index 403fd74f9c..9ebb0c099d 100644 --- a/GRDB.swift.podspec +++ b/GRDB.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'GRDB.swift' - s.version = '6.29.2' + s.version = '6.29.3' s.license = { :type => 'MIT', :file => 'LICENSE' } s.summary = 'A toolkit for SQLite databases, with a focus on application development.' diff --git a/GRDB/Core/Database.swift b/GRDB/Core/Database.swift index 474373db5f..9d5a13b7bd 100644 --- a/GRDB/Core/Database.swift +++ b/GRDB/Core/Database.swift @@ -1575,7 +1575,9 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib /// Frees as much memory as possible. public func releaseMemory() { SchedulingWatchdog.preconditionValidQueue(self) - sqlite3_db_release_memory(sqliteConnection) + if let sqliteConnection { + sqlite3_db_release_memory(sqliteConnection) + } schemaCache.clear() internalStatementCache.clear() publicStatementCache.clear() diff --git a/GRDB/Core/Support/Foundation/SQLiteDateParser.swift b/GRDB/Core/Support/Foundation/SQLiteDateParser.swift index 4f234749dc..74db8e5fdf 100644 --- a/GRDB/Core/Support/Foundation/SQLiteDateParser.swift +++ b/GRDB/Core/Support/Foundation/SQLiteDateParser.swift @@ -4,7 +4,6 @@ import Foundation @usableFromInline struct SQLiteDateParser { - // swiftlint:disable:next unneeded_synthesized_initializer @usableFromInline init() { } diff --git a/GRDB/QueryInterface/SQL/SQLRelation.swift b/GRDB/QueryInterface/SQL/SQLRelation.swift index 9f01841c2a..4488cc96f4 100644 --- a/GRDB/QueryInterface/SQL/SQLRelation.swift +++ b/GRDB/QueryInterface/SQL/SQLRelation.swift @@ -171,7 +171,7 @@ struct SQLRelation { var source: SQLSource var selectionPromise: DatabasePromise<[SQLSelection]> var filterPromise: DatabasePromise? - var ordering: SQLRelation.Ordering = SQLRelation.Ordering() + var ordering = SQLRelation.Ordering() var ctes: OrderedDictionary = [:] // See also `allCTEs` var children: OrderedDictionary = [:] diff --git a/GRDB/Record/EncodableRecord+Encodable.swift b/GRDB/Record/EncodableRecord+Encodable.swift index 4ecbd5f803..8ead9397bc 100644 --- a/GRDB/Record/EncodableRecord+Encodable.swift +++ b/GRDB/Record/EncodableRecord+Encodable.swift @@ -223,7 +223,7 @@ extension RecordEncoder: SingleValueEncodingContainer { unsupportedSingleValueEncoding() } - func encode(_ value: T) throws where T : Encodable { + func encode(_ value: T) throws where T: Encodable { if let record = value as? EncodableRecord { try record.encode(to: &_persistenceContainer) } else { diff --git a/README.md b/README.md index a5a40d8fc0..d5171c0c0c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ CI Status

-**Latest release**: August 24, 2024 • [version 6.29.2](https://github.com/groue/GRDB.swift/tree/v6.29.2) • [CHANGELOG](CHANGELOG.md) • [Migrating From GRDB 5 to GRDB 6](Documentation/GRDB6MigrationGuide.md) +**Latest release**: September 7, 2024 • [version 6.29.3](https://github.com/groue/GRDB.swift/tree/v6.29.3) • [CHANGELOG](CHANGELOG.md) • [Migrating From GRDB 5 to GRDB 6](Documentation/GRDB6MigrationGuide.md) **Requirements**: iOS 11.0+ / macOS 10.13+ / tvOS 11.0+ / watchOS 4.0+ • SQLite 3.19.3+ • Swift 5.7+ / Xcode 14+ diff --git a/Scripts/swiftlint.yml b/Scripts/swiftlint.yml index af49e16e21..4c2448eb54 100644 --- a/Scripts/swiftlint.yml +++ b/Scripts/swiftlint.yml @@ -15,6 +15,7 @@ disabled_rules: - is_disjoint - large_tuple - nesting + - non_optional_string_data_conversion - opening_brace - redundant_optional_initialization - syntactic_sugar diff --git a/Support/Info.plist b/Support/Info.plist index 08f23569db..5c8f9953f8 100644 --- a/Support/Info.plist +++ b/Support/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.29.2 + 6.29.3 CFBundleSignature ???? CFBundleVersion diff --git a/Tests/GRDBTests/DatabasePoolTests.swift b/Tests/GRDBTests/DatabasePoolTests.swift index 7580b1a347..8b45af6ab7 100644 --- a/Tests/GRDBTests/DatabasePoolTests.swift +++ b/Tests/GRDBTests/DatabasePoolTests.swift @@ -439,4 +439,12 @@ class DatabasePoolTests: GRDBTestCase { // In the zombie state, closing is a noop try dbPool.close() } + + // Regression test for + func test_releaseMemory_after_close() throws { + let dbPool = try makeDatabasePool() + try dbPool.read { _ in } // Create a reader + try dbPool.close() + dbPool.releaseMemory() + } } diff --git a/Tests/GRDBTests/DatabaseQueueTests.swift b/Tests/GRDBTests/DatabaseQueueTests.swift index 7bd5adf2b5..43c415a4fa 100644 --- a/Tests/GRDBTests/DatabaseQueueTests.swift +++ b/Tests/GRDBTests/DatabaseQueueTests.swift @@ -467,4 +467,11 @@ class DatabaseQueueTests: GRDBTestCase { try db.execute(sql: "SELECT * FROM sqlite_master") } } + + // Regression test for + func test_releaseMemory_after_close() throws { + let dbQueue = try makeDatabaseQueue() + try dbQueue.close() + dbQueue.releaseMemory() + } }