Skip to content

Commit

Permalink
Use custom tab width and tabs-to-spaces setting uniquely in all place…
Browse files Browse the repository at this point in the history
…s where we generate code. Provides a new CodeIndent() helper. Closes #1330
  • Loading branch information
ansgarbecker committed May 19, 2024
1 parent a378e6e commit db014bd
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 99 deletions.
11 changes: 11 additions & 0 deletions source/apphelpers.pas
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ TAppSettings = class(TObject)
procedure FindComponentInstances(BaseForm: TComponent; ClassType: TClass; var List: TObjectList);
function WebColorStrToColorDef(WebColor: string; Default: TColor): TColor;
function UserAgent(OwnerComponent: TComponent): String;
function CodeIndent(Steps: Integer=1): String;

var
AppSettings: TAppSettings;
Expand Down Expand Up @@ -2999,6 +3000,16 @@ function UserAgent(OwnerComponent: TComponent): String;
end;


function CodeIndent(Steps: Integer=1): String;
begin
// Provide tab or spaces for indentation, uniquely used for all SQL statements
if AppSettings.ReadBool(asTabsToSpaces) then
Result := StringOfChar(' ', AppSettings.ReadInt(asTabWidth) * Steps)
else
Result := StringOfChar(#9, Steps);
end;


{ Get SID of current Windows user, probably useful in the future
function GetCurrentUserSID: string;
type
Expand Down
4 changes: 2 additions & 2 deletions source/copytable.pas
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,12 @@ procedure TCopyTableForm.btnOKClick(Sender: TObject);
Column: TTableColumn;
Key: TTableKey;
ForeignKey: TForeignKey;
const
ClausePattern: String = #9 + '%s,' + CRLF;
ClausePattern: String;
begin
// Compose and run CREATE query

TargetTable := FConnection.QuotedDbAndTableName(comboDatabase.Text, editNewTablename.Text);
ClausePattern := CodeIndent + '%s,' + sLineBreak;

// Watch out if target table exists
try
Expand Down
2 changes: 1 addition & 1 deletion source/csv_detector.pas
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ function TfrmCsvDetector.ComposeCreateStatement(Columns: TTableColumnList): Stri
TableName := FConnection.CleanIdent(TableName);
Result := 'CREATE TABLE '+FConnection.QuoteIdent(FLoadDataFrm.comboDatabase.Text)+'.'+FConnection.QuoteIdent(TableName)+' (' + sLineBreak;
for Col in Columns do begin
Result := Result + #9 + Col.SQLCode;
Result := Result + CodeIndent + Col.SQLCode;
if Col <> Columns.Last then
Result := Result + ',';
Result := Result + sLineBreak;
Expand Down
8 changes: 4 additions & 4 deletions source/dbconnection.pas
Original file line number Diff line number Diff line change
Expand Up @@ -4077,25 +4077,25 @@ function TDBConnection.GetCreateCode(Obj: TDBObject): String;
Result := 'CREATE TABLE '+QuoteIdent(Obj.Name)+' (';
TableCols := Obj.GetTableColumns;
for TableCol in TableCols do begin
Result := Result + CRLF + #9 + TableCol.SQLCode + ',';
Result := Result + sLineBreak + CodeIndent + TableCol.SQLCode + ',';
end;
TableCols.Free;

TableKeys := Obj.GetTableKeys;
for TableKey in TableKeys do begin
Result := Result + CRLF + #9 + TableKey.SQLCode + ',';
Result := Result + sLineBreak + CodeIndent + TableKey.SQLCode + ',';
end;
TableKeys.Free;

TableForeignKeys := Obj.GetTableForeignKeys;
for TableForeignKey in TableForeignKeys do begin
Result := Result + CRLF + #9 + TableForeignKey.SQLCode(True) + ',';
Result := Result + sLineBreak + CodeIndent + TableForeignKey.SQLCode(True) + ',';
end;
TableForeignKeys.Free;

TableCheckConstraints := Obj.GetTableCheckConstraints;
for TableCheckConstraint in TableCheckConstraints do begin
Result := Result + CRLF + #9 + TableCheckConstraint.SQLCode + ',';
Result := Result + sLineBreak + CodeIndent + TableCheckConstraint.SQLCode + ',';
end;
TableCheckConstraints.Free;

Expand Down
14 changes: 7 additions & 7 deletions source/event_editor.pas
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ function TfrmEventEditor.ComposeStatement(CreateOrAlter, ObjName: String): Strin
Result := CreateOrAlter + ' ';
if comboDefiner.Text <> '' then
Result := Result + 'DEFINER='+DBObject.Connection.QuoteIdent(comboDefiner.Text, True, '@')+' ';
Result := Result + 'EVENT ' + DBObject.Connection.QuoteIdent(ObjName) + CRLF + #9 + 'ON SCHEDULE' + CRLF + #9#9;
Result := Result + 'EVENT ' + DBObject.Connection.QuoteIdent(ObjName) + sLineBreak + CodeIndent + 'ON SCHEDULE' + sLineBreak + CodeIndent(2);
if radioOnce.Checked then begin
d := dateOnce.DateTime;
ReplaceTime(d, timeOnce.DateTime);
Expand All @@ -297,14 +297,14 @@ function TfrmEventEditor.ComposeStatement(CreateOrAlter, ObjName: String): Strin
end;

if chkDropAfterExpiration.Checked then
Result := Result + #9 + 'ON COMPLETION NOT PRESERVE'
Result := Result + CodeIndent + 'ON COMPLETION NOT PRESERVE'
else
Result := Result + #9 + 'ON COMPLETION PRESERVE';
Result := Result + CodeIndent + 'ON COMPLETION PRESERVE';
if ObjectExists and (DBObject.Name <> editName.Text) then
Result := Result + CRLF + #9 + 'RENAME TO ' + DBObject.Connection.QuoteIdent(editName.Text);
Result := Result + CRLF + #9 + UpperCase(grpState.Items[grpState.ItemIndex]);
Result := Result + CRLF + #9 + 'COMMENT ' + DBObject.Connection.EscapeString(editComment.Text);
Result := Result + CRLF + #9 + 'DO ' + SynMemoBody.Text;
Result := Result + sLineBreak + CodeIndent + 'RENAME TO ' + DBObject.Connection.QuoteIdent(editName.Text);
Result := Result + sLineBreak + CodeIndent + UpperCase(grpState.Items[grpState.ItemIndex]);
Result := Result + sLineBreak + CodeIndent + 'COMMENT ' + DBObject.Connection.EscapeString(editComment.Text);
Result := Result + sLineBreak + CodeIndent + 'DO ' + SynMemoBody.Text;
end;


Expand Down
101 changes: 50 additions & 51 deletions source/exportgrid.pas
Original file line number Diff line number Diff line change
Expand Up @@ -681,47 +681,46 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
case ExportFormat of
efHTML: begin
Header :=
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' + CRLF +
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + CRLF + CRLF +
'<html>' + CRLF +
' <head>' + CRLF +
' <title>' + TableName + '</title>' + CRLF +
' <meta name="GENERATOR" content="'+ APPNAME+' '+Mainform.AppVersion + '">' + CRLF +
' <meta http-equiv="Content-Type" content="text/html; charset='+GetHTMLCharsetByEncoding(Encoding)+'" />' + CRLF +
' <style type="text/css">' + CRLF +
' th, td {vertical-align: top;}' + CRLF +
' table, td {border: 1px solid silver; padding: 2px;}' + CRLF +
' table {border-collapse: collapse;}' + CRLF;
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' + sLineBreak +
CodeIndent + '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' + sLineBreak + sLineBreak +
'<html>' + sLineBreak +
CodeIndent + '<head>' + sLineBreak +
CodeIndent(2) + '<title>' + TableName + '</title>' + sLineBreak +
CodeIndent(2) + '<meta name="GENERATOR" content="'+ APPNAME+' '+Mainform.AppVersion + '">' + sLineBreak +
CodeIndent(2) + '<meta http-equiv="Content-Type" content="text/html; charset='+GetHTMLCharsetByEncoding(Encoding)+'" />' + sLineBreak +
CodeIndent(2) + '<style type="text/css">' + sLineBreak +
CodeIndent(3) + 'th, td {vertical-align: top;}' + sLineBreak +
CodeIndent(3) + 'table, td {border: 1px solid silver; padding: 2px;}' + sLineBreak +
CodeIndent(3) + 'table {border-collapse: collapse;}' + sLineBreak;
Col := Grid.Header.Columns.GetFirstVisibleColumn(True);
while Col > NoColumn do begin
// Right-justify all cells to match the grid on screen.
if Grid.Header.Columns[Col].Alignment = taRightJustify then
Header := Header + ' .col' + IntToStr(Col) + ' {text-align: right;}' + CRLF;
Header := Header + CodeIndent(3) + '.col' + IntToStr(Col) + ' {text-align: right;}' + sLineBreak;
Col := Grid.Header.Columns.GetNextVisibleColumn(Col);
end;
Header := Header +
' </style>' + CRLF +
' </head>' + CRLF + CRLF +
' <body>' + CRLF + CRLF;
CodeIndent(2) + '</style>' + sLineBreak +
CodeIndent + '</head>' + sLineBreak + sLineBreak +
CodeIndent + '<body>' + sLineBreak + sLineBreak;
if chkIncludeQuery.Checked then
Header := Header + '<p style="font-family: monospace; white-space: pre;">' + GridData.SQL + '</p>' + CRLF + CRLF;
Header := Header + ' <table caption="' + TableName + ' (' + inttostr(NodeCount) + ' rows)">' + CRLF;
Header := Header + CodeIndent(2) + '<table caption="' + TableName + ' (' + inttostr(NodeCount) + ' rows)">' + sLineBreak;
if chkIncludeColumnNames.Checked then begin
Header := Header +
' <thead>' + CRLF +
' <tr>' + CRLF;
CodeIndent(3) + '<thead>' + sLineBreak +
CodeIndent(4) + '<tr>' + sLineBreak;
Col := Grid.Header.Columns.GetFirstVisibleColumn(True);
while Col > NoColumn do begin
if Col <> ExcludeCol then
Header := Header + ' <th class="col' + IntToStr(Col) + '">' + Grid.Header.Columns[Col].Text + '</th>' + CRLF;
Header := Header + CodeIndent(5) + '<th class="col' + IntToStr(Col) + '">' + Grid.Header.Columns[Col].Text + '</th>' + sLineBreak;
Col := Grid.Header.Columns.GetNextVisibleColumn(Col);
end;
Header := Header +
' </tr>' + CRLF +
' </thead>' + CRLF;
CodeIndent(4) + '</tr>' + sLineBreak +
CodeIndent(3) + '</thead>' + sLineBreak;
end;
Header := Header +
' <tbody>' + CRLF;
Header := Header + CodeIndent(3) + '<tbody>' + sLineBreak;
end;

efExcel, efCSV: begin
Expand Down Expand Up @@ -847,10 +846,10 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
// JavaScript Object Notation
Header := '{' + CRLF;
if chkIncludeQuery.Checked then
Header := Header + #9 + '"query": '+FormatPhp(GridData.SQL)+',' + CRLF
Header := Header + CodeIndent + '"query": '+FormatPhp(GridData.SQL)+',' + sLineBreak
else
Header := Header + #9 + '"table": '+FormatPhp(TableName)+',' + CRLF ;
Header := Header + #9 + '"rows":' + CRLF + #9 + '[';
Header := Header + CodeIndent + '"table": '+FormatPhp(TableName)+',' + sLineBreak ;
Header := Header + CodeIndent + '"rows":' + sLineBreak + CodeIndent + '[';
end;

end;
Expand All @@ -873,9 +872,9 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);

// Row preamble
case ExportFormat of
efHTML: tmp := ' <tr>' + CRLF;
efHTML: tmp := CodeIndent(4) + '<tr>' + sLineBreak;

efXML: tmp := #9'<row>' + CRLF;
efXML: tmp := CodeIndent + '<row>' + sLineBreak;

efSQLUpdate: begin
tmp := '';
Expand All @@ -891,7 +890,7 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
if ExportFormat in [efSQLInsert, efSQLDeleteInsert] then
tmp := tmp + 'INSERT'
else if ExportFormat = efSQLInsertIgnore then
tmp := tmp + 'INSERT IGNORE'
tmp := tmp + 'INSERT IGNORE'
else
tmp := tmp + 'REPLACE';
tmp := tmp + ' INTO '+GridData.Connection.QuoteIdent(Tablename);
Expand All @@ -912,15 +911,15 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);

efTextile, efJiraTextile: tmp := TrimLeft(Separator);

efPHPArray: tmp := #9 + 'array('+CRLF;
efPHPArray: tmp := CodeIndent + 'array(' + sLineBreak;

efMarkDown: tmp := '| ';

efJSON: begin
if chkIncludeColumnNames.Checked then
tmp := CRLF + #9#9 + '{' + CRLF
tmp := sLineBreak + CodeIndent(2) + '{' + sLineBreak
else
tmp := CRLF + #9#9 + '[' + CRLF
tmp := sLineBreak + CodeIndent(2) + '[' + sLineBreak
end;

efJSONLines: begin
Expand Down Expand Up @@ -961,7 +960,7 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
efHTML: begin
// Escape HTML control characters in data.
Data := HTMLSpecialChars(Data);
tmp := tmp + ' <td class="col' + IntToStr(Col) + '">' + Data + '</td>' + CRLF;
tmp := tmp + CodeIndent(5) + '<td class="col' + IntToStr(Col) + '">' + Data + '</td>' + sLineBreak;
end;

efExcel, efCSV: begin
Expand Down Expand Up @@ -994,7 +993,7 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);

efXML: begin
// Print cell start tag.
tmp := tmp + #9#9'<field';
tmp := tmp + CodeIndent(2) + '<field';
if chkIncludeColumnNames.Checked then
tmp := tmp + ' name="' + HTMLSpecialChars(Grid.Header.Columns[Col].Text) + '"';
if GridData.IsNull(ResultCol) then
Expand Down Expand Up @@ -1040,13 +1039,13 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
end;

if chkIncludeColumnNames.Checked then
tmp := tmp + #9#9 + FormatPhp(Grid.Header.Columns[Col].Text) + ' => ' + Data + ','+CRLF
tmp := tmp + CodeIndent(2) + FormatPhp(Grid.Header.Columns[Col].Text) + ' => ' + Data + ',' + sLineBreak
else
tmp := tmp + #9#9 + Data + ','+CRLF;
tmp := tmp + CodeIndent(2) + Data + ',' + sLineBreak;
end;

efJSON: begin
tmp := tmp + #9#9#9;
tmp := tmp + CodeIndent(3);
if chkIncludeColumnNames.Checked then
tmp := tmp + FormatPhp(Grid.Header.Columns[Col].Text) + ': ';
if GridData.IsNull(ResultCol) then
Expand Down Expand Up @@ -1087,13 +1086,13 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
// Row epilogue
case ExportFormat of
efHTML:
tmp := tmp + ' </tr>' + CRLF;
tmp := tmp + CodeIndent(4) + '</tr>' + sLineBreak;
efExcel, efCSV, efLaTeX, efTextile, efJiraTextile: begin
Delete(tmp, Length(tmp)-Length(Separator)+1, Length(Separator));
tmp := tmp + Terminator;
end;
efXML:
tmp := tmp + #9'</row>' + CRLF;
tmp := tmp + CodeIndent + '</row>' + sLineBreak;
efSQLInsert, efSQLInsertIgnore, efSQLReplace, efSQLDeleteInsert: begin
Delete(tmp, Length(tmp)-1, 2);
tmp := tmp + ');' + CRLF;
Expand All @@ -1103,15 +1102,15 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
tmp := tmp + ' WHERE' + GridData.GetWhereClause + ';' + sLineBreak;
end;
efPHPArray:
tmp := tmp + #9 + '),' + CRLF;
tmp := tmp + CodeIndent + '),' + sLineBreak;
efMarkDown:
tmp := tmp + Terminator;
efJSON: begin
Delete(tmp, length(tmp)-2,2);
if chkIncludeColumnNames.Checked then
tmp := tmp + #9#9 + '},'
tmp := tmp + CodeIndent(2) + '},'
else
tmp := tmp + #9#9 + '],';
tmp := tmp + CodeIndent(2) + '],';
end;
efJSONLines: begin
Delete(tmp, length(tmp)-1,2);
Expand All @@ -1130,14 +1129,14 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
case ExportFormat of
efHTML: begin
tmp :=
' </tbody>' + CRLF +
' </table>' + CRLF + CRLF +
' <p>' + CRLF +
' <em>generated ' + DateToStr(now) + ' ' + TimeToStr(now) +
' by <a href="'+APPDOMAIN+'">' + APPNAME + ' ' + Mainform.AppVersion + '</a></em>' + CRLF +
' </p>' + CRLF + CRLF +
' </body>' + CRLF +
'</html>' + CRLF;
CodeIndent(3) + '</tbody>' + sLineBreak +
CodeIndent(2) + '</table>' + sLineBreak + sLineBreak +
CodeIndent(2) + '<p>' + sLineBreak +
CodeIndent(3) + '<em>generated ' + DateToStr(now) + ' ' + TimeToStr(now) +
CodeIndent(3) + 'by <a href="'+APPDOMAIN+'">' + APPNAME + ' ' + Mainform.AppVersion + '</a></em>' + sLineBreak +
CodeIndent(2) + '</p>' + sLineBreak + sLineBreak +
CodeIndent + '</body>' + sLineBreak +
'</html>' + sLineBreak;
end;
efXML: begin
if chkIncludeQuery.Checked then
Expand All @@ -1152,7 +1151,7 @@ procedure TfrmExportGrid.btnOKClick(Sender: TObject);
end;
efJSON: begin
S.Size := S.Size - 1;
tmp := CRLF + #9 + ']' + CRLF + '}';
tmp := sLineBreak + CodeIndent + ']' + sLineBreak + '}';
end;
else
tmp := '';
Expand Down
18 changes: 9 additions & 9 deletions source/main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -13254,24 +13254,24 @@ procedure TMainForm.menuQueryHelpersGenerateStatementClick(Sender: TObject);


if MenuItem = menuQueryHelpersGenerateSelect then begin
sql := 'SELECT '+Implode(', ', ColumnNames)+CRLF+
#9'FROM '+ActiveDbObj.QuotedName(False);
sql := 'SELECT ' + Implode(', ', ColumnNames) + SLineBreak +
CodeIndent + 'FROM '+ActiveDbObj.QuotedName(False);

end else if MenuItem = menuQueryHelpersGenerateInsert then begin
sql := 'INSERT INTO '+ActiveDbObj.QuotedName(False)+CRLF+
#9'('+Implode(', ', ColumnNames)+')'+CRLF+
#9'VALUES ('+Implode(', ', DefaultValues)+')';
sql := 'INSERT INTO ' + ActiveDbObj.QuotedName(False) + SLineBreak +
CodeIndent + '(' + Implode(', ', ColumnNames) + ')' + SLineBreak +
CodeIndent + 'VALUES (' + Implode(', ', DefaultValues) + ')';

end else if MenuItem = menuQueryHelpersGenerateUpdate then begin
sql := 'UPDATE '+ActiveDbObj.QuotedName(False)+CRLF+#9'SET'+CRLF;
sql := 'UPDATE ' + ActiveDbObj.QuotedName(False) + SLineBreak + CodeIndent + 'SET' + SLineBreak;
if ColumnNames.Count > 0 then begin
for i:=0 to ColumnNames.Count-1 do begin
sql := sql + #9#9 + ColumnNames[i] + '=' + DefaultValues[i] + ',' + CRLF;
sql := sql + CodeIndent(2) + ColumnNames[i] + '=' + DefaultValues[i] + ',' + SLineBreak;
end;
Delete(sql, Length(sql)-2, 1);
end else
sql := sql + #9#9'??? # No column names selected!'+CRLF;
sql := sql + #9'WHERE ' + WhereClause;
sql := sql + CodeIndent(2) + '??? # No column names selected!' + SLineBreak;
sql := sql + CodeIndent + 'WHERE ' + WhereClause;

end else if MenuItem = menuQueryHelpersGenerateDelete then begin
sql := 'DELETE FROM '+ActiveDbObj.QuotedName(False)+' WHERE ' + WhereClause;
Expand Down
24 changes: 12 additions & 12 deletions source/preferences.pas
Original file line number Diff line number Diff line change
Expand Up @@ -560,18 +560,18 @@ procedure TfrmPreferences.FormCreate(Sender: TObject);
comboSQLFontName.Sorted := True;
updownCompletionProposalInterval.Min := 0;
updownCompletionProposalInterval.Max := MaxInt;
SynMemoSQLSample.Text := 'SELECT DATE_SUB(NOW(), INTERVAL 1 DAY),' + CRLF +
#9'''String literal'' AS lit' + CRLF +
'FROM tableA AS ta' + CRLF +
'WHERE `columnA` IS NULL;' + CRLF +
CRLF +
'-- A comment' + CRLF +
'# Old style comment' + CRLF +
'/* Multi line comment */' + CRLF +
CRLF +
'CREATE TABLE /*!32312 IF NOT EXISTS*/ tableB (' + CRLF +
#9'id INT,' + CRLF +
#9'name VARCHAR(30) DEFAULT "standard"' + CRLF +
SynMemoSQLSample.Text := 'SELECT DATE_SUB(NOW(), INTERVAL 1 DAY),' + sLineBreak +
CodeIndent + '''String literal'' AS lit' + sLineBreak +
'FROM tableA AS ta' + sLineBreak +
'WHERE `columnA` IS NULL;' + sLineBreak +
sLineBreak +
'-- A comment' + sLineBreak +
'# Old style comment' + sLineBreak +
'/* Multi line comment */' + sLineBreak +
sLineBreak +
'CREATE TABLE /*!32312 IF NOT EXISTS*/ tableB (' + sLineBreak +
CodeIndent + 'id INT,' + sLineBreak +
CodeIndent + 'name VARCHAR(30) DEFAULT "standard"' + sLineBreak +
')';
SynSQLSynSQLSample.TableNames.CommaText := 'tableA,tableB';
for i:=0 to SynSQLSynSQLSample.AttrCount - 1 do begin
Expand Down

0 comments on commit db014bd

Please sign in to comment.