1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Copyright (C) 2002 - 2016, The pgAdmin Development Team
6 // This software is released under the PostgreSQL Licence
7 //
8 // pgForeignDataWrapper.cpp - Foreign Data Wrapper class
9 //
10 //////////////////////////////////////////////////////////////////////////
11
12 // wxWindows headers
13 #include <wx/wx.h>
14
15 // App headers
16 #include "pgAdmin3.h"
17 #include "utils/misc.h"
18 #include "schema/pgForeignDataWrapper.h"
19 #include "schema/pgForeignServer.h"
20
21
pgForeignDataWrapper(const wxString & newName)22 pgForeignDataWrapper::pgForeignDataWrapper(const wxString &newName)
23 : pgDatabaseObject(foreignDataWrapperFactory, newName)
24 {
25 }
26
27
GetTranslatedMessage(int kindOfMessage) const28 wxString pgForeignDataWrapper::GetTranslatedMessage(int kindOfMessage) const
29 {
30 wxString message = wxEmptyString;
31
32 switch (kindOfMessage)
33 {
34 case RETRIEVINGDETAILS:
35 message = _("Retrieving details on foreign data wrapper");
36 message += wxT(" ") + GetName();
37 break;
38 case REFRESHINGDETAILS:
39 message = _("Refreshing foreign data wrapper");
40 message += wxT(" ") + GetName();
41 break;
42 case DROPINCLUDINGDEPS:
43 message = wxString::Format(_("Are you sure you wish to drop foreign data wrapper \"%s\" including all objects that depend on it?"),
44 GetFullIdentifier().c_str());
45 break;
46 case DROPEXCLUDINGDEPS:
47 message = wxString::Format(_("Are you sure you wish to drop foreign data wrapper \"%s\"?"),
48 GetFullIdentifier().c_str());
49 break;
50 case DROPCASCADETITLE:
51 message = _("Drop foreign data wrapper cascaded?");
52 break;
53 case DROPTITLE:
54 message = _("Drop foreign data wrapper?");
55 break;
56 case PROPERTIESREPORT:
57 message = _("Foreign data wrapper properties report");
58 message += wxT(" - ") + GetName();
59 break;
60 case PROPERTIES:
61 message = _("Foreign data wrapper properties");
62 break;
63 case DDLREPORT:
64 message = _("Foreign data wrapper DDL report");
65 message += wxT(" - ") + GetName();
66 break;
67 case DDL:
68 message = _("Foreign data wrapper DDL");
69 break;
70 case STATISTICSREPORT:
71 message = _("Foreign data wrapper statistics report");
72 message += wxT(" - ") + GetName();
73 break;
74 case OBJSTATISTICS:
75 message = _("Foreign data wrapper statistics");
76 break;
77 case DEPENDENCIESREPORT:
78 message = _("Foreign data wrapper dependencies report");
79 message += wxT(" - ") + GetName();
80 break;
81 case DEPENDENCIES:
82 message = _("Foreign data wrapper dependencies");
83 break;
84 case DEPENDENTSREPORT:
85 message = _("Foreign data wrapper dependents report");
86 message += wxT(" - ") + GetName();
87 break;
88 case DEPENDENTS:
89 message = _("Foreign data wrapper dependents");
90 break;
91 }
92
93 return message;
94 }
95
96
DropObject(wxFrame * frame,ctlTree * browser,bool cascaded)97 bool pgForeignDataWrapper::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
98 {
99 wxString sql = wxT("DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier();
100 if (cascaded)
101 sql += wxT(" CASCADE");
102 return GetDatabase()->ExecuteVoid(sql);
103 }
104
105
GetSql(ctlTree * browser)106 wxString pgForeignDataWrapper::GetSql(ctlTree *browser)
107 {
108 if (sql.IsNull())
109 {
110 sql = wxT("-- Foreign Data Wrapper: ") + GetQuotedFullIdentifier() + wxT("\n\n")
111 + wxT("-- DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier() + wxT(";")
112 + wxT("\n\nCREATE ");
113 sql += wxT("FOREIGN DATA WRAPPER ") + GetName();
114
115 if (!GetHandlerProc().IsEmpty())
116 sql += wxT("\n HANDLER ") + GetHandlerProc();
117
118 if (!GetValidatorProc().IsEmpty())
119 sql += wxT("\n VALIDATOR ") + GetValidatorProc();
120
121 if (!GetOptions().IsEmpty())
122 sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")");
123
124 sql += wxT(";\n")
125 + GetOwnerSql(8, 4, wxT("FOREIGN DATA WRAPPER ") + GetName())
126 + GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier());
127 }
128 return sql;
129 }
130
131
ShowTreeDetail(ctlTree * browser,frmMain * form,ctlListView * properties,ctlSQLBox * sqlPane)132 void pgForeignDataWrapper::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
133 {
134 if (!expandedKids)
135 {
136 expandedKids = true;
137
138 browser->RemoveDummyChild(this);
139
140 // Log
141 wxLogInfo(wxT("Adding child object to foreign data wrapper %s"), GetIdentifier().c_str());
142
143 if (settings->GetDisplayOption(_("Foreign Servers")))
144 browser->AppendCollection(this, foreignServerFactory);
145 }
146
147 if (properties)
148 {
149 CreateListColumns(properties);
150
151 properties->AppendItem(_("Name"), GetName());
152 properties->AppendItem(_("OID"), GetOid());
153 properties->AppendItem(_("Owner"), GetOwner());
154 properties->AppendItem(_("ACL"), GetAcl());
155 properties->AppendItem(_("Handler"), GetHandlerProc());
156 properties->AppendItem(_("Validator"), GetValidatorProc());
157 properties->AppendItem(_("Options"), GetOptions());
158 }
159 }
160
161
162
Refresh(ctlTree * browser,const wxTreeItemId item)163 pgObject *pgForeignDataWrapper::Refresh(ctlTree *browser, const wxTreeItemId item)
164 {
165 pgObject *fdw = 0;
166 pgCollection *coll = browser->GetParentCollection(item);
167 if (coll)
168 fdw = foreignDataWrapperFactory.CreateObjects(coll, 0, wxT("\n WHERE fdw.oid=") + GetOidStr());
169
170 return fdw;
171 }
172
173
174
GetNewMenu()175 wxMenu *pgForeignDataWrapper::GetNewMenu()
176 {
177 wxMenu *menu = pgObject::GetNewMenu();
178 if (database->GetCreatePrivilege())
179 {
180 foreignServerFactory.AppendMenu(menu);
181 }
182 return menu;
183 }
184
185
CreateObjects(pgCollection * collection,ctlTree * browser,const wxString & restriction)186 pgObject *pgForeignDataWrapperFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
187 {
188 wxString sql;
189 pgForeignDataWrapper *fdw = 0;
190
191 bool fdwHandlerSupport = (collection->GetDatabase()->BackendMinimumVersion(9, 1));
192
193 if(fdwHandlerSupport)
194 {
195
196 sql = wxT("SELECT fdw.oid, fdwname, fdwhandler, fdwvalidator, fdwacl, ")
197 wxT("vh.proname as fdwhan, vp.proname as fdwval, description, ")
198 wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ")
199 wxT("pg_get_userbyid(fdwowner) as fdwowner\n");
200 sql += wxT(" FROM pg_foreign_data_wrapper fdw\n")
201 wxT(" LEFT OUTER JOIN pg_proc vh on vh.oid=fdwhandler\n")
202 wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n")
203 wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=fdw.oid AND des.objsubid=0 AND des.classoid='pg_foreign_data_wrapper'::regclass)\n")
204 + restriction + wxT("\n")
205 wxT(" ORDER BY fdwname");
206 }
207 else
208 {
209
210 sql = wxT("SELECT fdw.oid, fdwname, fdwvalidator, fdwacl, ")
211 wxT("vp.proname as fdwval, description, ")
212 wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ")
213 wxT("pg_get_userbyid(fdwowner) as fdwowner\n");
214 sql += wxT(" FROM pg_foreign_data_wrapper fdw\n")
215 wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n")
216 wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=fdw.oid AND des.objsubid=0 AND des.classoid='pg_foreign_data_wrapper'::regclass)\n")
217 + restriction + wxT("\n")
218 wxT(" ORDER BY fdwname");
219 }
220 pgSet *fdws = collection->GetDatabase()->ExecuteSet(sql);
221
222 if (fdws)
223 {
224 while (!fdws->Eof())
225 {
226
227 fdw = new pgForeignDataWrapper(fdws->GetVal(wxT("fdwname")));
228 fdw->iSetDatabase(collection->GetDatabase());
229 fdw->iSetOid(fdws->GetOid(wxT("oid")));
230 fdw->iSetOwner(fdws->GetVal(wxT("fdwowner")));
231 fdw->iSetAcl(fdws->GetVal(wxT("fdwacl")));
232 if(fdwHandlerSupport)
233 fdw->iSetHandlerProc(fdws->GetVal(wxT("fdwhan")));
234 fdw->iSetValidatorProc(fdws->GetVal(wxT("fdwval")));
235 fdw->iSetOptions(fdws->GetVal(wxT("fdwoptions")));
236
237 if (browser)
238 {
239 browser->AppendObject(collection, fdw);
240
241 fdws->MoveNext();
242 }
243 else
244 break;
245 }
246
247 delete fdws;
248 }
249 return fdw;
250 }
251
252
GetCreateOptions()253 wxString pgForeignDataWrapper::GetCreateOptions()
254 {
255 wxString options_create = wxEmptyString;
256 wxString opt;
257 wxString val;
258
259 wxStringTokenizer tkz_options(options, wxT(","));
260 while (tkz_options.HasMoreTokens())
261 {
262 wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("="));
263 opt = tkz_option.GetNextToken();
264 val = tkz_option.GetNextToken();
265
266 if (!options_create.IsEmpty())
267 options_create += wxT(",");
268
269 options_create += opt + wxT(" '") + val + wxT("'");
270 }
271
272 return options_create;
273 }
274
275
276 ///////////////////////////////////////////////////////////////
277
SetForeignDataWrapper(pgForeignDataWrapper * newForeignDataWrapper)278 void pgForeignDataWrapperObject::SetForeignDataWrapper(pgForeignDataWrapper *newForeignDataWrapper)
279 {
280 fdw = newForeignDataWrapper;
281 database = fdw->GetDatabase();
282 }
283
CanDrop()284 bool pgForeignDataWrapperObject::CanDrop()
285 {
286 return true; //fdw->GetCreatePrivilege();
287 }
288
289
CanCreate()290 bool pgForeignDataWrapperObject::CanCreate()
291 {
292 return true; //fdw->GetCreatePrivilege();
293 }
294
295
SetContextInfo(frmMain * form)296 void pgForeignDataWrapperObject::SetContextInfo(frmMain *form)
297 {
298 }
299
300
ExecuteSet(const wxString & sql)301 pgSet *pgForeignDataWrapperObject::ExecuteSet(const wxString &sql)
302 {
303 return fdw->GetDatabase()->ExecuteSet(sql);
304 }
305
ExecuteScalar(const wxString & sql)306 wxString pgForeignDataWrapperObject::ExecuteScalar(const wxString &sql)
307 {
308 return fdw->GetDatabase()->ExecuteScalar(sql);
309 }
310
311
ExecuteVoid(const wxString & sql)312 bool pgForeignDataWrapperObject::ExecuteVoid(const wxString &sql)
313 {
314 return fdw->GetDatabase()->ExecuteVoid(sql);
315 }
316
317
318 /////////////////////////////////////////////////////
319
pgForeignDataWrapperObjCollection(pgaFactory * factory,pgForeignDataWrapper * newfdw)320 pgForeignDataWrapperObjCollection::pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *newfdw)
321 : pgCollection(factory)
322 {
323 fdw = newfdw;
324 database = fdw->GetDatabase();
325 server = database->GetServer();
326 iSetOid(fdw->GetOid());
327 }
328
329
GetTranslatedMessage(int kindOfMessage) const330 wxString pgForeignDataWrapperObjCollection::GetTranslatedMessage(int kindOfMessage) const
331 {
332 wxString message = wxEmptyString;
333
334 switch (kindOfMessage)
335 {
336 case RETRIEVINGDETAILS:
337 message = _("Retrieving details on foreign data wrappers");
338 break;
339 case REFRESHINGDETAILS:
340 message = _("Refreshing foreign data wrappers");
341 break;
342 case OBJECTSLISTREPORT:
343 message = _("Foreign data wrappers list report");
344 break;
345 }
346
347 return message;
348 }
349
CanCreate()350 bool pgForeignDataWrapperObjCollection::CanCreate()
351 {
352 return GetDatabase()->GetCreatePrivilege();
353 }
354
355
CreateCollection(pgObject * obj)356 pgCollection *pgForeignDataWrapperObjFactory::CreateCollection(pgObject *obj)
357 {
358 return new pgForeignDataWrapperObjCollection(GetCollectionFactory(), (pgForeignDataWrapper *)obj);
359 }
360
361
362 /////////////////////////////
363
pgForeignDataWrapperCollection(pgaFactory * factory,pgDatabase * db)364 pgForeignDataWrapperCollection::pgForeignDataWrapperCollection(pgaFactory *factory, pgDatabase *db)
365 : pgDatabaseObjCollection(factory, db)
366 {
367 }
368
369
GetTranslatedMessage(int kindOfMessage) const370 wxString pgForeignDataWrapperCollection::GetTranslatedMessage(int kindOfMessage) const
371 {
372 wxString message = wxEmptyString;
373
374 switch (kindOfMessage)
375 {
376 case RETRIEVINGDETAILS:
377 message = _("Retrieving details on foreign data wrappers");
378 break;
379 case REFRESHINGDETAILS:
380 message = _("Refreshing foreign data wrappers");
381 break;
382 case OBJECTSLISTREPORT:
383 message = _("Foreign data wrappers list report");
384 break;
385 }
386
387 return message;
388 }
389
390 ///////////////////////////////////////////////////
391
392 #include "images/foreigndatawrapper.pngc"
393 #include "images/foreigndatawrapper-sm.pngc"
394 #include "images/foreigndatawrappers.pngc"
395
pgForeignDataWrapperFactory()396 pgForeignDataWrapperFactory::pgForeignDataWrapperFactory()
397 : pgDatabaseObjFactory(__("Foreign Data Wrapper"), __("New Foreign Data Wrapper..."), __("Create a new Foreign Data Wrapper."), foreigndatawrapper_png_img, foreigndatawrapper_sm_png_img)
398 {
399 }
400
401
CreateCollection(pgObject * obj)402 pgCollection *pgForeignDataWrapperFactory::CreateCollection(pgObject *obj)
403 {
404 return new pgForeignDataWrapperCollection(GetCollectionFactory(), (pgDatabase *)obj);
405 }
406
407 pgForeignDataWrapperFactory foreignDataWrapperFactory;
408 static pgaCollectionFactory cf(&foreignDataWrapperFactory, __("Foreign Data Wrappers"), foreigndatawrappers_png_img);
409