All Projects → ChristianKienle → Bold

ChristianKienle / Bold

Licence: mit
A lightweight and extensible SQLite wrapper written in Swift.

Programming Languages

swift
15916 projects

Alt text

Branch Status
Master Build Status
Develop Build Status

Simple Example

The example below creates an in-memory database, opens it, creates a table, inserts a row and then queries the table. Please note that the result is closed automatically after a complete iteration by using for-in.

let db = Database(URL:":memory:")
db.open()
db.update("CREATE TABLE Person (firstName, lastName)")

let args = ["firstName" : "Christian", "lastName" : "Kienle"]
db.update("INSERT INTO Person (firstName, lastName) VALUES (:firstName, :lastName)", arguments:args)

let result = db.query(query: "SELECT firstName, lastName FROM Person")
for row in result {
    let firstName = row["firstName"].string
    let lastName = row["lastName"].string
    println("firstName: \(firstName)")
    println("lastName: \(lastName)")
}
// The result is automatically closed after a complete iteration.

Extend Bold: Custom Types

I wanted Bold to be easily extensible. There are basically two things that can be extended:

  1. Support for custom data types in the input arguments.
  2. Support for custom data types when accessing a row.

Extend Types for Input Arguments

You can support custom data types for input arguments simply by implementing Bindable. Lets assume you have a custom class called UUID which represents a UUID and you would like to pass UUIDs to Bold when inserting a new row. You could implement Bindable by doing something like this:

extension UUID : Bindable {
  public func bind(to statement:Statement, atIndex index:Int32) -> Bool {
    let value = stringRepresentation // assume this exists
    // call the existing implementation of `bind(to:atIndex:)`
    return value.bind(to: statement, atIndex:atIndex)
}

This is all you have to do. Now you could use UUID like this in combination with Bold:

let uuid = UUID()

db.update("INSERT INTO Person (id) VALUES (:id)", arguments:["id" : uuid])

Extend Types for Output Arguments

When you access the contents of a row you access the data by using methods like stringValue(columnName:), intValue(columnName:) and so on. If you would like to add support for your own data type (for example a method that uses the binary data in a column to create a UIImage) you simply extend Row. Let's see how this works with our custom UUID class from above.

extension Row {
    public func UUIDValue(columnName: String) -> UUID? {
        guard let stringValue = stringValue(forColumn: columnName) else {
            return nil
        }
        return UUID(stringValue)
    } 
}

Now you can use UUIDValue(columnName:) when accessing the data of your rows.

Why yet another SQLite wrapper?

I wanted to dive into Swift and writing a SQLite wrapper seemed like a good thing to do. So Bold is basically a just for fun project.

Lightweight

Bold is lightweight. This means that Bold does not try to be smart. For example it does not implement SQLITE_BUSY-handling like some other SQLite wrappers do. I believe that any implementation of SQLITE_BUSY-handling hides an underlying locking problem that you might have. Other wrappers simply wait for a couple of seconds until they time out. Please note that libsqlite3 already has ways to avoid SQLITE_BUSY related errors.

Bold also exposes the raw sqlite3 database handle and the raw sqlite3_stmt handle. You should try to avoid accessing those but if you need to access them they are there.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].