This commit is contained in:
lsv 2025-11-17 08:06:28 +05:00
commit 61e6d71621
13 changed files with 168 additions and 29 deletions

View file

@ -1,7 +1,11 @@
{
"files.associations": {
"regex": "cpp",
"*.pngc": "cpp"
"*.pngc": "cpp",
"*.inc": "c",
"vector": "cpp",
"string.h": "c",
"libpq-fe.h": "c"
},
"cmake.configureArgs": [

View file

@ -79,6 +79,7 @@ file(GLOB_RECURSE SOURCES
##########################################################
add_executable(${PROJECT_NAME} )
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:_DEBUG>)
target_sources(${PROJECT_NAME} PUBLIC pgAdmin3.cpp ${SOURCES})
if(CROSS_COMPILE STREQUAL "Windows")
ENABLE_LANGUAGE(RC)

View file

@ -89,7 +89,7 @@ ctlSQLBox::ctlSQLBox(wxWindow *parent, wxWindowID id, const wxPoint &pos, const
m_dlgFindReplace = 0;
m_dlgTransformText = 0;
m_database = NULL;
m_autocompDisabled = false;
process = 0;
processID = 0;
@ -1344,10 +1344,11 @@ wxString ctlSQLBox::ExternalFormat(int typecmd)
break;
}
wxArrayString choiceCmpOpts;
wxArrayInt choiceSelectOpts;
choiceCmpOpts.Add(_("All line (use all EOL)"));
choiceCmpOpts.Add(_("First line pattern (ignore all but the first EOL)"));
choiceCmpOpts.Add(_("Try looking for patterns above"));
choiceCmpOpts.Add(_("Compact view"));
choiceCmpOpts.Add(_("Remove multi spaces"));
wxMultiChoiceDialog dialog(this,
_("A multi-choice convenience dialog"),
@ -1362,7 +1363,8 @@ wxString ctlSQLBox::ExternalFormat(int typecmd)
if (choiceSelectOpts[n] == 0) cfg |= AlignWrap::ALL_LINES;
if (choiceSelectOpts[n] == 1 ) cfg |= AlignWrap::FIRST_LINE ;
if (choiceSelectOpts[n] == 2) cfg |= AlignWrap::FIND_UP_LONG_LINE;
if (choiceSelectOpts[n] == 3) cfg |= AlignWrap::ONLY_SINGLE_SPACE;
if (choiceSelectOpts[n] == 3) cfg |= AlignWrap::COMPACT_VIEW;
if (choiceSelectOpts[n] == 4) cfg |= AlignWrap::ONLY_SINGLE_SPACE;
}
if (CHKCFGPARAM(cfg, AlignWrap::ALL_LINES) && CHKCFGPARAM(cfg, AlignWrap::FIRST_LINE)) cfg -= AlignWrap::FIRST_LINE;
@ -1866,9 +1868,31 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
if (m_autocompDisabled)
return;
int pos = GetCurrentPos();
wxString what = GetCurLine().Left(pos - PositionFromLine(GetCurrentLine()));;
//wxString what = GetCurLine().Left(pos - PositionFromLine(GetCurrentLine()));
wxString what = GetTextRange(PositionFromLine(GetCurrentLine()),pos);
int spaceidx = what.Find(' ', true);
int spacecharidx=spaceidx;
int poshome=PositionFromLine(GetCurrentLine());
int posspc=PositionRelative(poshome,spaceidx);
if (spaceidx != -1) {
while (poshome< posspc) {
int ch = GetCharAt(posspc);
int st = GetStyleAt(posspc) & 0x1F;
if (st == wxSTC_SQL_STRING || st == wxSTC_SQL_CHARACTER)
{
posspc--;
} else if (ch=='"' || ch=='.') {
posspc--;
} else if (ch==' ') {
break;
}
}
wxString lastexp=GetTextRange(PositionFromLine(GetCurrentLine()),posspc);
spacecharidx=lastexp.Length();
spaceidx=posspc-poshome;
}
char *tab_ret;
if (spaceidx == -1)
tab_ret = tab_complete(what.mb_str(wxConvUTF8), 0, what.Len() + 1, m_database);
@ -2072,7 +2096,7 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
if (found) {
wxString flt="";
if (!fld.IsEmpty()) flt = " and a.attname ~ " + qtConnString(fld);
wxString sql=wxT("select string_agg(a.attname,E'\t') from pg_attribute a where a.attrelid = (select oid from pg_class p where relname=") +qtConnString(table)
wxString sql=wxT("select string_agg(a.attname,E'\t') from pg_attribute a where a.attrelid in (select oid from pg_class p where relname=") +qtConnString(table)
+wxT(") and a.attisdropped IS FALSE and a.attnum>=0 ")+flt
+wxT(" order by 1");
//pgSet *res = m_database->ExecuteSet(sql);
@ -2134,7 +2158,8 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
if (spaceidx == -1)
AutoCompShow(what.Len(), wxRet);
else
AutoCompShow(what.Len() - spaceidx - 1, wxRet);
//AutoCompShow(what.Len() - spacecharidx - 1, wxRet);
AutoCompShow(pos - posspc - 1, wxRet);
// Now switch back
#ifdef __WXMAC__
@ -2201,7 +2226,12 @@ char *pg_query_to_single_ordered_string(char *query, void *dbptr)
return strdup(ret.mb_str(wxConvUTF8));
}
extern "C"
int get_id_encoding(void *dbptr)
{
pgConn *db = (pgConn *)dbptr;
return db->Get_client_encoding_id();
}
// Find some text in the document.
CharacterRange ctlSQLBox::RegexFindText(int minPos, int maxPos, const wxString &text)

View file

@ -154,6 +154,8 @@ dlgFunction::dlgFunction(pgaFactory *f, frmMain *frame, pgFunction *node, pgSche
txtSqlBox->SetMarginType(1, wxSTC_MARGIN_NUMBER);
txtSqlBox->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x);
}
if (function && function->GetDatabase())
txtSqlBox->SetDatabase(function->GetDatabase()->GetConnection());
btnAdd->Disable();
btnRemove->Disable();
btnChange->Disable();

View file

@ -43,7 +43,7 @@
// Memory leak debugging
#ifdef _DEBUG
#define new DEBUG_NEW
//#define new DEBUG_NEW
#endif
// Legend margins

View file

@ -135,6 +135,7 @@ private:
dlgFindReplace *m_dlgFindReplace;
dlgTransformText *m_dlgTransformText;
pgConn *m_database;
wxArrayInt choiceSelectOpts;
bool m_autoIndent, m_autocompDisabled, m_hint_mode;
struct InsensitiveCompare {
bool operator() (const wxString& a, const wxString& b) const {

View file

@ -253,6 +253,11 @@ public:
{
return conn;
}
int Get_client_encoding_id()
{
return PQclientEncoding(conn);
}
void Notice(const char *msg);
pgNotification *GetNotification();
int GetTxStatus();

View file

@ -61,8 +61,8 @@ extern wxBitmapBundle GetBundleSVG(wxBitmap* std, wxString name, wxSize sz);
// Supported server minimum and maximum values.
const short SERVER_MIN_VERSION_N = 0x0804;
const wxString SERVER_MIN_VERSION_T = wxT("8.4");
const short SERVER_MAX_VERSION_N = 0x1200;
const wxString SERVER_MAX_VERSION_T = wxT("18");
const short SERVER_MAX_VERSION_N = 0x1400;
const wxString SERVER_MAX_VERSION_T = wxT("20");
// Supported Greenplum Database and Greenplum HAWQ minimum and maximum values.
const short GP_MIN_VERSION_N = 0x0802;
const wxString GP_MIN_VERSION_T = wxT("8.2");

View file

@ -16,7 +16,9 @@ public:
// и при помощи этого флага ищутся более длинные строки обработанные ранее
FIND_UP_LONG_LINE=4,
/// Заменить множественные пробелы на один. Выравнивание не производиться.
ONLY_SINGLE_SPACE=8
ONLY_SINGLE_SPACE=8,
/// Более копактный вид имеет смысл для ALL_LINES
COMPACT_VIEW=16
};
AlignWrap() {}

View file

@ -18,7 +18,7 @@
#define VERSION_NUM 1,22,0,0
#define VERSION_PACKAGE 1.22.2
#else
#define VERSION_STR wxT("1.26 Dev ASUTP support PG17")
#define VERSION_STR wxT("1.26 Dev ASUTP support PG18")
#define VERSION_NUM 1,26,0,0
#define VERSION_PACKAGE 1.26.0-dev

View file

@ -56,6 +56,9 @@ wxString AlignWrap::build(wxString& strsrc, int config,wxString linesep)
}
else {
//
bool iscompact=false;
if (CHKCFGPARAM(cfg, COMPACT_VIEW)) iscompact=true;
for (size_t l = 1; l < nline.size() - 1; l++)
{
@ -97,17 +100,21 @@ wxString AlignWrap::build(wxString& strsrc, int config,wxString linesep)
else {
// 4021196,'fffff',(
// (4155,'aaaa'
if (size_u > size_c) { // фиксируем верхний
// будем нижний подгонять под верхний
size_u = range_size(index_u);
idxU = index_u;
}
else
if (size_u < size_c) {
size_c = range_size(index_c);
idxC = index_c;
if (iscompact && du==0) {
list[idxC].setParent(idxU);
} else {
if (size_u > size_c) { // фиксируем верхний
// будем нижний подгонять под верхний
size_u = range_size(index_u);
idxU = index_u;
}
list[idxC].setParent(idxU);
else
if (size_u < size_c) {
size_c = range_size(index_c);
idxC = index_c;
}
list[idxC].setParent(idxU);
}
}
if (size_u < size_c) {
// вырхний короче, его дополняем
@ -378,6 +385,7 @@ int AlignWrap::chkspace(int &pos, bool& br) {
pos--;
break;
}
if (nl < parserows) l++;
// Не будем заменять переводы строк на пробел для ALL_LINES
if (nl < parserows && !CHKCFGPARAM(cfg,ALL_LINES)) l++;
return l;
}

View file

@ -39,9 +39,13 @@ wxString Item::print() {
wxString s = wxString::Format("%s", it);
wxString r(' ', rs), l(' ', ls);
s = l + s + r + wxString::Format("%s", comment);
if (br)
s = l + r + s + wxString::Format("%s", comment); // для последнего элемента строки пробелы справа не добавляем
else
s = l + s + r + wxString::Format("%s", comment);
#ifdef _DEBUG
std::cout << s;
#endif
return s;
}
const int Item::getMaxSize() {

View file

@ -26,7 +26,7 @@
* Callbacks to the C++ world
*/
char *pg_query_to_single_ordered_string(char *query, void *dbptr);
int get_id_encoding(void *dbptr);
/*
* Global vars for readline emulation
@ -170,6 +170,7 @@ static char *complete_from_schema_query(const char *text, const void* query, con
static char *complete_create_command(char *text);
static char *complete_filename();
/*
* Include the main tab completion functionality from psql
*/
@ -226,16 +227,97 @@ static char *complete_from_const(const char *text, const char *string)
{
return strdup(string);
}
static int lower_identifier(const char *ident, char *out,void *dbptr)
{
size_t buflen = strlen(ident) + 1;
char *sname;
char *oname;
char *optr;
char *tmp;
int inquotes=0;
int isneedlower=0;
int schemaquoted,objectquoted;
int encoding=6; // pg_enc.PG_UTF8
int enc_is_single_byte = 0;
int utf8len=0;
/* Initialize, making a certainly-large-enough output buffer */
schemaquoted = objectquoted = 0;
/* Scan */
inquotes = 0;
optr=out;
while (*ident)
{
unsigned char ch = (unsigned char) *ident++;
utf8len++;
if (ch == '"')
{
if (inquotes && *ident == '"')
{
/* two quote marks within a quoted identifier = emit quote */
*optr++ = '"';
ident++;
utf8len++;
}
else
{
inquotes = !inquotes;
objectquoted = 1;
*optr++ = '"';
}
}
else if (!enc_is_single_byte && ch>127)
{
/*
* Transfer multibyte characters without further processing. They
* wouldn't be affected by our downcasing rule anyway, and this
* avoids possibly doing the wrong thing in unsafe client
* encodings.
*/
int chlen = PQmblenBounded(ident - 1, encoding);
*optr++ = (char) ch;
while (--chlen > 0)
*optr++ = *ident++;
}
else
{
if (!inquotes)
{
/*
* This downcasing transformation should match the backend's
* downcase_identifier() as best we can. We do not know the
* backend's locale, though, so it's necessarily approximate.
* We assume that psql is operating in the same locale and
* encoding as the backend.
*/
if (ch >= 'A' && ch <= 'Z')
ch += 'a' - 'A';
else if (enc_is_single_byte && ch>127 && isupper(ch))
ch = tolower(ch);
}
*optr++ = (char) ch;
}
}
*optr = '\0';
return utf8len;
}
static char* _complete_from_query(const char* text, const char* query, const SchemaQuery* squery, const char* addon, void* dbptr)
{
int string_length = strlen(text);
char* e_text;
char* e_text_ident;
char* complete_query = NULL;
char* t;
e_text_ident = malloc(string_length * 2 + 1);
PQescapeString(e_text_ident,text, strlen(text));
string_length=strlen(e_text_ident);
e_text = malloc(string_length * 2 + 1);
PQescapeString(e_text, text, string_length);
int utf8len=lower_identifier(e_text_ident,e_text,dbptr);
string_length=utf8len;
free(e_text_ident);
if (query != NULL)
{