comparison util/sql.lua @ 11200:bf8f2da84007

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Thu, 05 Nov 2020 22:31:25 +0100
parents 8a42fd6702e6
children a20923f7d5fd
comparison
equal deleted inserted replaced
11199:6c7c50a4de32 11200:bf8f2da84007
199 if not self.conn then 199 if not self.conn then
200 local ok, err = self:connect(); 200 local ok, err = self:connect();
201 if not ok then return ok, err; end 201 if not ok then return ok, err; end
202 end 202 end
203 --assert(not self.__transaction, "Recursive transactions not allowed"); 203 --assert(not self.__transaction, "Recursive transactions not allowed");
204 log("debug", "SQL transaction begin [%s]", tostring(func)); 204 log("debug", "SQL transaction begin [%s]", func);
205 self.__transaction = true; 205 self.__transaction = true;
206 local success, a, b, c = xpcall(func, handleerr, ...); 206 local success, a, b, c = xpcall(func, handleerr, ...);
207 self.__transaction = nil; 207 self.__transaction = nil;
208 if success then 208 if success then
209 log("debug", "SQL transaction success [%s]", tostring(func)); 209 log("debug", "SQL transaction success [%s]", func);
210 local ok, err = self.conn:commit(); 210 local ok, err = self.conn:commit();
211 -- LuaDBI doesn't actually return an error message here, just a boolean 211 -- LuaDBI doesn't actually return an error message here, just a boolean
212 if not ok then return ok, err or "commit failed"; end 212 if not ok then return ok, err or "commit failed"; end
213 return success, a, b, c; 213 return success, a, b, c;
214 else 214 else
215 log("debug", "SQL transaction failure [%s]: %s", tostring(func), a.err); 215 log("debug", "SQL transaction failure [%s]: %s", func, a.err);
216 if self.conn then self.conn:rollback(); end 216 if self.conn then self.conn:rollback(); end
217 return success, a.err; 217 return success, a.err;
218 end 218 end
219 end 219 end
220 function engine:transaction(...) 220 function engine:transaction(...)
221 local ok, ret = self:_transaction(...); 221 local ok, ret, b, c = self:_transaction(...);
222 if not ok then 222 if not ok then
223 local conn = self.conn; 223 local conn = self.conn;
224 if not conn or not conn:ping() then 224 if not conn or not conn:ping() then
225 log("debug", "Database connection was closed. Will reconnect and retry."); 225 log("debug", "Database connection was closed. Will reconnect and retry.");
226 self.conn = nil; 226 self.conn = nil;
227 log("debug", "Retrying SQL transaction [%s]", tostring((...))); 227 log("debug", "Retrying SQL transaction [%s]", (...));
228 ok, ret = self:_transaction(...); 228 ok, ret, b, c = self:_transaction(...);
229 log("debug", "SQL transaction retry %s", ok and "succeeded" or "failed"); 229 log("debug", "SQL transaction retry %s", ok and "succeeded" or "failed");
230 else 230 else
231 log("debug", "SQL connection is up, so not retrying"); 231 log("debug", "SQL connection is up, so not retrying");
232 end 232 end
233 if not ok then 233 if not ok then
234 log("error", "Error in SQL transaction: %s", ret); 234 log("error", "Error in SQL transaction: %s", ret);
235 end 235 end
236 end 236 end
237 return ok, ret; 237 return ok, ret, b, c;
238 end 238 end
239 function engine:_create_index(index) 239 function engine:_create_index(index)
240 local sql = "CREATE INDEX \""..index.name.."\" ON \""..index.table.."\" ("; 240 local sql = "CREATE INDEX \""..index.name.."\" ON \""..index.table.."\" (";
241 if self.params.driver ~= "MySQL" then 241 if self.params.driver ~= "MySQL" then
242 sql = sql:gsub("^CREATE INDEX", "%1 IF NOT EXISTS"); 242 sql = sql:gsub("^CREATE INDEX", "%1 IF NOT EXISTS");
333 333
334 if driver == "MySQL" then 334 if driver == "MySQL" then
335 local ok, actual_charset = self:transaction(function () 335 local ok, actual_charset = self:transaction(function ()
336 return self:select"SHOW SESSION VARIABLES LIKE 'character_set_client'"; 336 return self:select"SHOW SESSION VARIABLES LIKE 'character_set_client'";
337 end); 337 end);
338 if not ok then
339 return false, "Failed to detect connection encoding";
340 end
338 local charset_ok = true; 341 local charset_ok = true;
339 for row in actual_charset do 342 for row in actual_charset do
340 if row[2] ~= charset then 343 if row[2] ~= charset then
341 log("error", "MySQL %s is actually %q (expected %q)", row[1], row[2], charset); 344 log("error", "MySQL %s is actually %q (expected %q)", row[1], row[2], charset);
342 charset_ok = false; 345 charset_ok = false;