Skip to content

Commit 8782119

Browse files
committed
test: add integration test
1 parent 67e1331 commit 8782119

File tree

2 files changed

+115
-2
lines changed

2 files changed

+115
-2
lines changed

Sources/Sqlite/Sqlite.swift

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ public final class Sqlite {
3030
)
3131
}
3232

33-
@discardableResult
34-
public func run(_ sql: String, _ bindings: Datatype...) throws -> [[Datatype]] {
33+
public func run(_ sql: String, _ bindings: [Datatype]) throws -> [[Datatype]] {
3534
var stmt: OpaquePointer?
3635
try self.validate(sqlite3_prepare_v2(self.handle, sql, -1, &stmt, nil))
3736
defer { sqlite3_finalize(stmt) }
@@ -74,6 +73,11 @@ public final class Sqlite {
7473
return rows
7574
}
7675

76+
@discardableResult
77+
public func run(_ sql: String, _ bindings: Datatype...) throws -> [[Datatype]] {
78+
try self.run(sql, bindings)
79+
}
80+
7781
public var lastInsertRowid: Int64 {
7882
sqlite3_last_insert_rowid(self.handle)
7983
}
@@ -105,3 +109,40 @@ extension Sqlite.Error {
105109
self.description = String(cString: sqlite3_errstr(code))
106110
}
107111
}
112+
113+
extension Sqlite.Datatype {
114+
115+
public var blobValue: [UInt8]? {
116+
guard case let .blob(value) = self else {
117+
return nil
118+
}
119+
120+
return value
121+
}
122+
123+
public var integerValue: Int64? {
124+
guard case let .integer(value) = self else {
125+
return nil
126+
}
127+
128+
return value
129+
}
130+
131+
public var realValue: Double? {
132+
guard case let .real(value) = self else {
133+
return nil
134+
}
135+
136+
return value
137+
}
138+
139+
public var textValue: String? {
140+
guard case let .text(value) = self else {
141+
return nil
142+
}
143+
144+
return value
145+
}
146+
147+
public var isNull: Bool { self == .null }
148+
}

Tests/SqliteTests/SqliteTests.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,76 @@ import XCTest
33
@testable import Sqlite
44

55
final class SqliteTests: XCTestCase {
6+
7+
func test_Sqlite_CreateTable_InsertAndQueryData() throws {
8+
let sqlite = try Sqlite(path: "")
9+
10+
try sqlite.execute(
11+
"""
12+
CREATE TABLE IF NOT EXISTS "logs" (
13+
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
14+
"inserted_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
15+
"level" INTEGER NOT NULL,
16+
"msg" TEXT
17+
);
18+
""")
19+
20+
try Log.create(in: sqlite, level: .warning, msg: "This is a warning message")
21+
try Log.create(in: sqlite, level: .error, msg: "This is an error message")
22+
23+
let allLogs = try Log.fetchAll(in: sqlite)
24+
25+
XCTAssertEqual(allLogs.count, 2)
26+
27+
XCTAssertEqual(allLogs[0].level, .warning)
28+
XCTAssertEqual(allLogs[0].msg, "This is a warning message")
29+
30+
XCTAssertEqual(allLogs[1].level, .error)
31+
XCTAssertEqual(allLogs[1].msg, "This is an error message")
32+
}
33+
}
34+
35+
struct Log {
36+
let id: Int64
37+
let insertedAt: Date
38+
let level: Level
39+
let msg: String
40+
41+
enum Level: Int {
42+
case warning, error
43+
}
44+
45+
static func create(in sqlite: Sqlite, level: Level, msg: String) throws {
46+
try sqlite.run(
47+
"""
48+
INSERT INTO "logs" (
49+
"level", "msg"
50+
)
51+
VALUES (
52+
?, ?
53+
);
54+
""",
55+
.integer(Int64(level.rawValue)),
56+
.text(msg)
57+
)
58+
}
59+
60+
static func fetchAll(in sqlite: Sqlite) throws -> [Log] {
61+
try sqlite.run(
62+
"""
63+
SELECT
64+
"id", "inserted_at", "level", "msg"
65+
FROM
66+
"logs"
67+
"""
68+
)
69+
.map { row in
70+
Log(
71+
id: row[0].integerValue ?? 0,
72+
insertedAt: row[1].realValue.flatMap(Date.init(timeIntervalSince1970:)) ?? Date(),
73+
level: row[2].integerValue.map { Int($0) }.flatMap(Level.init(rawValue:)) ?? .warning,
74+
msg: row[3].textValue ?? ""
75+
)
76+
}
77+
}
678
}

0 commit comments

Comments
 (0)