-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathg1sql.lua
157 lines (121 loc) · 3.23 KB
/
g1sql.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
-- g1sql
-- simple sync style mysqloo driver
-- designed to use in coroutines, fk callbacks
-- support prepared statements, transactions, sqlite sql.Query* style
assert(util.IsBinaryModuleInstalled("mysqloo"), "mysqloo modules isnt installed! get it from https://github.com/FredyH/MySQLOO")
require("mysqloo")
local db = {}
function db:IsConnected()
if not self.conn then return false end
return self.conn:status() == mysqloo.DATABASE_CONNECTED
end
function db:Connect(creds)
local co = coroutine.running()
self.conn = mysqloo.connect(
creds.host,
creds.user,
creds.pw,
creds.db,
creds.port or 3306
)
self.conn.onConnected = function()
if self.OnConnected then self:OnConnected() end
if co then coroutine.resume(co, true) end
end
self.conn.onConnectionFailed = function()
if self.OnConnectionFailed then self:OnConnectionFailed() end
if co then coroutine.resume(co, false) end
end
self.conn:connect()
if co then
return coroutine.yield()
end
end
-----
local type2setter = setmetatable({
string = "setString",
number = "setNumber",
boolean = "setBoolean"
}, {
__index = function() return "setNull" end
})
local function MakeSMT(conn, query, params)
local method = conn[params and "prepare" or "query"]
local smt = method(conn, query)
if params then
for i, arg in ipairs(params) do
local setter = smt[
type2setter[type(arg)]
]
setter(smt, i, arg)
end
end
return smt
end
-----
function db._Query(conn, query, params)
local co = coroutine.running()
local smt = MakeSMT(conn, query, params)
smt.onSuccess = co and function(this, rows)
coroutine.resume(co, rows, this:lastInsert(), this)
end
smt.onError = function(_, reason, sql)
ErrorNoHaltWithStack(string.format("mysqloo:Query Error!\nreason: %s\nquery: %s\n", reason, sql))
if co then coroutine.resume(co, false, reason) end
end
smt:start()
if co then
return coroutine.yield()
end
end
function db:Query(query, params)
return self._Query(self.conn, query, params)
end
-----
function db._QueryRow(conn, query, params, row)
local rows = db._Query(conn, query, params)
return rows[row or 1]
end
function db:QueryRow(query, params, row)
return self:_QueryRow(self.conn, query, params, row)
end
-----
function db._QueryValue(conn, query, params)
local row = db._QueryRow(conn, query, params)
return select(2, next(row))
end
function db:QueryValue(query, params)
return self._QueryValue(self.conn, query, params)
end
-----
local Transaction = {}
function Transaction:Push(query, params)
local smt = MakeSMT(self._conn, query, params)
self.transaction:addQuery(smt)
return self
end
function Transaction:Run()
local co = coroutine.running()
self._transaction.onSuccess = co and function()
coroutine.resume(co, true)
end
self._transaction.onError = co and function(_, reason)
ErrorNoHaltWithStack(string.format("transaction Error!\nreason: %s\n", reason))
coroutine.resume(co, false, reason)
end
self._transaction:start()
if co then
return coroutine.yield()
end
end
function db:Transaction()
return setmetatable({
_conn = self.conn,
_transaction = self.conn:createTransaction()
}, {__index = Transaction})
end
return function(creds)
local _db = setmetatable({}, {__index = db})
if creds then _db:Connect(creds)
return _db
end