Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feature: Add function to set journal mode on sqlite databases #443

Merged
merged 2 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions apollo-ios/Sources/ApolloSQLite/SQLiteDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public struct DatabaseRow {
}

public protocol SQLiteDatabase {

init(fileURL: URL) throws

func createRecordsTableIfNeeded() throws
Expand All @@ -23,7 +23,13 @@ public protocol SQLiteDatabase {
func deleteRecords(matching pattern: CacheKey) throws

func clearDatabase(shouldVacuumOnClear: Bool) throws


func setJournalMode<T: RawRepresentable>(mode: T) throws where T.RawValue == String

}

public extension SQLiteDatabase {
func setJournalMode<T>(mode: T) throws where T : RawRepresentable, T.RawValue == String { }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension ensures it's not a breaking change for projects that have written their own SQLiteDatabase implementation.

}

public extension SQLiteDatabase {
Expand Down
28 changes: 27 additions & 1 deletion apollo-ios/Sources/ApolloSQLite/SQLiteDotSwiftDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,26 @@ public final class SQLiteDotSwiftDatabase: SQLiteDatabase {
private let records: Table
private let keyColumn: SQLite.Expression<CacheKey>
private let recordColumn: SQLite.Expression<String>


public enum JournalMode: String {
/// The rollback journal is deleted at the conclusion of each transaction. This is the default behaviour.
case delete = "DELETE"
/// Commits transactions by truncating the rollback journal to zero-length instead of deleting it.
case truncate = "TRUNCATE"
/// Prevents the rollback journal from being deleted at the end of each transaction. Instead, the header
/// of the journal is overwritten with zeros.
case persist = "PERSIST"
/// Stores the rollback journal in volatile RAM. This saves disk I/O but at the expense of database
/// safety and integrity.
case memory = "MEMORY"
/// Uses a write-ahead log instead of a rollback journal to implement transactions. The WAL journaling
/// mode is persistent; after being set it stays in effect across multiple database connections and after
/// closing and reopening the database.
case wal = "WAL"
/// Disables the rollback journal completely
case off = "OFF"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible some other SQLite implementation would have different journal modes? Are these modes intrinsic to SQLite or just to the SQLite.swift implementation?

If the are universally the journal modes of SQLite, then I don't think this should be part of our specific implementation. The setJournalMode function in the protocol could just take in this enum instead of being generic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose there might be but these come directly from sqlite.org documentation so if there is an sqlite implementation that differs enough you'll probably want to write your own SQLiteDatabase implementation too at which point you get to define the new set of journal modes.

As for the generic parameter I simply wanted something that was able to be expressible as a String since that's how the pragma statement gets built. Moving the enum into SQLiteDatabase will serve the vast majority of users although I didn't like how protocols can't hold enums so we lost some namespacing there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored as we discussed in 27cc399.


public init(fileURL: URL) throws {
self.records = Table(Self.tableName)
self.keyColumn = Expression<CacheKey>(Self.keyColumnName)
Expand Down Expand Up @@ -66,4 +85,11 @@ public final class SQLiteDotSwiftDatabase: SQLiteDatabase {
try self.db.prepare("VACUUM;").run()
}
}

/// Sets the journal mode for the current database.
///
/// - Parameter mode: Use ``JournalMode``.
public func setJournalMode<T>(mode: T) throws where T : RawRepresentable, T.RawValue == String {
try self.db.run("PRAGMA journal_mode = \(mode.rawValue)")
}
}
Loading