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 // dlgTextSearchDictionary.cpp - PostgreSQL Text Search Dictionary 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/dlgTextSearchDictionary.h"
21 #include "schema/pgSchema.h"
22 #include "schema/pgTextSearchDictionary.h"
23 #include "schema/pgDatatype.h"
24 
25 
26 // pointer to controls
27 #define cbTemplate          CTRL_COMBOBOX2("cbTemplate")
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 
35 BEGIN_EVENT_TABLE(dlgTextSearchDictionary, dlgTypeProperty)
36 	EVT_TEXT(XRCID("cbTemplate"),               dlgTextSearchDictionary::OnChange)
37 	EVT_COMBOBOX(XRCID("cbTemplate"),           dlgTextSearchDictionary::OnChange)
38 	EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgTextSearchDictionary::OnSelChangeOption)
39 	EVT_TEXT(XRCID("txtOption"),                dlgTextSearchDictionary::OnChangeOptionName)
40 	EVT_BUTTON(wxID_ADD,                        dlgTextSearchDictionary::OnAddOption)
41 	EVT_BUTTON(wxID_REMOVE,                     dlgTextSearchDictionary::OnRemoveOption)
42 #ifdef __WXMAC__
43 	EVT_SIZE(                                   dlgTextSearchDictionary::OnChangeSize)
44 #endif
45 END_EVENT_TABLE();
46 
47 
48 
CreateDialog(frmMain * frame,pgObject * node,pgObject * parent)49 dlgProperty *pgTextSearchDictionaryFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
50 {
51 	return new dlgTextSearchDictionary(this, frame, (pgTextSearchDictionary *)node, (pgSchema *)parent);
52 }
53 
dlgTextSearchDictionary(pgaFactory * f,frmMain * frame,pgTextSearchDictionary * node,pgSchema * sch)54 dlgTextSearchDictionary::dlgTextSearchDictionary(pgaFactory *f, frmMain *frame, pgTextSearchDictionary *node, pgSchema *sch)
55 	: dlgTypeProperty(f, frame, wxT("dlgTextSearchDictionary"))
56 {
57 	schema = sch;
58 	dict = node;
59 }
60 
61 
GetObject()62 pgObject *dlgTextSearchDictionary::GetObject()
63 {
64 	return dict;
65 }
66 
67 
Go(bool modal)68 int dlgTextSearchDictionary::Go(bool modal)
69 {
70 	wxString qry;
71 	pgSet *set;
72 
73 	qry = wxT("SELECT tmplname, nspname\n")
74 	      wxT("  FROM pg_ts_template\n")
75 	      wxT("  JOIN pg_namespace n ON n.oid=tmplnamespace\n")
76 	      wxT("  ORDER BY tmplname\n");
77 
78 	set = connection->ExecuteSet(qry);
79 	if (set)
80 	{
81 		while (!set->Eof())
82 		{
83 			wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("tmplname"));
84 			cbTemplate->Append(procname);
85 			set->MoveNext();
86 		}
87 		delete set;
88 	}
89 
90 	lstOptions->AddColumn(_("Option"), 80);
91 	lstOptions->AddColumn(_("Value"), 40);
92 
93 	if (dict)
94 	{
95 		// edit mode
96 		cbSchema->Enable(connection->BackendMinimumVersion(9, 1));
97 		cbTemplate->SetValue(dict->GetTemplate());
98 		cbTemplate->Disable();
99 
100 		wxString options = dict->GetOptions();
101 		wxString option, optionname, optionvalue;
102 		while (options.Length() > 0)
103 		{
104 			option = options.BeforeFirst(',');
105 			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
106 			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
107 			lstOptions->AppendItem(optionname, optionvalue);
108 			options = options.AfterFirst(',');
109 		}
110 
111 		if (!connection->BackendMinimumVersion(8, 0))
112 			cbOwner->Disable();
113 	}
114 	else
115 	{
116 		// create mode
117 	}
118 
119 	txtOption->SetValue(wxT(""));
120 	txtValue->SetValue(wxT(""));
121 	btnAdd->Disable();
122 	btnRemove->Disable();
123 
124 	return dlgProperty::Go(modal);
125 }
126 
127 
CreateObject(pgCollection * collection)128 pgObject *dlgTextSearchDictionary::CreateObject(pgCollection *collection)
129 {
130 	pgObject *obj = textSearchDictionaryFactory.CreateObjects(collection, 0,
131 	                wxT("\n   AND dict.dictname=") + qtDbString(GetName()) +
132 	                wxT("\n   AND dict.dictnamespace=") + schema->GetOidStr());
133 
134 	return obj;
135 }
136 
137 
138 #ifdef __WXMAC__
OnChangeSize(wxSizeEvent & ev)139 void dlgTextSearchDictionary::OnChangeSize(wxSizeEvent &ev)
140 {
141 	lstOptions->SetSize(wxDefaultCoord, wxDefaultCoord,
142 	                    ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
143 	if (GetAutoLayout())
144 	{
145 		Layout();
146 	}
147 }
148 #endif
149 
150 
CheckChange()151 void dlgTextSearchDictionary::CheckChange()
152 {
153 	if (dict)
154 	{
155 		EnableOK(txtName->GetValue() != dict->GetName()
156 		         || cbSchema->GetValue() != dict->GetSchema()->GetName()
157 		         || txtComment->GetValue() != dict->GetComment()
158 		         || cbOwner->GetValue() != dict->GetOwner()
159 		         || GetOptionsSql().Length() > 0);
160 	}
161 	else
162 	{
163 		wxString name = GetName();
164 		bool enable = true;
165 		CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
166 		CheckValid(enable, cbTemplate->GetValue().Length() > 0 , _("Please select a template."));
167 
168 		EnableOK(enable);
169 	}
170 }
171 
172 
OnChange(wxCommandEvent & ev)173 void dlgTextSearchDictionary::OnChange(wxCommandEvent &ev)
174 {
175 	CheckChange();
176 }
177 
178 
OnChangeOptionName(wxCommandEvent & ev)179 void dlgTextSearchDictionary::OnChangeOptionName(wxCommandEvent &ev)
180 {
181 	btnAdd->Enable(txtOption->GetValue().Length() > 0);
182 }
183 
184 
OnSelChangeOption(wxListEvent & ev)185 void dlgTextSearchDictionary::OnSelChangeOption(wxListEvent &ev)
186 {
187 	int row = lstOptions->GetSelection();
188 	if (row >= 0)
189 	{
190 		txtOption->SetValue(lstOptions->GetText(row, 0));
191 		txtValue->SetValue(lstOptions->GetText(row, 1));
192 	}
193 
194 	btnRemove->Enable(row >= 0);
195 }
196 
197 
OnAddOption(wxCommandEvent & ev)198 void dlgTextSearchDictionary::OnAddOption(wxCommandEvent &ev)
199 {
200 	bool found = false;
201 
202 	for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
203 	{
204 		if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false))
205 		{
206 			lstOptions->SetItem(pos, 1, txtValue->GetValue());
207 			found = true;
208 			break;
209 		}
210 	}
211 
212 	if (!found)
213 	{
214 		lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue());
215 	}
216 
217 	txtOption->SetValue(wxT(""));
218 	txtValue->SetValue(wxT(""));
219 	btnAdd->Disable();
220 
221 	CheckChange();
222 }
223 
224 
OnRemoveOption(wxCommandEvent & ev)225 void dlgTextSearchDictionary::OnRemoveOption(wxCommandEvent &ev)
226 {
227 	int sel = lstOptions->GetSelection();
228 	lstOptions->DeleteItem(sel);
229 
230 	txtOption->SetValue(wxT(""));
231 	txtValue->SetValue(wxT(""));
232 	btnRemove->Disable();
233 
234 	CheckChange();
235 }
236 
237 
GetOptionsSql()238 wxString dlgTextSearchDictionary::GetOptionsSql()
239 {
240 	wxString options = dict->GetOptions();
241 	wxString option, optionname, optionvalue, sqloptions;
242 	bool found;
243 	int pos;
244 
245 	while (options.Length() > 0)
246 	{
247 		option = options.BeforeFirst(',');
248 		optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
249 		optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
250 
251 		// check for options
252 		found = false;
253 		for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++)
254 		{
255 			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
256 			if (found) break;
257 		}
258 
259 		if (found)
260 		{
261 			if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0)
262 			{
263 				if (sqloptions.Length() > 0)
264 					sqloptions += wxT(", ");
265 				sqloptions += optionname + wxT("=") + lstOptions->GetText(pos, 1);
266 			}
267 		}
268 		else
269 		{
270 			if (sqloptions.Length() > 0)
271 				sqloptions += wxT(", ");
272 			sqloptions += optionname;
273 		}
274 
275 		options = options.AfterFirst(',');
276 	}
277 
278 	for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
279 	{
280 		options = dict->GetOptions();
281 		found = false;
282 
283 		while (options.Length() > 0 && !found)
284 		{
285 			option = options.BeforeFirst(',');
286 			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
287 			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
288 			options = options.AfterFirst(',');
289 		}
290 
291 		if (!found)
292 		{
293 			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
294 
295 			if (sqloptions.Length() > 0)
296 				sqloptions += wxT(", ");
297 			sqloptions += lstOptions->GetText(pos, 0) + wxT("=") + lstOptions->GetText(pos, 1);
298 		}
299 	}
300 
301 	return sqloptions;
302 }
303 
304 
GetSql()305 wxString dlgTextSearchDictionary::GetSql()
306 {
307 	wxString sql;
308 	wxString objname;
309 
310 	if (dict)
311 	{
312 		// edit mode
313 		objname = schema->GetQuotedPrefix() + qtIdent(GetName());
314 		AppendNameChange(sql, wxT("TEXT SEARCH DICTIONARY ") + dict->GetQuotedFullIdentifier());
315 
316 		wxString sqloptions = GetOptionsSql();
317 		if (sqloptions.Length() > 0)
318 		{
319 			sql += wxT("ALTER TEXT SEARCH DICTIONARY ") + objname
320 			       + wxT("\n  (") + sqloptions + wxT(");\n");
321 		}
322 		AppendOwnerChange(sql, wxT("TEXT SEARCH DICTIONARY ") + objname);
323 
324 		AppendSchemaChange(sql, wxT("TEXT SEARCH DICTIONARY ") + objname);
325 	}
326 	else
327 	{
328 		// create mode
329 		objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName());
330 		sql = wxT("CREATE TEXT SEARCH DICTIONARY ")
331 		      + objname
332 		      + wxT("\n  (")
333 		      + wxT("\n  TEMPLATE = ") + cbTemplate->GetValue();
334 
335 		// check for options
336 		for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
337 		{
338 			sql += wxT(", ") + lstOptions->GetText(pos, 0)
339 			       + wxT("=") + lstOptions->GetText(pos, 1);
340 		}
341 
342 		sql += wxT("\n);\n");
343 
344 		AppendOwnerNew(sql, wxT("TEXT SEARCH DICTIONARY ") + objname);
345 	}
346 
347 	AppendComment(sql, wxT("TEXT SEARCH DICTIONARY ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), dict);
348 
349 	return sql;
350 }
351