mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
Fix generate Insert SQL instruction. Copying result lines based on a template.
1. При некоторых настройках при генерации Insert инструкций, пустые строки заменялись на null.
Этот коммит исправлет проблему.
2. Результаты запросов можно оформить произвольным образом используя шаблоны указанные в однострочных
коментариях.
Формат шаблона: --@gen:Имя шаблона в контестном меню результата:Тут текст шаблона - cols = @colname@,@colname2,a@\n
Для добавлнения перевода строк в вывод можно использовать \n.
Коментарии указывается в теле запроса (можно указать перед запросом).
Можно указать строку из которой нужно сделать выбрать содержимое:
@colname[-1]@ - содержимое колонки colname предыдущей строки(относительная адресация).
@colname[0]@ - содержимое колонки colname 1 строки (или выделенного диапазона строк).
Адресация с начинается с 0. Это абсолютная адресация строк.
@colname2,a@ - Указание что результат нужно будет выровнять.
Флаг "а" глобальный его можно указать у любой колонки.
Флаги указываются в самом конце определения колонки после запятой. Пример: @col1[-1],a@
Если перечень имен колонок запроса не совпадает со списком полей шаблона то шаблон не будет добавлен
в контекстное меню Generate.
Полученный текст копируется в буфер обмена.
При генерации текста используются настройки "Вид кавычек" и "Что брать в кавычки".
Шаблоны сохраняются перед выполнением SQL команды и после редактирования шаблона
запрос нужно выполнить повторно.
This commit is contained in:
parent
087ad55c34
commit
a8ddbc4999
8 changed files with 235 additions and 10 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -9,7 +9,8 @@
|
|||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"ranges": "cpp"
|
||||
"ranges": "cpp",
|
||||
"optional": "cpp"
|
||||
},
|
||||
"cmake.configureArgs": [
|
||||
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
|
||||
if (GetNumberCols() == 0 || GetRowSize(row) == 0)
|
||||
return str;
|
||||
sqlResultTable *t=(sqlResultTable *)GetTable();
|
||||
wxString colsep = settings->GetCopyColSeparator();
|
||||
if (generatesql == 2 || generatesql == 1) colsep = wxT(",");
|
||||
if (generatesql == 3) colsep = wxT(" and ");
|
||||
|
|
@ -297,7 +298,14 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
str.Append(colsep);
|
||||
if (col > 0) head.Append(colsep);
|
||||
head = head + GetColumnName(cols[col]);
|
||||
wxString text = GetCellValue(row, cols[col]);
|
||||
wxString text;
|
||||
bool isnull=false;
|
||||
if ( t && generatesql > 0)
|
||||
{
|
||||
// only insert , in_list and where list
|
||||
text = t->GetValueWithNull( row, cols[col] , &isnull );
|
||||
} else text = GetCellValue(row, cols[col]);
|
||||
|
||||
wxString cname = GetColumnName(cols[col]);
|
||||
bool needQuote = false;
|
||||
if (settings->GetCopyQuoting() == 1)
|
||||
|
|
@ -307,12 +315,12 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
else if (settings->GetCopyQuoting() == 2)
|
||||
/* Quote everything */
|
||||
needQuote = true;
|
||||
if (text.Length() == 0 && generatesql > 0) { needQuote = false; }
|
||||
if (isnull && generatesql > 0) { needQuote = false; }
|
||||
else
|
||||
if (generatesql > 0) needQuote = IsColText(cols[col]);
|
||||
|
||||
if (generatesql > 0) {
|
||||
if (text.Length() != 0) {
|
||||
if (!isnull) {
|
||||
text.Replace(wxT("'"), wxT("''"));
|
||||
}
|
||||
else
|
||||
|
|
@ -320,7 +328,7 @@ wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols)
|
|||
|
||||
}
|
||||
if (generatesql == 3) {
|
||||
if (text == "null")
|
||||
if (isnull)
|
||||
str.Append(cname).Append(" is ");
|
||||
else
|
||||
str.Append(cname).Append("=");
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "frm/mathplot.h"
|
||||
#include "frm/frmPlot.h"
|
||||
#include "ctl/SourceViewDialog.h"
|
||||
|
||||
#include "utils/align/AlignWrap.h"
|
||||
|
||||
ctlSQLResult::ctlSQLResult(wxWindow *parent, pgConn *_conn, wxWindowID id, const wxPoint &pos, const wxSize &size)
|
||||
: ctlSQLGrid(parent, id, pos, size)
|
||||
|
|
@ -339,6 +339,160 @@ wxString ctlSQLResult::OnGetItemText(long item, long col) const
|
|||
}
|
||||
return wxEmptyString;
|
||||
}
|
||||
struct type_temp_flag {
|
||||
uint8_t colvalue:1;
|
||||
uint8_t colname:1;
|
||||
uint8_t indexrow:1;
|
||||
};
|
||||
struct ElementTempl {
|
||||
wxString txt;
|
||||
type_temp_flag flags = {0};
|
||||
int column=-1;
|
||||
int row=-1;
|
||||
};
|
||||
|
||||
wxString ctlSQLResult::GenerateTemplate(wxString &templ,int action)
|
||||
{
|
||||
std::vector<ElementTempl> tmplvector;
|
||||
wxString rez;
|
||||
int qt=settings->GetCopyQuoting();
|
||||
wxString qtsimbol = settings->GetCopyQuoteChar();
|
||||
wxString qtsimbol2=qtsimbol+qtsimbol;
|
||||
// Parse and prepare template string
|
||||
wxChar c;
|
||||
int isalign=false;
|
||||
int len=templ.Len();
|
||||
int pos=0;
|
||||
ElementTempl e;
|
||||
bool isvar=false;
|
||||
wxString col;
|
||||
while (pos<len)
|
||||
{
|
||||
c=templ[pos++];
|
||||
if (c=='\\' && pos<len) {
|
||||
c=templ[pos++];
|
||||
if (c=='n') c='\n';
|
||||
}
|
||||
if (isvar) {
|
||||
if (c==',') {
|
||||
while (pos<len && ((c=templ[pos++])!='@'))
|
||||
{
|
||||
//if (c=='n') e.flags.colname=true;
|
||||
if (c=='a') isalign=true;
|
||||
}
|
||||
}
|
||||
if (c=='[') {
|
||||
wxString strrow;
|
||||
while (pos<len && ((c=templ[pos++])!=']'))
|
||||
{
|
||||
strrow.Append(c);
|
||||
}
|
||||
if (strrow.Len()>0) {
|
||||
long rr=StrToLong(strrow);
|
||||
e.row=rr;
|
||||
e.flags.indexrow=true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (c=='@') {
|
||||
isvar=false;
|
||||
int idx=colNames.Index(col);
|
||||
if (idx==wxNOT_FOUND) {
|
||||
if (action == 0) wxMessageBox(wxString::Format("Not found col name %s in result query.",col));
|
||||
return wxEmptyString;
|
||||
}
|
||||
e.column=idx;
|
||||
tmplvector.push_back(e);
|
||||
e.flags={0};
|
||||
} else
|
||||
col.Append(c);
|
||||
continue;
|
||||
}
|
||||
if (c!='@') {
|
||||
e.txt.Append(c);
|
||||
} else {
|
||||
isvar=true;
|
||||
tmplvector.push_back(e);
|
||||
e.txt.Clear();
|
||||
col.Clear();
|
||||
e.flags.colvalue=true;
|
||||
}
|
||||
}
|
||||
if (isvar )
|
||||
{
|
||||
if (action == 0) wxMessageBox(wxString::Format("No close col name %s",col));
|
||||
return wxEmptyString;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.txt.Len()>0) tmplvector.push_back(e);
|
||||
}
|
||||
//
|
||||
if (action==1) return "OK"; // only correct parse
|
||||
|
||||
wxArrayInt rows = GetSelectedRows();
|
||||
size_t numRows = GetNumberRows();
|
||||
size_t numRows2 = GetNumberRows();
|
||||
if (rows.Count()>0) numRows=rows.Count();
|
||||
size_t row=0;
|
||||
sqlResultTable *t=(sqlResultTable *)GetTable();
|
||||
while (row < numRows)
|
||||
{
|
||||
int r=0;
|
||||
if (rows.Count()>0) r=rows[row++]; else r=row++;
|
||||
wxString strrow;
|
||||
for (auto e:tmplvector)
|
||||
{
|
||||
if (e.flags.colvalue==false) {
|
||||
strrow.Append(e.txt);
|
||||
continue;
|
||||
}
|
||||
if (e.flags.indexrow) {
|
||||
int dr=e.row;
|
||||
if (dr<0) dr=row+dr-1;
|
||||
if (dr>=0 && dr<numRows) r=dr;
|
||||
if (rows.Count()>0) r=rows[r]; else r=r;
|
||||
}
|
||||
bool isnull=false;
|
||||
wxString text = t->GetValueWithNull( r, e.column , &isnull );
|
||||
bool needQuote = false;
|
||||
if (qt == 1)
|
||||
{
|
||||
needQuote = IsColText(e.column);
|
||||
}
|
||||
else if (qt == 2)
|
||||
/* Quote everything */
|
||||
needQuote = true;
|
||||
if (needQuote) text.Replace(qtsimbol, qtsimbol2);
|
||||
if (isnull) strrow.Append("null");
|
||||
else
|
||||
{
|
||||
if (needQuote)
|
||||
strrow.Append(qtsimbol);
|
||||
strrow.Append(text);
|
||||
if (needQuote)
|
||||
strrow.Append(qtsimbol);
|
||||
}
|
||||
|
||||
}
|
||||
rez.Append(strrow);
|
||||
}
|
||||
if (isalign) {
|
||||
int cfg = AlignWrap::ALL_LINES| AlignWrap::FIRST_LINE;
|
||||
AlignWrap a;
|
||||
wxString lineEnd = wxT("\n");
|
||||
rez=a.build(rez,cfg,lineEnd);
|
||||
|
||||
}
|
||||
if (wxTheClipboard->Open())
|
||||
{
|
||||
wxTheClipboard->SetData(new wxTextDataObject(rez));
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
|
||||
return rez;
|
||||
}
|
||||
|
||||
wxString ctlSQLResult::CopySelColumnNameType(bool onlyname)
|
||||
{
|
||||
wxString ss = wxEmptyString;
|
||||
|
|
@ -1151,6 +1305,24 @@ wxString sqlResultTable::GetValueFast(int row, int col)
|
|||
}
|
||||
return "";
|
||||
}
|
||||
wxString sqlResultTable::GetValueWithNull(int row, int col, bool *isnull) {
|
||||
wxString s;
|
||||
if (thread && thread->DataValid())
|
||||
{
|
||||
if (col >= 0)
|
||||
{
|
||||
if (use_map) row=maplines[row];
|
||||
thread->DataSet()->Locate(row + 1);
|
||||
wxString s = thread->DataSet()->GetVal(col);
|
||||
*isnull = thread->DataSet()->IsNull(col);
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
wxString sqlResultTable::GetValue(int row, int col)
|
||||
{
|
||||
if (thread && thread->DataValid())
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ BEGIN_EVENT_TABLE(frmQuery, pgFrame)
|
|||
EVT_MENU(MNU_AUTOEDITOBJECT, frmQuery::OnAutoEditObject)
|
||||
EVT_MENU_RANGE(MNU_FAVOURITES_MANAGE + 1, MNU_FAVOURITES_MANAGE + 999, frmQuery::OnSelectFavourite)
|
||||
EVT_MENU_RANGE(MNU_MACROS_MANAGE + 1, MNU_MACROS_MANAGE + 99, frmQuery::OnMacroInvoke)
|
||||
EVT_MENU_RANGE(MNU_GENERATESQL + 1, MNU_GENERATESQL + 199, frmQuery::OnGenerateInvoke)
|
||||
EVT_ACTIVATE( frmQuery::OnActivate)
|
||||
EVT_STC_MODIFIED(CTL_SQLQUERY, frmQuery::OnChangeStc)
|
||||
EVT_STC_UPDATEUI(CTL_SQLQUERY, frmQuery::OnPositionStc)
|
||||
|
|
@ -2228,6 +2229,21 @@ void frmQuery::OnLabelRightClick(wxGridEvent &event)
|
|||
xmenu->Append(MNU_COPY_INLIST, _("IN list format copy"), _("Copy In list format."));
|
||||
xmenu->Append(MNU_COPY_WHERELIST, _("WHERE list format copy"), _("Copy where list format."));
|
||||
xmenu->Append(MNU_COPY_TABLEHTML, _("Copy table html format"), _("Copy table html format."));
|
||||
if (body_template.Count()>0) {
|
||||
//MNU_GENERATE_TEMPLATE
|
||||
wxMenu *submenu = new wxMenu();
|
||||
//wxString t="begin @obj_id@ end";
|
||||
int cnt=0;
|
||||
for(int i=0;i<body_template.Count();i++) {
|
||||
wxString s=sqlResult->GenerateTemplate(body_template[i],1);
|
||||
if (s=="OK")
|
||||
{
|
||||
cnt++;
|
||||
submenu->Append(MNU_GENERATESQL+cnt,title_template[i],body_template[i]);
|
||||
}
|
||||
}
|
||||
if (cnt>0) xmenu->Append(MNU_GENERATESQL,"Generate",submenu);
|
||||
}
|
||||
xmenu->AppendSeparator();
|
||||
xmenu->Append(MNU_AUTOCOLSPLOT, _("Draw plot LY(bar) or LXY or XYYY..."), _("Draw plot LY(bar) LXY or XYYY..."));
|
||||
xmenu->Append(MNU_SUMMARY_COL, _("Summary"), _("Summary selected cells."));
|
||||
|
|
@ -2288,6 +2304,19 @@ void frmQuery::OnCopy_WhereList(wxCommandEvent& ev)
|
|||
SetStatusText(s, STATUSPOS_MSGS);
|
||||
}
|
||||
}
|
||||
|
||||
void frmQuery::OnGenerateInvoke(wxCommandEvent& ev)
|
||||
{
|
||||
// if (currentControl() == sqlResult)
|
||||
int id=ev.GetId();
|
||||
wxMenu* mi = static_cast<wxMenu*>(ev.GetEventObject());
|
||||
wxString templ = mi->GetHelpString(id);
|
||||
{
|
||||
wxString s = wxT("Where list format copy buffer.");
|
||||
s=sqlResult->GenerateTemplate(templ,0);
|
||||
SetStatusText(s, STATUSPOS_MSGS);
|
||||
}
|
||||
}
|
||||
void frmQuery::OnCopy_TableToHtml(wxCommandEvent& ev)
|
||||
{
|
||||
// if (currentControl() == sqlResult)
|
||||
|
|
@ -3063,6 +3092,8 @@ void frmQuery::OnExecute(wxCommandEvent &event)
|
|||
FSQL::view_item v;
|
||||
bool isddm = false;
|
||||
std::vector<var_query> v_list;
|
||||
body_template.Clear();
|
||||
title_template.Clear();
|
||||
while (f.GetNextPositionSqlParse() < query.length() && f.ParseSql(0) >= 0) { // many querys
|
||||
|
||||
int i = 0;
|
||||
|
|
@ -3075,6 +3106,14 @@ void frmQuery::OnExecute(wxCommandEvent &event)
|
|||
}
|
||||
n_check++;
|
||||
}
|
||||
if (v.type == FSQL::type_item::comment) {
|
||||
wxString kw = v.txt;
|
||||
if (kw.Find("@gen:")>0) {
|
||||
wxString t=kw.AfterFirst(':');
|
||||
body_template.Add(t.AfterFirst(':'));
|
||||
title_template.Add(t.BeforeFirst(':'));
|
||||
}
|
||||
}
|
||||
// check bindarg
|
||||
if (n_check == 1 && v.type == FSQL::type_item::bindarg) {
|
||||
if (!isddm) break;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ public:
|
|||
}
|
||||
int CopyTableToHtml(wxString htmlquery);
|
||||
int Copy(int gensql);
|
||||
|
||||
virtual bool CheckRowPresent(int row)
|
||||
{
|
||||
return true;
|
||||
|
|
@ -62,7 +61,7 @@ public:
|
|||
wxString GetRowLabelValue(int row);
|
||||
void SetRowGroup(int row);
|
||||
GroupRows* grp;
|
||||
int generatesql; // 0 -<EFBFBD><EFBFBD><EFBFBD>, 1 - insert , 2 - in_list
|
||||
int generatesql; // 0 -copy, 1 - insert , 2 - in_list, 3 - where list
|
||||
wxString sqlquerytext;
|
||||
// Fast searh
|
||||
wxString searchStr;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ public:
|
|||
wxString AutoColsPlot(int flags,frmQuery *parent);
|
||||
wxString CheckSelColumnDate();
|
||||
wxString CopySelColumnNameType(bool onlyname);
|
||||
wxString GenerateTemplate(wxString &templ,int action);
|
||||
|
||||
void ClearFilter();
|
||||
bool IsColText(int col);
|
||||
bool hasRowNumber()
|
||||
|
|
@ -95,6 +97,7 @@ public:
|
|||
sqlResultTable();
|
||||
wxString GetValue(int row, int col);
|
||||
wxString GetValueFast(int row, int col);
|
||||
wxString GetValueWithNull(int row, int col, bool *isnull);
|
||||
wxString GetRowLabelValue( int row ) ;
|
||||
int GetNumberRows();
|
||||
int GetNumberCols();
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ private:
|
|||
ctlAuiNotebook *outputPane;
|
||||
wxString outputPaneInfo;
|
||||
ctlSQLResult *sqlResult;
|
||||
wxArrayString body_template,title_template; // @gen:title menu:body generator @column_name@ end
|
||||
#define MAX_RESULT_COUNT 10
|
||||
ctlSQLResult *ctlSQL[MAX_RESULT_COUNT];
|
||||
ctlSQLBox *ctlSBox[MAX_RESULT_COUNT];
|
||||
|
|
@ -220,6 +221,7 @@ private:
|
|||
void OnCopy_InList(wxCommandEvent& event);
|
||||
void OnCopy_WhereList(wxCommandEvent& event);
|
||||
void OnCopy_TableToHtml(wxCommandEvent& ev);
|
||||
void OnGenerateTemplate(wxCommandEvent& ev);
|
||||
void OnClear_Filter(wxCommandEvent &event);
|
||||
void OnCopy_NameTypeCols(wxCommandEvent& ev);
|
||||
void OnCheck_Column_Date(wxCommandEvent& ev);
|
||||
|
|
@ -288,6 +290,7 @@ private:
|
|||
void OnAutoEditObject(wxCommandEvent &event);
|
||||
void SetEOLModeDisplay(int mode);
|
||||
void OnMacroInvoke(wxCommandEvent &event);
|
||||
void OnGenerateInvoke(wxCommandEvent &event);
|
||||
void OnMacroManage(wxCommandEvent &event);
|
||||
void OnAutoReplaceManage(wxCommandEvent &event);
|
||||
void LoadQueries();
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ enum
|
|||
// This is a dummy menu item
|
||||
MNU_DUMMY = QUERY_COMPLETE + 1000,
|
||||
|
||||
//Menu Test
|
||||
MNU_GENERATESQL
|
||||
//Menu Generate
|
||||
MNU_GENERATESQL = MNU_DUMMY + 200
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue