update pgadmin3.exe

This commit is contained in:
lsv 2026-03-19 13:32:57 +05:00
commit 88f1160280
16 changed files with 41207 additions and 41075 deletions

3
.vscode/launch.json vendored
View file

@ -20,6 +20,9 @@
"ignoreFailures": true "ignoreFailures": true
} }
] ]
,"env": {
"LD_LIBRARY_PATH": "${workspaceFolder}/build"
}
} }
] ]
} }

View file

@ -77,7 +77,8 @@ file(GLOB_RECURSE SOURCES
) )
########################################################## ##########################################################
set(RPATH ".")
list(APPEND CMAKE_BUILD_RPATH ${RPATH})
add_executable(${PROJECT_NAME} ) add_executable(${PROJECT_NAME} )
# После сборки — разделить символы и приложение # После сборки — разделить символы и приложение
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD

View file

@ -1047,9 +1047,6 @@ bool pgConn::IsAlive()
int pgConn::GetStatus() const int pgConn::GetStatus() const
{ {
if (!this)
return PGCONN_BAD;
if (conn) if (conn)
((pgConn *)this)->connStatus = PQstatus(conn); ((pgConn *)this)->connStatus = PQstatus(conn);
@ -1246,7 +1243,7 @@ bool pgConn::TableHasColumn(wxString schemaname, wxString tblname, const wxStrin
if (schemaname.IsEmpty()) if (schemaname.IsEmpty())
schemaname = wxT("public"); schemaname = wxT("public");
if (this && GetStatus() == PGCONN_OK) if (GetStatus() == PGCONN_OK)
{ {
tblname.Replace(wxT("\\"), wxT("\\\\")); tblname.Replace(wxT("\\"), wxT("\\\\"));
tblname.Replace(wxT("'"), wxT("''")); tblname.Replace(wxT("'"), wxT("''"));

View file

@ -27,8 +27,10 @@
#define CTRLID_CBDATABASE 4243 #define CTRLID_CBDATABASE 4243
#define CTRLID_CBUSERNAME 4244 #define CTRLID_CBUSERNAME 4244
#define CTRLID_CBROLENAME 4245 #define CTRLID_CBROLENAME 4245
#define CTRLID_CBGROUP 4246
BEGIN_EVENT_TABLE(dlgSelectConnection, DialogWithHelp) BEGIN_EVENT_TABLE(dlgSelectConnection, DialogWithHelp)
EVT_COMBOBOX(CTRLID_CBGROUP, dlgSelectConnection::OnChangeGroup)
EVT_COMBOBOX(CTRLID_CBSERVER, dlgSelectConnection::OnChangeServer) EVT_COMBOBOX(CTRLID_CBSERVER, dlgSelectConnection::OnChangeServer)
EVT_COMBOBOX(CTRLID_CBDATABASE, dlgSelectConnection::OnChangeDatabase) EVT_COMBOBOX(CTRLID_CBDATABASE, dlgSelectConnection::OnChangeDatabase)
EVT_TEXT(CTRLID_CBSERVER, dlgSelectConnection::OnTextChange) EVT_TEXT(CTRLID_CBSERVER, dlgSelectConnection::OnTextChange)
@ -56,17 +58,31 @@ dlgSelectConnection::dlgSelectConnection(wxWindow *parent, frmMain *form) :
if (form != NULL) if (form != NULL)
style |= wxCB_READONLY; style |= wxCB_READONLY;
cbServer = new ctlComboBoxFix(this, CTRLID_CBSERVER, ConvertDialogToPixels(wxPoint(65, 5)), ConvertDialogToPixels(wxSize(135, 12)), style); cbGroup = new wxComboBox(this, CTRLID_CBGROUP, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 5)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style);
cbDatabase = new wxComboBox(this, CTRLID_CBDATABASE, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 20)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); cbServer = new ctlComboBoxFix(this, CTRLID_CBSERVER, ConvertDialogToPixels(wxPoint(70, 20)), ConvertDialogToPixels(wxSize(135, 12)), style);
cbUsername = new wxComboBox(this, CTRLID_CBUSERNAME, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 35)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); cbDatabase = new wxComboBox(this, CTRLID_CBDATABASE, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 35)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style);
cbRolename = new wxComboBox(this, CTRLID_CBROLENAME, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 50)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); cbUsername = new wxComboBox(this, CTRLID_CBUSERNAME, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 50)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style);
cbRolename = new wxComboBox(this, CTRLID_CBROLENAME, wxEmptyString, ConvertDialogToPixels(wxPoint(70, 75)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style);
if (form == NULL) if (form == NULL)
{ {
cbServer->SetValue(settings->Read(wxT("QuickConnect/server"), wxEmptyString)); cbServer->SetValue(settings->Read(wxT("QuickConnect/server"), wxEmptyString));
cbGroup->SetValue(settings->Read(wxT("QuickConnect/group"), wxEmptyString));
cbDatabase->SetValue(settings->Read(wxT("QuickConnect/database"), wxEmptyString)); cbDatabase->SetValue(settings->Read(wxT("QuickConnect/database"), wxEmptyString));
cbUsername->SetValue(settings->Read(wxT("QuickConnect/username"), wxEmptyString)); cbUsername->SetValue(settings->Read(wxT("QuickConnect/username"), wxEmptyString));
cbRolename->SetValue(settings->Read(wxT("QuickConnect/rolename"), wxEmptyString)); cbRolename->SetValue(settings->Read(wxT("QuickConnect/rolename"), wxEmptyString));
} else {
wxTreeItemIdValue foldercookie, servercookie;
wxTreeItemId folderitem, serveritem;
ctlTree *browser = mainForm->GetBrowser();
folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie);
cbGroup->Append("");
while (folderitem)
{
wxString grp=browser->GetItemText(folderitem);
cbGroup->Append(grp);
folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie);
}
} }
btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0);
@ -84,7 +100,16 @@ wxString dlgSelectConnection::GetHelpPage() const
return wxT("connect"); return wxT("connect");
} }
void dlgSelectConnection::OnChangeGroup(wxCommandEvent &ev)
{
int sel = cbGroup->GetCurrentSelection();
if (sel >= 0)
{
bool found=BuildServerCombo(currconn);
if (!found) cbServer->SetSelection(0);
OnChangeServer(ev);
}
}
void dlgSelectConnection::OnChangeServer(wxCommandEvent &ev) void dlgSelectConnection::OnChangeServer(wxCommandEvent &ev)
{ {
int item; int item;
@ -307,6 +332,7 @@ pgConn *dlgSelectConnection::CreateConn(wxString &server, wxString &dbname, wxSt
if (writeMRU) if (writeMRU)
{ {
settings->Write(wxT("QuickConnect/server"), cbServer->GetValue()); settings->Write(wxT("QuickConnect/server"), cbServer->GetValue());
settings->Write(wxT("QuickConnect/group"), cbGroup->GetValue());
settings->Write(wxT("QuickConnect/database"), cbDatabase->GetValue()); settings->Write(wxT("QuickConnect/database"), cbDatabase->GetValue());
settings->Write(wxT("QuickConnect/username"), cbUsername->GetValue()); settings->Write(wxT("QuickConnect/username"), cbUsername->GetValue());
settings->Write(wxT("QuickConnect/rolename"), cbRolename->GetValue()); settings->Write(wxT("QuickConnect/rolename"), cbRolename->GetValue());
@ -314,11 +340,8 @@ pgConn *dlgSelectConnection::CreateConn(wxString &server, wxString &dbname, wxSt
} }
return newconn; return newconn;
} }
bool dlgSelectConnection::BuildServerCombo(pgConn *conn) {
int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb)
{
bool foundServer = false; bool foundServer = false;
cbConnection = cb;
if (mainForm != NULL) if (mainForm != NULL)
{ {
ctlTree *browser = mainForm->GetBrowser(); ctlTree *browser = mainForm->GetBrowser();
@ -326,11 +349,18 @@ int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb)
wxTreeItemId folderitem, serveritem; wxTreeItemId folderitem, serveritem;
pgObject *object; pgObject *object;
pgServer *server; pgServer *server;
wxString grp;
cbServer->Clear();
if (cbGroup->GetCurrentSelection() != wxNOT_FOUND) {
grp=cbGroup->GetValue();
}
folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie);
while (folderitem) while (folderitem)
{ {
if (browser->ItemHasChildren(folderitem)) bool isGroup=true;
if (grp.Length()>0)
if (browser->GetItemText(folderitem)!=grp ) isGroup=false;
if (browser->ItemHasChildren(folderitem) && isGroup)
{ {
serveritem = browser->GetFirstChild(folderitem, servercookie); serveritem = browser->GetFirstChild(folderitem, servercookie);
while (serveritem) while (serveritem)
@ -355,7 +385,6 @@ int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb)
folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie);
} }
} }
cbServer->SetFocus(); cbServer->SetFocus();
wxCommandEvent ev; wxCommandEvent ev;
@ -390,6 +419,15 @@ int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb)
} }
} }
} }
return foundServer;
}
int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb)
{
bool foundServer = false;
cbConnection = cb;
currconn=conn;
foundServer = BuildServerCombo(conn);
return ShowModal(); return ShowModal();
} }

View file

@ -267,8 +267,12 @@ frmMain::frmMain(const wxString &title)
browser->SetFocus(); browser->SetFocus();
wxString selServerName=settings->Read(wxT("Servers/SelectItem"), ""); wxString selServerName=settings->Read(wxT("Servers/SelectItem"), "");
if (selServerName.Len()>0) { if (selServerName.Len()>0) {
wxTreeItemId sel=browser->FindItem(root,selServerName,true); wxTreeItemId sel=browser->FindItem(root,selServerName,false);
if (sel.IsOk()) browser->SelectItem(sel); if (sel.IsOk()) {
browser->SelectItem(sel);
currentObject=browser->GetObject(sel);
//execSelChange(sel, true);
}
} }
@ -1148,6 +1152,25 @@ wxTreeItemId frmMain::RestoreEnvironment(pgServer *server)
int frmMain::ReconnectServer(pgServer *server, bool restore) int frmMain::ReconnectServer(pgServer *server, bool restore)
{ {
if (server->GetPuttyTunnel()) {
// check open port
int port=server->GetPort();
wxString localhost=server->GetName(); // localhost
if (!isPortOpen(localhost,port,500)) {
server->GetPuttyTunnel()->StartDialog(winMain, server); // execute plugin
int count=0;
do {
wxMilliSleep(200);
count++;
} while (!isPortOpen(localhost,port,500) && count<20); // wait create putty tunnel
if (count>=20) {
StartMsg(_("Create putty tunnel error."));
EndMsg(true);
return -1;
}
}
}
// Create a server object and connect it. // Create a server object and connect it.
wxBusyInfo waiting(wxString::Format(_("Connecting to server %s (%s:%d)"), wxBusyInfo waiting(wxString::Format(_("Connecting to server %s (%s:%d)"),
server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this); server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this);
@ -1312,7 +1335,7 @@ void frmMain::StoreServers()
{ {
wxString key; wxString key;
++numServers; ++numServers;
if (cursoritem==serveritem) selServerName=server->GetName(); if (cursoritem==serveritem) selServerName=browser->GetItemText((serveritem));
key.Printf(wxT("Servers/%d/"), numServers); key.Printf(wxT("Servers/%d/"), numServers);
settings->Write(key + wxT("Server"), server->GetName()); settings->Write(key + wxT("Server"), server->GetName());
settings->Write(key + wxT("HostAddr"), server->GetHostAddr()); settings->Write(key + wxT("HostAddr"), server->GetHostAddr());

View file

@ -382,7 +382,7 @@ wxWindow *pluginUtilityFactory::StartDialog(frmMain *form, pgObject *obj)
return 0; return 0;
} }
extern pluginUtilityFactory *puttyTunnel;
bool pluginUtilityFactory::CheckEnable(pgObject *obj) bool pluginUtilityFactory::CheckEnable(pgObject *obj)
{ {
// First check that this is one of the supported server types // First check that this is one of the supported server types
@ -403,7 +403,6 @@ bool pluginUtilityFactory::CheckEnable(pgObject *obj)
if (server_types.Index(serverType) == wxNOT_FOUND) if (server_types.Index(serverType) == wxNOT_FOUND)
return false; return false;
} }
// Now check that this is one of the supported object types // Now check that this is one of the supported object types
// for this plugin. If none are specified, then anything goes // for this plugin. If none are specified, then anything goes
if (obj && applies_to.Count() > 0) if (obj && applies_to.Count() > 0)
@ -414,11 +413,14 @@ bool pluginUtilityFactory::CheckEnable(pgObject *obj)
else { else {
//"puttyforward" //"puttyforward"
int id=GetId(); int id=GetId();
if (winMain==NULL) return false; wxMenu *m=NULL;
wxMenu *m=winMain->GetPluginsMenu(); if (winMain) {
m->SetLabel(id,"[Putty tunnel forward]"); m=winMain->GetPluginsMenu();
m->SetLabel(id,"[Putty tunnel forward]");
}
if (obj->GetMetaType()==PGM_SERVER) { if (obj->GetMetaType()==PGM_SERVER) {
pgServer* srv = (pgServer*) obj; pgServer* srv = (pgServer*) obj;
srv->SetPuttyTunnel(NULL);
wxString host=obj->GetName(); wxString host=obj->GetName();
wxString sport=NumToStr((long)srv->GetPort()); wxString sport=NumToStr((long)srv->GetPort());
wxString f ; wxString f ;
@ -447,8 +449,10 @@ bool pluginUtilityFactory::CheckEnable(pgObject *obj)
if (port.Len()>0 && port[0]=='L' && sport==port.substr(1)) { if (port.Len()>0 && port[0]=='L' && sport==port.substr(1)) {
// found putty config // found putty config
title=filename; title=filename;
m->SetLabel(id,title); if (winMain) m->SetLabel(id,title);
isfound=true; isfound=true;
srv->SetPuttyTunnel(this);
if (!winMain) return false;
return true; return true;
} }
} }

View file

@ -220,7 +220,7 @@ wxSize GetBestSize(wxGrid& grid,
public: public:
void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
const wxRect& rect, int row, int col, bool isSelected); const wxRect& rect, int row, int col, bool isSelected) wxOVERRIDE;
CursorCellRenderer(int thous_pixel_sep); CursorCellRenderer(int thous_pixel_sep);
private: private:
int thousands_pixel_sep; int thousands_pixel_sep;

View file

@ -36,15 +36,17 @@ public:
private: private:
void OnChangeServer(wxCommandEvent &ev); void OnChangeServer(wxCommandEvent &ev);
void OnChangeGroup(wxCommandEvent &ev);
void OnChangeDatabase(wxCommandEvent &ev); void OnChangeDatabase(wxCommandEvent &ev);
void OnTextChange(wxCommandEvent &ev); void OnTextChange(wxCommandEvent &ev);
void OnOK(wxCommandEvent &ev); void OnOK(wxCommandEvent &ev);
void OnCancel(wxCommandEvent &ev); void OnCancel(wxCommandEvent &ev);
bool BuildServerCombo(pgConn *conn);
pgServer *remoteServer; pgServer *remoteServer;
wxBitmapComboBox *cbConnection; wxBitmapComboBox *cbConnection;
ctlComboBoxFix *cbServer; ctlComboBoxFix *cbServer;
wxComboBox *cbDatabase, *cbUsername, *cbRolename; pgConn *currconn;
wxComboBox *cbDatabase, *cbUsername, *cbRolename, *cbGroup;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View file

@ -17,6 +17,7 @@
class frmMain; class frmMain;
class pgServer; class pgServer;
class pluginUtilityFactory;
class pgServerFactory : public pgaFactory class pgServerFactory : public pgaFactory
{ {
@ -366,6 +367,10 @@ public:
void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0);
void ShowHint(frmMain *form, bool force); void ShowHint(frmMain *form, bool force);
void ShowStatistics(frmMain *form, ctlListView *statistics); void ShowStatistics(frmMain *form, ctlListView *statistics);
void SetPuttyTunnel(pluginUtilityFactory *puttytunnel) {
puttyTunnel=puttytunnel;
}
pluginUtilityFactory* GetPuttyTunnel() {return puttyTunnel;}
wxString GetHelpPage(bool forCreate) const wxString GetHelpPage(bool forCreate) const
{ {
return wxT("pg/managing-databases"); return wxT("pg/managing-databases");
@ -448,6 +453,7 @@ public:
{ {
sslcompression = b; sslcompression = b;
} }
#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) #if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT)
//SSH Tunnel //SSH Tunnel
@ -560,6 +566,7 @@ private:
bool inRecovery, replayPaused; bool inRecovery, replayPaused;
wxString receiveLoc, replayLoc, replayTimestamp; wxString receiveLoc, replayLoc, replayTimestamp;
wxDateTime confLoadedSince; wxDateTime confLoadedSince;
pluginUtilityFactory *puttyTunnel=NULL; // if exists putty tunnel for pgServer
#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) #if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT)
bool createSSHTunnel(); bool createSSHTunnel();

View file

@ -282,6 +282,7 @@ wxString qtTypeIdent(const wxString &value); // add " if necessary
bool make_identifier(const wxString &strname, wxString &s, wxString &n, bool islower); bool make_identifier(const wxString &strname, wxString &s, wxString &n, bool islower);
wxSize getScreenSizeForPoint(const wxPoint screenPos); wxSize getScreenSizeForPoint(const wxPoint screenPos);
void showHelpHtml(wxWindow *parent, const wxString &htmlHelp,wxPoint screenPos, wxSize size); void showHelpHtml(wxWindow *parent, const wxString &htmlHelp,wxPoint screenPos, wxSize size);
bool isPortOpen(const wxString& host, int port , int timeout_ms);
#endif #endif

View file

@ -202,7 +202,10 @@ public:
wxDataObjectComposite* dataobj = new wxDataObjectComposite(); wxDataObjectComposite* dataobj = new wxDataObjectComposite();
dataobj->Add(new wxHTMLDataObject(h)); dataobj->Add(new wxHTMLDataObject(h));
wxTheClipboard->SetData(dataobj); wxTheClipboard->SetData(dataobj);
wxTheClipboard->Close(); // fix for linux app crush
wxSafeYield();
wxTheClipboard->Close(); // crush app without wxSafeYield();
} }
else else
{ {

View file

@ -2,39 +2,43 @@
<resource> <resource>
<object class="wxDialog" name="dlgSelectConnection"> <object class="wxDialog" name="dlgSelectConnection">
<title>Connect to Server</title> <title>Connect to Server</title>
<size>205,98d</size> <size>205,109d</size>
<style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU</style> <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU</style>
<object class="wxStaticText" name="stGroup">
<label>Group</label>
<pos>5,7d</pos>
</object>
<object class="wxStaticText" name="stServer"> <object class="wxStaticText" name="stServer">
<label>Server</label> <label>Server</label>
<pos>5,7d</pos> <pos>5,22d</pos>
</object> </object>
<object class="wxStaticText" name="stDatabase"> <object class="wxStaticText" name="stDatabase">
<label>Database</label> <label>Database</label>
<pos>5,22d</pos> <pos>5,37d</pos>
</object> </object>
<object class="wxStaticText" name="stUsername"> <object class="wxStaticText" name="stUsername">
<label>Username</label> <label>Username</label>
<pos>5,37d</pos> <pos>5,54d</pos>
</object> </object>
<object class="wxStaticText" name="stRolename"> <object class="wxStaticText" name="stRolename">
<label>Rolename</label> <label>Rolename</label>
<pos>5,54d</pos> <pos>5,80d</pos>
</object> </object>
<object class="wxButton" name="wxID_HELP"> <object class="wxButton" name="wxID_HELP">
<label>&amp;Help</label> <label>&amp;Help</label>
<pos>2,80d</pos> <pos>2,95d</pos>
<style></style> <style></style>
</object> </object>
<object class="wxButton" name="wxID_OK"> <object class="wxButton" name="wxID_OK">
<label>&amp;OK</label> <label>&amp;OK</label>
<default>1</default> <default>1</default>
<pos>97,80d</pos> <pos>97,95d</pos>
<style></style> <style></style>
</object> </object>
<object class="wxButton" name="wxID_CANCEL"> <object class="wxButton" name="wxID_CANCEL">
<label>&amp;Cancel</label> <label>&amp;Cancel</label>
<default>0</default> <default>0</default>
<pos>150,80d</pos> <pos>150,95d</pos>
</object> </object>
</object> </object>
</resource> </resource>

File diff suppressed because it is too large Load diff

View file

@ -972,16 +972,16 @@ int FormatterSQL::ParseSql(int flags) {
vi.txt = tmp; vi.txt = tmp;
vi.type = keyword; vi.type = keyword;
vi.flags = flg; vi.flags = flg;
if (tmp == "from" && i2 >= 2) { if (tmp == "from" && i2 >= 2) { // special case "distinct from" this no "from"
wxString s = items[items.size() - 2].txt; wxString s = items[items.size() - 2].txt;
if (s.Len() >= 8 && s.substr(s.Len() - 8).CmpNoCase("distinct") == 0) { if (s.Len() >= 8 && s.substr(s.Len() - 8).CmpNoCase("distinct") == 0) {
vi.flags = 0; vi.flags = 0;
} }
} }
if (keyEntities[n].name == "case") { if (strcmp(keyEntities[n].name,"case") == 0) {
bracket.push(items.size()); bracket.push(items.size());
} }
else if (keyEntities[n].name == "end") { else if (strcmp(keyEntities[n].name,"end") == 0) {
int idx = -1; int idx = -1;
if (bracket.size() > 0) { if (bracket.size() > 0) {
idx = bracket.top(); idx = bracket.top();
@ -994,14 +994,17 @@ int FormatterSQL::ParseSql(int flags) {
vi.endlevel = idx; vi.endlevel = idx;
if (idx != -1) items[idx].endlevel = items.size(); if (idx != -1) items[idx].endlevel = items.size();
} else if (keyEntities[n].name == "then"|| } else if (strcmp(keyEntities[n].name, "then")== 0 ||
keyEntities[n].name == "loop" ) { // for plpgsql strcmp(keyEntities[n].name,"loop") == 0 ) { // for plpgsql query without ";"
// if ... then // if ... then
// while ... loop or for .. in query loop // while ... loop or for .. in query loop
// special break parse query ONLY recurse level == 0
if (bracket.size() == 0) { if (bracket.size() == 0) {
i=i+tmp.Len()-1; i=i+tmp.Len()-1; // skip stop keyword
break; break;
} }
//
} }
} }
i += tmp.Len() - 1; i += tmp.Len() - 1;

View file

@ -1535,5 +1535,49 @@ void showHelpHtml(wxWindow *parent, const wxString &htmlHelp,wxPoint screenPos,
} }
#include <wx/socket.h>
bool isPortOpen(const wxString& host, int port , int timeout_ms) {
wxSocketClient client;
//client.SetTimeout(1); // 1 секунда таймаут (можно уменьшить до 0.5 или 0.2)
wxIPV4address addr;
addr.Hostname(host);
addr.Service(port);
// Issue the connection request
client.Connect(addr, false);
// Wait until the request completes or until we decide to give up
while ( !client.WaitOnConnect(0, timeout_ms) )
{
break;
}
bool success = client.IsConnected();
return success;
/* int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
return false;
}
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_pton(AF_INET, host.c_str(), &addr.sin_addr);
// Установка таймаута (опционально, для ускорения)
timeval tv{};
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
int result = connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
close(sock);
return result == 0; // true, если порт открыт (сервер принимает соединения)
*/
}

Binary file not shown.