Convert Figma logo to code with AI

stephencelis logoSQLite.swift

A type-safe, Swift-language layer over SQLite3.

9,661
1,559
9,661
128

Top Related Projects

A toolkit for SQLite databases, with a focus on application development

13,840

A Cocoa / Objective-C wrapper around SQLite

Realm is a mobile database: a replacement for Core Data & SQLite

1,316

Vapor ORM (queries, models, and relations) for NoSQL and SQL databases

Quick Overview

SQLite.swift is a type-safe, Swift-language layer over SQLite3, implementing a flexible and expressive query and parameter binding interface. It provides a powerful abstraction over raw SQLite operations, allowing developers to work with databases in a more Swift-like manner.

Pros

  • Type-safe API, reducing runtime errors and improving code reliability
  • Expressive query interface, making database operations more intuitive
  • Supports custom SQL functions and collations
  • Lightweight and performant, with minimal overhead over raw SQLite

Cons

  • Limited to SQLite databases, not suitable for other database systems
  • Requires knowledge of SQL for complex queries
  • May have a learning curve for developers new to SQLite or database programming
  • Not as feature-rich as some full-fledged ORM solutions

Code Examples

  1. Creating a table and inserting data:
let db = try Connection("path/to/db.sqlite3")

try db.run(users.create { t in
    t.column(id, primaryKey: true)
    t.column(name)
    t.column(email, unique: true)
})

let insert = users.insert(name <- "Alice", email <- "alice@mac.com")
let rowId = try db.run(insert)
  1. Querying data:
for user in try db.prepare(users) {
    print("id: \(user[id]), name: \(user[name]), email: \(user[email])")
}

let alice = users.filter(email == "alice@mac.com")
for user in try db.prepare(alice) {
    print("id: \(user[id]), name: \(user[name]), email: \(user[email])")
}
  1. Updating and deleting data:
let alice = users.filter(email == "alice@mac.com")
try db.run(alice.update(email <- "alice@me.com"))

try db.run(alice.delete())

Getting Started

  1. Add SQLite.swift to your project using Swift Package Manager:
dependencies: [
    .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1")
]
  1. Import the module in your Swift file:
import SQLite
  1. Create a database connection and start using SQLite.swift:
do {
    let db = try Connection("path/to/db.sqlite3")
    let users = Table("users")
    let id = Expression<Int64>("id")
    let name = Expression<String>("name")
    let email = Expression<String>("email")
    
    // Use the db object to perform database operations
} catch {
    print("Error: \(error)")
}

Competitor Comparisons

A toolkit for SQLite databases, with a focus on application development

Pros of GRDB.swift

  • More comprehensive documentation and extensive guides
  • Built-in support for full-text search and custom SQLite extensions
  • Stronger focus on type-safety and compile-time checks

Cons of GRDB.swift

  • Steeper learning curve due to more advanced features
  • Slightly more complex API compared to SQLite.swift's simplicity
  • Less widespread adoption in the Swift community

Code Comparison

SQLite.swift:

let db = try Connection("path/to/db.sqlite3")
try db.run("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
try db.run("INSERT INTO users (name) VALUES (?)", "Alice")

GRDB.swift:

let dbQueue = try DatabaseQueue(path: "path/to/db.sqlite3")
try dbQueue.write { db in
    try db.create(table: "users") { t in
        t.autoIncrementedPrimaryKey("id")
        t.column("name", .text)
    }
    try db.execute(sql: "INSERT INTO users (name) VALUES (?)", arguments: ["Alice"])
}

Both libraries offer similar functionality for basic SQLite operations, but GRDB.swift provides more advanced features and type-safety at the cost of increased complexity. SQLite.swift focuses on simplicity and ease of use, making it a good choice for smaller projects or developers new to SQLite in Swift. GRDB.swift is better suited for larger, more complex applications that require advanced SQLite features and stronger type-safety guarantees.

13,840

A Cocoa / Objective-C wrapper around SQLite

Pros of FMDB

  • Mature and well-established project with a long history of use in iOS development
  • Simple and straightforward API, making it easy to learn and use
  • Supports both synchronous and asynchronous operations

Cons of FMDB

  • Relies on Objective-C, which may not be ideal for modern Swift-based projects
  • Less type-safe compared to SQLite.swift, requiring more manual type casting
  • Lacks some advanced features and Swift-specific optimizations

Code Comparison

FMDB:

FMDatabase *db = [FMDatabase databaseWithPath:@"test.db"];
[db open];
[db executeUpdate:@"INSERT INTO users (name) VALUES (?)", @"John"];
FMResultSet *rs = [db executeQuery:@"SELECT * FROM users"];
while ([rs next]) {
    NSString *name = [rs stringForColumn:@"name"];
}

SQLite.swift:

let db = try Connection("test.db")
try db.run(users.insert(name: "John"))
for user in try db.prepare(users) {
    print("name: \(user[name])")
}

The SQLite.swift code is more concise and type-safe, leveraging Swift's language features. FMDB requires more verbose code and manual type handling, but offers a familiar Objective-C style API.

Realm is a mobile database: a replacement for Core Data & SQLite

Pros of Realm

  • Object-oriented database with a more intuitive API for working with data models
  • Better performance for large datasets and complex queries
  • Built-in support for real-time synchronization and offline-first capabilities

Cons of Realm

  • Steeper learning curve due to its unique architecture and concepts
  • Less flexibility in terms of raw SQL queries and database schema modifications
  • Larger binary size and potential memory footprint

Code Comparison

SQLite.swift:

let db = try Connection("path/to/db.sqlite3")
let users = Table("users")
let id = Expression<Int64>("id")
let name = Expression<String>("name")
try db.run(users.create { t in
    t.column(id, primaryKey: true)
    t.column(name)
})

Realm:

class User: Object {
    @Persisted(primaryKey: true) var id: Int64
    @Persisted var name: String
}
let realm = try! Realm()
try! realm.write {
    realm.add(User(value: ["id": 1, "name": "John"]))
}

Both SQLite.swift and Realm offer robust solutions for local data storage in Swift applications. SQLite.swift provides a more traditional SQL-based approach with greater flexibility, while Realm offers an object-oriented model with better performance for complex scenarios and built-in synchronization features. The choice between them depends on specific project requirements and developer preferences.

1,316

Vapor ORM (queries, models, and relations) for NoSQL and SQL databases

Pros of Fluent

  • Supports multiple databases (PostgreSQL, MySQL, SQLite, MongoDB)
  • Integrates seamlessly with the Vapor web framework
  • Provides a powerful ORM with type-safe query building

Cons of Fluent

  • Steeper learning curve due to its broader scope
  • May have more overhead for simple SQLite-only projects
  • Less focused on SQLite-specific optimizations

Code Comparison

SQLite.swift:

let db = try Connection("path/to/db.sqlite3")
try db.run("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
try db.run("INSERT INTO users (name) VALUES (?)", "Alice")

Fluent:

struct User: Model {
    @ID var id: UUID?
    @Field(key: "name") var name: String
}
try await app.databases.use(.sqlite(.file("path/to/db.sqlite3")), as: .sqlite)
try await User.create(on: database)
let user = User(name: "Alice")
try await user.save(on: database)

Summary

SQLite.swift is a lightweight, SQLite-focused library, while Fluent is a more comprehensive ORM supporting multiple databases. SQLite.swift offers simplicity and direct SQLite access, whereas Fluent provides a higher-level abstraction and integrates well with the Vapor ecosystem. Choose based on your project's complexity and database requirements.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

SQLite.swift

Build Status CocoaPods Version Swift5 compatible Platform Carthage compatible Join the chat at https://gitter.im/stephencelis/SQLite.swift

A type-safe, Swift-language layer over SQLite3.

SQLite.swift provides compile-time confidence in SQL statement syntax and intent.

Features

  • A pure-Swift interface
  • A type-safe, optional-aware SQL expression builder
  • A flexible, chainable, lazy-executing query layer
  • Automatically-typed data access
  • A lightweight, uncomplicated query and parameter binding interface
  • Developer-friendly error handling and debugging
  • Full-text search support
  • Well-documented
  • Extensively tested
  • SQLCipher support via CocoaPods
  • Schema query/migration
  • Works on Linux (with some limitations)
  • Active support at StackOverflow, and Gitter Chat Room (experimental)

Usage

import SQLite

// Wrap everything in a do...catch to handle errors
do {
    let db = try Connection("path/to/db.sqlite3")

    let users = Table("users")
    let id = Expression<Int64>("id")
    let name = Expression<String?>("name")
    let email = Expression<String>("email")

    try db.run(users.create { t in
        t.column(id, primaryKey: true)
        t.column(name)
        t.column(email, unique: true)
    })
    // CREATE TABLE "users" (
    //     "id" INTEGER PRIMARY KEY NOT NULL,
    //     "name" TEXT,
    //     "email" TEXT NOT NULL UNIQUE
    // )

    let insert = users.insert(name <- "Alice", email <- "alice@mac.com")
    let rowid = try db.run(insert)
    // INSERT INTO "users" ("name", "email") VALUES ('Alice', 'alice@mac.com')

    for user in try db.prepare(users) {
        print("id: \(user[id]), name: \(user[name]), email: \(user[email])")
        // id: 1, name: Optional("Alice"), email: alice@mac.com
    }
    // SELECT * FROM "users"

    let alice = users.filter(id == rowid)

    try db.run(alice.update(email <- email.replace("mac.com", with: "me.com")))
    // UPDATE "users" SET "email" = replace("email", 'mac.com', 'me.com')
    // WHERE ("id" = 1)

    try db.run(alice.delete())
    // DELETE FROM "users" WHERE ("id" = 1)

    try db.scalar(users.count) // 0
    // SELECT count(*) FROM "users"
} catch {
    print (error)
}

SQLite.swift also works as a lightweight, Swift-friendly wrapper over the C API.

// Wrap everything in a do...catch to handle errors
do {
    // ...

    let stmt = try db.prepare("INSERT INTO users (email) VALUES (?)")
    for email in ["betty@icloud.com", "cathy@icloud.com"] {
        try stmt.run(email)
    }

    db.totalChanges    // 3
    db.changes         // 1
    db.lastInsertRowid // 3

    for row in try db.prepare("SELECT id, email FROM users") {
        print("id: \(row[0]), email: \(row[1])")
        // id: Optional(2), email: Optional("betty@icloud.com")
        // id: Optional(3), email: Optional("cathy@icloud.com")
    }

    try db.scalar("SELECT count(*) FROM users") // 2
} catch {
    print (error)
}

Read the documentation or explore more, interactively, from the Xcode project’s playground.

SQLite.playground Screen Shot

Installation

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code.

  1. Add the following to your Package.swift file:
dependencies: [
    .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3")
]
  1. Build your project:
$ swift build

See the Tests/SPM folder for a small demo project which uses SPM.

Carthage

Carthage is a simple, decentralized dependency manager for Cocoa. To install SQLite.swift with Carthage:

  1. Make sure Carthage is installed.

  2. Update your Cartfile to include the following:

    github "stephencelis/SQLite.swift" ~> 0.15.3
    
  3. Run carthage update and add the appropriate framework.

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. To install SQLite.swift with CocoaPods:

  1. Make sure CocoaPods is installed.

    # Using the default Ruby install will require you to use sudo when
    # installing and updating gems.
    [sudo] gem install cocoapods
    
  2. Update your Podfile to include the following:

    use_frameworks!
    
    target 'YourAppTargetName' do
        pod 'SQLite.swift', '~> 0.14.0'
    end
    
  3. Run pod install --repo-update.

Manual

To install SQLite.swift as an Xcode sub-project:

  1. Drag the SQLite.xcodeproj file into your own project. (Submodule, clone, or download the project first.)

    Installation Screen Shot

  2. In your target’s General tab, click the + button under Linked Frameworks and Libraries.

  3. Select the appropriate SQLite.framework for your platform.

  4. Add.

Some additional steps are required to install the application on an actual device:

  1. In the General tab, click the + button under Embedded Binaries.

  2. Select the appropriate SQLite.framework for your platform.

  3. Add.

Communication

See the planning document for a roadmap and existing feature requests.

Read the contributing guidelines. The TL;DR (but please; R):

Original author

License

SQLite.swift is available under the MIT license. See the LICENSE file for more information.

Related

These projects enhance or use SQLite.swift:

Alternatives

Looking for something else? Try another Swift wrapper (or FMDB):