· 9 years ago · Oct 27, 2016, 08:48 AM
1import Foundation
2
3enum SQLite3Error : Error {
4 case connectionError(String)
5 case queryError(String)
6 case valueError(String)
7 case otherError(String)
8}
9
10class SQLite3Conn {
11 var stmt: OpaquePointer? = nil
12 var db: OpaquePointer? = nil
13
14 init?() {
15 var needsSetup = false
16 let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
17 .last!.appendingPathComponent("data.db").path
18 if !FileManager.default.fileExists(atPath: path) {
19 print("no database file. setup.")
20 needsSetup = true
21
22 }
23 /*
24 func sqlite3_open(_ filename: UnsafePointer<Int8>!, _ ppDb: UnsafeMutablePointer<OpaquePointer?>!) -> Int32
25 */
26 if sqlite3_open(path, &db) != SQLITE_OK {
27 return nil
28 }
29 if needsSetup {
30 let query = "CREATE TABLE IF NOT EXISTS test ( num INT, text TEXT );"
31 do {
32 try prepare(query: query){ () -> Void in
33 if sqlite3_step(stmt) != SQLITE_DONE {
34 throw SQLite3Error.valueError("Fail to create table")
35 }
36 }
37
38 } catch {
39 print("Error")
40 return nil
41 }
42 }
43 }
44
45 deinit {
46 if let db = db {
47 sqlite3_close(db)
48 }
49 }
50
51 func prepare<ResultType>(query: String, _ body: () throws -> ResultType) throws -> ResultType {
52 /*
53 func sqlite3_prepare_v2(
54 _ db: OpaquePointer!,
55 _ zSql: UnsafePointer<Int8>!,
56 _ nByte: Int32,
57 _ ppStmt: UnsafeMutablePointer<OpaquePointer?>!,
58 _ pzTail: UnsafeMutablePointer<UnsafePointer<Int8>?>!
59 ) -> Int32
60 */
61 guard sqlite3_prepare_v2(db, query, -1, &stmt, nil) == SQLITE_OK
62 else { throw SQLite3Error.queryError("Fail to compile Query:\n\(query)")}
63 defer {sqlite3_finalize(stmt)}
64 let r = try body()
65 return r
66 }
67}
68
69extension SQLite3Conn {
70 func insert(num: Int32, text: String) {
71 let query = "INSERT INTO test (num, text) VALUES (?, ?)"
72 do {
73 try prepare(query: query){ () -> Void in
74 guard sqlite3_bind_int(stmt, 1, num) == SQLITE_OK else { throw SQLite3Error.valueError("can't bind num") }
75 guard sqlite3_bind_text(stmt, 2, text, -1, nil) == SQLITE_OK else {throw SQLite3Error.valueError("can't bind text")}
76 guard sqlite3_step(stmt) == SQLITE_DONE else {throw SQLite3Error.otherError("Fail to insert")}
77 print("ok")
78 }
79 } catch {
80 print("fail")
81 }
82 }
83}
84
85
86let d = SQLite3Conn()!
87d.insert(num: 2, text: "World")
88d.insert(num: 43, text: "TEST")
89d.insert(num:55, text: "Anna")