Mercurial > prosody-hg
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 |
| parents | 8a6c7c4b15fb |
| children | 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 |
