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 // dlgForeignServer.cpp - PostgreSQL Foreign Server Property
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 "utils/pgDefs.h"
19 
20 #include "dlg/dlgForeignServer.h"
21 #include "schema/pgForeignServer.h"
22 
23 
24 // pointer to controls
25 #define cbForeignDataWrapper CTRL_COMBOBOX("cbForeignDataWrapper")
26 #define txtType              CTRL_TEXT("txtType")
27 #define txtVersion           CTRL_TEXT("txtVersion")
28 #define lstOptions           CTRL_LISTVIEW("lstOptions")
29 #define txtOption            CTRL_TEXT("txtOption")
30 #define txtValue             CTRL_TEXT("txtValue")
31 #define btnAdd               CTRL_BUTTON("wxID_ADD")
32 #define btnRemove            CTRL_BUTTON("wxID_REMOVE")
33 
34 
CreateDialog(frmMain * frame,pgObject * node,pgObject * parent)35 dlgProperty *pgForeignServerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
36 {
37 	return new dlgForeignServer(this, frame, (pgForeignServer *)node, (pgForeignDataWrapper *)parent);
38 }
39 
40 
41 BEGIN_EVENT_TABLE(dlgForeignServer, dlgSecurityProperty)
42 	EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignServer::OnSelChangeOption)
43 	EVT_TEXT(XRCID("txtOption"),                dlgForeignServer::OnChangeOptionName)
44 	EVT_BUTTON(wxID_ADD,                        dlgForeignServer::OnAddOption)
45 	EVT_BUTTON(wxID_REMOVE,                     dlgForeignServer::OnRemoveOption)
46 END_EVENT_TABLE();
47 
48 
dlgForeignServer(pgaFactory * f,frmMain * frame,pgForeignServer * node,pgForeignDataWrapper * parent)49 dlgForeignServer::dlgForeignServer(pgaFactory *f, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent)
50 	: dlgSecurityProperty(f, frame, node, wxT("dlgForeignServer"), wxT("USAGE"), "U")
51 {
52 	foreigndatawrapper = parent;
53 	foreignserver = node;
54 }
55 
56 
GetObject()57 pgObject *dlgForeignServer::GetObject()
58 {
59 	return foreignserver;
60 }
61 
62 
Go(bool modal)63 int dlgForeignServer::Go(bool modal)
64 {
65 	// Initialize options listview and buttons
66 	lstOptions->AddColumn(_("Option"), 80);
67 	lstOptions->AddColumn(_("Value"), 40);
68 	txtOption->SetValue(wxT(""));
69 	txtValue->SetValue(wxT(""));
70 	btnAdd->Disable();
71 	btnRemove->Disable();
72 
73 	if (foreignserver)
74 	{
75 		// edit mode
76 		txtName->Enable(connection->BackendMinimumVersion(9, 2));
77 		txtType->Disable();
78 
79 		txtType->SetValue(foreignserver->GetType());
80 		txtVersion->SetValue(foreignserver->GetVersion());
81 
82 		wxString options = foreignserver->GetOptions();
83 		wxString option, optionname, optionvalue;
84 		while (options.Length() > 0)
85 		{
86 			option = options.BeforeFirst(',');
87 			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
88 			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
89 			lstOptions->AppendItem(optionname, optionvalue);
90 			options = options.AfterFirst(',');
91 		}
92 	}
93 	else
94 	{
95 		// create mode
96 	}
97 
98 	return dlgSecurityProperty::Go(modal);
99 }
100 
101 
CreateObject(pgCollection * collection)102 pgObject *dlgForeignServer::CreateObject(pgCollection *collection)
103 {
104 	wxString name = txtName->GetValue();
105 
106 	pgObject *obj = foreignServerFactory.CreateObjects(collection, 0, wxT("\n   AND srvname ILIKE ") + qtDbString(name));
107 	return obj;
108 }
109 
110 
CheckChange()111 void dlgForeignServer::CheckChange()
112 {
113 	bool didChange = true;
114 	wxString name = txtName->GetValue();
115 	if (foreignserver)
116 	{
117 		didChange = name != foreignserver->GetName()
118 		            || txtComment->GetValue() != foreignserver->GetComment()
119 		            || cbOwner->GetValue() != foreignserver->GetOwner()
120 		            || txtType->GetValue() != foreignserver->GetType()
121 		            || txtVersion->GetValue() != foreignserver->GetVersion()
122 		            || GetOptionsSql().Length() > 0;
123 		EnableOK(didChange);
124 	}
125 	else
126 	{
127 		bool enable = true;
128 
129 		CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
130 		EnableOK(enable);
131 	}
132 }
133 
134 
135 
OnChange(wxCommandEvent & ev)136 void dlgForeignServer::OnChange(wxCommandEvent &ev)
137 {
138 	CheckChange();
139 }
140 
141 
OnChangeOptionName(wxCommandEvent & ev)142 void dlgForeignServer::OnChangeOptionName(wxCommandEvent &ev)
143 {
144 	btnAdd->Enable(txtOption->GetValue().Length() > 0);
145 }
146 
147 
OnSelChangeOption(wxListEvent & ev)148 void dlgForeignServer::OnSelChangeOption(wxListEvent &ev)
149 {
150 	int row = lstOptions->GetSelection();
151 	if (row >= 0)
152 	{
153 		txtOption->SetValue(lstOptions->GetText(row, 0));
154 		txtValue->SetValue(lstOptions->GetText(row, 1));
155 	}
156 
157 	btnRemove->Enable(row >= 0);
158 }
159 
160 
OnAddOption(wxCommandEvent & ev)161 void dlgForeignServer::OnAddOption(wxCommandEvent &ev)
162 {
163 	bool found = false;
164 
165 	for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
166 	{
167 		if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false))
168 		{
169 			lstOptions->SetItem(pos, 1, txtValue->GetValue());
170 			found = true;
171 			break;
172 		}
173 	}
174 
175 	if (!found)
176 	{
177 		lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue());
178 	}
179 
180 	txtOption->SetValue(wxT(""));
181 	txtValue->SetValue(wxT(""));
182 	btnAdd->Disable();
183 
184 	CheckChange();
185 }
186 
187 
OnRemoveOption(wxCommandEvent & ev)188 void dlgForeignServer::OnRemoveOption(wxCommandEvent &ev)
189 {
190 	int sel = lstOptions->GetSelection();
191 	lstOptions->DeleteItem(sel);
192 
193 	txtOption->SetValue(wxT(""));
194 	txtValue->SetValue(wxT(""));
195 	btnRemove->Disable();
196 
197 	CheckChange();
198 }
199 
200 
GetOptionsSql()201 wxString dlgForeignServer::GetOptionsSql()
202 {
203 	wxString options = foreignserver->GetOptions();
204 	wxString option, optionname, optionvalue, sqloptions;
205 	bool found;
206 	int pos;
207 
208 	while (options.Length() > 0)
209 	{
210 		option = options.BeforeFirst(',');
211 		optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
212 		optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
213 
214 		// check for options
215 		found = false;
216 		for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++)
217 		{
218 			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
219 			if (found) break;
220 		}
221 
222 		if (found)
223 		{
224 			if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0)
225 			{
226 				if (sqloptions.Length() > 0)
227 					sqloptions += wxT(", ");
228 				sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'");
229 			}
230 		}
231 		else
232 		{
233 			if (sqloptions.Length() > 0)
234 				sqloptions += wxT(", ");
235 			sqloptions += wxT("DROP ") + optionname;
236 		}
237 
238 		options = options.AfterFirst(',');
239 	}
240 
241 	for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
242 	{
243 		options = foreignserver->GetOptions();
244 		found = false;
245 
246 		while (options.Length() > 0 && !found)
247 		{
248 			option = options.BeforeFirst(',');
249 			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
250 			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
251 			options = options.AfterFirst(',');
252 		}
253 
254 		if (!found)
255 		{
256 			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
257 
258 			if (sqloptions.Length() > 0)
259 				sqloptions += wxT(", ");
260 			sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'");
261 		}
262 	}
263 
264 	return sqloptions;
265 }
266 
267 
GetSql()268 wxString dlgForeignServer::GetSql()
269 {
270 	wxString sql, name;
271 	name = txtName->GetValue();
272 
273 	if (foreignserver)
274 	{
275 		// edit mode
276 		AppendNameChange(sql, wxT("SERVER ") + qtIdent(foreignserver->GetName()));
277 
278 		if (txtVersion->GetValue() != foreignserver->GetVersion())
279 		{
280 			sql = wxT("ALTER SERVER ") + qtIdent(name)
281 			      + wxT("\n  VERSION ") + qtDbString(txtVersion->GetValue()) + wxT(";\n");
282 		}
283 
284 		wxString sqloptions = GetOptionsSql();
285 		if (sqloptions.Length() > 0)
286 		{
287 			sql += wxT("ALTER SERVER ") + name
288 			       + wxT("\n  OPTIONS (") + sqloptions + wxT(");\n");
289 		}
290 
291 		AppendOwnerChange(sql, wxT("SERVER ") + qtIdent(name));
292 	}
293 	else
294 	{
295 		// create mode
296 		sql = wxT("CREATE SERVER ") + qtIdent(name);
297 		if (!(txtType->GetValue()).IsEmpty())
298 			sql += wxT("\n   TYPE ") + qtDbString(txtType->GetValue());
299 		if (!(txtVersion->GetValue()).IsEmpty())
300 			sql += wxT("\n   VERSION ") + qtDbString(txtVersion->GetValue());
301 		sql += wxT("\n   FOREIGN DATA WRAPPER ") + qtIdent(foreigndatawrapper->GetName());
302 
303 		// check for options
304 		if (lstOptions->GetItemCount() > 0)
305 		{
306 			wxString options = wxEmptyString;
307 			for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
308 			{
309 				if (options.Length() > 0)
310 					options += wxT(", ");
311 
312 				options += lstOptions->GetText(pos, 0)
313 				           + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' ");
314 			}
315 			sql += wxT("\n  OPTIONS (") + options + wxT(")");
316 		}
317 
318 		sql += wxT(";\n");
319 		AppendOwnerNew(sql, wxT("SERVER ") + qtIdent(name));
320 	}
321 
322 	sql += GetGrant(wxT("U"), wxT("SERVER ") + qtIdent(name));
323 	AppendComment(sql, wxT("SERVER"), 0, foreignserver);
324 
325 	return sql;
326 }
327 
328 
329 
330