mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Modify identifier quoting logic:
- Move QuoteIdent() and DeQuoteIdent() out of TMySQLConnection, make them classless - Remove TMainForm.mask(), instead always use QuoteIdent() - Introduce a third parameter to QuoteIdent(): "AlwaysQuote" - setting this to false will quote only if required - Set AlwaysQuote to false for all stuff which drops some code into the query editor, see http://www.heidisql.com/forum.php?t=6986
This commit is contained in:
@ -355,3 +355,5 @@ const
|
||||
HELPERNODE_SNIPPETS = 3;
|
||||
HELPERNODE_PROFILE = 4;
|
||||
|
||||
// A set of characters which need not to be quoted
|
||||
IDENTCHARS = ['A'..'z', '0'..'9'];
|
||||
|
@ -355,8 +355,8 @@ var
|
||||
DoData: Boolean;
|
||||
begin
|
||||
// Compose and run CREATE query
|
||||
TargetTable := Mainform.mask(comboDatabase.Text)+'.'+Mainform.mask(editNewTablename.Text);
|
||||
TableExistance := MainForm.ActiveConnection.GetVar('SHOW TABLES FROM '+MainForm.mask(comboDatabase.Text)+' LIKE '+esc(editNewTablename.Text));
|
||||
TargetTable := QuoteIdent(comboDatabase.Text)+'.'+QuoteIdent(editNewTablename.Text);
|
||||
TableExistance := MainForm.ActiveConnection.GetVar('SHOW TABLES FROM '+QuoteIdent(comboDatabase.Text)+' LIKE '+esc(editNewTablename.Text));
|
||||
if TableExistance <> '' then begin
|
||||
if MessageDlg('Target table exists. Drop it and overwrite?', mtConfirmation, [mbYes, mbCancel], 0) = mrCancel then begin
|
||||
ModalResult := mrNone;
|
||||
@ -377,7 +377,7 @@ begin
|
||||
case ParentNode.Index of
|
||||
nColumns: begin
|
||||
Clause := FColumns[Node.Index].SQLCode;
|
||||
DataCols := DataCols + MainForm.mask(FColumns[Node.Index].Name) + ', ';
|
||||
DataCols := DataCols + QuoteIdent(FColumns[Node.Index].Name) + ', ';
|
||||
end;
|
||||
nKeys: Clause := FKeys[Node.Index].SQLCode;
|
||||
nForeignkeys: Clause := FForeignKeys[Node.Index].SQLCode(False);
|
||||
@ -414,7 +414,7 @@ begin
|
||||
if DoData and (DataCols <> '') then begin
|
||||
DataCols := Trim(DataCols);
|
||||
Delete(DataCols, Length(DataCols), 1);
|
||||
InsertCode := 'INSERT INTO '+TargetTable+' ('+DataCols+') SELECT ' + DataCols + ' FROM ' + MainForm.mask(FDBObj.Name);
|
||||
InsertCode := 'INSERT INTO '+TargetTable+' ('+DataCols+') SELECT ' + DataCols + ' FROM ' + QuoteIdent(FDBObj.Name);
|
||||
if MemoFilter.GetTextLen > 0 then
|
||||
InsertCode := InsertCode + ' WHERE ' + MemoFilter.Text;
|
||||
end;
|
||||
|
@ -98,7 +98,7 @@ begin
|
||||
editDBName.SelectAll;
|
||||
|
||||
// Detect current charset and collation to be able to preselect them in the pulldowns
|
||||
sql_create := MainForm.ActiveConnection.GetVar('SHOW CREATE DATABASE '+Mainform.mask(modifyDB), 1);
|
||||
sql_create := MainForm.ActiveConnection.GetVar('SHOW CREATE DATABASE '+QuoteIdent(modifyDB), 1);
|
||||
currentCharset := Copy( sql_create, pos('CHARACTER SET', sql_create)+14, Length(sql_create));
|
||||
currentCharset := GetFirstWord( currentCharset );
|
||||
if currentCharset <> '' then
|
||||
@ -192,7 +192,7 @@ begin
|
||||
MessageDlg( 'Creating database "'+editDBName.Text+'" failed:'+CRLF+CRLF+E.Message, mtError, [mbOK], 0 );
|
||||
// Keep form open
|
||||
end else try
|
||||
sql := 'ALTER DATABASE ' + Mainform.mask( modifyDB );
|
||||
sql := 'ALTER DATABASE ' + QuoteIdent( modifyDB );
|
||||
if comboCharset.Enabled and (comboCharset.Text <> '') then
|
||||
begin
|
||||
sql := sql + ' CHARACTER SET ' + comboCharset.Text;
|
||||
@ -237,8 +237,8 @@ begin
|
||||
// Move all tables, views and procedures to target db
|
||||
sql := '';
|
||||
for i:=0 to ObjectsInOldDb.Count-1 do begin
|
||||
sql := sql + Mainform.mask(modifyDb)+'.'+Mainform.mask(ObjectsInOldDb[i].Name)+' TO '+
|
||||
Mainform.mask(editDBName.Text)+'.'+Mainform.mask(ObjectsInOldDb[i].Name)+', ';
|
||||
sql := sql + QuoteIdent(modifyDb)+'.'+QuoteIdent(ObjectsInOldDb[i].Name)+' TO '+
|
||||
QuoteIdent(editDBName.Text)+'.'+QuoteIdent(ObjectsInOldDb[i].Name)+', ';
|
||||
end;
|
||||
if sql <> '' then begin
|
||||
Delete(sql, Length(sql)-1, 2);
|
||||
@ -250,7 +250,7 @@ begin
|
||||
// Last check if old db is really empty, before we drop it.
|
||||
ObjectsLeft := MainForm.ActiveConnection.GetDBObjects(modifyDB);
|
||||
if ObjectsLeft.Count = 0 then begin
|
||||
MainForm.ActiveConnection.Query('DROP DATABASE '+Mainform.mask(modifyDB));
|
||||
MainForm.ActiveConnection.Query('DROP DATABASE '+QuoteIdent(modifyDB));
|
||||
MainForm.RefreshTree;
|
||||
end;
|
||||
end;
|
||||
@ -292,7 +292,7 @@ end;
|
||||
}
|
||||
function TCreateDatabaseForm.GetCreateStatement: String;
|
||||
begin
|
||||
Result := 'CREATE DATABASE ' + Mainform.mask( editDBName.Text );
|
||||
Result := 'CREATE DATABASE ' + QuoteIdent( editDBName.Text );
|
||||
if comboCharset.Enabled and (comboCharset.Text <> '') then
|
||||
begin
|
||||
Result := Result + ' /*!40100 CHARACTER SET ' + comboCharset.Text;
|
||||
|
@ -244,13 +244,13 @@ end;
|
||||
|
||||
function TfrmEventEditor.ComposeCreateStatement: String;
|
||||
begin
|
||||
Result := 'CREATE EVENT ' + Mainform.mask(editName.Text) + ' ' + ComposeBaseStatement;
|
||||
Result := 'CREATE EVENT ' + QuoteIdent(editName.Text) + ' ' + ComposeBaseStatement;
|
||||
end;
|
||||
|
||||
|
||||
function TfrmEventEditor.ComposeAlterStatement: String;
|
||||
begin
|
||||
Result := 'ALTER EVENT ' + Mainform.mask(DBObject.Name) + ' ' + ComposeBaseStatement;
|
||||
Result := 'ALTER EVENT ' + QuoteIdent(DBObject.Name) + ' ' + ComposeBaseStatement;
|
||||
end;
|
||||
|
||||
|
||||
@ -289,7 +289,7 @@ begin
|
||||
else
|
||||
Result := Result + #9 + 'ON COMPLETION PRESERVE';
|
||||
if (DBObject.Name <> '') and (DBObject.Name <> editName.Text) then
|
||||
Result := Result + CRLF + #9 + 'RENAME TO ' + MainForm.mask(editName.Text);
|
||||
Result := Result + CRLF + #9 + 'RENAME TO ' + QuoteIdent(editName.Text);
|
||||
Result := Result + CRLF + #9 + UpperCase(grpState.Items[grpState.ItemIndex]);
|
||||
Result := Result + CRLF + #9 + 'COMMENT ' + esc(editComment.Text);
|
||||
Result := Result + CRLF + #9 + 'DO ' + SynMemoBody.Text;
|
||||
|
@ -590,10 +590,10 @@ begin
|
||||
efXML: tmp := #9'<row>' + CRLF;
|
||||
|
||||
efSQL: begin
|
||||
tmp := 'INSERT INTO '+Mainform.Mask(Tablename)+' (';
|
||||
tmp := 'INSERT INTO '+QuoteIdent(Tablename)+' (';
|
||||
Col := Grid.Header.Columns.GetFirstVisibleColumn;
|
||||
while Col > NoColumn do begin
|
||||
tmp := tmp + Mainform.mask(Grid.Header.Columns[Col].Text)+', ';
|
||||
tmp := tmp + QuoteIdent(Grid.Header.Columns[Col].Text)+', ';
|
||||
Col := Grid.Header.Columns.GetNextVisibleColumn(Col);
|
||||
end;
|
||||
Delete(tmp, Length(tmp)-1, 2);
|
||||
@ -1875,7 +1875,7 @@ begin
|
||||
sort := TXT_ASC
|
||||
else
|
||||
sort := TXT_DESC;
|
||||
result := result + Mainform.Mask( Cols[i].ColumnName ) + ' ' + sort;
|
||||
result := result + QuoteIdent( Cols[i].ColumnName ) + ' ' + sort;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2276,7 +2276,7 @@ end;
|
||||
function TDBObjectEditor.GetDefiners: TStringList;
|
||||
function q(s: String): String;
|
||||
begin
|
||||
Result := DBObject.Connection.QuoteIdent(s);
|
||||
Result := QuoteIdent(s);
|
||||
end;
|
||||
begin
|
||||
// For populating combobox items
|
||||
|
@ -112,7 +112,7 @@ var
|
||||
begin
|
||||
setlength(cols, 0);
|
||||
if ComboBoxTables.ItemIndex > -1 then begin
|
||||
Results := MainForm.ActiveConnection.GetResults('SHOW FIELDS FROM '+mainform.mask(ComboBoxDBs.Text)+'.'+mainform.mask(ComboBoxTables.Text));
|
||||
Results := MainForm.ActiveConnection.GetResults('SHOW FIELDS FROM '+QuoteIdent(ComboBoxDBs.Text)+'.'+QuoteIdent(ComboBoxTables.Text));
|
||||
while not Results.Eof do begin
|
||||
setlength(cols, length(cols)+1);
|
||||
cols[length(cols)-1].Name := Results.Col(0);
|
||||
@ -369,12 +369,12 @@ begin
|
||||
ListViewFiles.Selected := ListViewFiles.ItemFocused;
|
||||
ListViewFiles.ItemFocused.MakeVisible(False);
|
||||
ListViewFiles.Repaint;
|
||||
sql := 'INSERT INTO '+mainform.mask(ComboBoxDBs.Text)+'.'+mainform.mask(ComboBoxTables.Text) +
|
||||
' (' + mainform.mask(ComboBoxColumns.Text);
|
||||
sql := 'INSERT INTO '+QuoteIdent(ComboBoxDBs.Text)+'.'+QuoteIdent(ComboBoxTables.Text) +
|
||||
' (' + QuoteIdent(ComboBoxColumns.Text);
|
||||
for j:=0 to length(cols)-1 do begin
|
||||
if cols[j].Name = ComboBoxColumns.Text then
|
||||
Continue;
|
||||
sql := sql + ', ' + mainform.mask(cols[j].Name);
|
||||
sql := sql + ', ' + QuoteIdent(cols[j].Name);
|
||||
end;
|
||||
FileStream := TFileStream.Create( filename, fmShareDenyWrite );
|
||||
try
|
||||
|
@ -158,7 +158,7 @@ begin
|
||||
Charset := MainForm.GetCharsetByEncoding(Encoding);
|
||||
// Detect db charset
|
||||
DefCharset := 'Let server/database decide';
|
||||
dbcreate := MainForm.ActiveConnection.GetVar('SHOW CREATE DATABASE '+Mainform.mask(comboDatabase.Text), 1);
|
||||
dbcreate := MainForm.ActiveConnection.GetVar('SHOW CREATE DATABASE '+QuoteIdent(comboDatabase.Text), 1);
|
||||
rx := TRegExpr.Create;
|
||||
rx.ModifierG := True;
|
||||
rx.Expression := 'CHARACTER SET (\w+)';
|
||||
@ -325,7 +325,7 @@ begin
|
||||
1: SQL := SQL + 'IGNORE ';
|
||||
2: SQL := SQL + 'REPLACE ';
|
||||
end;
|
||||
SQL := SQL + 'INTO TABLE ' + Mainform.Mask(comboDatabase.Text) + '.' + Mainform.Mask(comboTable.Text) + ' ';
|
||||
SQL := SQL + 'INTO TABLE ' + QuoteIdent(comboDatabase.Text) + '.' + QuoteIdent(comboTable.Text) + ' ';
|
||||
|
||||
if comboEncoding.ItemIndex > 0 then begin
|
||||
MainForm.ActiveConnection.CharsetTable.RecNo := comboEncoding.ItemIndex-1;
|
||||
@ -358,10 +358,10 @@ begin
|
||||
if chklistColumns.Checked[i] then begin
|
||||
if chkLocalNumbers.Checked and (Columns[i].DataType.Category in [dtcInteger, dtcReal]) then begin
|
||||
SQL := SQL + '@ColVar' + IntToStr(i) + ', ';
|
||||
SetColVars := SetColVars + Mainform.Mask(chklistColumns.Items[i]) +
|
||||
SetColVars := SetColVars + QuoteIdent(chklistColumns.Items[i]) +
|
||||
' = REPLACE(REPLACE(@ColVar' + IntToStr(i) + ', '+esc(ThousandSeparator)+', ''''), '+esc(DecimalSeparator)+', ''.''), ';
|
||||
end else
|
||||
SQL := SQL + Mainform.Mask(chklistColumns.Items[i]) + ', ';
|
||||
SQL := SQL + QuoteIdent(chklistColumns.Items[i]) + ', ';
|
||||
end;
|
||||
end;
|
||||
SetLength(SQL, Length(SQL)-2);
|
||||
@ -434,10 +434,10 @@ const
|
||||
1: SQL := 'INSERT '+LowPrio+'IGNORE ';
|
||||
2: SQL := 'REPLACE '+LowPrio;
|
||||
end;
|
||||
SQL := SQL + 'INTO '+MainForm.mask(comboDatabase.Text)+'.'+MainForm.mask(comboTable.Text)+' (';
|
||||
SQL := SQL + 'INTO '+QuoteIdent(comboDatabase.Text)+'.'+QuoteIdent(comboTable.Text)+' (';
|
||||
for i:=0 to chkListColumns.Items.Count-1 do begin
|
||||
if chkListColumns.Checked[i] then
|
||||
SQL := SQL + MainForm.mask(chkListColumns.Items[i]) + ', ';
|
||||
SQL := SQL + QuoteIdent(chkListColumns.Items[i]) + ', ';
|
||||
end;
|
||||
SetLength(SQL, Length(SQL)-2);
|
||||
SQL := SQL + ') VALUES (';
|
||||
|
@ -528,7 +528,6 @@ type
|
||||
procedure actPrintListExecute(Sender: TObject);
|
||||
procedure actCopyTableExecute(Sender: TObject);
|
||||
procedure ShowStatusMsg(Msg: String=''; PanelNr: Integer=6);
|
||||
function mask(str: String; Glue: Char=#0) : String;
|
||||
procedure actExecuteQueryExecute(Sender: TObject);
|
||||
procedure actCreateDatabaseExecute(Sender: TObject);
|
||||
procedure actDataCancelChangesExecute(Sender: TObject);
|
||||
@ -2104,13 +2103,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
// Escape database, table, field, index or key name.
|
||||
function TMainform.mask(str: String; Glue: Char=#0) : String;
|
||||
begin
|
||||
result := ActiveConnection.QuoteIdent(str, Glue);
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.actExportSettingsExecute(Sender: TObject);
|
||||
begin
|
||||
// Export settings to .reg-file
|
||||
@ -2625,7 +2617,7 @@ begin
|
||||
db := Conn.Database;
|
||||
Node := FindDBNode(DBtree, db);
|
||||
SetActiveDatabase('', Conn);
|
||||
Conn.Query('DROP DATABASE ' + mask(db));
|
||||
Conn.Query('DROP DATABASE ' + QuoteIdent(db));
|
||||
DBtree.DeleteNode(Node);
|
||||
Conn.ClearDbObjects(db);
|
||||
except
|
||||
@ -2667,7 +2659,7 @@ begin
|
||||
// Compose and run DROP [TABLE|VIEW|...] queries
|
||||
Editor := ActiveObjectEditor;
|
||||
for DBObject in ObjectList do begin
|
||||
Conn.Query('DROP '+UpperCase(DBObject.ObjType)+' '+Mask(DBObject.Name));
|
||||
Conn.Query('DROP '+UpperCase(DBObject.ObjType)+' '+QuoteIdent(DBObject.Name));
|
||||
if Assigned(Editor) and Editor.Modified and Editor.DBObject.IsSameAs(DBObject) then
|
||||
Editor.Modified := False;
|
||||
end;
|
||||
@ -2962,7 +2954,7 @@ begin
|
||||
EnableProgressBar(Objects.Count);
|
||||
try
|
||||
for TableOrView in Objects do begin
|
||||
ActiveConnection.Query('TRUNCATE ' + mask(TableOrView.Name));
|
||||
ActiveConnection.Query('TRUNCATE ' + QuoteIdent(TableOrView.Name));
|
||||
ProgressBarStatus.StepIt;
|
||||
end;
|
||||
actRefresh.Execute;
|
||||
@ -3018,7 +3010,7 @@ begin
|
||||
end;
|
||||
Parameters := TRoutineParamList.Create;
|
||||
Obj.Connection.ParseRoutineStructure(Obj.CreateCode, Parameters, DummyBool, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr);
|
||||
Query := Query + mask(Obj.Name);
|
||||
Query := Query + QuoteIdent(Obj.Name);
|
||||
ParamInput := '';
|
||||
for i:=0 to Parameters.Count-1 do begin
|
||||
if ParamInput <> '' then
|
||||
@ -3925,9 +3917,9 @@ begin
|
||||
and (not IsKeyColumn) // We need full length of any key column, so DataGridLoadFullRow() has the chance to fetch the right row
|
||||
and ((ColLen > GRIDMAXDATA) or (ColLen = 0)) // No need to blow SQL with LEFT() if column is shorter anyway
|
||||
then
|
||||
Select := Select + ' LEFT(' + Mask(c.Name) + ', ' + IntToStr(GRIDMAXDATA) + '), '
|
||||
Select := Select + ' LEFT(' + QuoteIdent(c.Name) + ', ' + IntToStr(GRIDMAXDATA) + '), '
|
||||
else
|
||||
Select := Select + ' ' + Mask(c.Name) + ', ';
|
||||
Select := Select + ' ' + QuoteIdent(c.Name) + ', ';
|
||||
WantedColumns.Add(c);
|
||||
WantedColumnOrgnames.Add(c.Name);
|
||||
end;
|
||||
@ -3935,7 +3927,7 @@ begin
|
||||
// Cut last comma
|
||||
Delete(Select, Length(Select)-1, 2);
|
||||
// Include db name for cases in which dbtree is switching databases and pending updates are in process
|
||||
Select := Select + ' FROM '+mask(ActiveDatabase)+'.'+mask(ActiveDbObj.Name);
|
||||
Select := Select + ' FROM '+QuoteIdent(ActiveDatabase)+'.'+QuoteIdent(ActiveDbObj.Name);
|
||||
|
||||
// Signal for the user if we hide some columns
|
||||
if WantedColumns.Count = SelectedTableColumns.Count then
|
||||
@ -4500,7 +4492,7 @@ var
|
||||
dbname := Copy( tablename, 0, Pos( '.', tablename )-1 );
|
||||
tablename := Copy( tablename, Pos( '.', tablename )+1, Length(tablename) );
|
||||
end;
|
||||
// Do not mask db and table name to avoid double masking.
|
||||
// Do not quote db and table name to avoid double masking.
|
||||
// Rely on what the user typed is already a valid masked/quoted identifier.
|
||||
if dbname <> '' then
|
||||
tablename := dbname + '.' + tablename;
|
||||
@ -4783,7 +4775,7 @@ begin
|
||||
// Try to rename, on any error abort and don't rename ListItem
|
||||
try
|
||||
// rename table
|
||||
ActiveConnection.Query('RENAME TABLE ' + mask(Obj.Name) + ' TO ' + mask(NewText));
|
||||
ActiveConnection.Query('RENAME TABLE ' + QuoteIdent(Obj.Name) + ' TO ' + QuoteIdent(NewText));
|
||||
|
||||
if SynSQLSyn1.TableNames.IndexOf( NewText ) = -1 then begin
|
||||
SynSQLSyn1.TableNames.Add(NewText);
|
||||
@ -4853,15 +4845,15 @@ begin
|
||||
if Val = 'Value' then
|
||||
Filter := ''
|
||||
else if Item = QF8 then
|
||||
Filter := mask(Col) + ' = ''' + Val + ''''
|
||||
Filter := QuoteIdent(Col) + ' = ''' + Val + ''''
|
||||
else if Item = QF9 then
|
||||
Filter := mask(Col) + ' != ''' + Val + ''''
|
||||
Filter := QuoteIdent(Col) + ' != ''' + Val + ''''
|
||||
else if Item = QF10 then
|
||||
Filter := mask(Col) + ' > ''' + Val + ''''
|
||||
Filter := QuoteIdent(Col) + ' > ''' + Val + ''''
|
||||
else if Item = QF11 then
|
||||
Filter := mask(Col) + ' < ''' + Val + ''''
|
||||
Filter := QuoteIdent(Col) + ' < ''' + Val + ''''
|
||||
else if Item = QF12 then
|
||||
Filter := mask(Col) + ' LIKE ''%' + Val + '%''';
|
||||
Filter := QuoteIdent(Col) + ' LIKE ''%' + Val + '%''';
|
||||
end else
|
||||
Filter := Item.Hint;
|
||||
|
||||
@ -4949,11 +4941,11 @@ begin
|
||||
if src = DBtree then begin
|
||||
// Insert table or database name. If a table is dropped and Shift is pressed, prepend the db name.
|
||||
case ActiveDbObj.NodeType of
|
||||
lntDb: Text := mask(ActiveDbObj.Database);
|
||||
lntDb: Text := QuoteIdent(ActiveDbObj.Database, False);
|
||||
lntTable..lntEvent: begin
|
||||
if ShiftPressed then
|
||||
Text := mask(ActiveDbObj.Database) + '.';
|
||||
Text := Text + mask(ActiveDbObj.Name);
|
||||
Text := QuoteIdent(ActiveDbObj.Database, False) + '.';
|
||||
Text := Text + QuoteIdent(ActiveDbObj.Name, False);
|
||||
end;
|
||||
end;
|
||||
end else if src = Tree then begin
|
||||
@ -4967,7 +4959,7 @@ begin
|
||||
if Tree.Selected[Node] then begin
|
||||
ItemText := Tree.Text[Node, 0];
|
||||
if Node.Parent.Index = HELPERNODE_COLUMNS then
|
||||
ItemText := mask(ItemText); // Quote column names
|
||||
ItemText := QuoteIdent(ItemText, False); // Quote column names
|
||||
if ShiftPressed then
|
||||
Text := Text + ItemText + ',' + CRLF
|
||||
else
|
||||
@ -5346,7 +5338,7 @@ begin
|
||||
AnyGridEnsureFullRow(Grid, Grid.FocusedNode);
|
||||
RowNumber := Grid.GetNodeData(Grid.FocusedNode);
|
||||
Results.RecNo := RowNumber^;
|
||||
Col := mask(Results.ColumnOrgNames[Grid.FocusedColumn]);
|
||||
Col := QuoteIdent(Results.ColumnOrgNames[Grid.FocusedColumn]);
|
||||
// 1. block: include selected columnname and value from datagrid in caption
|
||||
if Results.IsNull(Grid.FocusedColumn) then begin
|
||||
QF1.Hint := Col + ' IS NULL';
|
||||
@ -5425,8 +5417,8 @@ begin
|
||||
Exit;
|
||||
Col := DataGridResult.ColumnOrgNames[DataGrid.FocusedColumn];
|
||||
ShowStatusMsg('Fetching distinct values ...');
|
||||
Data := ActiveConnection.GetResults('SELECT '+mask(Col)+', COUNT(*) AS c FROM '+mask(ActiveDbObj.Name)+
|
||||
' GROUP BY '+mask(Col)+' ORDER BY c DESC, '+mask(Col)+' LIMIT 30');
|
||||
Data := ActiveConnection.GetResults('SELECT '+QuoteIdent(Col)+', COUNT(*) AS c FROM '+QuoteIdent(ActiveDbObj.Name)+
|
||||
' GROUP BY '+QuoteIdent(Col)+' ORDER BY c DESC, '+QuoteIdent(Col)+' LIMIT 30');
|
||||
for i:=0 to Data.RecordCount-1 do begin
|
||||
if QFvalues.Count > i then
|
||||
Item := QFvalues[i]
|
||||
@ -5434,7 +5426,7 @@ begin
|
||||
Item := TMenuItem.Create(QFvalues);
|
||||
QFvalues.Add(Item);
|
||||
end;
|
||||
Item.Hint := mask(Col)+'='+esc(Data.Col(Col));
|
||||
Item.Hint := QuoteIdent(Col)+'='+esc(Data.Col(Col));
|
||||
Item.Caption := sstr(Item.Hint, 100) + ' (' + FormatNumber(Data.Col('c')) + ')';
|
||||
Item.OnClick := QuickFilterClick;
|
||||
Data.Next;
|
||||
@ -7011,7 +7003,7 @@ begin
|
||||
for i:=0 to SelectedTableColumns.Count-1 do begin
|
||||
if i > 0 then
|
||||
Clause := Clause + ' OR ';
|
||||
Clause := Clause + mask(SelectedTableColumns[i].Name) + ' LIKE ' + esc('%'+ed.Text+'%');
|
||||
Clause := Clause + QuoteIdent(SelectedTableColumns[i].Name) + ' LIKE ' + esc('%'+ed.Text+'%');
|
||||
end;
|
||||
end;
|
||||
// Add linebreaks at near right window edge
|
||||
@ -7379,7 +7371,7 @@ begin
|
||||
idx := ForeignKey.Columns.IndexOf(DataGrid.Header.Columns[Column].Text);
|
||||
if idx > -1 then begin
|
||||
// Find the first text column if available and use that for displaying in the pulldown instead of using meaningless id numbers
|
||||
CreateTable := ActiveConnection.GetVar('SHOW CREATE TABLE '+Mask(ForeignKey.ReferenceTable, '.'), 1);
|
||||
CreateTable := ActiveConnection.GetVar('SHOW CREATE TABLE '+QuoteIdent(ForeignKey.ReferenceTable, True, '.'), 1);
|
||||
Columns := TTableColumnList.Create;
|
||||
Keys := nil;
|
||||
ForeignKeys := nil;
|
||||
@ -7392,11 +7384,11 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
KeyCol := Mask(ForeignKey.ForeignColumns[idx]);
|
||||
KeyCol := QuoteIdent(ForeignKey.ForeignColumns[idx]);
|
||||
SQL := 'SELECT '+KeyCol;
|
||||
if TextCol <> '' then SQL := SQL + ', LEFT(' + Mask(TextCol) + ', 256)';
|
||||
SQL := SQL + ' FROM '+Mask(ForeignKey.ReferenceTable, '.')+' GROUP BY '+KeyCol+' ORDER BY ';
|
||||
if TextCol <> '' then SQL := SQL + Mask(TextCol) else SQL := SQL + KeyCol;
|
||||
if TextCol <> '' then SQL := SQL + ', LEFT(' + QuoteIdent(TextCol) + ', 256)';
|
||||
SQL := SQL + ' FROM '+QuoteIdent(ForeignKey.ReferenceTable, True, '.')+' GROUP BY '+KeyCol+' ORDER BY ';
|
||||
if TextCol <> '' then SQL := SQL + QuoteIdent(TextCol) else SQL := SQL + KeyCol;
|
||||
SQL := SQL + ' LIMIT 1000';
|
||||
|
||||
ForeignResults := ActiveConnection.GetResults(SQL);
|
||||
@ -7577,7 +7569,7 @@ begin
|
||||
DataGridFocusedCell := TStringList.Create;
|
||||
// Remember focused node and column for selected table
|
||||
if Assigned(DataGrid.FocusedNode) then begin
|
||||
KeyName := Mask(DataGridDB)+'.'+Mask(DataGridTable);
|
||||
KeyName := QuoteIdent(DataGridDB)+'.'+QuoteIdent(DataGridTable);
|
||||
FocusedCol := '';
|
||||
if DataGrid.FocusedColumn > NoColumn then
|
||||
FocusedCol := DataGrid.Header.Columns[DataGrid.FocusedColumn].Text;
|
||||
@ -7585,7 +7577,7 @@ begin
|
||||
end;
|
||||
DataGridFocusedNodeIndex := 0;
|
||||
DataGridFocusedColumnName := '';
|
||||
KeyName := Mask(ActiveDbObj.Database)+'.'+Mask(ActiveDbObj.Name);
|
||||
KeyName := QuoteIdent(ActiveDbObj.Database)+'.'+QuoteIdent(ActiveDbObj.Name);
|
||||
CellFocus := DataGridFocusedCell.Values[KeyName];
|
||||
if CellFocus <> '' then begin
|
||||
DataGridFocusedNodeIndex := MakeInt(Explode(DELIM, CellFocus)[0]);
|
||||
@ -7745,7 +7737,7 @@ begin
|
||||
vt.Clear;
|
||||
try
|
||||
if ActiveConnection.InformationSchemaObjects.IndexOf('SCHEMATA') > -1 then
|
||||
AllDatabasesDetails := ActiveConnection.GetResults('SELECT * FROM '+mask(DBNAME_INFORMATION_SCHEMA)+'.'+mask('SCHEMATA'));
|
||||
AllDatabasesDetails := ActiveConnection.GetResults('SELECT * FROM '+QuoteIdent(DBNAME_INFORMATION_SCHEMA)+'.'+QuoteIdent('SCHEMATA'));
|
||||
except
|
||||
on E:EDatabaseError do
|
||||
LogSQL(E.Message, lcError);
|
||||
@ -8006,9 +7998,9 @@ begin
|
||||
vt.Clear;
|
||||
if ActiveConnection.InformationSchemaObjects.IndexOf('PROCESSLIST') > -1 then begin
|
||||
// Minimize network traffic on newer servers by fetching only first KB of SQL query in "Info" column
|
||||
Results := ActiveConnection.GetResults('SELECT '+mask('ID')+', '+mask('USER')+', '+mask('HOST')+', '+mask('DB')+', '
|
||||
+ mask('COMMAND')+', '+mask('TIME')+', '+mask('STATE')+', LEFT('+mask('INFO')+', '+IntToStr(InfoLen)+') AS '+mask('Info')
|
||||
+ ' FROM '+mask(DBNAME_INFORMATION_SCHEMA)+'.'+mask('PROCESSLIST'));
|
||||
Results := ActiveConnection.GetResults('SELECT '+QuoteIdent('ID')+', '+QuoteIdent('USER')+', '+QuoteIdent('HOST')+', '+QuoteIdent('DB')+', '
|
||||
+ QuoteIdent('COMMAND')+', '+QuoteIdent('TIME')+', '+QuoteIdent('STATE')+', LEFT('+QuoteIdent('INFO')+', '+IntToStr(InfoLen)+') AS '+QuoteIdent('Info')
|
||||
+ ' FROM '+QuoteIdent(DBNAME_INFORMATION_SCHEMA)+'.'+QuoteIdent('PROCESSLIST'));
|
||||
end else begin
|
||||
// Older servers fetch the whole query length, but at least we cut them off below, so a high memory usage is just a peak
|
||||
Results := ActiveConnection.GetResults('SHOW FULL PROCESSLIST');
|
||||
@ -9329,7 +9321,7 @@ begin
|
||||
Node := Tree.GetFirstChild(FindNode(Tree, HELPERNODE_COLUMNS, nil));
|
||||
while Assigned(Node) do begin
|
||||
if Tree.Selected[Node] then begin
|
||||
ColumnNames.Add(mask(Tree.Text[Node, 0]));
|
||||
ColumnNames.Add(QuoteIdent(Tree.Text[Node, 0], False));
|
||||
Column := SelectedTableColumns[Node.Index];
|
||||
case Column.DataType.Category of
|
||||
dtcInteger, dtcReal: Val := '0';
|
||||
@ -9352,21 +9344,21 @@ begin
|
||||
KeyColumns := ActiveConnection.GetKeyColumns(SelectedTableColumns, SelectedTableKeys);
|
||||
WhereClause := '';
|
||||
for i:=0 to KeyColumns.Count-1 do begin
|
||||
idx := ColumnNames.IndexOf(mask(KeyColumns[i]));
|
||||
idx := ColumnNames.IndexOf(QuoteIdent(KeyColumns[i], False));
|
||||
if idx > -1 then begin
|
||||
if WhereClause <> '' then
|
||||
WhereClause := WhereClause + ' AND ';
|
||||
WhereClause := WhereClause + mask(KeyColumns[i])+'='+DefaultValues[idx];
|
||||
WhereClause := WhereClause + QuoteIdent(KeyColumns[i], False)+'='+DefaultValues[idx];
|
||||
end;
|
||||
end;
|
||||
|
||||
if MenuItem = menuQueryHelpersGenerateInsert then begin
|
||||
sql := 'INSERT INTO '+mask(ActiveDbObj.Name)+CRLF+
|
||||
sql := 'INSERT INTO '+QuoteIdent(ActiveDbObj.Name, False)+CRLF+
|
||||
#9'('+ImplodeStr(', ', ColumnNames)+')'+CRLF+
|
||||
#9'VALUES ('+ImplodeStr(', ', DefaultValues)+')';
|
||||
|
||||
end else if MenuItem = menuQueryHelpersGenerateUpdate then begin
|
||||
sql := 'UPDATE '+mask(ActiveDbObj.Name)+CRLF+#9'SET'+CRLF;
|
||||
sql := 'UPDATE '+QuoteIdent(ActiveDbObj.Name, False)+CRLF+#9'SET'+CRLF;
|
||||
if ColumnNames.Count > 0 then begin
|
||||
for i:=0 to ColumnNames.Count-1 do begin
|
||||
sql := sql + #9#9 + ColumnNames[i] + '=' + DefaultValues[i] + ',' + CRLF;
|
||||
@ -9377,7 +9369,7 @@ begin
|
||||
sql := sql + #9'WHERE ' + WhereClause;
|
||||
|
||||
end else if MenuItem = menuQueryHelpersGenerateDelete then begin
|
||||
sql := 'DELETE FROM '+mask(ActiveDbObj.Name)+' WHERE ' + WhereClause;
|
||||
sql := 'DELETE FROM '+QuoteIdent(ActiveDbObj.Name, False)+' WHERE ' + WhereClause;
|
||||
|
||||
end;
|
||||
ActiveQueryMemo.UndoList.AddGroupBreak;
|
||||
@ -9487,7 +9479,7 @@ begin
|
||||
// Click on "Explain" link label, in process viewer
|
||||
actNewQueryTabExecute(Sender);
|
||||
Tab := QueryTabs[QueryTabs.Count-1];
|
||||
Tab.Memo.Text := 'USE '+mask(listProcesses.Text[listProcesses.FocusedNode, 3])+';'+CRLF+
|
||||
Tab.Memo.Text := 'USE '+QuoteIdent(listProcesses.Text[listProcesses.FocusedNode, 3])+';'+CRLF+
|
||||
'EXPLAIN'+CRLF+SynMemoProcessView.Text;
|
||||
Tab.TabSheet.Show;
|
||||
actExecuteQueryExecute(Sender);
|
||||
|
@ -261,8 +261,6 @@ type
|
||||
function EscapeString(Text: String; ProcessJokerChars: Boolean=False): String;
|
||||
function escChars(const Text: String; EscChar, Char1, Char2, Char3, Char4: Char): String;
|
||||
function UnescapeString(Text: String): String;
|
||||
class function QuoteIdent(Identifier: String; Glue: Char=#0): String;
|
||||
function DeQuoteIdent(Identifier: String; Glue: Char=#0): String;
|
||||
function ConvertServerVersion(Version: Integer): String;
|
||||
function GetResults(SQL: String): TMySQLQuery;
|
||||
function GetCol(SQL: String; Column: Integer=0): TStringList;
|
||||
@ -399,6 +397,8 @@ type
|
||||
end;
|
||||
PMySQLQuery = ^TMySQLQuery;
|
||||
|
||||
function QuoteIdent(Identifier: String; AlwaysQuote: Boolean=True; Glue: Char=#0): String;
|
||||
function DeQuoteIdent(Identifier: String; Glue: Char=#0): String;
|
||||
|
||||
implementation
|
||||
|
||||
@ -1047,17 +1047,37 @@ end;
|
||||
Add backticks to identifier
|
||||
Todo: Support ANSI style
|
||||
}
|
||||
class function TMySQLConnection.QuoteIdent(Identifier: String; Glue: Char=#0): String;
|
||||
function QuoteIdent(Identifier: String; AlwaysQuote: Boolean=True; Glue: Char=#0): String;
|
||||
var
|
||||
GluePos, i: Integer;
|
||||
begin
|
||||
Result := Identifier;
|
||||
GluePos := 0;
|
||||
if Glue <> #0 then begin
|
||||
GluePos := Pos(Glue, Result);
|
||||
if GluePos > 0 then
|
||||
Result := QuoteIdent(Copy(Result, 1, GluePos-1)) + Glue + QuoteIdent(Copy(Result, GluePos+1, MaxInt));
|
||||
end;
|
||||
if GluePos = 0 then begin
|
||||
if not AlwaysQuote then begin
|
||||
if MySQLKeywords.IndexOf(Result) > -1 then
|
||||
AlwaysQuote := True
|
||||
else for i:=1 to Length(Result) do begin
|
||||
if not CharInSet(Result[i], IDENTCHARS) then begin
|
||||
AlwaysQuote := True;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if AlwaysQuote then begin
|
||||
Result := StringReplace(Result, '`', '``', [rfReplaceAll]);
|
||||
if Glue <> #0 then
|
||||
Result := StringReplace(Result, Glue, '`'+Glue+'`', [rfReplaceAll]);
|
||||
Result := '`' + Result + '`';
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TMySQLConnection.DeQuoteIdent(Identifier: String; Glue: Char=#0): String;
|
||||
function DeQuoteIdent(Identifier: String; Glue: Char=#0): String;
|
||||
begin
|
||||
Result := Identifier;
|
||||
if (Result[1] = '`') and (Result[Length(Identifier)] = '`') then
|
||||
@ -2509,7 +2529,7 @@ begin
|
||||
for i:=0 to FColumnOrgNames.Count-1 do begin
|
||||
if sql <> '' then
|
||||
sql := sql + ', ';
|
||||
sql := sql + Connection.QuoteIdent(FColumnOrgNames[i]);
|
||||
sql := sql + QuoteIdent(FColumnOrgNames[i]);
|
||||
end;
|
||||
Data := Connection.GetResults('SELECT '+sql+' FROM '+QuotedDbAndTableName+' WHERE '+GetWhereClause+' LIMIT 1');
|
||||
Result := Data.RecordCount = 1;
|
||||
@ -2584,8 +2604,8 @@ begin
|
||||
dtcInteger, dtcReal: Val := Cell.NewText;
|
||||
else Val := Connection.EscapeString(Cell.NewText);
|
||||
end;
|
||||
sqlUpdate := sqlUpdate + Connection.QuoteIdent(FColumnOrgNames[i]) + '=' + Val;
|
||||
sqlInsertColumns := sqlInsertColumns + Connection.QuoteIdent(FColumnOrgNames[i]);
|
||||
sqlUpdate := sqlUpdate + QuoteIdent(FColumnOrgNames[i]) + '=' + Val;
|
||||
sqlInsertColumns := sqlInsertColumns + QuoteIdent(FColumnOrgNames[i]);
|
||||
sqlInsertValues := sqlInsertValues + Val;
|
||||
end;
|
||||
|
||||
@ -2748,8 +2768,8 @@ begin
|
||||
// Return `db`.`table` if necessairy, otherwise `table`
|
||||
db := DatabaseName;
|
||||
if Connection.Database <> db then
|
||||
Result := Connection.QuoteIdent(db)+'.';
|
||||
Result := Result + Connection.QuoteIdent(TableName);
|
||||
Result := QuoteIdent(db)+'.';
|
||||
Result := Result + QuoteIdent(TableName);
|
||||
end;
|
||||
|
||||
|
||||
@ -2805,7 +2825,7 @@ begin
|
||||
raise EDatabaseError.Create('Cannot compose WHERE clause - column missing: '+NeededCols[i]);
|
||||
if Result <> '' then
|
||||
Result := Result + ' AND';
|
||||
Result := Result + ' ' + Connection.QuoteIdent(FColumnOrgNames[j]);
|
||||
Result := Result + ' ' + QuoteIdent(FColumnOrgNames[j]);
|
||||
if Modified(j) then begin
|
||||
ColVal := FCurrentUpdateRow[j].OldText;
|
||||
ColIsNull := FCurrentUpdateRow[j].OldIsNull;
|
||||
@ -2978,7 +2998,7 @@ begin
|
||||
else Exception.Create('Unhandled list node type in '+ClassName+'.GetCreateCode');
|
||||
end;
|
||||
if not FCreateCodeFetched then try
|
||||
FCreateCode := FConnection.GetVar('SHOW CREATE '+UpperCase(ObjType)+' '+FConnection.QuoteIdent(Database)+'.'+FConnection.QuoteIdent(Name), Column)
|
||||
FCreateCode := FConnection.GetVar('SHOW CREATE '+UpperCase(ObjType)+' '+QuoteIdent(Database)+'.'+QuoteIdent(Name), Column)
|
||||
except
|
||||
end;
|
||||
FCreateCodeFetched := True;
|
||||
@ -3017,7 +3037,7 @@ end;
|
||||
|
||||
function TTableColumn.SQLCode: String;
|
||||
begin
|
||||
Result := TMySQLConnection.QuoteIdent(Name) + ' ' +DataType.Name;
|
||||
Result := QuoteIdent(Name) + ' ' +DataType.Name;
|
||||
if LengthSet <> '' then
|
||||
Result := Result + '(' + LengthSet + ')';
|
||||
if (DataType.Category in [dtcInteger, dtcReal]) and Unsigned then
|
||||
@ -3076,11 +3096,11 @@ begin
|
||||
else begin
|
||||
if IndexType <> KEY then
|
||||
Result := Result + IndexType + ' ';
|
||||
Result := Result + 'INDEX ' + TMySQLConnection.QuoteIdent(Name) + ' ';
|
||||
Result := Result + 'INDEX ' + QuoteIdent(Name) + ' ';
|
||||
end;
|
||||
Result := Result + '(';
|
||||
for i:=0 to Columns.Count-1 do begin
|
||||
Result := Result + TMySQLConnection.QuoteIdent(Columns[i]);
|
||||
Result := Result + QuoteIdent(Columns[i]);
|
||||
if SubParts[i] <> '' then
|
||||
Result := Result + '(' + SubParts[i] + ')';
|
||||
Result := Result + ', ';
|
||||
@ -3120,14 +3140,14 @@ begin
|
||||
Result := '';
|
||||
// Symbol names are unique in a db. In order to autocreate a valid name we leave the constraint clause away.
|
||||
if IncludeSymbolName then
|
||||
Result := 'CONSTRAINT '+TMySQLConnection.QuoteIdent(KeyName)+' ';
|
||||
Result := 'CONSTRAINT '+QuoteIdent(KeyName)+' ';
|
||||
Result := Result + 'FOREIGN KEY (';
|
||||
for i:=0 to Columns.Count-1 do
|
||||
Result := Result + TMySQLConnection.QuoteIdent(Columns[i]) + ', ';
|
||||
Result := Result + QuoteIdent(Columns[i]) + ', ';
|
||||
if Columns.Count > 0 then Delete(Result, Length(Result)-1, 2);
|
||||
Result := Result + ') REFERENCES ' + TMySQLConnection.QuoteIdent(ReferenceTable, '.') + ' (';
|
||||
Result := Result + ') REFERENCES ' + QuoteIdent(ReferenceTable, True, '.') + ' (';
|
||||
for i:=0 to ForeignColumns.Count-1 do
|
||||
Result := Result + TMySQLConnection.QuoteIdent(ForeignColumns[i]) + ', ';
|
||||
Result := Result + QuoteIdent(ForeignColumns[i]) + ', ';
|
||||
if ForeignColumns.Count > 0 then Delete(Result, Length(Result)-1, 2);
|
||||
Result := Result + ')';
|
||||
if OnUpdate <> '' then
|
||||
|
@ -440,7 +440,7 @@ begin
|
||||
if DBObject.Name <> '' then begin
|
||||
// Create temp name
|
||||
i := 0;
|
||||
allRoutineNames := MainForm.ActiveConnection.GetCol('SELECT ROUTINE_NAME FROM '+Mainform.mask(DBNAME_INFORMATION_SCHEMA)+'.'+Mainform.mask('ROUTINES')+
|
||||
allRoutineNames := MainForm.ActiveConnection.GetCol('SELECT ROUTINE_NAME FROM '+QuoteIdent(DBNAME_INFORMATION_SCHEMA)+'.'+QuoteIdent('ROUTINES')+
|
||||
' WHERE ROUTINE_SCHEMA = '+esc(Mainform.ActiveDatabase)+
|
||||
' AND ROUTINE_TYPE = '+esc(ProcOrFunc)
|
||||
);
|
||||
@ -460,12 +460,12 @@ begin
|
||||
end;
|
||||
MainForm.ActiveConnection.Query(ComposeCreateStatement(tempName));
|
||||
// Drop temporary routine, used for syntax checking
|
||||
MainForm.ActiveConnection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(TempName));
|
||||
MainForm.ActiveConnection.Query('DROP '+ProcOrFunc+' IF EXISTS '+QuoteIdent(TempName));
|
||||
// Drop edited routine
|
||||
MainForm.ActiveConnection.Query('DROP '+FAlterRoutineType+' IF EXISTS '+Mainform.mask(DBObject.Name));
|
||||
MainForm.ActiveConnection.Query('DROP '+FAlterRoutineType+' IF EXISTS '+QuoteIdent(DBObject.Name));
|
||||
if TargetExists then begin
|
||||
// Drop target routine - overwriting has been confirmed, see above
|
||||
MainForm.ActiveConnection.Query('DROP '+ProcOrFunc+' IF EXISTS '+Mainform.mask(editName.Text));
|
||||
MainForm.ActiveConnection.Query('DROP '+ProcOrFunc+' IF EXISTS '+QuoteIdent(editName.Text));
|
||||
end;
|
||||
end;
|
||||
MainForm.ActiveConnection.Query(ComposeCreateStatement(editName.Text));
|
||||
@ -498,12 +498,12 @@ begin
|
||||
ProcOrFunc := UpperCase(GetFirstWord(comboType.Text));
|
||||
Result := 'CREATE ';
|
||||
if comboDefiner.Text <> '' then
|
||||
Result := Result + 'DEFINER='+DBObject.Connection.QuoteIdent(comboDefiner.Text, '@')+' ';
|
||||
Result := Result + ProcOrFunc+' '+Mainform.mask(NameOfObject)+'(';
|
||||
Result := Result + 'DEFINER='+QuoteIdent(comboDefiner.Text, True, '@')+' ';
|
||||
Result := Result + ProcOrFunc+' '+QuoteIdent(NameOfObject)+'(';
|
||||
for i:=0 to Parameters.Count-1 do begin
|
||||
if ProcOrFunc = 'PROCEDURE' then
|
||||
Result := Result + Parameters[i].Context + ' ';
|
||||
Result := Result + Mainform.Mask(Parameters[i].Name) + ' ' + Parameters[i].Datatype;
|
||||
Result := Result + QuoteIdent(Parameters[i].Name) + ' ' + Parameters[i].Datatype;
|
||||
if i < Parameters.Count-1 then
|
||||
Result := Result + ', ';
|
||||
end;
|
||||
|
@ -379,12 +379,12 @@ begin
|
||||
// ALTER TABLE statement. Separate statements are required."
|
||||
for i:=0 to FForeignKeys.Count-1 do begin
|
||||
if FForeignKeys[i].Modified and (not FForeignKeys[i].Added) then
|
||||
Specs.Add('DROP FOREIGN KEY '+Mainform.mask(FForeignKeys[i].OldKeyName));
|
||||
Specs.Add('DROP FOREIGN KEY '+QuoteIdent(FForeignKeys[i].OldKeyName));
|
||||
end;
|
||||
end;
|
||||
try
|
||||
if Specs.Count > 0 then
|
||||
MainForm.ActiveConnection.Query('ALTER TABLE '+Mainform.mask(DBObject.Name)+' '+ImplodeStr(', ', Specs));
|
||||
MainForm.ActiveConnection.Query('ALTER TABLE '+QuoteIdent(DBObject.Name)+' '+ImplodeStr(', ', Specs));
|
||||
MainForm.ActiveConnection.Query(sql);
|
||||
tabALTERcode.TabVisible := DBObject.Name <> '';
|
||||
if chkCharsetConvert.Checked then begin
|
||||
@ -467,7 +467,7 @@ begin
|
||||
Screen.Cursor := crHourglass;
|
||||
Specs := TStringList.Create;
|
||||
if editName.Text <> DBObject.Name then
|
||||
Specs.Add('RENAME TO ' + Mainform.mask(editName.Text));
|
||||
Specs.Add('RENAME TO ' + QuoteIdent(editName.Text));
|
||||
if memoComment.Tag = ModifiedFlag then
|
||||
Specs.Add('COMMENT=' + esc(memoComment.Text));
|
||||
if (comboCollation.Tag = ModifiedFlag) or (chkCharsetConvert.Checked) then
|
||||
@ -511,7 +511,7 @@ begin
|
||||
Mainform.ProgressBarStatus.StepIt;
|
||||
Col := listColumns.GetNodeData(Node);
|
||||
if Col.Status <> esUntouched then begin
|
||||
ColSpec := Mainform.mask(Col.Name);
|
||||
ColSpec := QuoteIdent(Col.Name);
|
||||
ColSpec := ColSpec + ' ' + Col.DataType.Name;
|
||||
if Col.LengthSet <> '' then
|
||||
ColSpec := ColSpec + '(' + Col.LengthSet + ')';
|
||||
@ -540,10 +540,10 @@ begin
|
||||
if PreviousCol = nil then
|
||||
ColSpec := ColSpec + ' FIRST'
|
||||
else
|
||||
ColSpec := ColSpec + ' AFTER '+Mainform.mask(PreviousCol.Name);
|
||||
ColSpec := ColSpec + ' AFTER '+QuoteIdent(PreviousCol.Name);
|
||||
end;
|
||||
if Col.Status = esModified then
|
||||
Specs.Add('CHANGE COLUMN '+Mainform.mask(Col.OldName) + ' ' + ColSpec)
|
||||
Specs.Add('CHANGE COLUMN '+QuoteIdent(Col.OldName) + ' ' + ColSpec)
|
||||
else if Col.Status in [esAddedUntouched, esAddedModified] then
|
||||
Specs.Add('ADD COLUMN ' + ColSpec);
|
||||
end;
|
||||
@ -554,7 +554,7 @@ begin
|
||||
// Deleted columns, not available as Node in above loop
|
||||
for i:=0 to FColumns.Count-1 do begin
|
||||
if FColumns[i].Status = esDeleted then
|
||||
Specs.Add('DROP COLUMN '+Mainform.mask(FColumns[i].OldName));
|
||||
Specs.Add('DROP COLUMN '+QuoteIdent(FColumns[i].OldName));
|
||||
end;
|
||||
|
||||
// Drop indexes, also changed indexes, which will be readded below
|
||||
@ -563,7 +563,7 @@ begin
|
||||
if DeletedKeys[i] = PKEY then
|
||||
IndexSQL := 'PRIMARY KEY'
|
||||
else
|
||||
IndexSQL := 'INDEX ' + Mainform.Mask(DeletedKeys[i]);
|
||||
IndexSQL := 'INDEX ' + QuoteIdent(DeletedKeys[i]);
|
||||
Specs.Add('DROP '+IndexSQL);
|
||||
end;
|
||||
// Add changed or added indexes
|
||||
@ -573,7 +573,7 @@ begin
|
||||
if FKeys[i].OldIndexType = PKEY then
|
||||
IndexSQL := 'PRIMARY KEY'
|
||||
else
|
||||
IndexSQL := 'INDEX ' + Mainform.Mask(FKeys[i].OldName);
|
||||
IndexSQL := 'INDEX ' + QuoteIdent(FKeys[i].OldName);
|
||||
Specs.Add('DROP '+IndexSQL);
|
||||
end;
|
||||
if FKeys[i].Added or FKeys[i].Modified then
|
||||
@ -581,13 +581,13 @@ begin
|
||||
end;
|
||||
|
||||
for i:=0 to DeletedForeignKeys.Count-1 do
|
||||
Specs.Add('DROP FOREIGN KEY '+Mainform.mask(DeletedForeignKeys[i]));
|
||||
Specs.Add('DROP FOREIGN KEY '+QuoteIdent(DeletedForeignKeys[i]));
|
||||
for i:=0 to FForeignKeys.Count-1 do begin
|
||||
if FForeignKeys[i].Added or FForeignKeys[i].Modified then
|
||||
Specs.Add('ADD '+FForeignKeys[i].SQLCode(True));
|
||||
end;
|
||||
|
||||
Result := 'ALTER TABLE '+Mainform.mask(DBObject.Name) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Result := 'ALTER TABLE '+QuoteIdent(DBObject.Name) + CRLF + #9 + ImplodeStr(',' + CRLF + #9, Specs);
|
||||
Result := Trim(Result);
|
||||
FreeAndNil(Specs);
|
||||
Mainform.ShowStatusMsg;
|
||||
@ -604,7 +604,7 @@ var
|
||||
tmp: String;
|
||||
begin
|
||||
// Compose CREATE query, called by buttons and for SQL code tab
|
||||
Result := 'CREATE TABLE '+Mainform.mask(editName.Text)+' ('+CRLF;
|
||||
Result := 'CREATE TABLE '+QuoteIdent(editName.Text)+' ('+CRLF;
|
||||
Node := listColumns.GetFirst;
|
||||
while Assigned(Node) do begin
|
||||
Col := listColumns.GetNodeData(Node);
|
||||
@ -1933,7 +1933,7 @@ begin
|
||||
MessageDlg('Please select a reference table before selecting foreign columns.', mtError, [mbOk], 0)
|
||||
else begin
|
||||
try
|
||||
MainForm.ActiveConnection.GetVar('SELECT 1 FROM '+Mainform.Mask(Key.ReferenceTable, '.'));
|
||||
MainForm.ActiveConnection.GetVar('SELECT 1 FROM '+QuoteIdent(Key.ReferenceTable, True, '.'));
|
||||
Allowed := True;
|
||||
except
|
||||
// Leave Allowed = False
|
||||
@ -1985,7 +1985,7 @@ begin
|
||||
3: begin
|
||||
Key := FForeignKeys[Node.Index];
|
||||
SetEditor := TSetEditorLink.Create(VT);
|
||||
SetEditor.ValueList := MainForm.ActiveConnection.GetCol('SHOW COLUMNS FROM '+Mainform.Mask(Key.ReferenceTable, '.'));
|
||||
SetEditor.ValueList := MainForm.ActiveConnection.GetCol('SHOW COLUMNS FROM '+QuoteIdent(Key.ReferenceTable, True, '.'));
|
||||
EditLink := SetEditor;
|
||||
end;
|
||||
4, 5: begin
|
||||
|
@ -551,7 +551,7 @@ begin
|
||||
AddNotes(DBObj.Database, DBObj.Name, STRSKIPPED+'a '+LowerCase(DBObj.ObjType)+' cannot be maintained.', '');
|
||||
Exit;
|
||||
end;
|
||||
SQL := UpperCase(comboOperation.Text) + ' TABLE ' + Mainform.mask(DBObj.Database) + '.' + Mainform.mask(DBObj.Name);
|
||||
SQL := UpperCase(comboOperation.Text) + ' TABLE ' + QuoteIdent(DBObj.Database) + '.' + QuoteIdent(DBObj.Name);
|
||||
if chkQuick.Enabled and chkQuick.Checked then SQL := SQL + ' QUICK';
|
||||
if chkFast.Enabled and chkFast.Checked then SQL := SQL + ' FAST';
|
||||
if chkMedium.Enabled and chkMedium.Checked then SQL := SQL + ' MEDIUM';
|
||||
@ -580,16 +580,16 @@ begin
|
||||
for Col in Columns do begin
|
||||
if (comboDatatypes.ItemIndex = 0) or (Integer(Col.DataType.Category) = comboDatatypes.ItemIndex-1) then begin
|
||||
if chkCaseSensitive.Checked then
|
||||
SQL := SQL + Mainform.mask(Col.Name) + ' LIKE BINARY ' + esc('%'+memoFindText.Text+'%') + ' OR '
|
||||
SQL := SQL + QuoteIdent(Col.Name) + ' LIKE BINARY ' + esc('%'+memoFindText.Text+'%') + ' OR '
|
||||
else
|
||||
SQL := SQL + 'LOWER(CONVERT('+Mainform.mask(Col.Name)+' USING '+DBObj.Connection.CharacterSet+')) LIKE ' + esc('%'+LowerCase(memoFindText.Text)+'%') + ' OR '
|
||||
SQL := SQL + 'LOWER(CONVERT('+QuoteIdent(Col.Name)+' USING '+DBObj.Connection.CharacterSet+')) LIKE ' + esc('%'+LowerCase(memoFindText.Text)+'%') + ' OR '
|
||||
end;
|
||||
end;
|
||||
if SQL <> '' then begin
|
||||
Delete(SQL, Length(SQL)-3, 3);
|
||||
FFindSeeResultSQL[FFindSeeResultSQL.Count-1] := 'SELECT * FROM '+Mainform.mask(DBObj.Database)+'.'+Mainform.mask(DBObj.Name)+' WHERE ' + SQL;
|
||||
FFindSeeResultSQL[FFindSeeResultSQL.Count-1] := 'SELECT * FROM '+QuoteIdent(DBObj.Database)+'.'+QuoteIdent(DBObj.Name)+' WHERE ' + SQL;
|
||||
SQL := 'SELECT '''+DBObj.Database+''' AS `Database`, '''+DBObj.Name+''' AS `Table`, COUNT(*) AS `Found rows`, '
|
||||
+ 'CONCAT(ROUND(100 / '+IntToStr(Max(DBObj.Rows,1))+' * COUNT(*), 1), ''%'') AS `Relevance` FROM '+Mainform.mask(DBObj.Database)+'.'+Mainform.mask(DBObj.Name)+' WHERE '
|
||||
+ 'CONCAT(ROUND(100 / '+IntToStr(Max(DBObj.Rows,1))+' * COUNT(*), 1), ''%'') AS `Relevance` FROM '+QuoteIdent(DBObj.Database)+'.'+QuoteIdent(DBObj.Name)+' WHERE '
|
||||
+ SQL;
|
||||
AddResults(SQL);
|
||||
end else
|
||||
@ -1002,12 +1002,6 @@ var
|
||||
const
|
||||
TempDelim = '//';
|
||||
|
||||
// Short version of Mainform.Mask()
|
||||
function m(s: String): String;
|
||||
begin
|
||||
Result := Mainform.mask(s);
|
||||
end;
|
||||
|
||||
procedure LogStatistic(RowsDone: Int64);
|
||||
var
|
||||
LogRow: TStringlist;
|
||||
@ -1022,10 +1016,10 @@ const
|
||||
|
||||
begin
|
||||
// Handle one table, view or whatever in SQL export mode
|
||||
AddResults('SELECT '+esc(DBObj.Database)+' AS '+Mainform.mask('Database')+', ' +
|
||||
esc(DBObj.Name)+' AS '+Mainform.mask('Table')+', ' +
|
||||
IntToStr(DBObj.Rows)+' AS '+Mainform.mask('Rows')+', '+
|
||||
'0 AS '+Mainform.mask('Duration')
|
||||
AddResults('SELECT '+esc(DBObj.Database)+' AS '+QuoteIdent('Database')+', ' +
|
||||
esc(DBObj.Name)+' AS '+QuoteIdent('Table')+', ' +
|
||||
IntToStr(DBObj.Rows)+' AS '+QuoteIdent('Rows')+', '+
|
||||
'0 AS '+QuoteIdent('Duration')
|
||||
);
|
||||
ToFile := comboExportOutputType.Text = OUTPUT_FILE;
|
||||
ToDir := comboExportOutputType.Text = OUTPUT_DIR;
|
||||
@ -1076,23 +1070,23 @@ begin
|
||||
if chkExportDatabasesDrop.Checked or chkExportDatabasesCreate.Checked then begin
|
||||
Output(CRLF+CRLF+'# Dumping database structure for '+DBObj.Database+CRLF, False, NeedsDBStructure, False, False, False);
|
||||
if chkExportDatabasesDrop.Checked and chkExportDatabasesDrop.Enabled then
|
||||
Output('DROP DATABASE IF EXISTS '+m(FinalDbName), True, NeedsDBStructure, False, False, NeedsDBStructure);
|
||||
Output('DROP DATABASE IF EXISTS '+QuoteIdent(FinalDbName), True, NeedsDBStructure, False, False, NeedsDBStructure);
|
||||
if chkExportDatabasesCreate.Checked and chkExportDatabasesCreate.Enabled then begin
|
||||
if MainForm.ActiveConnection.ServerVersionInt >= 40100 then begin
|
||||
Struc := MainForm.ActiveConnection.GetVar('SHOW CREATE DATABASE '+m(DBObj.Database), 1);
|
||||
Struc := MainForm.ActiveConnection.GetVar('SHOW CREATE DATABASE '+QuoteIdent(DBObj.Database), 1);
|
||||
// Gracefully ignore it when target database exists, important in server mode
|
||||
Insert('IF NOT EXISTS ', Struc, Pos('DATABASE', Struc) + 9);
|
||||
// Create the right dbname
|
||||
Struc := StringReplace(Struc, DBObj.Database, FinalDbName, []);
|
||||
end else
|
||||
Struc := 'CREATE DATABASE IF NOT EXISTS '+m(FinalDbName);
|
||||
Struc := 'CREATE DATABASE IF NOT EXISTS '+QuoteIdent(FinalDbName);
|
||||
Output(Struc, True, NeedsDBStructure, False, False, NeedsDBStructure);
|
||||
Output('USE '+m(FinalDbName), True, NeedsDBStructure, False, False, NeedsDBStructure);
|
||||
Output('USE '+QuoteIdent(FinalDbName), True, NeedsDBStructure, False, False, NeedsDBStructure);
|
||||
end;
|
||||
end;
|
||||
if ToServer and (not chkExportDatabasesCreate.Checked) then begin
|
||||
// Export to server without "CREATE/USE dbname" and "Same dbs as on source server" - needs a "USE dbname"
|
||||
Output('USE '+m(FinalDbName), True, False, False, False, NeedsDBStructure);
|
||||
Output('USE '+QuoteIdent(FinalDbName), True, False, False, False, NeedsDBStructure);
|
||||
end;
|
||||
|
||||
// Table structure
|
||||
@ -1101,8 +1095,8 @@ begin
|
||||
if chkExportTablesDrop.Checked then begin
|
||||
Struc := 'DROP '+UpperCase(DBObj.ObjType)+' IF EXISTS ';
|
||||
if ToDb then
|
||||
Struc := Struc + m(FinalDbName)+'.';
|
||||
Struc := Struc + m(DBObj.Name);
|
||||
Struc := Struc + QuoteIdent(FinalDbName)+'.';
|
||||
Struc := Struc + QuoteIdent(DBObj.Name);
|
||||
Output(Struc, True, True, True, True, True);
|
||||
end;
|
||||
if chkExportTablesCreate.Checked then begin
|
||||
@ -1120,7 +1114,7 @@ begin
|
||||
end;
|
||||
Insert('IF NOT EXISTS ', Struc, Pos('TABLE', Struc) + 6);
|
||||
if ToDb then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('EXISTS', Struc) + 7 )
|
||||
Insert(QuoteIdent(FinalDbName)+'.', Struc, Pos('EXISTS', Struc) + 7 )
|
||||
end;
|
||||
|
||||
lntView: begin
|
||||
@ -1131,8 +1125,8 @@ begin
|
||||
Struc := '# Creating temporary table to overcome VIEW dependency errors'+CRLF+
|
||||
'CREATE TABLE ';
|
||||
if ToDb then
|
||||
Struc := Struc + m(FinalDbName) + '.';
|
||||
Struc := Struc + m(DBObj.Name)+' (';
|
||||
Struc := Struc + QuoteIdent(FinalDbName) + '.';
|
||||
Struc := Struc + QuoteIdent(DBObj.Name)+' (';
|
||||
for Column in ColumnList do
|
||||
Struc := Struc + CRLF + #9 + Column.SQLCode + ',';
|
||||
Delete(Struc, Length(Struc), 1);
|
||||
@ -1142,21 +1136,21 @@ begin
|
||||
Struc := '# Removing temporary table and create final VIEW structure'+CRLF+
|
||||
'DROP TABLE IF EXISTS ';
|
||||
if ToDb then
|
||||
Struc := Struc + m(FinalDbName)+'.';
|
||||
Struc := Struc + m(DBObj.Name);
|
||||
Struc := Struc + QuoteIdent(FinalDbName)+'.';
|
||||
Struc := Struc + QuoteIdent(DBObj.Name);
|
||||
Output(Struc, True, True, True, True, True);
|
||||
Struc := DBObj.CreateCode;
|
||||
if ToDb then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('VIEW', Struc) + 5 );
|
||||
Insert(QuoteIdent(FinalDbName)+'.', Struc, Pos('VIEW', Struc) + 5 );
|
||||
end;
|
||||
end;
|
||||
|
||||
lntTrigger: begin
|
||||
StrucResult := MainForm.ActiveConnection.GetResults('SHOW TRIGGERS FROM '+m(DBObj.Database)+' WHERE `Trigger`='+esc(DBObj.Name));
|
||||
Struc := 'CREATE '+UpperCase(DBObj.ObjType)+' '+m(DBObj.Name)+' '+StrucResult.Col('Timing')+' '+StrucResult.Col('Event')+
|
||||
' ON '+m(StrucResult.Col('Table'))+' FOR EACH ROW '+StrucResult.Col('Statement');
|
||||
StrucResult := MainForm.ActiveConnection.GetResults('SHOW TRIGGERS FROM '+QuoteIdent(DBObj.Database)+' WHERE `Trigger`='+esc(DBObj.Name));
|
||||
Struc := 'CREATE '+UpperCase(DBObj.ObjType)+' '+QuoteIdent(DBObj.Name)+' '+StrucResult.Col('Timing')+' '+StrucResult.Col('Event')+
|
||||
' ON '+QuoteIdent(StrucResult.Col('Table'))+' FOR EACH ROW '+StrucResult.Col('Statement');
|
||||
if ToDb then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('TRIGGER', Struc) + 8 );
|
||||
Insert(QuoteIdent(FinalDbName)+'.', Struc, Pos('TRIGGER', Struc) + 8 );
|
||||
if ToFile or ToClipboard or ToDir then begin
|
||||
Struc := 'SET SESSION SQL_MODE=' + esc(StrucResult.Col('sql_mode')) + ';' + CRLF +
|
||||
'DELIMITER ' + TempDelim + CRLF +
|
||||
@ -1170,9 +1164,9 @@ begin
|
||||
Struc := DBObj.CreateCode;
|
||||
if ToDb then begin
|
||||
if DBObj.NodeType = lntProcedure then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('PROCEDURE', Struc) + 10 )
|
||||
Insert(QuoteIdent(FinalDbName)+'.', Struc, Pos('PROCEDURE', Struc) + 10 )
|
||||
else if DBObj.NodeType = lntFunction then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('FUNCTION', Struc) + 9 );
|
||||
Insert(QuoteIdent(FinalDbName)+'.', Struc, Pos('FUNCTION', Struc) + 9 );
|
||||
end;
|
||||
// Change delimiter for file output, so readers split queries at the right string position
|
||||
if ToFile or ToDir or ToClipboard then
|
||||
@ -1182,7 +1176,7 @@ begin
|
||||
lntEvent: begin
|
||||
Struc := DBObj.CreateCode;
|
||||
if ToDb then
|
||||
Insert(m(FinalDbName)+'.', Struc, Pos('EVENT', Struc) + 6 );
|
||||
Insert(QuoteIdent(FinalDbName)+'.', Struc, Pos('EVENT', Struc) + 6 );
|
||||
if ToFile or ToDir or ToClipboard then
|
||||
Struc := 'DELIMITER ' + TempDelim + CRLF + Struc + TempDelim + CRLF + 'DELIMITER ';
|
||||
end;
|
||||
@ -1208,9 +1202,9 @@ begin
|
||||
if LowerCase(DBObj.Engine) = 'innodb' then
|
||||
tmp := '~'+tmp+' (approximately)';
|
||||
Output(CRLF+'# Dumping data for table '+DBObj.Database+'.'+DBObj.Name+': '+tmp+CRLF, False, True, True, False, False);
|
||||
TargetDbAndObject := m(DBObj.Name);
|
||||
TargetDbAndObject := QuoteIdent(DBObj.Name);
|
||||
if ToDb then
|
||||
TargetDbAndObject := m(FinalDbName) + '.' + TargetDbAndObject;
|
||||
TargetDbAndObject := QuoteIdent(FinalDbName) + '.' + TargetDbAndObject;
|
||||
Offset := 0;
|
||||
RowCount := 0;
|
||||
// Calculate limit so we select ~100MB per loop
|
||||
@ -1219,7 +1213,7 @@ begin
|
||||
Output('DELETE FROM '+TargetDbAndObject, True, True, True, True, True);
|
||||
Output('/*!40000 ALTER TABLE '+TargetDbAndObject+' DISABLE KEYS */', True, True, True, True, True);
|
||||
while true do begin
|
||||
Data := MainForm.ActiveConnection.GetResults('SELECT * FROM '+m(DBObj.Database)+'.'+m(DBObj.Name)+' LIMIT '+IntToStr(Offset)+', '+IntToStr(Limit));
|
||||
Data := MainForm.ActiveConnection.GetResults('SELECT * FROM '+QuoteIdent(DBObj.Database)+'.'+QuoteIdent(DBObj.Name)+' LIMIT '+IntToStr(Offset)+', '+IntToStr(Limit));
|
||||
Inc(Offset, Limit);
|
||||
if Data.RecordCount = 0 then
|
||||
break;
|
||||
@ -1230,7 +1224,7 @@ begin
|
||||
BaseInsert := 'REPLACE INTO ';
|
||||
BaseInsert := BaseInsert + TargetDbAndObject + ' (';
|
||||
for i:=0 to Data.ColumnCount-1 do
|
||||
BaseInsert := BaseInsert + m(Data.ColumnNames[i]) + ', ';
|
||||
BaseInsert := BaseInsert + QuoteIdent(Data.ColumnNames[i]) + ', ';
|
||||
Delete(BaseInsert, Length(BaseInsert)-1, 2);
|
||||
BaseInsert := BaseInsert + ') VALUES'+CRLF+#9+'(';
|
||||
while true do begin
|
||||
@ -1316,15 +1310,15 @@ var
|
||||
rx: TRegExpr;
|
||||
HasCharsetClause: Boolean;
|
||||
begin
|
||||
AddResults('SELECT '+esc(DBObj.Database)+' AS '+Mainform.mask('Database')+', ' +
|
||||
esc(DBObj.Name)+' AS '+Mainform.mask('Table')+', ' +
|
||||
esc('Updating...')+' AS '+Mainform.mask('Operation')+', '+
|
||||
''''' AS '+Mainform.mask('Result')
|
||||
AddResults('SELECT '+esc(DBObj.Database)+' AS '+QuoteIdent('Database')+', ' +
|
||||
esc(DBObj.Name)+' AS '+QuoteIdent('Table')+', ' +
|
||||
esc('Updating...')+' AS '+QuoteIdent('Operation')+', '+
|
||||
''''' AS '+QuoteIdent('Result')
|
||||
);
|
||||
Specs := TStringList.Create;
|
||||
if chkBulkTableEditDatabase.Checked and (comboBulkTableEditDatabase.Text <> DBObj.Database) then begin
|
||||
case DBObj.NodeType of
|
||||
lntTable: Specs.Add('RENAME ' + Mainform.mask(comboBulkTableEditDatabase.Text)+'.'+Mainform.mask(DBObj.Name));
|
||||
lntTable: Specs.Add('RENAME ' + QuoteIdent(comboBulkTableEditDatabase.Text)+'.'+QuoteIdent(DBObj.Name));
|
||||
lntView: begin
|
||||
// Although RENAME works for views, that does not work for moving to another database without getting
|
||||
// a "Changing schema from x to y is not allowed". Instead, recreate them manually
|
||||
@ -1333,13 +1327,13 @@ begin
|
||||
rx.ModifierI := True;
|
||||
// Replace old database references in VIEW body
|
||||
rx.Expression := '(["`])'+QuoteRegExprMetaChars(DBObj.Database)+'(["`])';
|
||||
CreateView := rx.Replace(CreateView, Mainform.mask(comboBulkTableEditDatabase.Text), false);
|
||||
CreateView := rx.Replace(CreateView, QuoteIdent(comboBulkTableEditDatabase.Text), false);
|
||||
rx.Free;
|
||||
// Temporarily switch to new database for VIEW creation, so the database references are correct
|
||||
DBObj.Connection.Database := comboBulkTableEditDatabase.Text;
|
||||
DBObj.Connection.Query(CreateView);
|
||||
DBObj.Connection.Database := DBObj.Database;
|
||||
DBObj.Connection.Query('DROP VIEW '+Mainform.mask(DBObj.Name));
|
||||
DBObj.Connection.Query('DROP VIEW '+QuoteIdent(DBObj.Name));
|
||||
end;
|
||||
end;
|
||||
FModifiedDbs.Add(DBObj.Database);
|
||||
@ -1370,7 +1364,7 @@ begin
|
||||
|
||||
LogRow := FResults.Last;
|
||||
if Specs.Count > 0 then begin
|
||||
DBObj.Connection.Query('ALTER TABLE ' + Mainform.mask(DBObj.Database) + '.' + Mainform.mask(DBObj.Name) + ' ' + ImplodeStr(', ', Specs));
|
||||
DBObj.Connection.Query('ALTER TABLE ' + QuoteIdent(DBObj.Database) + '.' + QuoteIdent(DBObj.Name) + ' ' + ImplodeStr(', ', Specs));
|
||||
LogRow[2] := 'Done';
|
||||
LogRow[3] := 'Success';
|
||||
end else begin
|
||||
|
@ -101,7 +101,7 @@ begin
|
||||
if DBObject.Name <> '' then begin
|
||||
// Edit mode
|
||||
editName.Text := DBObject.Name;
|
||||
Definitions := MainForm.ActiveConnection.GetResults('SHOW TRIGGERS FROM '+Mainform.mask(Mainform.ActiveDatabase));
|
||||
Definitions := MainForm.ActiveConnection.GetResults('SHOW TRIGGERS FROM '+QuoteIdent(Mainform.ActiveDatabase));
|
||||
Found := False;
|
||||
while not Definitions.Eof do begin
|
||||
if Definitions.Col('Trigger') = DBObject.Name then begin
|
||||
@ -175,7 +175,7 @@ begin
|
||||
// his statement. The user must fix such errors and re-press "Save" while we have them in memory,
|
||||
// otherwise the trigger attributes are lost forever.
|
||||
if DBObject.Name <> '' then try
|
||||
MainForm.ActiveConnection.Query('DROP TRIGGER '+Mainform.mask(DBObject.Name));
|
||||
MainForm.ActiveConnection.Query('DROP TRIGGER '+QuoteIdent(DBObject.Name));
|
||||
except
|
||||
end;
|
||||
// CREATE
|
||||
@ -184,10 +184,10 @@ begin
|
||||
// ON tbl_name FOR EACH ROW trigger_stmt
|
||||
sql := 'CREATE ';
|
||||
if comboDefiner.Text <> '' then
|
||||
sql := sql + 'DEFINER='+DBObject.Connection.QuoteIdent(comboDefiner.Text, '@')+' ';
|
||||
sql := sql + 'TRIGGER '+Mainform.mask(editName.Text)+' '+
|
||||
sql := sql + 'DEFINER='+QuoteIdent(comboDefiner.Text, True, '@')+' ';
|
||||
sql := sql + 'TRIGGER '+QuoteIdent(editName.Text)+' '+
|
||||
comboTiming.Items[comboTiming.ItemIndex]+' '+comboEvent.Items[comboEvent.ItemIndex]+
|
||||
' ON '+Mainform.mask(comboTable.Text)+
|
||||
' ON '+QuoteIdent(comboTable.Text)+
|
||||
' FOR EACH ROW '+SynMemoStatement.Text;
|
||||
MainForm.ActiveConnection.Query(sql);
|
||||
DBObject.Name := editName.Text;
|
||||
@ -222,7 +222,7 @@ begin
|
||||
if comboTable.Text = '' then
|
||||
CanExecute := False
|
||||
else try
|
||||
Columns := MainForm.ActiveConnection.GetResults('SHOW COLUMNS FROM '+Mainform.mask(comboTable.Text));
|
||||
Columns := MainForm.ActiveConnection.GetResults('SHOW COLUMNS FROM '+QuoteIdent(comboTable.Text));
|
||||
while not Columns.Eof do begin
|
||||
Proposal.InsertList.Add(Columns.Col('Field'));
|
||||
Proposal.ItemList.Add(Format(SYNCOMPLETION_PATTERN, [ICONINDEX_FIELD, GetFirstWord(Columns.Col('Type')), Columns.Col('Field')]) );
|
||||
|
@ -230,10 +230,10 @@ begin
|
||||
// Load user@host list
|
||||
try
|
||||
FUsers := MainForm.ActiveConnection.GetCol(
|
||||
'SELECT CONCAT('+MainForm.mask('user')+', '+esc('@')+', '+MainForm.mask('host')+') '+
|
||||
'FROM '+MainForm.mask('mysql')+'.'+MainForm.mask('user')+' '+
|
||||
'WHERE '+MainForm.mask('Password')+'!='+esc('!')+' '+
|
||||
'ORDER BY LOWER('+MainForm.mask('user')+'), LOWER('+MainForm.mask('host')+')');
|
||||
'SELECT CONCAT('+QuoteIdent('user')+', '+esc('@')+', '+QuoteIdent('host')+') '+
|
||||
'FROM '+QuoteIdent('mysql')+'.'+QuoteIdent('user')+' '+
|
||||
'WHERE '+QuoteIdent('Password')+'!='+esc('!')+' '+
|
||||
'ORDER BY LOWER('+QuoteIdent('user')+'), LOWER('+QuoteIdent('host')+')');
|
||||
InvalidateVT(listUsers, VTREE_NOTLOADED, False);
|
||||
FPrivObjects := TPrivObjList.Create(TPrivComparer.Create, True);
|
||||
Modified := False;
|
||||
@ -475,8 +475,8 @@ begin
|
||||
for Ptmp in FPrivObjects do begin
|
||||
if Ptmp.DBObj.NodeType = lntColumn then begin
|
||||
Ptmp.GrantCode := 'GRANT ' + Copy(Ptmp.GrantCode, 1, Length(Ptmp.GrantCode)-2) + ' ON ' +
|
||||
MainForm.mask(Ptmp.DBObj.Database) + '.' +
|
||||
MainForm.mask(Ptmp.DBObj.Name) +
|
||||
QuoteIdent(Ptmp.DBObj.Database) + '.' +
|
||||
QuoteIdent(Ptmp.DBObj.Name) +
|
||||
' TO ' + UserHost;
|
||||
end;
|
||||
// Flag all privs as added, so "Save" action applies them
|
||||
@ -819,11 +819,11 @@ begin
|
||||
lntNone:
|
||||
OnObj := '*.*';
|
||||
lntDb:
|
||||
OnObj := Mainform.mask(P.DBObj.Database) + '.*';
|
||||
OnObj := QuoteIdent(P.DBObj.Database) + '.*';
|
||||
lntTable, lntFunction, lntProcedure:
|
||||
OnObj := UpperCase(P.DBObj.ObjType) + ' ' + Mainform.mask(P.DBObj.Database) + '.' + Mainform.mask(P.DBObj.Name);
|
||||
OnObj := UpperCase(P.DBObj.ObjType) + ' ' + QuoteIdent(P.DBObj.Database) + '.' + QuoteIdent(P.DBObj.Name);
|
||||
lntColumn:
|
||||
OnObj := 'TABLE ' + Mainform.mask(P.DBObj.Database) + '.' + Mainform.mask(P.DBObj.Name);
|
||||
OnObj := 'TABLE ' + QuoteIdent(P.DBObj.Database) + '.' + QuoteIdent(P.DBObj.Name);
|
||||
else
|
||||
raise Exception.Create('Unhandled privilege object: '+P.DBObj.ObjType);
|
||||
end;
|
||||
@ -836,7 +836,7 @@ begin
|
||||
if P.DeletedPrivs[i] = 'GRANT' then
|
||||
Revoke := Revoke + ' OPTION';
|
||||
if P.DBObj.NodeType = lntColumn then
|
||||
Revoke := Revoke + '('+Mainform.mask(P.DBObj.Column)+')';
|
||||
Revoke := Revoke + '('+QuoteIdent(P.DBObj.Column)+')';
|
||||
Revoke := Revoke + ', ';
|
||||
end;
|
||||
Delete(Revoke, Length(Revoke)-1, 1);
|
||||
@ -852,7 +852,7 @@ begin
|
||||
Continue;
|
||||
Grant := Grant + P.AddedPrivs[i];
|
||||
if P.DBObj.NodeType = lntColumn then
|
||||
Grant := Grant + '('+Mainform.mask(P.DBObj.Column)+')';
|
||||
Grant := Grant + '('+QuoteIdent(P.DBObj.Column)+')';
|
||||
Grant := Grant + ', ';
|
||||
end;
|
||||
Delete(Grant, Length(Grant)-1, 1);
|
||||
@ -877,7 +877,7 @@ begin
|
||||
else begin
|
||||
Tables := Explode(',', 'user,db,tables_priv,columns_priv');
|
||||
for Table in Tables do begin
|
||||
Conn.Query('UPDATE '+Mainform.mask('mysql')+'.'+Mainform.mask(Table)+
|
||||
Conn.Query('UPDATE '+QuoteIdent('mysql')+'.'+QuoteIdent(Table)+
|
||||
' SET User='+esc(editUsername.Text)+', Host='+esc(editFromHost.Text)+
|
||||
' WHERE User='+esc(OrgUsername)+' AND Host='+esc(OrgFromHost)
|
||||
);
|
||||
|
@ -155,11 +155,11 @@ begin
|
||||
sql := 'ALTER ';
|
||||
viewname := DBObject.Name;
|
||||
end;
|
||||
viewname := Mainform.mask(viewname);
|
||||
viewname := QuoteIdent(viewname);
|
||||
if rgAlgorithm.Enabled and (rgAlgorithm.ItemIndex > -1) then
|
||||
sql := sql + 'ALGORITHM = '+Uppercase(rgAlgorithm.Items[rgAlgorithm.ItemIndex])+' ';
|
||||
if comboDefiner.Text <> '' then
|
||||
sql := sql + 'DEFINER='+DBObject.Connection.QuoteIdent(comboDefiner.Text, '@')+' ';
|
||||
sql := sql + 'DEFINER='+QuoteIdent(comboDefiner.Text, True, '@')+' ';
|
||||
sql := sql + 'VIEW ' + viewname+' AS '+SynMemoSelect.Text+' ';
|
||||
if rgCheck.Enabled and (rgCheck.ItemIndex > 0) then
|
||||
sql := sql + 'WITH '+Uppercase(rgCheck.Items[rgCheck.ItemIndex])+' CHECK OPTION';
|
||||
@ -168,7 +168,7 @@ begin
|
||||
MainForm.ActiveConnection.Query(sql);
|
||||
// Probably rename view
|
||||
if (DBObject.Name <> '') and (DBObject.Name <> editName.Text) then begin
|
||||
renamed := Mainform.mask(editName.Text);
|
||||
renamed := QuoteIdent(editName.Text);
|
||||
MainForm.ActiveConnection.Query('RENAME TABLE '+viewname + ' TO '+renamed);
|
||||
end;
|
||||
DBObject.Name := editName.Text;
|
||||
|
Reference in New Issue
Block a user