[iOS] SQLite.swift ライブラリを使いたい! その2

2014/12/4

こんにちは。きんくまです。

SQLite.swiftの使い方を調べてます。

結局説明ページがわかりやすかったので、そちらを見ながら書いてます。

なんとなくわかった気がするので、これを下の本をみながらActive Recordパターンで書いてみました。
高かったので中古で買ってしまった、、。
なんか有名な本らしいです。

日本語だとこっち。

Active Recordパターンは、ドメインオブジェクトの中にDBの操作が含まれるパターンなようです。
いろいろと調べたのですが、日本語でこの解説がわかりやすかったです。
>> PDOの真の力を開放する – PHPでデータベースを扱う(3)

あと検索するとこのページが出てきまして、この中ではsaveを呼ぶことでDBと同期をはかっていました。
>> Active Record vs Data Mapper for Persistence

ただ、オリジナルの上の本のコードでは特にそういうしばりがなくって、オブジェクトの中にDBのテーブルと1対1対応するプロパティと、DBの操作メソッドが入っていればいいのだと思います。自信ない、、。

まちがっている気もするけど、コード載せてみる。

import Foundation
import SQLite

class User{
    private class var db:Database{
        return SharedDB.instance.db
    }
    
    private class var usersQuery:Query{
        return User.db["users"]
    }
    
    private class var expId:Expression<Int>{
        return Expression<Int>("id")
    }
    
    private class var expEmail:Expression<String>{
        return Expression<String>("email")
    }
    
    private class var expName:Expression<String?>{
        return Expression<String?>("name")
    }
    
    var id:Int!
    var email:String!
    var name:String?
    
    class func createTable()->Statement{
        let result = User.db.create(table: User.usersQuery, ifNotExists:true) { table in
            table.column(User.expId, primaryKey: true)
            table.column(User.expEmail, unique: true)
            table.column(User.expName)
        }
        return result
    }
    
    class func find(id:Int)->User!{
        let query = User.usersQuery
                        .filter(User.expId == id)
        if let rowUser = query.first {
            let user:User = User()
            user.id = rowUser[User.expId]
            user.email = rowUser[User.expEmail]
            user.name = rowUser[User.expName]
            return user
        }
        return nil
    }
    
    func insert()->Int!{
        let rowId = User.usersQuery.insert(
            User.expEmail <- self.email
            ,User.expName <- self.name
        )?
        if rowId != nil {
            self.id = rowId
        }else{
            println("insert error")
        }
        return rowId
    }
    
    func update(){
        let query = User.usersQuery
        User.db.transaction(
            query.update(User.expName <- self.name)
            ,query.update(User.expEmail <- self.email)
        )
    }
}

class SharedDB{
    private struct InstanceContainer{
        static let instance:SharedDB = SharedDB()
    }
    class var instance:SharedDB{
        return InstanceContainer.instance
    }
    
    var db:Database!
    func setup(filePath:String!){
        if filePath != nil {
            self.db = Database(filePath)
        }else{
            self.db = Database()
        }
        
        #if DEBUG
        self.db.trace(println)
        #endif
    }
}

class SQLiteSample{

    init(){
        SharedDB.instance.setup(nil)
        
        User.createTable()
        
        println("insert ==")
        let user1 = User()
        user1.name = "Taro"
        user1.email = "taro@swift.com"
        let user1Id = user1.insert()
        if let selectedUser1 = User.find(user1Id) {
            printUser(selectedUser1)
        }
        
        
        println("update ==")
        user1.name = "John"
        user1.email = "john@swift.com"
        user1.update()
        
        if let selectedUser1_1 = User.find(user1Id) {
            printUser(selectedUser1_1)
        }
        
        println("user2 ==")
        let user2 = User()
        user2.name = "Jiro"
        user2.email = "jiro@swift.com"
        let user2Id = user2.insert()
        if let selectedUser2 = User.find(user2Id) {
            printUser(selectedUser2)
        }
    }
    
    func printUser(user:User){
        println("selcted id:\(user.id), name:\(user.name), email:\(user.email)")
    }
}

次回は、より柔軟だといわれるData Mapperパターンで書いてみます。

LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る