mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
Added new features autocomplite.
1. Добавлена подстановка соединений таблиц(и представлений) по их FK. Подстановка работает в двух вариантах: 1.1 После ключевого слова ON:самая правая таблица соединяется с любой левой. 1.2 После ключевого слова WHERE AND OR все таблицы соединяются со всеми. 2. Дополнение условия соединения после символа = . Представления можно соединить только если поле представления является полем таблицы. 3. Стандартное автодополнение теперь выдаёт список таблиц и представление после JOIN.
This commit is contained in:
parent
b7b911c93b
commit
21ee30844a
10 changed files with 1873 additions and 916 deletions
|
|
@ -29,6 +29,7 @@
|
|||
#include "utils/popuphelp.h"
|
||||
#include "utils/FormatterSQL.h"
|
||||
#include "utils/dlgTransformText.h"
|
||||
#include "utils/TableColsMap.h"
|
||||
|
||||
wxString ctlSQLBox::sqlKeywords;
|
||||
static const wxString s_leftBrace(_T("([{"));
|
||||
|
|
@ -239,6 +240,7 @@ void ctlSQLBox::Create(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons
|
|||
AutoCompSetIgnoreCase(true);
|
||||
AutoCompSetFillUps(wxT(" \t"));
|
||||
AutoCompSetDropRestOfWord(true);
|
||||
AutoCompSetMaxHeight(10);
|
||||
|
||||
SetEOLMode(settings->GetLineEndingType());
|
||||
}
|
||||
|
|
@ -1748,7 +1750,12 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
|
|||
else
|
||||
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)>' ')){
|
||||
if (tab_ret != NULL) {
|
||||
wxRet = wxString(tab_ret, wxConvUTF8);
|
||||
free(tab_ret);
|
||||
}
|
||||
if ((wxRet.IsEmpty())){ // my autocomplite
|
||||
int extflag = 0;
|
||||
auto [s,e] = SelectQuery(pos);
|
||||
wxString sql = GetTextRange(s, e);
|
||||
FSQL::FormatterSQL f(sql);
|
||||
|
|
@ -1763,10 +1770,23 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
|
|||
if (vi.type == FSQL::spaces) {
|
||||
ItemPos--;
|
||||
f.GetItem(ItemPos, vi);
|
||||
extflag += TableColsMap::Flag::NOT_ADD_FIRST_SPACE;
|
||||
}
|
||||
wxString leftexp;
|
||||
if (vi.type == FSQL::separation && vi.txt == '=') {
|
||||
f.GetItem(ItemPos, vi);
|
||||
ItemPos--;
|
||||
if (f.next_item_no_space(ItemPos, -1) != -1) {
|
||||
f.GetItem(ItemPos, vi);
|
||||
if (vi.type == FSQL::identifier || vi.type == FSQL::name) {
|
||||
leftexp = vi.txt;
|
||||
}
|
||||
else return;
|
||||
};
|
||||
}
|
||||
wxString field;
|
||||
bool ast = false;
|
||||
if (vi.type == FSQL::separation) {
|
||||
if (vi.type == FSQL::separation && !CHKFLAG(extflag, TableColsMap::Flag::NOT_ADD_FIRST_SPACE)) {
|
||||
ast=vi.txt == ".*";
|
||||
while (f.GetItem(--ItemPos, vi)) {
|
||||
if (vi.type == FSQL::identifier || vi.type == FSQL::name) {
|
||||
|
|
@ -1776,9 +1796,32 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
|
|||
if (vi.srcpos != -1) break;
|
||||
};
|
||||
}
|
||||
else if (vi.type == FSQL::identifier) {
|
||||
else if (vi.type == FSQL::identifier && !CHKFLAG(extflag, TableColsMap::Flag::NOT_ADD_FIRST_SPACE && leftexp.IsEmpty())) {
|
||||
field = vi.txt;
|
||||
}
|
||||
else if (vi.type == FSQL::keyword || !leftexp.IsEmpty()) {
|
||||
// where, on ,and , ...
|
||||
wxArrayString tn, an;
|
||||
int ccc=f.GetTableListBeforePosition(ItemPos,tn,an);
|
||||
if (ccc > 1) {
|
||||
// decode view select field
|
||||
TableColsMap tmaps;
|
||||
int flag = TableColsMap::Flag::ALL_LEFT_TO_RIGHT | TableColsMap::Flag::USE_TRANSIT_FK;
|
||||
if (leftexp.IsEmpty()) {
|
||||
if (vi.txt.Lower() == "where" || vi.txt.Lower() == "and" || vi.txt.Lower() == "or") flag = TableColsMap::Flag::SEQUENCE_LIST_TABLE | TableColsMap::Flag::USE_TRANSIT_FK;
|
||||
} else flag = TableColsMap::Flag::SEQUENCE_LIST_TABLE | TableColsMap::Flag::USE_TRANSIT_FK;
|
||||
flag |= extflag;
|
||||
wxString list=tmaps.AddTableList(m_database, tn, an, (TableColsMap::Flag) flag,leftexp);
|
||||
if (!list.IsEmpty()) {
|
||||
int l2 = 0;
|
||||
AutoCompShow(l2, list);
|
||||
}
|
||||
|
||||
//
|
||||
//wxString r = wxJoin(tn, '\t');
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!field.IsEmpty()) {
|
||||
wxString lf;
|
||||
wxString tabn;
|
||||
|
|
@ -1820,6 +1863,30 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
|
|||
r=wxJoin(sort, '\t');
|
||||
AutoCompShow(l2, r);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (vi.type == FSQL::name) {
|
||||
field = vi.txt;
|
||||
// for any name found table
|
||||
bool isok = false;
|
||||
while (f.GetItem(ItemPos--, vi)) {
|
||||
if (vi.endlevel != -1 && vi.endlevel < ItemPos) ItemPos = vi.endlevel;
|
||||
if (vi.type == FSQL::keyword && vi.txt.Lower() == "from") { isok = true; break; }
|
||||
if (vi.type == FSQL::keyword && vi.txt.Lower() == "where") { break; }
|
||||
if (vi.type == FSQL::keyword && vi.txt.Lower() == "group") { break; }
|
||||
}
|
||||
if (isok) {
|
||||
what = "from " + field;
|
||||
spaceidx = what.Find(' ');
|
||||
tab_ret = tab_complete(what.mb_str(wxConvUTF8), spaceidx + 1, what.Len() + 1, m_database);
|
||||
if (tab_ret != NULL) {
|
||||
wxString wxRet;
|
||||
wxRet = wxString(tab_ret, wxConvUTF8);
|
||||
bool empty = tab_ret[0] == '\0';
|
||||
free(tab_ret);
|
||||
if (!empty) AutoCompShow(what.Len() - spaceidx - 1, wxRet);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -1932,8 +1999,6 @@ void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev)
|
|||
spaceidx = -1;
|
||||
//return; /* No autocomplete available for this string */
|
||||
} else {
|
||||
wxRet = wxString(tab_ret, wxConvUTF8);
|
||||
free(tab_ret);
|
||||
}
|
||||
// Switch to the generic list control. Native doesn't play well with
|
||||
// autocomplete on Mac.
|
||||
|
|
|
|||
1798
ctl/ctlSQLGrid.cpp
1798
ctl/ctlSQLGrid.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -536,6 +536,8 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
wxArrayString leg;
|
||||
wxArrayInt colsY;
|
||||
wxString rez="Draw plot";
|
||||
wxString sss;
|
||||
std::vector<long> typeCols;
|
||||
if (IsSelection()) {
|
||||
unsigned int i;
|
||||
int col;
|
||||
|
|
@ -551,13 +553,20 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
{
|
||||
for (col = topLeft[i].GetCol(); col <= bottomRight[i].GetCol(); col++) {
|
||||
//clearCellData(row, col);
|
||||
wxString aa = wxString::Format(",%d,", col);
|
||||
if (sss.Find(aa) != -1) continue;
|
||||
sss += aa;
|
||||
cols.Add(col);
|
||||
typeCols.push_back(colTypClasses.Item(col));
|
||||
}
|
||||
}
|
||||
}
|
||||
wxArrayInt cls = GetSelectedCols();
|
||||
for (i = 0; i < cls.Count(); i++) {
|
||||
if (cols.Index(cls[i])== wxNOT_FOUND) cols.Add(cls[i]);
|
||||
if (cols.Index(cls[i]) == wxNOT_FOUND) {
|
||||
cols.Add(cls[i]);
|
||||
typeCols.push_back(colTypClasses.Item(cls[i]));
|
||||
}
|
||||
// for (row = 1; row < GetNumberRows(); row++) {
|
||||
// clearCellData(row, cols[i]);
|
||||
// }
|
||||
|
|
@ -575,10 +584,10 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
int legC = -1;
|
||||
int xC = -1;
|
||||
//cols = GetSelectedCols();
|
||||
if (cols.Count() == 2) {
|
||||
legC = cl1; idx++;
|
||||
if (cols.Count() == 2 && typeCols[idx]!= PGTYPCLASS_NUMERIC) {
|
||||
legC = cl1; idx++; // 1 cols = legend
|
||||
cl1 = cols[idx];
|
||||
if (colTypClasses.Item(cl1) != PGTYPCLASS_NUMERIC) {
|
||||
if (typeCols[idx] != PGTYPCLASS_NUMERIC) {
|
||||
wxMessageBox("The number of selected column 2 needed Number type\nExample: LY", "Plot");
|
||||
return "";
|
||||
}
|
||||
|
|
@ -604,17 +613,29 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
}
|
||||
if (cols.Count() < 3) {
|
||||
|
||||
wxMessageBox("The number of selected columns must be more than 1\nExample: LXY or XYYYY...", "Plot");
|
||||
return "";
|
||||
// wxMessageBox("The number of selected columns must be more than 1\nExample: LXY or XYYYY...", "Plot");
|
||||
// return "";
|
||||
}
|
||||
}
|
||||
else {
|
||||
wxMessageBox("The number of selected columns must be more than 0\nExample: LXY or Y or XYYYY...", "Plot");
|
||||
return "";
|
||||
|
||||
}
|
||||
int idx = 0;
|
||||
int cl1 = cols[idx];
|
||||
int legC = -1;
|
||||
int xC = -1;
|
||||
int typeAxisX = mpX_DATETIME;
|
||||
// Leg col
|
||||
if (colTypClasses.Item(cl1) == PGTYPCLASS_STRING) { legC = cl1; idx++; }
|
||||
if (typeCols[idx] == PGTYPCLASS_STRING) {
|
||||
legC = cl1;
|
||||
idx++;
|
||||
if (cols.Count() < 2) {
|
||||
wxMessageBox("Column 2 must be numeric\nExample: LY or LXY", "Plot");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
cl1 = cols[idx];
|
||||
// X col
|
||||
wxString xA, yA;
|
||||
|
|
@ -622,6 +643,16 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
if (colTypClasses.Item(cl1) == PGTYPCLASS_DATE) { xC = cl1; idx++; }
|
||||
else if (colTypClasses.Item(cl1) == PGTYPCLASS_NUMERIC) { xC = cl1; typeAxisX = mpX_NORMAL; idx++; }
|
||||
if (xC == -1) { wxMessageBox("The value type of column X must be a date or a number", "Plot"); return ""; }
|
||||
if (cols.GetCount() == 1 && typeCols[0]!= PGTYPCLASS_NUMERIC) {
|
||||
wxMessageBox("The value type of column Y must be a number", "Plot");
|
||||
return "";
|
||||
}
|
||||
if (cols.GetCount() == 1 && typeCols[0] == PGTYPCLASS_NUMERIC) {
|
||||
// only Y
|
||||
xC = -1;
|
||||
idx = 0;
|
||||
xA = "NumRow";
|
||||
}
|
||||
// Y cols
|
||||
for (size_t col = idx; col < cols.Count(); col++)
|
||||
{
|
||||
|
|
@ -695,6 +726,7 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
int fmttype = -1;
|
||||
wxDateTime dt;
|
||||
bool first = true;
|
||||
if (cols.GetCount() == 1) first = false;
|
||||
for (size_t col = 0; col < colsY.Count(); col++)
|
||||
{
|
||||
lg = leg[col];
|
||||
|
|
@ -726,6 +758,10 @@ wxString ctlSQLResult::AutoColsPlot(int flags,frmQuery* parent) {
|
|||
y.push_back(yv);
|
||||
|
||||
}
|
||||
if (cols.GetCount() == 1) {
|
||||
double nrows = 1;
|
||||
for (int i = 0; i < numRows; i++) x.push_back(nrows++);
|
||||
}
|
||||
frame->AddSeries(lg, x, y,lbar);
|
||||
y.clear();
|
||||
first = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue