diff --git a/README.md b/README.md index 8f1a6ff..49b4d94 100644 --- a/README.md +++ b/README.md @@ -329,7 +329,7 @@ English version issue #18 24.09.2024 - Компиляция для win с использованием настройки stdcpp17 - - В редактор запросов добавлен диалог трансформации текста при помощи PCRE выражения, с подсветкой ситаксиса и найденных групп. + - В редактор запросов добавлен диалог трансформации текста при помощи PCRE выражения, с подсветкой синтаксиса и найденных групп. Вызывается Ctrl+M. Настройки диалога сохраняются в pgadmin3opt.json. Статья в wiki https://github.com/levinsv/pgadmin3/wiki/Transformation-text - Для редактирования pgadmin3opt.json добавлен элемент в диалог настройки. Json настройки представлены в виде дерева. @@ -344,4 +344,19 @@ English version issue #18 Т.е. это ожидание данных от клиента только при начатых транзакциях. Статья в wiki https://github.com/levinsv/pgadmin3/wiki/Waits-events +17.12.2024 + + - Добавлена возможность быстрой подстановки слов на латинице по нажатию + Alt+RIGHT. Возможность включается настройкой "Use word hints". + Список слов составляется при загрузке запроса и по мере ввода новых слов. + - При выполнении запроса добавлена возможность заменять переменные вида + $1, $2, ... или :variableName на пользовательские значения введённые + в диалоге. Пока можно заменять переменные в запросах select,update,delete,insert. + Перед отправкой запроса на сервер переменные заменяются простой текстовой заменой. + Запрос который выполнен на сервере можно посмотреть на вкладке История. + Возможность включается настройкой "Replace variables in a query". + Выделить правой кнопкой выполненый запрос не получиться т.к. текст выполненого запроса + и текст в редакторе будет отличаться. + Значения для замены сохраняются в pgadmin3opt.json (при завершении программы). + diff --git a/ctl/ctlSQLBox.cpp b/ctl/ctlSQLBox.cpp index e5a3b00..1071cea 100644 --- a/ctl/ctlSQLBox.cpp +++ b/ctl/ctlSQLBox.cpp @@ -90,7 +90,7 @@ ctlSQLBox::ctlSQLBox(wxWindow *parent, wxWindowID id, const wxPoint &pos, const m_autocompDisabled = false; process = 0; processID = 0; - + m_hint_mode = false; Create(parent, id, pos, size, style); } //void ctlSQLBox::OnBackGround(wxEraseEvent &event) { @@ -596,11 +596,70 @@ void ctlSQLBox::OnFuncHelp(wxCommandEvent& ev) { } } +void ctlSQLBox::Colourise(int start, int end) +{ + wxStyledTextCtrl::Colourise(start, end); + if (start == 0 && end == GetLength() && settings->GetUseHintWords()) { + // build hint dictionary + m_hint_words.clear(); + wxString s = GetText(); + int pos = start; + int pend = -1; + int endPos = end; + int hword = pos; + wxChar ch; + int st; + bool isword = false; + while (pos < endPos) { + ch = GetCharAt(pos); + st = GetStyleAt(pos) & 0x1F; + if ( + // st != wxSTC_SQL_COMMENTLINE && + st == wxSTC_SQL_STRING + || st == wxSTC_SQL_CHARACTER + // && st != wxSTC_SQL_COMMENT + ) + { + if (isword) goto add_dic; + goto nextchar; + } + if (wxIsalnum(ch)|| ch=='_') { + if (!isword || pos==0) { + isword = true; hword = pos; + goto nextchar; + } + else + goto nextchar; + } + else { + // no word + if (!isword) goto nextchar; + } + // + add_dic: + isword = false; + if (hword >= 0) { + wxString w = GetTextRange(hword, pos); + if (w.length() > 1 && !wxIsdigit(w[0])) { + auto [iter, has_been_inserted] = m_hint_words.insert(w); + } + } + hword = -1; + +nextchar: +#ifdef WIN32 + int i = IsDBCSLeadByte(ch) ? 2 : 1; +#else + int i = 1; + if (ch > 255) i = 2; +#endif + pos = pos + i; + } + } +} void ctlSQLBox::OnKeyDown(wxKeyEvent &event) { - - if (event.GetKeyCode() == WXK_ESCAPE && m_PopupHelp) { delete m_PopupHelp; m_PopupHelp = NULL; } int pos = GetCurrentPos(); wxChar ch = GetCharAt(pos - 1); @@ -639,6 +698,8 @@ void ctlSQLBox::OnKeyDown(wxKeyEvent &event) if (match != wxSTC_INVALID_POSITION) BraceHighlight(pos, match); } + int homewordpos = pos; + bool istop = false; while ((pos--) >= 0) { ch = GetCharAt(pos); @@ -654,9 +715,106 @@ void ctlSQLBox::OnKeyDown(wxKeyEvent &event) BraceBadLight(pos); } } + if ((wxIsalnum(ch)|| ch =='_') && !istop && st != 7) homewordpos--; else istop = true; } + // hints words + wxChar uc = event.GetUnicodeKey(); + bool rep = event.IsAutoRepeat(); + if (event.GetModifiers() == wxMOD_SHIFT && uc == '-') uc = '_'; + pos = GetCurrentPos(); + wxString s; + wxString hint; + int showpos; + if (settings->GetUseHintWords()) { + if (homewordpos >= 0 && homewordpos != pos && !rep) { + bool isAddDict = false; + s = GetTextRange(homewordpos, pos); + if (uc != WXK_NONE) + if (uc == 8) s = s.Left(s.length() - 1); + else if (uc >= 'A') s += uc; + if (uc >= ' ' && uc < 'A') isAddDict = true; + auto it = m_hint_words.lower_bound(s); + wxString strlist; + if (s.length() > 0) { + while (it != m_hint_words.end()) { + hint = *it++; + wxString f1 = s.Upper(); + wxString f2 = hint.substr(0, s.length()).Upper(); + if (!(f1 == f2)) { + hint = ""; + break; + } + if (s.length() == hint.length()) { + hint = ""; + isAddDict = false; + continue; + } + break; + } + } + showpos = PositionRelative(pos, -s.length()); + if (isAddDict && hint.IsEmpty()) { + if (s.length() > 1 && !wxIsdigit(s[0])) { + auto [iter, has_been_inserted] = m_hint_words.insert(s); + } + } + if ((uc >= ' ' && uc < 'A')) hint = ""; + } + if (m_hint_mode) { + if (event.GetKeyCode() == WXK_RIGHT && event.GetModifiers() == wxMOD_ALT && !hint.IsEmpty()) { + wxString ins = hint.substr(s.length()); + InsertText(GetCurrentPos(), ins); + SetCurrentPos(GetCurrentPos() + ins.Length()); + SetSelection(GetCurrentPos(), GetCurrentPos()); + CallTipCancel(); + m_hint_mode = false; + return; + } + if (hint.IsEmpty() && !(event.GetModifiers() == wxMOD_ALT || event.GetModifiers() == wxMOD_CONTROL)) { + m_hint_mode = false; + CallTipCancel(); + } + else { + if (uc != WXK_NONE && !hint.IsEmpty()) { + if (uc == 8 && CallTipActive()) { + //CallTipSetPosAtStart(0); + CallTipSetHighlight(s.length(), hint.length()); + } + else { + CallTipShow(showpos, hint); + CallTipSetPosAtStart(0); + CallTipSetHighlight(s.length(), hint.length()); + m_hint_mode = true; + } + } + } + } + else { + if (!CallTipActive() && !hint.IsEmpty() && !(event.GetModifiers() == wxMOD_ALT || event.GetModifiers() == wxMOD_CONTROL)) { + if (uc != WXK_NONE) { + if (uc == 8) { + //showpos--; + showpos = showpos - 1; + } + else showpos += 1; + if (!CallTipActive()) CallTipShow(showpos, hint); + CallTipSetPosAtStart(0); + CallTipSetHighlight(s.length(), hint.length()); + m_hint_mode = true; + } + else { + if (CallTipActive()) { + CallTipCancel(); + m_hint_mode = false; + } + } + } + + } + // + } //wxString autoreplace[]={wxT("se"),wxT("select * from"),wxT("sc"),wxT("select count(*) from"),wxT("si"),wxT("select * from info_oper where"),wxT("sh"),wxT("select * from info_history where")}; #ifdef __WXGTK__ event.m_metaDown = false; @@ -670,6 +828,7 @@ void ctlSQLBox::OnKeyDown(wxKeyEvent &event) if (CallTipActive()) CallTipCancel(); event.Skip(); + m_hint_mode = false; return; } @@ -702,7 +861,7 @@ void ctlSQLBox::OnKeyDown(wxKeyEvent &event) CallTipShow(pos-l,calltip); CallTipSetHighlight(0,ct_hl); - + m_hint_mode = false; } //t = GetTextRange(pos-rpl.Length(), pos); @@ -1193,13 +1352,14 @@ void ctlSQLBox::AbortProcess() processID = 0; } } -long ctlSQLBox::SelectQuery(int startposition) +std::pair ctlSQLBox::SelectQuery(int startposition) { + struct result { int start; int end; }; int pos = GetCurrentPos(); wxChar ch = GetCharAt(pos - 1); wxChar nextch = GetCharAt(pos); int st = GetStyleAt(pos - 1); - int endPos = GetTextLength(); + int endPos = GetLength(); int pend=endPos; int pstart=0; @@ -1256,7 +1416,8 @@ long ctlSQLBox::SelectQuery(int startposition) } if (startposition<0) SetSelection(pstart,pend); - return (pstart <<16)+pend; + //return result {pstart,pend}; + return std::make_pair(pstart, pend); } void ctlSQLBox::HighlightBrace(int lb, int rb) { @@ -1586,10 +1747,8 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev) tab_ret = tab_complete(what.mb_str(wxConvUTF8), spaceidx + 1, what.Len() + 1, m_database); wxString wxRet; if ((tab_ret == NULL || tab_ret[0] == '\0')&&(what.Right(1)>' ')){ - long p = SelectQuery(pos); - int s = p >> 16; - - wxString sql = GetTextRange(s, p & 65535); + auto [s,e] = SelectQuery(pos); + wxString sql = GetTextRange(s, e); FSQL::FormatterSQL f(sql); int rez = f.ParseSql(0); if (rez >= 0) { diff --git a/dlg/dlgVariable.cpp b/dlg/dlgVariable.cpp new file mode 100644 index 0000000..98a0792 --- /dev/null +++ b/dlg/dlgVariable.cpp @@ -0,0 +1,299 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgVariable.cpp - Variable replace +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgVariable.h" +#include "ctl/ctlSQLBox.h" +#include +#include + +BEGIN_EVENT_TABLE(dlgVariable, pgDialog) +EVT_BUTTON(wxID_CANCEL, dlgVariable::OnCancel) +EVT_BUTTON(wxID_OK, dlgVariable::OnOk) +EVT_BUTTON(wxID_IGNORE, dlgVariable::OnIgnore) +EVT_CLOSE(dlgVariable::OnClose) +END_EVENT_TABLE() + + +#define btnOk CTRL_BUTTON("wxID_OK") +#define btnCancel CTRL_BUTTON("wxID_CANCEL") + + +const char* const xrc_data_head = R"( + + + Variables + 300,166d + + + 1 + 0 + 0 + + + 2 + 1 + +)"; +const char* const xrc_data_tail = R"( + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + Ignore variable replace + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + Close the dialog + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + +)"; +dlgVariable::dlgVariable(ctlSQLBox* parent, wxString& query, std::vector& var_list) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + wxString varname = "var"; + wxString xmlbody; + wxString l = R"( + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + %s + Enter the variable value + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 4 + +)"; + wxJSONValue def(wxJSONType::wxJSONTYPE_OBJECT); + opt.SetType(wxJSONType::wxJSONTYPE_OBJECT); + dlgName = wxT("dlgVariable"); + settings->ReloadJsonFileIfNeed(); + settings->ReadJsonObect(dlgName, opt, def); + + int idx = 1; + for (int i = 0; i < var_list.size(); i++) + { + wxString name = var_list[i].txtVar; + if (name.length() > 1) name = name.substr(1); + + if (unic_name.count(name) > 0) { + idx = unic_name[name]; + continue; + } + else + unic_name[name] = i; + wxString content=""; + varname = wxString::Format("var%d", idx); + xmlbody += wxString::Format(l, varname, name, name,content); + idx++; + } + wxString xrc_data = xrc_data_head + xmlbody + xrc_data_tail; + + wxMemoryInputStream mis(xrc_data, strlen(xrc_data)); + wxScopedPtr xmlDoc(new wxXmlDocument(mis, "UTF-8")); + if (!xmlDoc->IsOk()) + { + return; + } + + if (!wxXmlResource::Get()->LoadDocument(xmlDoc.release(), dlgName)) + { + return; + } + + LoadResource(parent, dlgName); + RestorePosition(); + //wxStaticText statusBar = new wxStatusBar(this, -1, flags); + int flags = 0; + + // Icon + appearanceFactory->SetIcons(this); + //if (startsqlbox->GetQueryBook()==NULL) chkOptionsAllFind->Disable(); + // Load up the defaults + wxString val; + bool bVal; + v_list = var_list; + originalquery = query; + + for (int i = 0; i < v_list.size(); i++) + { + wxString name = v_list[i].txtVar; + if (name.length() > 1) name = name.substr(1); + ctlComboBox* cb = CTRL_COMBOBOX2("cb" + name); + if (cb) { + if (opt.HasMember(name) && cb->GetCount()==0) { + + cb->Bind(wxEVT_COMMAND_TEXT_UPDATED, &dlgVariable::OnChangeCombo,this); + wxJSONValue ar(wxJSONType::wxJSONTYPE_ARRAY); + int ar_size = opt[name].Size(); + for (int i = 0; i < opt[name].Size(); i++) { + wxString val = opt[name][i].AsString(); + cb->AppendString(val); + } + if (ar_size > 0) cb->SetSelection(0); + } + } + } + + wxCommandEvent ev; + OnChange(ev); + ResetTabOrder(); +} +void dlgVariable::OnChangeCombo(wxCommandEvent& ev) { + ctlComboBox *c= (ctlComboBox *) ev.GetEventObject(); + c->GuessSelection(ev); +} +wxString dlgVariable::GetQuery() { + return modquery; +} +dlgVariable::~dlgVariable() +{ + SavePosition(); + wxXmlResource::Get()->Unload(dlgName); +} + +void dlgVariable::SaveSettings() +{ + +} + +void dlgVariable::OnClose(wxCloseEvent &ev) +{ + SaveSettings(); + pgDialog::OnClose(ev); +} + +void dlgVariable::OnCancel(wxCommandEvent &ev) +{ + //SaveSettings(); + wxCloseEvent e; + pgDialog::OnClose(e); +} + +void dlgVariable::OnChange(wxCommandEvent &ev) +{ +} + +void dlgVariable::OnIgnore(wxCommandEvent &ev) +{ + //if (txtFind->GetValue().IsEmpty()) return; + if (IsModal()) + EndModal(wxID_IGNORE); + +} + +void dlgVariable::OnOk(wxCommandEvent &ev) +{ + //if (txtFind->GetValue().IsEmpty()) return; + + int idx = 0; + int lastpos = 0; + std::map unic_n; + for (int i = 0; i < v_list.size(); i++) + { + wxString name = v_list[i].txtVar; + if (name.length() > 1) name = name.substr(1); + ctlComboBox* cb = CTRL_COMBOBOX2("cb"+name); + wxString varVal=cb->GetValue(); + v_list[i].txtReplace = varVal; + // save json + if (unic_n.count(name) > 0) { + + } + else { + unic_n[name] = i; + int sel = cb->GetGuessedSelection(); + wxJSONValue ar(wxJSONType::wxJSONTYPE_ARRAY); + int limit = 20; + if (opt.HasMember(name)) { + int ar_size = opt[name].Size(); + for (int i = 0; i < ar_size; i++) { + wxString val = opt[name][i].AsString(); + if (i == 0) ar.Append(varVal); + if (i == sel) continue; + ar.Append(val); + if (i == limit) break; + } + } + else { + // first + ar.Append(varVal); + } + opt[name] = ar; + } + // var replace + int startv = v_list[i].position; + modquery += originalquery.substr(lastpos, startv - lastpos); + lastpos += startv - lastpos; + modquery += varVal; + lastpos += v_list[i].txtVar.length(); + } + if (lastpos< originalquery.length()) modquery += originalquery.substr(lastpos); + + settings->WriteJsonObect(dlgName, opt); + SaveSettings(); + if (IsModal()) + EndModal(wxID_OK); + +} + +void dlgVariable::FindNext() +{ +} + + +void dlgVariable::ResetTabOrder() +{ +// btnOk->MoveAfterInTabOrder(chkOptionsUseRegexps); +// btnCancel->MoveAfterInTabOrder(btnReplaceAll); +} + diff --git a/frm/frmOptions.cpp b/frm/frmOptions.cpp index d370e83..9ddcbbf 100644 --- a/frm/frmOptions.cpp +++ b/frm/frmOptions.cpp @@ -139,6 +139,8 @@ #define chkASUTPstyle CTRL_CHECKBOX("chkASUTPstyle") #define chkHideQueryHistory CTRL_CHECKBOX("chkHideQueryHistory") #define chkAutosaveQuery CTRL_CHECKBOX("chkAutosaveQuery") +#define chkUseHintWords CTRL_CHECKBOX("chkUseHintWords") +#define chkReplaceVars CTRL_CHECKBOX("chkReplaceVars") #define chkJumpRoot CTRL_CHECKBOX("chkJumpRoot") #define menus CTRL_TREE("menus") #define pnlBrowserDisplay CTRL_PANEL("pnlBrowserDisplay") @@ -386,6 +388,9 @@ frmOptions::frmOptions(frmMain *parent) chkASUTPstyle->SetValue(settings->GetASUTPstyle()); chkHideQueryHistory->SetValue(settings->GetHideQueryHistory()); chkAutosaveQuery->SetValue(settings->GetAutosaveQuery()); + chkUseHintWords->SetValue(settings->GetUseHintWords()); + chkReplaceVars->SetValue(settings->GetReplaceVars()); + chkJumpRoot->SetValue(settings->GetJumpRoot()); chkNumberPretty->SetValue(settings->GetNumberPretty()); cbLanguage->Append(_("Default")); @@ -938,6 +943,16 @@ void frmOptions::OnOK(wxCommandEvent &ev) changed = true; settings->SetAutosaveQuery(chkAutosaveQuery->GetValue()); } + if (settings->GetUseHintWords() != chkUseHintWords->GetValue()) + { + changed = true; + settings->SetUseHintWords(chkUseHintWords->GetValue()); + } + if (settings->GetReplaceVars() != chkReplaceVars->GetValue()) + { + changed = true; + settings->SetReplaceVars(chkReplaceVars->GetValue()); + } if (settings->GetJumpRoot() != chkJumpRoot->GetValue()) { changed = true; diff --git a/frm/frmQuery.cpp b/frm/frmQuery.cpp index 3aa2a26..38bc07c 100644 --- a/frm/frmQuery.cpp +++ b/frm/frmQuery.cpp @@ -59,7 +59,7 @@ #include "utils/misc.h" #include "pgscript/pgsApplication.h" #include "schema/pgPartition.h" - +#include "dlg/dlgVariable.h" // Icons #include "images/sql-32.pngc" @@ -845,7 +845,7 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w lastDir = fn.GetPath(); lastPath = fn.GetFullPath(); OpenLastFile(); - sqlQuery->Colourise(0, query.Length()); + sqlQuery->Colourise(0, sqlQuery->GetLength()); } else if (!query.IsNull()) { @@ -853,7 +853,7 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w SqlBookAddPage(t); sqlQuery->SetText(query); SetLineEndingStyle(); - sqlQuery->Colourise(0, query.Length()); + sqlQuery->Colourise(0, sqlQuery->GetLength()); wxSafeYield(); // needed to process sqlQuery modify event sqlQuery->SetChanged(false); sqlQuery->SetOrigin(ORIGIN_INITIAL); @@ -919,7 +919,7 @@ frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const w SqlBookAddPage(filename); //SqlBookAddPage(true); sqlQuery->SetText(str); - sqlQuery->Colourise(0, str.Length()); + sqlQuery->Colourise(0, sqlQuery->GetLength()); sqlQuery->EmptyUndoBuffer(); sqlQuery->GotoPos(nl); @@ -2297,8 +2297,8 @@ void frmQuery::OnCopy_TableToHtml(wxCommandEvent& ev) if (q.IsEmpty()) return; ctlSQLBox *box = new ctlSQLBox(sqlNotebook, CTL_SQLQUERY, wxDefaultPosition, wxSize(0,0), wxTE_MULTILINE | wxTE_RICH2); box->SetText(q); - box->Colourise(0, box->GetTextLength()); - wxString html = box->TextToHtml(0, box->GetTextLength()); + box->Colourise(0, box->GetLength()); + wxString html = box->TextToHtml(0, box->GetLength()); delete box; sqlResult->CopyTableToHtml(html); @@ -2407,7 +2407,7 @@ void frmQuery::OpenLastFile() if (!str.IsEmpty()) { sqlQuery->SetText(str); - sqlQuery->Colourise(0, str.Length()); + sqlQuery->Colourise(0, sqlQuery->GetLength()); sqlQuery->EmptyUndoBuffer(); wxSafeYield(); // needed to process sqlQuery modify event sqlQuery->SetFilename(lastPath); @@ -2946,7 +2946,7 @@ bool frmQuery::updateFromGqb(bool executing) if(canGenerate) { sqlQuery->SetText(newQuery + wxT("\n")); - sqlQuery->Colourise(0, sqlQuery->GetText().Length()); + sqlQuery->Colourise(0, sqlQuery->GetLength()); wxSafeYield(); // needed to process sqlQuery modify event sqlNotebook->SetSelection(0); sqlQuery->SetChanged(true); @@ -2964,39 +2964,18 @@ void frmQuery::SelectQuery() { bool selected = false; //sqlQuery->GetSelection(); wxString name = sqlQuery->GetSelectedText(); - wxString *q=new wxString[30]; int s,e,i=0; if (!name.IsEmpty()) { - // get the word under cursor: - int endDoc = sqlQuery->GetLength(); - int endPos = sqlQuery->GetSelectionEnd(); - int startPos = sqlQuery->GetSelectionStart(); - while(endPosSelectQuery(startPos); - s=p>>16; - e=p & 65535; - q[i++]=sqlQuery->GetTextRange(s, e); - startPos=e+1; - } - querys=new wxString[i]; - for (int j = 0; j < i; j++) { - querys[j]=q[j]; - } + // never execute //name = sqlQuery->GetTextRange(startPos, endPos); //selected = false; } else { int curPos = sqlQuery->GetCurrentPos(); - p=sqlQuery->SelectQuery(curPos); - s=p>>16; - e=p & 65535; - querys=new wxString[1]; - querys[0]=sqlQuery->GetTextRange(s, e); + auto [s,e] = sqlQuery->SelectQuery(curPos); // группы серверов/Серверы/serverN/Datebases/dbname sqlQuery->SetSelection(s,e); } - delete [] q; } void frmQuery::OnExecuteShift(wxCommandEvent &event) @@ -3031,8 +3010,7 @@ void frmQuery::OnExecute(wxCommandEvent &event) if (queryMenu->IsChecked(MNU_AUTOSELECTQUERY)) { // Auto-select SelectQuery(); - //query = sqlQuery->GetSelectedText(); - query = querys[0]; + query = sqlQuery->GetSelectedText(); } else query = sqlQuery->GetText(); if (query.IsNull()) @@ -3051,6 +3029,49 @@ void frmQuery::OnExecute(wxCommandEvent &event) } //sqlResult->SetRangeLineExecuteSQL(hline,eline); } + if (settings->GetReplaceVars()) { + //check replace parameters + FSQL::FormatterSQL f(query); + FSQL::view_item v; + bool isddm = false; + std::vector v_list; + while (f.GetNextPositionSqlParse() < query.length() && f.ParseSql(0) >= 0) { // many querys + + int i = 0; + int n_check = 0; + while (f.GetItem(i++, v)) { + if (n_check == 0 && v.type == FSQL::type_item::keyword) { + wxString kw = v.txt.Upper(); + if (kw == "WITH" || kw == "SELECT" || kw == "UPDATE" || kw == "INSERT" || kw == "DELETE") { + isddm = true; + } + n_check++; + } + // check bindarg + if (n_check == 1 && v.type == FSQL::type_item::bindarg) { + if (!isddm) break; + + v_list.push_back({ v.srcpos,v.txt,"" }); + } + } + + if (isddm && v_list.size() > 0 && f.GetNextPositionSqlParse() >= query.length()) { + dlgVariable* m_dlgVar = new dlgVariable(sqlQuery, query, v_list); + int rez = m_dlgVar->ShowModal(); + if (rez == wxID_OK) { + query = m_dlgVar->GetQuery(); + } + else if (rez == wxID_IGNORE) { + + } + else { + } + m_dlgVar->Destroy(); + if (rez == wxID_CANCEL) { return; } + break; + } + } + } execQuery(query); sqlQuery->SetFocus(); } @@ -4302,7 +4323,7 @@ void frmQuery::OnChangeQuery(wxCommandEvent &event) if (query.Length() > 0) { sqlQuery->SetText(query); - sqlQuery->Colourise(0, query.Length()); + sqlQuery->Colourise(0, sqlQuery->GetLength()); wxSafeYield(); // needed to process sqlQuery modify event sqlQuery->SetChanged(true); sqlQuery->SetOrigin(ORIGIN_HISTORY); diff --git a/include/ctl/ctlSQLBox.h b/include/ctl/ctlSQLBox.h index cadbdb2..58dfb84 100644 --- a/include/ctl/ctlSQLBox.h +++ b/include/ctl/ctlSQLBox.h @@ -23,7 +23,7 @@ #include "ctl/ctlAuiNotebook.h" #include "utils/popuphelp.h" #include "utils/dlgTransformText.h" - +#include // These structs are from Scintilla.h which isn't easily #included :-( struct CharacterRange { @@ -64,6 +64,7 @@ public: void OnKillFocus(wxFocusEvent &event); // void OnBackGround(wxEraseEvent &event); void SetQueryBook(ctlAuiNotebook *query_book); + void Colourise(int start, int end); ctlAuiNotebook* GetQueryBook() { return sql_query_book; @@ -102,7 +103,7 @@ public: void SetTitle(wxString &title); wxString GetTitle(bool withChangeInd = true); wxString GetChangeIndicator(); - long SelectQuery(int startposition); + std::pair SelectQuery(int startposition); DECLARE_DYNAMIC_CLASS(ctlSQLBox) DECLARE_EVENT_TABLE() @@ -133,8 +134,14 @@ private: dlgFindReplace *m_dlgFindReplace; dlgTransformText *m_dlgTransformText; pgConn *m_database; - bool m_autoIndent, m_autocompDisabled; - + bool m_autoIndent, m_autocompDisabled, m_hint_mode; + struct InsensitiveCompare { + bool operator() (const wxString& a, const wxString& b) const { + return a.CmpNoCase(b)<0; + //return strcasecmp(a.c_str(), b.c_str()) < 0; + } + }; + std::set m_hint_words; // Variables to track info per SQL box wxString m_filename; time_t time_file_mod; diff --git a/include/dlg/dlgVariable.h b/include/dlg/dlgVariable.h new file mode 100644 index 0000000..498eb62 --- /dev/null +++ b/include/dlg/dlgVariable.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgVariable.h - Variables replace +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgVariable_H +#define dlgVariable_H +//#include "pgAdmin3.h" +#include "dlg/dlgClasses.h" +#include "ctl/ctlAuiNotebook.h" + +class ctlSQLBox; +struct var_query { int position = -1; wxString txtVar; wxString txtReplace; }; + +// Class declarations +class dlgVariable : public pgDialog +{ +public: + dlgVariable(ctlSQLBox *parent,wxString &query, std::vector &var_list); + ~dlgVariable(); + void FindNext(); + wxString GetQuery(); + void OnChangeCombo(wxCommandEvent& ev); + +private: + + void OnClose(wxCloseEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnOk(wxCommandEvent &ev); + void OnIgnore(wxCommandEvent &ev); + void ResetTabOrder(); + void SaveSettings(); + wxString modquery,originalquery; + std::map unic_name; + + std::vector v_list; + wxJSONValue opt; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/frm/frmQuery.h b/include/frm/frmQuery.h index 35190bf..1aee9d3 100644 --- a/include/frm/frmQuery.h +++ b/include/frm/frmQuery.h @@ -157,7 +157,7 @@ private: wxStringOutputStream pgsStringOutput; wxTextOutputStream pgsOutput; pgScriptTimer *pgsTimer; - wxString *querys; + //wxString *querys; //GQB related void OnChangeNotebook(wxAuiNotebookEvent &event); void OnChangeNotebookOutpane(wxAuiNotebookEvent &event); diff --git a/include/utils/FormatterSQL.h b/include/utils/FormatterSQL.h index b6f1b86..372e245 100644 --- a/include/utils/FormatterSQL.h +++ b/include/utils/FormatterSQL.h @@ -105,6 +105,7 @@ namespace FSQL { { "having", 6, new_line_align_no_pad | end_from}, { "except", 6, new_line_align_no_pad | end_from}, { "offset", 6, none | end_from}, + { "cursor", 6, none}, { "nothing", 7, none}, { "lateral", 7, none}, { "between", 7, none}, @@ -112,12 +113,16 @@ namespace FSQL { { "nothing", 7, none}, { "default", 7, none}, { "current", 7, none}, + { "prepare", 7, none}, + { "execute", 7, none}, + { "declare", 7, none}, { "distinct", 8, special}, { "conflict", 8, none}, { "recursive", 9, none}, { "intersect", 9, new_line_align_no_pad | end_from}, { "returning", 9, none}, { "ordinality", 10, none}, + { "deallocate", 10, none}, { "materialized", 12, none}, }; struct complite_element { @@ -152,8 +157,9 @@ namespace FSQL { // int ParseSql(int flags); wxString printParseArray(); - void SetSql(const wxString& sqlsrc) { sql = sqlsrc; } + void SetSql(const wxString& sqlsrc) { sql = sqlsrc; lastposition = 0; } int GetIndexItemNextSqlPosition(int sqlPosition); + int GetNextPositionSqlParse(); bool GetItem(int index, FSQL::view_item& item); private: wxString get_list_columns(int startindex, union FSQL::Byte zone); @@ -171,6 +177,7 @@ namespace FSQL { wxPoint neededNewLine; // добавляет новую строку перед первым встреченным не пробельным символом wxRect rect; wxString sql; + int lastposition = 0; std::vector items; std::vector listTable; // перечень таблиц синонимов, подзапросов и функций с колонками //int recurse(int level); diff --git a/include/utils/sysSettings.h b/include/utils/sysSettings.h index ef037b8..cf72fbe 100644 --- a/include/utils/sysSettings.h +++ b/include/utils/sysSettings.h @@ -856,6 +856,27 @@ public: { WriteBool(wxT("HideQueryHistory"), newval); } + + bool GetUseHintWords() const + { + bool b; + Read(wxT("UseHintWords"), &b, false); + return b; + } + void SetUseHintWords(const bool newval) + { + WriteBool(wxT("UseHintWords"), newval); + } + bool GetReplaceVars() const + { + bool b; + Read(wxT("ReplaceVars"), &b, false); + return b; + } + void SetReplaceVars(const bool newval) + { + WriteBool(wxT("ReplaceVars"), newval); + } bool GetAutosaveQuery() const { bool b; diff --git a/pgAdmin3.vcxproj b/pgAdmin3.vcxproj index eb4883b..7bced2f 100644 --- a/pgAdmin3.vcxproj +++ b/pgAdmin3.vcxproj @@ -920,6 +920,7 @@ + @@ -1588,6 +1589,7 @@ + diff --git a/pgAdmin3.vcxproj.filters b/pgAdmin3.vcxproj.filters index bb6d989..76de1ed 100644 --- a/pgAdmin3.vcxproj.filters +++ b/pgAdmin3.vcxproj.filters @@ -523,6 +523,9 @@ dlg + + dlg + frm @@ -2620,6 +2623,9 @@ include\dlg + + include\dlg + include\frm diff --git a/ui/frmOptions.xrc b/ui/frmOptions.xrc index 854b190..bbb0836 100644 --- a/ui/frmOptions.xrc +++ b/ui/frmOptions.xrc @@ -649,6 +649,36 @@ wxEXPAND|wxTOP|wxLEFT|wxRIGHT 4 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxTOP|wxLEFT|wxRIGHT diff --git a/ui/xrcDialogs.cpp b/ui/xrcDialogs.cpp index 63f9a9e..ca69594 100644 --- a/ui/xrcDialogs.cpp +++ b/ui/xrcDialogs.cpp @@ -36333,7 +36333,7 @@ static unsigned char xml_res_file_80[] = { 47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, 10}; -static size_t xml_res_size_81 = 74242; +static size_t xml_res_size_81 = 75702; static unsigned char xml_res_file_81[] = { 60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, 110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, @@ -37781,33 +37781,99 @@ static unsigned char xml_res_file_81[] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, 60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, -116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, -103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69, -70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, -47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,72,105,110, +116,87,111,114,100,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32, +119,111,114,100,32,104,105,110,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,115,101, +72,105,110,116,87,111,114,100,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, -114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, -110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121,84, -111,111,108,67,111,108,111,117,114,115,34,62,10,32,32,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104, -105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, -108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, -99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, -60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, -32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, -47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, -108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, -32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,101,112,108,97,99,101,86,97,114,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,112,108,97,99,101,32,118,97,114,105, +97,98,108,101,115,32,105,110,32,97,32,113,117,101,114,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,82,101,112,108,97,99,101,86,97,114,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111, +108,67,111,108,111,117,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100, +100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, 101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, 120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, 32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,101, diff --git a/utils/FormatterSQL.cpp b/utils/FormatterSQL.cpp index a76410b..8e6ec79 100644 --- a/utils/FormatterSQL.cpp +++ b/utils/FormatterSQL.cpp @@ -25,7 +25,7 @@ int FormatterSQL::GetIndexItemNextSqlPosition(int sqlPosition) { p++; if (it.srcpos < sqlPosition) continue; - while (p >= 0 && items[--p].srcpos == -1) {}; + while (p > 0 && items[--p].srcpos == -1) {}; vi = items[p]; return p; } @@ -421,13 +421,16 @@ wxString FormatterSQL::BuildAutoComplite(int startIndex, int level) { else return wxJoin(cols, ','); } +int FormatterSQL::GetNextPositionSqlParse() { + return lastposition; +} /// /// ParseSql Выполнение разбора текста как SQL выражения /// /// /// Возвращает код ошибки если SQL выражение было не полное или не корректное int FormatterSQL::ParseSql(int flags) { - int i = 0; + int i = lastposition; int lhome = 0; bool str_literal = false; bool ext = false; @@ -708,6 +711,10 @@ int FormatterSQL::ParseSql(int flags) { if ((i - 1) > k) { if (items.size() != 0 && items[items.size() - 1].type == spaces) { // multi space ---> one spaces + if (items[items.size() - 1].srcpos == -1) { // change real space + items[items.size() - 1].srcpos = vi.srcpos; + vi.srcpos = i - 1; + } } else vi.type = spaces; @@ -824,6 +831,18 @@ int FormatterSQL::ParseSql(int flags) { continue; } } + // naming arg + if ((c==':') && ((c2 >= 'a' && c2 <= 'z') || ((c2 >= 'A' && c2 <= 'Z')))) { + k = i - 1; + while (wxIsalpha(c2) || c2 == '_') { + if (i < sql.length()) c2 = sql[i++]; else { i++; break; }; + } + vi.txt = sql.substr(k, i - k - 1); + vi.type = bindarg; + i--; + continue; + } + if (c == ';') break; // separat if (c == ',') { @@ -879,7 +898,7 @@ int FormatterSQL::ParseSql(int flags) { } if (bracket.size() > 0) return -1; // bracet no close - + lastposition = i; return 0; } // mode =2 draw position x,y diff --git a/x64/Release_(3.0)/pgAdmin3.exe b/x64/Release_(3.0)/pgAdmin3.exe index 3eb4b07..12a454a 100644 Binary files a/x64/Release_(3.0)/pgAdmin3.exe and b/x64/Release_(3.0)/pgAdmin3.exe differ