Skip to content

Commit

Permalink
adds documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
tanner0101 committed Jun 8, 2016
1 parent 79162d4 commit e66137e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 27 deletions.
99 changes: 74 additions & 25 deletions Sources/SQLite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,65 @@
let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)

public class SQLite {
/**
The prepare closure is used
to bind values to the SQLite statement
in a safe, escaped manner.
*/
typealias PrepareClosure = ((Statement) throws -> ())

/**
Provides more useful type
information for the Database pointer.
*/
typealias Database = OpaquePointer

/**
An optional pointer to the
connection to the SQLite database.
*/
var database: Database?

/**
Opens a connection to the SQLite
database at a given path.

If the database does not already exist,
it will be created.
*/
init(path: String) throws {
let options = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX
if sqlite3_open_v2(path, &database, options, nil) != SQLITE_OK {
throw Error.connection(database?.errorMessage ?? "")
}
}

/**
Closes a connetion to the database.
*/
func close() {
sqlite3_close(database)
}

struct Result {
struct Row {
var data: [String: String]

init() {
data = [:]
}
}

var rows: [Row]

init() {
rows = []
}
/**
Closes the database when deinitialized.
*/
deinit {
self.close()
}

/**
Executes a statement query string
and calls the prepare closure to bind
any prepared values.

The resulting rows are returned if
no errors occur.
*/
func execute(_ queryString: String, prepareClosure: PrepareClosure = { _ in }) throws -> [Result.Row] {
guard let database = self.database else {
throw Error.execute("No database")
}
bindPosition = 0

let statementContainer = UnsafeMutablePointer<OpaquePointer?>.init(allocatingCapacity: 1)
defer {
Expand Down Expand Up @@ -96,35 +118,56 @@ public class SQLite {
return result.rows
}

var lastId: Int {
/**
Returns an identifier for the last
inserted row.
*/
var lastId: Int? {
guard let database = database else {
return nil
}

let id = sqlite3_last_insert_rowid(database)
return Int(id)
}

//MARK: Error

public enum Error: ErrorProtocol {
case connection(String)
case close(String)
case prepare(String)
case bind(String)
case execute(String)
}
}

//MARK: Bind
extension SQLite {
/**
Represents a row of data from
a SQLite table.
*/
struct Result {
struct Row {
var data: [String: String]

var bindPosition: Int32 = 0

var nextBindPosition: Int32 {
bindPosition += 1
return bindPosition
}

init() {
data = [:]
}
}

var rows: [Row]

init() {
rows = []
}
}
}

extension SQLite.Database {
/**
Returns the last error message
for the current database connection.
*/
var errorMessage: String {
if let raw = sqlite3_errmsg(self) {
return String(cString: raw) ?? "Unknown"
Expand All @@ -136,6 +179,12 @@ extension SQLite.Database {
}

extension SQLite {
/**
Represents a single database statement.
The statement is used to bind prepared
values and contains a pointer to the
underlying SQLite statement memory.
*/
class Statement {
typealias Pointer = OpaquePointer

Expand Down
11 changes: 9 additions & 2 deletions Sources/SQLiteDriver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public class SQLiteDriver: Fluent.Driver {
try self.bind(statement: statement, to: sql.values)
}

if query.action == .create {
if let id = database.lastId where query.action == .create {
return [
[idKey : database.lastId]
[idKey : id]
]
} else {
return map(results: results)
Expand All @@ -54,6 +54,10 @@ public class SQLiteDriver: Fluent.Driver {
return map(results: results)
}

/**
Binds an array of values to the
SQLite statement.
*/
func bind(statement: SQLite.Statement, to values: [Value]) throws {
for value in values {
switch value.structuredData {
Expand All @@ -76,6 +80,9 @@ public class SQLiteDriver: Fluent.Driver {
}
}

/**
Maps SQLite Results to Fluent results.
*/
func map(results: [SQLite.Result.Row]) -> [[String: Value]] {
return results.map { row in
var data: [String: Value] = [:]
Expand Down

0 comments on commit e66137e

Please sign in to comment.