Skip to content

Instantly share code, notes, and snippets.

@jparishy
Created December 12, 2015 01:20
Show Gist options
  • Save jparishy/2642d694128444cfee4a to your computer and use it in GitHub Desktop.
Save jparishy/2642d694128444cfee4a to your computer and use it in GitHub Desktop.
do {
let db = try Database(databaseName: "notes", username: "jp")
try db.transaction {
t in
let query = ModelQuery<Note>(transaction: t)
let results = try query.all()
print(results)
}
} catch DatabaseError.OpenFailure(let status, let message) {
print("Failed to open database (statusCode=\(status)):\n\(message)")
} catch DatabaseError.TransactionFailure(let status, let message) {
print("Transaction failed (statusCode=\(status)):\n\(message)")
}
//
// Model.swift
// Swerver
//
// Created by Julius Parishy on 12/11/15.
// Copyright © 2015 Julius Parishy. All rights reserved.
//
import Foundation
enum ModelError : ErrorType {
case MustOverrideInSubclass
}
public protocol BaseProperty {
func databaseReadFromValue(value: String) throws
func databaseValueForWriting() throws -> String
}
public class Property<T> : BaseProperty, CustomStringConvertible {
let column: String
private var internalValue: T
private init(column: String, initialValue: T) {
self.column = column
self.internalValue = initialValue
}
func update(value: T) -> T {
internalValue = value
return internalValue
}
func value() -> T {
return internalValue
}
public func databaseReadFromValue(value: String) throws {
throw ModelError.MustOverrideInSubclass
}
public func databaseValueForWriting() throws -> String {
throw ModelError.MustOverrideInSubclass
}
public var description: String {
do {
return try databaseValueForWriting()
} catch {
return ""
}
}
}
public class StringProperty : Property<String> {
init(column: String) {
super.init(column: column, initialValue: "")
}
override public func databaseReadFromValue(value: String) {
update(value)
}
override public func databaseValueForWriting() -> String {
return value()
}
}
extension String {
init(stringProperty: StringProperty) {
self.init(stringProperty.value())
}
}
public class IntProperty : Property<Int> {
init(column: String) {
super.init(column: column, initialValue: 0)
}
override public func databaseReadFromValue(value: String) {
update(value.bridge().integerValue)
}
override public func databaseValueForWriting() -> String {
return String(value())
}
}
extension Int {
init(intProperty: IntProperty) {
self.init(intProperty.value())
}
}
public protocol Model {
init()
static var table: String { get }
static var columns: [String] { get }
var map: [String:BaseProperty] { get }
}
//
// ModelQuery.swift
// Swerver
//
// Created by Julius Parishy on 12/11/15.
// Copyright © 2015 Julius Parishy. All rights reserved.
//
import Foundation
class ModelQuery<T : Model> {
let transaction: Transaction
init(transaction: Transaction) {
self.transaction = transaction
}
func all() throws -> [T] {
var results = [T]()
let rows = try self.transaction.query("SELECT * FROM \(T.table)")
for row in rows {
let m = T()
for (k,v) in row {
if let p = m.map[k] {
try p.databaseReadFromValue(v)
}
}
results.append(m)
}
return results
}
}
//
// Note.swift
// Swerver
//
// Created by Julius Parishy on 12/11/15.
// Copyright © 2015 Julius Parishy. All rights reserved.
//
import Foundation
class Note {
required init() {
}
let id = IntProperty(column: "id")
let text = StringProperty(column: "text")
}
extension Note : CustomStringConvertible {
var description: String {
return "<Note: id=\(id); text=\"\(text)\";>"
}
}
extension Note : Model {
static var table: String {
return "notes"
}
static var columns: [String] {
return [
"id",
"text"
]
}
var map: [String : BaseProperty] {
return [
"id" : self.id,
"text" : self.text
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment