mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
355 lines
9.4 KiB
C++
355 lines
9.4 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// edbPackage.cpp - EnterpriseDB Package class
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// wxWindows headers
|
|
#include <wx/wx.h>
|
|
|
|
// App headers
|
|
#include "pgAdmin3.h"
|
|
#include "utils/misc.h"
|
|
#include "schema/edbPackage.h"
|
|
#include "schema/edbPackageFunction.h"
|
|
#include "schema/edbPackageVariable.h"
|
|
|
|
edbPackage::edbPackage(pgSchema *newSchema, const wxString &newName)
|
|
: pgSchemaObject(newSchema, packageFactory, newName)
|
|
{
|
|
}
|
|
|
|
wxString edbPackage::GetTranslatedMessage(int kindOfMessage) const
|
|
{
|
|
wxString message = wxEmptyString;
|
|
|
|
switch (kindOfMessage)
|
|
{
|
|
case RETRIEVINGDETAILS:
|
|
message = _("Retrieving details on package");
|
|
message += wxT(" ") + GetName();
|
|
break;
|
|
case REFRESHINGDETAILS:
|
|
message = _("Refreshing package");
|
|
message += wxT(" ") + GetName();
|
|
break;
|
|
case DROPINCLUDINGDEPS:
|
|
message = wxString::Format(_("Are you sure you wish to drop package \"%s\" including all objects that depend on it?"),
|
|
GetFullIdentifier().c_str());
|
|
break;
|
|
case DROPEXCLUDINGDEPS:
|
|
message = wxString::Format(_("Are you sure you wish to drop package \"%s\"?"),
|
|
GetFullIdentifier().c_str());
|
|
break;
|
|
case DROPCASCADETITLE:
|
|
message = _("Drop package cascaded?");
|
|
break;
|
|
case DROPTITLE:
|
|
message = _("Drop package?");
|
|
break;
|
|
case PROPERTIESREPORT:
|
|
message = _("Package properties report");
|
|
message += wxT(" - ") + GetName();
|
|
break;
|
|
case PROPERTIES:
|
|
message = _("Package properties");
|
|
break;
|
|
case DDLREPORT:
|
|
message = _("Package DDL report");
|
|
message += wxT(" - ") + GetName();
|
|
break;
|
|
case DDL:
|
|
message = _("Package DDL");
|
|
break;
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
|
|
bool edbPackage::IsUpToDate()
|
|
{
|
|
pgConn *conn = GetDatabase()->GetConnection();
|
|
if (!conn)
|
|
return false;
|
|
|
|
wxString sql;
|
|
if(conn->EdbMinimumVersion(8, 2))
|
|
sql = wxT("SELECT xmin FROM pg_namespace WHERE oid = ") + this->GetOidStr();
|
|
else
|
|
sql = wxT("SELECT xmin FROM edb_package WHERE oid = ") + this->GetOidStr();
|
|
|
|
if (conn->ExecuteScalar(sql) != NumToStr(GetXid()))
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
bool edbPackage::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
|
|
{
|
|
wxString sql = wxT("DROP PACKAGE ") + GetQuotedFullIdentifier();
|
|
|
|
return GetDatabase()->ExecuteVoid(sql);
|
|
}
|
|
|
|
wxString edbPackage::GetSql(ctlTree *browser)
|
|
{
|
|
wxString qtName = GetQuotedFullIdentifier();
|
|
|
|
if (sql.IsNull())
|
|
{
|
|
sql = wxT("-- Package: ") + qtName + wxT("\n\n")
|
|
wxT("-- DROP PACKAGE ") + qtName;
|
|
|
|
sql += wxT(";\n\n");
|
|
sql += wxT("CREATE OR REPLACE PACKAGE ") + qtName + wxT("\nIS\n");
|
|
sql += GetHeaderInner();
|
|
sql += wxT("\nEND ") + qtIdent(GetName()) + wxT(";\n\n");
|
|
|
|
if (!GetBodyInner().Trim().IsEmpty())
|
|
{
|
|
sql += wxT("CREATE OR REPLACE PACKAGE BODY ") + qtName + wxT("\nIS\n");
|
|
sql += GetBodyInner();
|
|
sql += wxT("\nEND ") + qtIdent(GetName()) + wxT(";\n\n");
|
|
}
|
|
|
|
sql += GetGrant(wxT("X"), wxT("PACKAGE ") + qtName);
|
|
|
|
sql += wxT("\n");
|
|
}
|
|
|
|
return sql;
|
|
}
|
|
|
|
wxString edbPackage::GetHeaderInner()
|
|
{
|
|
return GetInner(GetHeader());
|
|
}
|
|
|
|
wxString edbPackage::GetBodyInner()
|
|
{
|
|
return GetInner(GetBody());
|
|
}
|
|
|
|
wxString edbPackage::GetInner(const wxString &def)
|
|
{
|
|
long start = 0, end = 0;
|
|
|
|
wxStringTokenizer tkz(def, wxT("\t\r\n "));
|
|
|
|
// Find the opening AS/IF keyword
|
|
while ( tkz.HasMoreTokens() )
|
|
{
|
|
wxString token = tkz.GetNextToken();
|
|
if (token.Lower() == wxT("as") || token.Lower() == wxT("is"))
|
|
{
|
|
start = tkz.GetPosition();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Find the closing END keyword
|
|
wxString tmp = def;
|
|
tmp.Replace(wxT("\n"), wxT(" "));
|
|
tmp.Replace(wxT("\r"), wxT(" "));
|
|
tmp.Replace(wxT("\t"), wxT(" "));
|
|
|
|
int e1 = tmp.Lower().rfind(wxT(" end;"));
|
|
int e2 = tmp.Lower().rfind(wxT(" end "));
|
|
|
|
end = (e1 > e2 ? e1 : e2);
|
|
|
|
return def.Mid(start, end - start);
|
|
}
|
|
|
|
void edbPackage::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
|
|
{
|
|
if (!expandedKids)
|
|
{
|
|
expandedKids = true;
|
|
|
|
browser->RemoveDummyChild(this);
|
|
|
|
// Log
|
|
wxLogInfo(wxT("Adding child object to package %s"), GetIdentifier().c_str());
|
|
|
|
browser->AppendCollection(this, packageFunctionFactory);
|
|
browser->AppendCollection(this, packageProcedureFactory);
|
|
browser->AppendCollection(this, packageVariableFactory);
|
|
}
|
|
|
|
|
|
if (properties)
|
|
{
|
|
CreateListColumns(properties);
|
|
|
|
properties->AppendItem(_("Name"), GetName());
|
|
properties->AppendItem(_("OID"), GetOid());
|
|
properties->AppendItem(_("Owner"), GetOwner());
|
|
properties->AppendItem(_("Header"), firstLineOnly(GetHeader()));
|
|
properties->AppendItem(_("Body"), firstLineOnly(GetBody()));
|
|
properties->AppendItem(_("ACL"), GetAcl());
|
|
properties->AppendYesNoItem(_("System package?"), GetSystemObject());
|
|
if (GetConnection()->EdbMinimumVersion(8, 2))
|
|
properties->AppendItem(_("Comment"), firstLineOnly(GetComment()));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pgObject *edbPackage::Refresh(ctlTree *browser, const wxTreeItemId item)
|
|
{
|
|
pgObject *package = 0;
|
|
|
|
pgCollection *coll = browser->GetParentCollection(item);
|
|
if (coll)
|
|
{
|
|
if (coll->GetConnection()->EdbMinimumVersion(8, 2))
|
|
package = packageFactory.CreateObjects(coll, 0, wxT(" AND nspname=") + qtDbString(GetName()));
|
|
else
|
|
package = packageFactory.CreateObjects(coll, 0, wxT(" AND pkgname=") + qtDbString(GetName()));
|
|
}
|
|
|
|
return package;
|
|
}
|
|
|
|
|
|
|
|
pgObject *edbPackageFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
|
|
{
|
|
edbPackage *package = 0;
|
|
|
|
wxString sql, pkgsrc;
|
|
|
|
wxString whereclause;
|
|
|
|
if (collection->GetConnection()->EdbMinimumVersion(9, 0))
|
|
pkgsrc = wxT("pg_catalog.edb_get_packagebodydef(nsp.oid) AS pkgbodysrc, ")
|
|
wxT("pg_catalog.edb_get_packageheaddef(nsp.oid) AS pkgheadsrc,\n");
|
|
else if (collection->GetConnection()->EdbMinimumVersion(8, 2))
|
|
pkgsrc = wxT("nspbodysrc AS pkgbodysrc, nspheadsrc AS pkgheadsrc,\n");
|
|
|
|
if (collection->GetConnection()->EdbMinimumVersion(8, 2))
|
|
{
|
|
whereclause = wxT(" WHERE nspparent = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n");
|
|
if (collection->GetConnection()->EdbMinimumVersion(9, 2))
|
|
whereclause += wxT(" AND nspobjecttype = 0 ");
|
|
|
|
sql = wxT("SELECT nsp.oid, nsp.xmin, nspname AS pkgname,\n") + pkgsrc +
|
|
wxT(" nspacl AS pkgacl, pg_get_userbyid(nspowner) AS owner, description\n")
|
|
wxT(" FROM pg_namespace nsp")
|
|
wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n")
|
|
+ whereclause
|
|
+ restriction +
|
|
wxT(" ORDER BY nspname;");
|
|
}
|
|
else
|
|
{
|
|
|
|
sql = wxT("SELECT oid, xmin, *, pg_get_userbyid(pkgowner) AS owner\n")
|
|
wxT(" FROM edb_package")
|
|
wxT(" WHERE pkgnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n")
|
|
+ restriction +
|
|
wxT(" ORDER BY pkgname;");
|
|
}
|
|
|
|
pgSet *packages = collection->GetDatabase()->ExecuteSet(sql);
|
|
|
|
if (packages)
|
|
{
|
|
while (!packages->Eof())
|
|
{
|
|
wxString name = packages->GetVal(wxT("pkgname"));
|
|
package = new edbPackage(collection->GetSchema(), name);
|
|
|
|
package->iSetOid(packages->GetOid(wxT("oid")));
|
|
package->iSetXid(packages->GetOid(wxT("xmin")));
|
|
package->iSetDatabase(collection->GetDatabase());
|
|
package->iSetOwner(packages->GetVal(wxT("owner")));
|
|
if (collection->GetConnection()->EdbMinimumVersion(8, 2))
|
|
package->iSetComment(packages->GetVal(wxT("description")));
|
|
|
|
// EnterpriseDB's CVS code has some new parser code
|
|
// which is stricter about the formatting of body &
|
|
// header code and leaves off trailing ;'s
|
|
wxString tmp = packages->GetVal(wxT("pkgheadsrc")).Strip(wxString::both);
|
|
if (!tmp.EndsWith(wxT(";")))
|
|
package->iSetHeader(tmp + wxT(";"));
|
|
else
|
|
package->iSetHeader(tmp);
|
|
|
|
tmp = packages->GetVal(wxT("pkgbodysrc")).Strip(wxString::both);
|
|
if (!tmp.EndsWith(wxT(";")) && !tmp.IsEmpty())
|
|
package->iSetBody(tmp + wxT(";"));
|
|
else
|
|
package->iSetBody(tmp);
|
|
|
|
package->iSetAcl(packages->GetVal(wxT("pkgacl")));
|
|
|
|
if (browser)
|
|
{
|
|
browser->AppendObject(collection, package);
|
|
packages->MoveNext();
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
delete packages;
|
|
}
|
|
return package;
|
|
}
|
|
|
|
/////////////////////////////
|
|
|
|
edbPackageCollection::edbPackageCollection(pgaFactory *factory, pgSchema *sch)
|
|
: pgSchemaObjCollection(factory, sch)
|
|
{
|
|
}
|
|
|
|
wxString edbPackageCollection::GetTranslatedMessage(int kindOfMessage) const
|
|
{
|
|
wxString message = wxEmptyString;
|
|
|
|
switch (kindOfMessage)
|
|
{
|
|
case RETRIEVINGDETAILS:
|
|
message = _("Retrieving details on packages");
|
|
break;
|
|
case REFRESHINGDETAILS:
|
|
message = _("Refreshing packages");
|
|
break;
|
|
case GRANTWIZARDTITLE:
|
|
message = _("Privileges for packages");
|
|
break;
|
|
case OBJECTSLISTREPORT:
|
|
message = _("Packages list report");
|
|
break;
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
/////////////////////////////
|
|
|
|
#include "images/package.pngc"
|
|
#include "images/packages.pngc"
|
|
|
|
edbPackageFactory::edbPackageFactory()
|
|
: pgSchemaObjFactory(__("Package"), __("New Package..."), __("Create a new package."), package_png_img)
|
|
{
|
|
metaType = EDB_PACKAGE;
|
|
}
|
|
|
|
|
|
pgCollection *edbPackageFactory::CreateCollection(pgObject *obj)
|
|
{
|
|
return new edbPackageCollection(GetCollectionFactory(), (pgSchema *)obj);
|
|
}
|
|
|
|
edbPackageFactory packageFactory;
|
|
static pgaCollectionFactory cf(&packageFactory, __("Packages"), packages_png_img);
|