Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions out/locale/en/LC_MESSAGES/default.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ msgid ""
msgstr ""
"Project-Id-Version: HeidiSQL\n"
"POT-Creation-Date: 2012-11-05 21:40\n"
"PO-Revision-Date: 2022-12-31 11:47+0100\n"
"PO-Revision-Date: 2023-09-24 18:57+0200\n"
"Last-Translator: Ansgar Becker <anse@heidisql.com>\n"
"Language-Team: English (http://www.transifex.com/projects/p/heidisql/language/en/)\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.2.2\n"
"X-Generator: Poedit 3.3.2\n"

#. AboutBox..Caption
#: about.dfm:5
Expand Down Expand Up @@ -6601,3 +6601,15 @@ msgstr "Generate SQL"

msgid "Execute in new tab"
msgstr "Execute in new tab"

msgid "Select reformatter"
msgstr "Select reformatter"

msgid "Internal"
msgstr "Internal"

msgid "Online on %s (%s)"
msgstr "Online on %s (%s)"

msgid "Empty result from online reformatter"
msgstr "Empty result from online reformatter"
3 changes: 2 additions & 1 deletion packages/Delphi11.2/heidisql.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ uses
generic_types in '..\..\source\generic_types.pas',
customize_highlighter in '..\..\source\customize_highlighter.pas' {frmCustomizeHighlighter},
Xml.VerySimple in '..\..\source\Xml.VerySimple.pas',
Sequal.Suggest in '..\..\source\Sequal.Suggest.pas' {SequalSuggestForm};
Sequal.Suggest in '..\..\source\Sequal.Suggest.pas' {SequalSuggestForm},
reformatter in '..\..\source\reformatter.pas' {frmReformatter};

{.$R *.RES}
{$R ..\..\res\icon.RES}
Expand Down
4 changes: 4 additions & 0 deletions packages/Delphi11.2/heidisql.dproj
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@
<Form>SequalSuggestForm</Form>
<FormType>dfm</FormType>
</DCCReference>
<DCCReference Include="..\..\source\reformatter.pas">
<Form>frmReformatter</Form>
<FormType>dfm</FormType>
</DCCReference>
<None Include="..\..\source\const.inc"/>
<BuildConfiguration Include="Base">
<Key>Base</Key>
Expand Down
112 changes: 2 additions & 110 deletions source/apphelpers.pas
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ TSqlTranspiler = class(TObject)
asThemePreviewWidth, asThemePreviewHeight, asThemePreviewTop, asThemePreviewLeft,
asCreateDbCollation, asRealTrailingZeros,
asSequalSuggestWindowWidth, asSequalSuggestWindowHeight, asSequalSuggestPrompt, asSequalSuggestRecentPrompts,
asReformatter,
asUnused);
TAppSetting = record
Name: String;
Expand Down Expand Up @@ -359,7 +360,6 @@ TAppSettings = class(TObject)
function DateTimeToStrDef(DateTime: TDateTime; Default: String): String;
function TruncDef(X: Real; Default: Int64): Int64;
function GetLightness(AColor: TColor): Byte;
function ReformatSQL(SQL: String): String;
function ParamBlobToStr(lpData: Pointer): String;
function ParamStrToBlob(out cbData: DWORD): Pointer;
function CheckForSecondInstance: Boolean;
Expand Down Expand Up @@ -1712,115 +1712,6 @@ function GetLightness(AColor: TColor): Byte;
end;


function ReformatSQL(SQL: String): String;
var
Conn: TDBConnection;
SQLFunc: TSQLFunction;
AllKeywords, ImportantKeywords, PairKeywords: TStringList;
i, Run, KeywordMaxLen: Integer;
IsEsc, IsQuote, InComment, InBigComment, InString, InKeyword, InIdent, LastWasComment: Boolean;
c, p: Char;
Keyword, PreviousKeyword, TestPair: String;
Datatypes: TDBDataTypeArray;
const
WordChars = ['a'..'z', 'A'..'Z', '0'..'9', '_', '.'];
WhiteSpaces = [#9, #10, #13, #32];
begin
Conn := MainForm.ActiveConnection;
// Known SQL keywords, get converted to UPPERCASE
AllKeywords := TStringList.Create;
AllKeywords.Text := MySQLKeywords.Text;

for SQLFunc in Conn.SQLFunctions do begin
// Leave out operator functions like ">>", and the "X()" function so hex values don't get touched
if (SQLFunc.Declaration <> '') and (SQLFunc.Name <> 'X') then
AllKeywords.Add(SQLFunc.Name);
end;
Datatypes := Conn.Datatypes;
for i:=Low(Datatypes) to High(Datatypes) do
AllKeywords.Add(Datatypes[i].Name);
KeywordMaxLen := 0;
for i:=0 to AllKeywords.Count-1 do
KeywordMaxLen := Max(KeywordMaxLen, Length(AllKeywords[i]));

// A subset of the above list, each of them will get a linebreak left to it
ImportantKeywords := Explode(',', 'SELECT,FROM,LEFT,RIGHT,STRAIGHT,NATURAL,INNER,JOIN,WHERE,GROUP,ORDER,HAVING,LIMIT,CREATE,DROP,UPDATE,INSERT,REPLACE,TRUNCATE,DELETE');
// Keywords which followers should not get separated into a new line
PairKeywords := Explode(',', 'LEFT,RIGHT,STRAIGHT,NATURAL,INNER,ORDER,GROUP');

IsEsc := False;
InComment := False;
InBigComment := False;
LastWasComment := False;
InString := False;
InIdent := False;
Run := 1;
Result := '';
SQL := SQL + ' ';
SetLength(Result, Length(SQL)*2);
Keyword := '';
PreviousKeyword := '';
for i:=1 to Length(SQL) do begin
c := SQL[i]; // Current char
if i > 1 then p := SQL[i-1] else p := #0; // Previous char

// Detection logic - where are we?
if c = '\' then IsEsc := not IsEsc
else IsEsc := False;
IsQuote := (c = '''') or (c = '"');
if c = '`' then InIdent := not InIdent;
if (not IsEsc) and IsQuote then InString := not InString;
if (c = '#') or ((c = '-') and (p = '-')) then InComment := True;
if ((c = #10) or (c = #13)) and InComment then begin
LastWasComment := True;
InComment := False;
end;
if (c = '*') and (p = '/') and (not InComment) and (not InString) then InBigComment := True;
if (c = '/') and (p = '*') and (not InComment) and (not InString) then InBigComment := False;
InKeyword := (not InComment) and (not InBigComment) and (not InString) and (not InIdent) and CharInSet(c, WordChars);

// Creation of returning text
if InKeyword then begin
Keyword := Keyword + c;
end else begin
if Keyword <> '' then begin
if AllKeywords.IndexOf(KeyWord) > -1 then begin
while (Run > 1) and CharInSet(Result[Run-1], WhiteSpaces) do
Dec(Run);
Keyword := UpperCase(Keyword);
if Run > 1 then begin
// SELECT, WHERE, JOIN etc. get a new line, but don't separate LEFT JOIN with linebreaks
if LastWasComment or ((ImportantKeywords.IndexOf(Keyword) > -1) and (PairKeywords.IndexOf(PreviousKeyword) = -1)) then
Keyword := CRLF + Keyword
else if (Result[Run-1] <> '(') then
Keyword := ' ' + Keyword;
end;
LastWasComment := False;
end;
PreviousKeyword := Trim(Keyword);
Insert(Keyword, Result, Run);
Inc(Run, Length(Keyword));
Keyword := '';
end;
if (not InComment) and (not InBigComment) and (not InString) and (not InIdent) then begin
TestPair := Result[Run-1] + c;
if (TestPair = ' ') or (TestPair = '( ') then begin
c := Result[Run-1];
Dec(Run);
end;
if (TestPair = ' )') or (TestPair = ' ,') then
Dec(Run);
end;
Result[Run] := c;
Inc(Run);
end;

end;

// Cut overlength
SetLength(Result, Run-2);
end;


{ *** TSortItem }

Expand Down Expand Up @@ -3884,6 +3775,7 @@ constructor TAppSettings.Create;
InitSetting(asSequalSuggestWindowHeight, 'SequalSuggestWindowHeight', 400);
InitSetting(asSequalSuggestPrompt, 'SequalSuggestPrompt', 0, False, '');
InitSetting(asSequalSuggestRecentPrompts, 'SequalSuggestRecentPrompts', 0, False, '');
InitSetting(asReformatter, 'Reformatter', 0);

// Default folder for snippets
if FPortableMode then
Expand Down
29 changes: 16 additions & 13 deletions source/main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,8 @@ implementation

uses
About, printlist, dbstructures, dbstructures.mysql, UpdateCheck,
column_selection, data_sorting, grideditlinks, ExportGrid, Vcl.Imaging.jpeg, Vcl.Imaging.GIFImg;
column_selection, data_sorting, grideditlinks, ExportGrid, Vcl.Imaging.jpeg, Vcl.Imaging.GIFImg,
reformatter;



Expand Down Expand Up @@ -12948,7 +12949,6 @@ procedure TMainForm.actReformatSQLExecute(Sender: TObject);
var
m: TCustomSynEdit;
CursorPosStart, CursorPosEnd: Integer;
NewSQL: String;
begin
// Reformat SQL query
m := ActiveSynMemo(False);
Expand All @@ -12960,19 +12960,22 @@ procedure TMainForm.actReformatSQLExecute(Sender: TObject);
CursorPosEnd := m.SelEnd;
if not m.SelAvail then
m.SelectAll;
NewSQL := m.SelText;
if Length(NewSQL) = 0 then
if m.SelLength = 0 then
ErrorDialog(_('Cannot reformat'), _('The current editor is empty.'))
else begin
Screen.Cursor := crHourglass;
m.UndoList.AddGroupBreak;
NewSQL := ReformatSQL(NewSQL);
m.SelText := NewSQL;
m.SelStart := CursorPosStart;
if CursorPosEnd > CursorPosStart then
m.SelEnd := CursorPosStart + Length(NewSQL);
m.UndoList.AddGroupBreak;
Screen.Cursor := crDefault;
frmReformatter := TfrmReformatter.Create(Self);
frmReformatter.InputCode := m.SelText;
if frmReformatter.ShowModal = mrOk then begin
Screen.Cursor := crHourglass;
m.UndoList.AddGroupBreak;
m.SelText := frmReformatter.OutputCode;
m.SelStart := CursorPosStart;
if CursorPosEnd > CursorPosStart then
m.SelEnd := CursorPosStart + Length(frmReformatter.OutputCode);
m.UndoList.AddGroupBreak;
Screen.Cursor := crDefault;
end;
frmReformatter.Free;
end;
end;

Expand Down
59 changes: 59 additions & 0 deletions source/reformatter.dfm
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
object frmReformatter: TfrmReformatter
Left = 0
Top = 0
BorderStyle = bsDialog
Caption = 'Reformat SQL'
ClientHeight = 172
ClientWidth = 328
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = 'Segoe UI'
Font.Style = []
Position = poOwnerFormCenter
OnCreate = FormCreate
OnDestroy = FormDestroy
DesignSize = (
328
172)
TextHeight = 15
object grpReformatter: TRadioGroup
Left = 8
Top = 8
Width = 312
Height = 125
Anchors = [akLeft, akTop, akRight, akBottom]
Caption = 'Select reformatter'
ItemIndex = 0
Items.Strings = (
'Internal'
'Online (heidisql.com)')
TabOrder = 0
end
object btnCancel: TButton
Left = 245
Top = 139
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Cancel = True
Caption = 'Cancel'
ModalResult = 2
TabOrder = 1
ExplicitTop = 200
end
object btnOk: TButton
Left = 164
Top = 139
Width = 75
Height = 25
Anchors = [akRight, akBottom]
Caption = 'OK'
Default = True
ModalResult = 1
TabOrder = 2
OnClick = btnOkClick
ExplicitTop = 200
end
end
Loading