Swiftpack.co - Package - moshegottlieb/SwiftSQLite



SQLite wrapper for swift, nothing more, nothing less.

What is it?

A simple straight forward wrapper for the C API of SQLite.
Connect to SQLite databases, run queries, prepare statements and bind parameters, just like you'd do with the regular SQLite API, just with a swift wrapper.
If you want a light local database API without all the bells and whistles of other SQLite wrappers - this library is for you

What it is NOT

  • This is not another ORM database
  • It will not try to save you from using the wrong thread when you shouldn't be doing that
  • It will not guess your scheme, create it, maintain it, and automagically sync to a remote server with zero code on your part - if you like the idea of zero coding - you're in the wrong line of work

Cook book

Create a DB connection

// For example, place the database in the user's library folder
guard let path = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first?.appendingPathComponent("db.sqlite").absoluteString else { fatalError("Could not create path") }
let db = try Database(path:path)

Open or close a DB connection explicitly

Sometimes you'd want to close or open a databasse explicitly, and not just using the CTOR and DTOR.

db.close() // will silently do nothing if already closed
try db.open(pathToFile) // Open a new connection, the old handle is closed first

Run a simple SQL statement


Prepare a statement and run with parameters

// Prepare once
let insert = try db.statement(sql: "INSERT INTO demo (b) VALUES (?)")
for i in 0..<10 {
    // Parameters are 1 based, this is how SQLite works
    try insert.bind(param: 1,i)
    try insert.step() // Run the statement
    let last_row_id = db.lastInsertRowId
    print("Last row id is: \(last_row_id)")
    try insert.reset() // must reset before we can run it again
    try insert.clearBindings() // Bindings are not cleared automatically, since we bind the same param again, this is not strictly required in this example, but it's good practice to clear the bindings.

Run SELECT queries

let select = try db.statement(sql: "SELECT a,b FROM demo WHERE b > ?")
try select.bind(param: 1, 5)
while try select.step() {
    guard let a = select.integer(column: 0), let b = select.string(column: 1) else {
        fatalError("Expected b to be non nil")
    print("a: \(a), b: \(b)")

Additional helpers and wrappers

Use codables

struct C : Codable {
    let a:Int

db.useJSON1 = true
try db.exec("CREATE TABLE json_t(a JSON NOT NULL)") // JSON1 extension, JSON is actually TEXT
let ins = try db.statement(sql: "INSERT INTO json_t (a) VALUES (?)")
try ins.bind(param: 1,C(a: 0)) // Bind a decodable object
try ins.step()
let sel = try db.statement(sql: "SELECT a FROM json_t LIMIT 1")
guard try sel.step() else { fatalError("Expected step to succeed") }
guard let o:C? = sel.object(column: 0) // deduce that the object is C by the return type, which must be an optional Decodable
else { fatalError("Expected object to be decoded to a C instance") }

Set journal mode

try db.set(journalMode: .wal) // Set journaling mode to WAL, useful when several processes read the datbase file, such as with an app and an app extension
let current_mode = try db.journalMode()

Auto vacuum

let db.set(autoVacuum:.incremental)
// do some inserts, deletes here
try db.incrementalVacuum()


try db.vacuum()

Foreign keys on/off

db.foreignKeys = true
// foreign keys are now enforced
try db.withoutForeignKeys {
    // This code will run without foreign keys enforcement 
try db.withForeignKeys {
    // This code will run with foreign keys enforcement

Set busy timeout

try db.set(busyTimoeut:30)

This will install a busy handler that will sleep until the database unlocks or until the timeout expires, useful for WAL mode.
See busy handler and PRAGMA busy_timouet.
Note that there can be only a single busy handler for a database connection.


Set the user version or get the user, data or schema versions.
See PRAGMA data_version
See PRAGMA schema_version
See PRAGMA user_version

let user_version = try db.get(version: .user) // 0 by default
let schema_version = try db.get(version: .schema) 
let data_version = try db.get(version: .data) 
try db.set(version:12)


Swift Package Manager

Add the following to your Package.swift dependencies:

dependencies: [
.package(url: "https://github.com/moshegottlieb/SwiftSQLite.git", from: "1.0.8")

How to add to an existing Xcode project

Select your project, in the general tab, under Frameworks and Libraries, hit the + button.
Enter the URL:
Choose your version, and you're done.


Stars: 0


Used By

Total: 0


enabled open mode (readonly, readwrite, create + readwrite) and threading model - 2020-09-15 13:31:30

- 2020-09-14 10:00:57

- 2020-09-14 09:18:00

Codable support - 2020-09-14 09:07:33

- 2020-09-11 14:26:12

- 2020-09-09 08:26:58

Added explicit open/close Added UUID bindings

Added version get/set - 2020-09-08 11:55:49

- 2020-09-08 10:18:45

Added missing 'public' for some methods, added set busy handler.

- 2020-08-24 15:19:51

Added foreign keys support and wrappers:
try db.withForeignKeys { // Foreign keys are on inside this block! } Added vacuum and auto vacuum helpers.

Added journal mode wrappers - 2020-08-22 10:00:09

- 2020-08-21 13:26:01

First release - 2020-08-21 13:12:50