#include "pgAdmin3.h" #include #include #include #include #include "db/pgSet.h" #include "frm/frmMain.h" #include "ctl/ctlSQLBox.h" extern sysSettings* settings; extern frmMain *winMain; wxString FunctionPGHelper::getHelpString(wxString fnd, bool isPart) { if (!isValid()) return wxEmptyString; auto search = body.find(fnd); wxString txt; if (search != body.end()) txt = search->second; else { std::vector list; int l = fnd.Len(); wxString b; for (const auto& e : body) { if (e.first.Len() > l && e.first.StartsWith(fnd)) { list.push_back(e.first); b = e.second; } } if (list.size() == 1) txt = b; else { for (const auto& s : list) { txt += wxString::Format("%s
", s, s); } } } //if (i == wxNOT_FOUND) return wxEmptyString; return txt; } void FunctionPGHelper::setDbConn(pgConn *db) { dblast=db; } #include "schema/pgDatabase.h" #include "schema/pgSchema.h" #include "schema/pgTable.h" #include "schema/pgView.h" #include "schema/pgFunction.h" #include "schema/pgTrigger.h" extern pgDatabaseFactory databaseFactory; extern pgSchemaFactory schemaFactory; extern pgTableFactory tableFactory; extern pgViewFactory viewFactory; extern pgFunctionFactory functionFactory; extern pgProcedureFactory procedureFactory; extern pgTriggerFunctionFactory triggerFunctionFactory; wxString FunctionPGHelper::getDBinfoKeyword(wxString objname, bool islower) { if (dblast) { wxString s,n,a,tmp; tmp=objname; a=objname.AfterFirst('('); if (!a.IsEmpty()) { tmp=objname.BeforeFirst('('); a=a.substr(0,a.Len()-1); } else a="%"; make_identifier(tmp,s,n,islower); if (s.IsEmpty()) { s="%"; } wxString querytemplate=R"( select p.oid,p.relnamespace::regnamespace nsp,p.relname objname, p.relkind::text, case when p.relkind in ('v','m') then --pg_get_viewdef(p.oid,true) '' else '' end define , '' args, obj_description(oid,'pg_class') comment from pg_class p where p.relkind in ('r','p','m','v') and p.relnamespace::regnamespace::text not in ('pg_catalog','information_schema') and p.relnamespace::regnamespace::text like '%s' and p.relname like '%s' and (select count(*) from pg_partition_ancestors(oid) ) <=1 union all select p.oid,p.pronamespace::regnamespace nsp,p.proname objname, case when pg_get_function_result(p.oid) is null then 'P' when pg_get_function_result(p.oid) = 'trigger' then 't' else 'f' end, '' prosrc ,pg_get_function_arguments(oid), obj_description(oid,'pg_proc') from pg_proc p where p.pronamespace::regnamespace::text like '%s' and p.proname like '%s' and pg_get_function_arguments(oid) like '%s' and p.pronamespace::regnamespace::text not in ('pg_catalog','information_schema') order by objname; )"; wxString es=s; wxString en=n; es.Replace("'","''"); en.Replace("'","''"); wxString sql=wxString::Format(querytemplate ,es,en,es,en,a); pgSet *res = dblast->ExecuteSet(sql); wxString txt,ns,on,kind,args,def,oid; bool isfunc=false; int c=0; while (!res->Eof()) { ns = res->GetVal("nsp"); oid = res->GetVal("oid"); on = res->GetVal("objname"); kind = res->GetVal("relkind"); args = res->GetVal("args"); def = res->GetVal("define"); wxString link=ns+"."+on; if (kind=="f" || kind=="p") { link+="("+args+")"; isfunc=true; } else isfunc=false; txt += wxString::Format("%s
", link, link); c++; res->MoveNext(); } if(res) { delete res; res = NULL; } if (c>1) return txt; if (c==1) { wxString html; if (def.IsEmpty()) { wxTreeItemIdValue foldercookie; ctlTree *browser=winMain->GetBrowser(); wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); while (folderitem) { if (browser->ItemHasChildren(folderitem)) { wxTreeItemIdValue servercookie; wxTreeItemId serveritem = browser->GetFirstChild(folderitem, servercookie); wxString host=dblast->GetHost(); wxString db=dblast->GetDbname(); int port=dblast->GetPort(); wxString fullid=on; if (!args.IsEmpty()) fullid+="("+args+")"; wxString idf=wxString::Format("%s:%d",host,port); while (serveritem) { pgServer *server = (pgServer *)browser->GetItemData(serveritem); if (server != NULL && server->IsCreatedBy(serverFactory)) { if (server->GetIdentifier()==idf ) { if (server->connection()) { // is open connect //wxTreeItemId serveritemc1 = browser->GetFirstChild(folderitem, servercookie); pgCollection *coll=browser->FindCollection(databaseFactory,serveritem); wxTreeItemId dbssId; if (coll) dbssId=coll->GetId(); wxCookieType cookie2; wxTreeItemId item = browser->GetFirstChild(dbssId, cookie2); while (item && item.IsOk()) { //wxString tt=browser->GetItemText(item); pgObject *obj = browser->GetObject(item); if (obj && obj->IsCreatedBy(databaseFactory) && db==obj->GetName() ) { pgCollection *coll=browser->FindCollection(schemaFactory,item); wxTreeItemId schemasId; if (coll) schemasId=coll->GetId(); if (schemasId) { pgObject *obj2 = browser->GetObject(item); //obj2->expandedKids wxCookieType cookie4; item = browser->GetFirstChild(schemasId, cookie4); while (item) { pgSchema *obj3 = (pgSchema *)browser->GetObject(item); if (obj3 && obj3->IsCreatedBy(schemaFactory) && ns==obj3->GetName() ) { obj3->ShowTreeDetail(browser); wxTreeItemId objcollId; pgCollection *coll=NULL; if (kind=='r'||kind=='p' ) coll = browser->FindCollection(tableFactory,item); if (kind=='v'||kind=='m') coll = browser->FindCollection(viewFactory,item); if (kind=='f') coll = browser->FindCollection(functionFactory,item); if (kind=='P') coll = browser->FindCollection(procedureFactory,item); //if (kind=='p') coll = browser->FindCollection(pg_partitionFactory,item); if (kind=='t') coll = browser->FindCollection(triggerFunctionFactory,item); if (coll) { objcollId=coll->GetId(); pgObject *obj4 = browser->GetObject(objcollId); obj4->ShowTreeDetail(browser); } wxCookieType cookie5; item = browser->GetFirstChild(objcollId, cookie5); while (item) { pgObject *obj5 = browser->GetObject(item); //wxString soid=obj5->GetOidStr(); if (obj5 && NumToStr(obj5->GetOid())==oid) { pgObject *obj5 = browser->GetObject(item); obj5->ShowTreeDetail(browser); def=obj5->GetSql(browser); if (kind=='r'|| kind=='m' || kind=='v' || kind=='f') { //pgTable *o=(pgTable *)(obj5); //brower->FindObject(tableFactory,) //o->AppendStuff(def,browser,tableFactory); } goto exitloop; } item = browser->GetNextChild(objcollId, cookie5); } } item = browser->GetNextChild(schemasId, cookie4); } } goto exitloop; } item = browser->GetNextChild(dbssId, cookie2); } // next } goto exitloop; } } serveritem = browser->GetNextChild(folderitem, servercookie); } } folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); } } exitloop: FSQL::FormatterSQL f(def); std::vector listobj=f.ParsePLpgsql(); ctlSQLBox* box = new ctlSQLBox((wxWindow*) winMain, CTL_SQLQUERY, wxDefaultPosition, wxSize(0, 0), wxTE_MULTILINE | wxTE_RICH2); box->SetText(def); int l = def.Length(); box->Colourise(0, box->GetLength()); //bg = box->SetSQLBoxColourBackground(false).GetAsString(wxC2S_CSS_SYNTAX); html = box->TextToHtml(0, box->GetLength(),false,listobj); wxColour cbg=box->GetBackgroundColour(); wxString bg=cbg.GetAsString(wxC2S_HTML_SYNTAX); delete box; html = "" + html + ""; return html; } } return wxEmptyString; } wxString FunctionPGHelper::getSqlCommandHelp(wxString fnd) { wxUniChar sep = wxFileName::GetPathSeparator(); fnd.Replace(" ", ""); wxString f = wxFindFirstFile(path + sep + "sql-" + fnd + "*.html"); wxString last, txt; int c = 0; while (!f.empty()) { f = f.AfterLast(sep); last = f; txt += wxString::Format("%s
", f, f); f = wxFindNextFile(); c++; } if (last.empty()) { return wxEmptyString; } else if (c == 1) { return getHelpFile(last); } else { return txt; } } wxString FunctionPGHelper::getHelpFile(wxString filename) { wxString tempDir = path + wxFileName::GetPathSeparator() + filename; if (!wxFileExists(tempDir)) return wxEmptyString; wxTextFile tfile; tfile.Open(tempDir); // read the first line wxString str, sbody; sbody = tfile.GetFirstLine(); bool flag = true; wxRegEx b("()"); while (!tfile.Eof()) { str = tfile.GetNextLine(); if (flag && b.Matches(str)) { size_t start, len; b.GetMatch(&start, &len, 0); str = str.Mid(start + len); sbody = ""; flag = false; } sbody += str; } return sbody; } bool FunctionPGHelper::isValid() { if (!isload) loadfile(); return isload; } void FunctionPGHelper::loadfile() { if (isload) return; body.clear(); path = settings->GetPgHelpPath(); wxString tempDir = path + "_func.txt"; //tempDir="C:\\Users\\lsv\\Source\\Repos\\wxHtmlhint\\1"; if (!wxFileExists(tempDir)) return; wxTextFile tfile; tfile.Open(tempDir); // read the first line wxString str, sbody; wxString name = tfile.GetFirstLine(); //wxSortedArrayString names; name = name.AfterFirst('#'); // read all lines one by one // until the end of the file while (!tfile.Eof()) { str = tfile.GetNextLine(); if (str.Left(1) == '#') { body.emplace(name, sbody); sbody = ""; name = str.AfterFirst('#'); } else sbody += str; } body.emplace(name, sbody); isload = true; };