pgadmin3/include/utils/FormatterSQL.h
lsv 1f7decd73f Added the possibility of contextual help on user functions.
Добавлена возможность просмотра скриптов создания пользовательских объектов
в контестной помощи. В скриптах имена других объектов заменяются на ссылки.
Описание Readme.md
2025-11-21 16:23:26 +05:00

204 lines
No EOL
7.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <wx/wx.h>
namespace FSQL {
/// <summary>
/// Formatter SQL
/// </summary>
enum type_item {
unknown
, spaces
, keyword
, literal
, separation
, bracket
, identifier
, name
, numeric
, bindarg
, comment
};
struct view_item {
type_item type = unknown;
int srcpos = -1; // start position sql text -1 needed ignore
int width = 0; //
int height = 0;
int endlevel = -1; // end bracet or home
bool newline = false;
int x = 0, y = 0, flags = 0;
wxString txt;
};
enum f_key {
none,
new_line_align_no_pad = 1,
new_line_align_next = 2,
newLineComma = 4,
newLineXPrevValue = 8,
isCASE = 16,
special = 32,
newLineBracet = 64,
HorizontalAlign = 128,
isFUNCTION = 256,
end_from = 256 << 1,
limit = 256 << 2,
fetch = 256 << 3,
for_up = 256 << 4,
fix_position_new_line = 256 << 5,
};
const struct KEYWORDEntity
{
const char* name;
int len; // == strlen(name)
int flags;
} keyEntities[] =
{
{ "as", 2, none },
{ "is", 2, none },
{ "by", 2, none },
{ "in", 2, none },
{ "on", 2, HorizontalAlign },
{ "of", 2, none },
{ "or", 2, newLineXPrevValue },
{ "and", 3, newLineXPrevValue},
{ "not", 3, none},
{ "asc", 3, none},
{ "set", 3, none},
{ "all", 3, none},
{ "end", 3, special},
{ "desc", 4, none },
{ "like", 4, none},
{ "null", 4, none},
{ "from", 4, new_line_align_no_pad },
{ "case", 4, isCASE },
{ "when", 4, new_line_align_no_pad },
{ "else", 4, new_line_align_no_pad },
{ "with", 4, special },
{ "join", 4, new_line_align_next },
{ "left", 4, new_line_align_next },
{ "full", 4, new_line_align_next },
{ "then", 4, none},
{ "loop", 4, none}, // for plpgsql
{ "into", 4, none},
{ "last", 4, none},
{ "next", 4, none},
{ "only", 4, none},
{ "cube", 4, none},
{ "rows", 4, none},
{ "sets", 4, none},
{ "where", 5, new_line_align_no_pad | end_from},
{ "outer", 5, none},
{ "grant", 5, none},
{ "begin", 5, none}, //plpgsql
{ "while", 5, none}, //plpgsql
{ "union", 5, new_line_align_no_pad | end_from},
{ "order", 5, new_line_align_no_pad | end_from},
{ "limit", 5, new_line_align_no_pad | end_from},
{ "group", 5, new_line_align_no_pad | end_from},
{ "count", 5, none},
{ "using", 5, none},
{ "first", 5, none},
{ "inner", 5, none},
{ "nulls", 5, none},
{ "cross", 5, none},
{ "select", 6, newLineComma | new_line_align_no_pad},
{ "update", 6, newLineComma | new_line_align_no_pad},
{ "insert", 6, newLineComma | new_line_align_no_pad},
{ "values", 6, newLineComma | new_line_align_no_pad},
{ "window", 6, new_line_align_no_pad | end_from},
{ "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},
{ "create", 6, none},
{ "nothing", 7, none},
{ "lateral", 7, none},
{ "between", 7, none},
{ "comment", 7, none},
{ "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 {
wxString table;
wxString alias;
wxString columnList;
int startIndex = -1;
int endIndex = -1;
int level = 0;
};
struct bits {
unsigned int from : 1;
unsigned int select_list : 1;
unsigned int with : 1;
unsigned int skip : 1;
};
union Byte {
unsigned char byte;
struct bits b;
};
class FormatterSQL {
public:
FormatterSQL(const wxString& sqlsrc) {
sql = sqlsrc;
}
std::vector<complite_element> ParsePLpgsql();
void Formating(wxDC& d, wxRect re, bool isTest = false); // draw
wxString Formating(wxRect re); //
//
wxString BuildAutoComplite(int startIndex, int level);
wxString GetListTable(int cursorPos);
wxString GetListTable(const std::vector<complite_element> &list);
wxString GetColsList(wxString what, wxString& listfieldOut, wxString& nameTableOut);
/// <summary>
/// Возращает количество таблиц слева от курсора и заполняет их имена и псевдонимы.
///
/// </summary>
int GetTableListBeforePosition(int positem, wxArrayString& listtable, wxArrayString& listalias);
//
int ParseSql(int flags);
wxString printParseArray();
void SetSql(const wxString& sqlsrc) { sql = sqlsrc; lastposition = 0; }
int GetIndexItemNextSqlPosition(int sqlPosition);
int GetNextPositionSqlParse();
bool GetItem(int index, FSQL::view_item& item);
int next_item_no_space(int& index, int direction = 1);
private:
wxString get_list_columns(int startindex, union FSQL::Byte zone);
void _addfunc(const view_item *vi);
void _addfunc_in_braket(int start,int end);
wxPoint align_level(int start_i, int level, int Xpos, int Ypos, int flag);
int check_bracket(int index);
int get_prev_value(int indx, wxString keyword);
wxSize max_width_size(int index); // index bracet
wxSize best_sizeAndDraw(wxDC& dc, wxPoint& pos, FSQL::view_item& vi, int mode);
int maxYheightLine = 0;
int max_exp_bracet_width = 200;
int pad = 16;
int casepad = 8;
wxPoint neededNewLine; // добавляет новую строку перед первым встреченным не пробельным символом
wxRect rect;
wxString sql;
int lastposition = 0;
int errorposition=-1;
std::vector<FSQL::view_item> items;
std::vector<FSQL::complite_element> listTable; // перечень таблиц синонимов, подзапросов и функций с колонками
std::vector<FSQL::complite_element> listFunction; // перечень функций используемых в запросе
//int recurse(int level);
};
}