Skip to content

Commit 54551c4

Browse files
committed
added BaseStorage+CRUD
1 parent 8845c93 commit 54551c4

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import Foundation
2+
3+
extension BaseStorage {
4+
func deleteInternal<T>(_ object: T) -> Result<Void, Error> {
5+
guard let anyTable = self.tables.first(where: { $0.type == T.self }) else {
6+
return .failure(Error.typeIsNotMapped)
7+
}
8+
let primaryKeyColumnNames = anyTable.primaryKeyColumnNames
9+
guard !primaryKeyColumnNames.isEmpty else {
10+
return .failure(Error.unableToDeleteObjectWithoutPrimaryKeys)
11+
}
12+
var sql = "DELETE FROM '\(anyTable.name)' WHERE"
13+
for (primaryKeyColumnNameIndex, primaryKeyColumnName) in primaryKeyColumnNames.enumerated() {
14+
sql += " \"" + primaryKeyColumnName + "\" = ?"
15+
if primaryKeyColumnNameIndex < primaryKeyColumnNames.count - 1 {
16+
sql += " AND"
17+
}
18+
}
19+
let connectionRefResult = self.connection.createConnectionRef()
20+
switch connectionRefResult {
21+
case .success(let connectionRef):
22+
let statementResult = connectionRef.prepare(sql: sql)
23+
switch statementResult {
24+
case .success(let statement):
25+
var bindIndex = 1
26+
for column in anyTable.columns {
27+
guard column.isPrimaryKey else { continue }
28+
let binder = BinderImpl(columnIndex: bindIndex, columnBinder: statement)
29+
let resultCodeResult = column.bind(binder: binder, object: object)
30+
switch resultCodeResult {
31+
case .success(let resultCode):
32+
guard resultCode == self.apiProvider.SQLITE_OK else {
33+
let errorString = connectionRef.errorMessage
34+
return .failure(Error.sqliteError(code: resultCode, text: errorString))
35+
}
36+
bindIndex += 1
37+
case .failure(let error):
38+
return .failure(error)
39+
}
40+
}
41+
let resultCode = statement.step()
42+
guard self.apiProvider.SQLITE_DONE == resultCode else {
43+
let errorString = connectionRef.errorMessage
44+
return .failure(Error.sqliteError(code: resultCode, text: errorString))
45+
}
46+
return .success(())
47+
case .failure(let error):
48+
return .failure(error)
49+
}
50+
case .failure(let error):
51+
return .failure(error)
52+
}
53+
}
54+
55+
func updateInternal<T>(_ object: T) -> Result<Void, Error> {
56+
guard let anyTable = self.tables.first(where: { $0.type == T.self }) else {
57+
return .failure(Error.typeIsNotMapped)
58+
}
59+
let primaryKeyColumnNames = anyTable.primaryKeyColumnNames
60+
guard !primaryKeyColumnNames.isEmpty else {
61+
return .failure(Error.unableToGetObjectWithoutPrimaryKeys)
62+
}
63+
var sql = "UPDATE '\(anyTable.name)' SET"
64+
var setColumnNames = [String]()
65+
for column in anyTable.columns {
66+
if !column.isPrimaryKey {
67+
setColumnNames.append(column.name)
68+
}
69+
}
70+
for (columnIndex, columnName) in setColumnNames.enumerated() {
71+
sql += " \"\(columnName)\" = ?"
72+
if columnIndex < setColumnNames.count - 1 {
73+
sql += ", "
74+
}
75+
}
76+
sql += " WHERE"
77+
for (primaryKeyColumnNameIndex, primaryKeyColumnName) in primaryKeyColumnNames.enumerated() {
78+
sql += " \"" + primaryKeyColumnName + "\" = ?"
79+
if primaryKeyColumnNameIndex < primaryKeyColumnNames.count - 1 {
80+
sql += " AND"
81+
}
82+
}
83+
let connectionRefResult = self.connection.createConnectionRef()
84+
switch connectionRefResult {
85+
case .success(let connectionRef):
86+
let prepareResult = connectionRef.prepare(sql: sql)
87+
switch prepareResult {
88+
case .success(let statement):
89+
var bindIndex = 1
90+
for column in anyTable.columns {
91+
guard !column.isPrimaryKey else { continue }
92+
let binder = BinderImpl(columnIndex: bindIndex, columnBinder: statement)
93+
let bindResult = column.bind(binder: binder, object: object)
94+
switch bindResult {
95+
case .success(let resultCode):
96+
guard resultCode == self.apiProvider.SQLITE_OK else {
97+
let errorString = connectionRef.errorMessage
98+
return .failure(Error.sqliteError(code: resultCode, text: errorString))
99+
}
100+
bindIndex += 1
101+
case .failure(let error):
102+
return .failure(error)
103+
}
104+
}
105+
for column in anyTable.columns {
106+
guard column.isPrimaryKey else { continue }
107+
let binder = BinderImpl(columnIndex: bindIndex, columnBinder: statement)
108+
let bindResult = column.bind(binder: binder, object: object)
109+
switch bindResult {
110+
case .success(let resultCode):
111+
bindIndex += 1
112+
guard resultCode == self.apiProvider.SQLITE_OK else {
113+
let errorString = connectionRef.errorMessage
114+
return .failure(Error.sqliteError(code: resultCode, text: errorString))
115+
}
116+
case .failure(let error):
117+
return .failure(error)
118+
}
119+
}
120+
let resultCode = statement.step()
121+
guard apiProvider.SQLITE_DONE == resultCode else {
122+
let errorString = connectionRef.errorMessage
123+
return .failure(Error.sqliteError(code: resultCode, text: errorString))
124+
}
125+
return .success(())
126+
case .failure(let error):
127+
return .failure(error)
128+
}
129+
case .failure(let error):
130+
return .failure(error)
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)