Comparison

util/sql.lua @ 8073:7361412a9664

SQL: Use standard quotes for columns and other identifiers, rewrite to grave accents for MySQL only (fixes #885)
author Kim Alvefur <zash@zash.se>
date Mon, 10 Apr 2017 23:13:39 +0200
parent 7513:8a6c7c4b15fb
child 8076:6e0defa19ab9
comparison
equal deleted inserted replaced
8072:194409dcba22 8073:7361412a9664
126 function engine:onconnect() 126 function engine:onconnect()
127 -- Override from create_engine() 127 -- Override from create_engine()
128 end 128 end
129 129
130 function engine:prepquery(sql) 130 function engine:prepquery(sql)
131 if self.params.driver == "PostgreSQL" then 131 if self.params.driver == "MySQL" then
132 sql = sql:gsub("`", "\""); 132 sql = sql:gsub("\"", "`");
133 end 133 end
134 return sql; 134 return sql;
135 end 135 end
136 136
137 function engine:execute(sql, ...) 137 function engine:execute(sql, ...)
240 end 240 end
241 end 241 end
242 return ok, ret; 242 return ok, ret;
243 end 243 end
244 function engine:_create_index(index) 244 function engine:_create_index(index)
245 local sql = "CREATE INDEX `"..index.name.."` ON `"..index.table.."` ("; 245 local sql = "CREATE INDEX \""..index.name.."\" ON \""..index.table.."\" (";
246 for i=1,#index do 246 for i=1,#index do
247 sql = sql.."`"..index[i].."`"; 247 sql = sql.."\""..index[i].."\"";
248 if i ~= #index then sql = sql..", "; end 248 if i ~= #index then sql = sql..", "; end
249 end 249 end
250 sql = sql..");" 250 sql = sql..");"
251 if self.params.driver == "PostgreSQL" then 251 if self.params.driver == "MySQL" then
252 sql = sql:gsub("`", "\""); 252 sql = sql:gsub("\"([,)])", "\"(20)%1");
253 elseif self.params.driver == "MySQL" then
254 sql = sql:gsub("`([,)])", "`(20)%1");
255 end 253 end
256 if index.unique then 254 if index.unique then
257 sql = sql:gsub("^CREATE", "CREATE UNIQUE"); 255 sql = sql:gsub("^CREATE", "CREATE UNIQUE");
258 end 256 end
257 sql = self:prepquery(sql);
259 if self._debug then 258 if self._debug then
260 debugquery("create", sql); 259 debugquery("create", sql);
261 end 260 end
262 return self:execute(sql); 261 return self:execute(sql);
263 end 262 end
264 function engine:_create_table(table) 263 function engine:_create_table(table)
265 local sql = "CREATE TABLE `"..table.name.."` ("; 264 local sql = "CREATE TABLE \""..table.name.."\" (";
266 for i,col in ipairs(table.c) do 265 for i,col in ipairs(table.c) do
267 local col_type = col.type; 266 local col_type = col.type;
268 if col_type == "MEDIUMTEXT" and self.params.driver ~= "MySQL" then 267 if col_type == "MEDIUMTEXT" and self.params.driver ~= "MySQL" then
269 col_type = "TEXT"; -- MEDIUMTEXT is MySQL-specific 268 col_type = "TEXT"; -- MEDIUMTEXT is MySQL-specific
270 end 269 end
271 if col.auto_increment == true and self.params.driver == "PostgreSQL" then 270 if col.auto_increment == true and self.params.driver == "PostgreSQL" then
272 col_type = "BIGSERIAL"; 271 col_type = "BIGSERIAL";
273 end 272 end
274 sql = sql.."`"..col.name.."` "..col_type; 273 sql = sql.."\""..col.name.."\" "..col_type;
275 if col.nullable == false then sql = sql.." NOT NULL"; end 274 if col.nullable == false then sql = sql.." NOT NULL"; end
276 if col.primary_key == true then sql = sql.." PRIMARY KEY"; end 275 if col.primary_key == true then sql = sql.." PRIMARY KEY"; end
277 if col.auto_increment == true then 276 if col.auto_increment == true then
278 if self.params.driver == "MySQL" then 277 if self.params.driver == "MySQL" then
279 sql = sql.." AUTO_INCREMENT"; 278 sql = sql.." AUTO_INCREMENT";
282 end 281 end
283 end 282 end
284 if i ~= #table.c then sql = sql..", "; end 283 if i ~= #table.c then sql = sql..", "; end
285 end 284 end
286 sql = sql.. ");" 285 sql = sql.. ");"
287 if self.params.driver == "PostgreSQL" then 286 if self.params.driver == "MySQL" then
288 sql = sql:gsub("`", "\"");
289 elseif self.params.driver == "MySQL" then
290 sql = sql:gsub(";$", (" CHARACTER SET '%s' COLLATE '%s_bin';"):format(self.charset, self.charset)); 287 sql = sql:gsub(";$", (" CHARACTER SET '%s' COLLATE '%s_bin';"):format(self.charset, self.charset));
291 end 288 end
289 sql = self:prepquery(sql);
292 if self._debug then 290 if self._debug then
293 debugquery("create", sql); 291 debugquery("create", sql);
294 end 292 end
295 local success,err = self:execute(sql); 293 local success,err = self:execute(sql);
296 if not success then return success,err; end 294 if not success then return success,err; end
314 end 312 end
315 local set_names_query = "SET NAMES '%s';" 313 local set_names_query = "SET NAMES '%s';"
316 local charset = "utf8"; 314 local charset = "utf8";
317 if driver == "MySQL" then 315 if driver == "MySQL" then
318 self:transaction(function() 316 self:transaction(function()
319 for row in self:select"SELECT `CHARACTER_SET_NAME` FROM `information_schema`.`CHARACTER_SETS` WHERE `CHARACTER_SET_NAME` LIKE 'utf8%' ORDER BY MAXLEN DESC LIMIT 1;" do 317 for row in self:select"SELECT \"CHARACTER_SET_NAME\" FROM \"information_schema\".\"CHARACTER_SETS\" WHERE \"CHARACTER_SET_NAME\" LIKE 'utf8%' ORDER BY MAXLEN DESC LIMIT 1;" do
320 charset = row and row[1] or charset; 318 charset = row and row[1] or charset;
321 end 319 end
322 end); 320 end);
323 set_names_query = set_names_query:gsub(";$", (" COLLATE '%s';"):format(charset.."_bin")); 321 set_names_query = set_names_query:gsub(";$", (" COLLATE '%s';"):format(charset.."_bin"));
324 end 322 end