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 // dlgConversion.cpp - PostgreSQL Conversion 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/dlgConversion.h"
21 #include "schema/pgConversion.h"
22 #include "schema/pgSchema.h"
23 
24 
25 // pointer to controls
26 #define cbSourceEncoding    CTRL_COMBOBOX("cbSourceEncoding")
27 #define cbTargetEncoding    CTRL_COMBOBOX("cbTargetEncoding")
28 #define cbFunction          CTRL_COMBOBOX("cbFunction")
29 #define chkDefault          CTRL_CHECKBOX("chkDefault")
30 
31 
32 
33 BEGIN_EVENT_TABLE(dlgConversion, dlgProperty)
34 	EVT_TEXT(XRCID("cbSourceEncoding"),     dlgProperty::OnChange)
35 	EVT_COMBOBOX(XRCID("cbSourceEncoding"), dlgProperty::OnChange)
36 	EVT_TEXT(XRCID("cbTargetEncoding"),     dlgProperty::OnChange)
37 	EVT_COMBOBOX(XRCID("cbTargetEncoding"), dlgProperty::OnChange)
38 	EVT_TEXT(XRCID("cbFunction"),           dlgProperty::OnChange)
39 	EVT_COMBOBOX(XRCID("cbFunction"),       dlgProperty::OnChange)
40 END_EVENT_TABLE();
41 
42 
CreateDialog(frmMain * frame,pgObject * node,pgObject * parent)43 dlgProperty *pgConversionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
44 {
45 	return new dlgConversion(this, frame, (pgConversion *)node, (pgSchema *)parent);
46 }
47 
48 
49 
dlgConversion(pgaFactory * f,frmMain * frame,pgConversion * node,pgSchema * sch)50 dlgConversion::dlgConversion(pgaFactory *f, frmMain *frame, pgConversion *node, pgSchema *sch)
51 	: dlgProperty(f, frame, wxT("dlgConversion"))
52 {
53 	conversion = node;
54 	schema = sch;
55 }
56 
57 
GetObject()58 pgObject *dlgConversion::GetObject()
59 {
60 	return conversion;
61 }
62 
63 
Go(bool modal)64 int dlgConversion::Go(bool modal)
65 {
66 	if (!connection->BackendMinimumVersion(7, 4))
67 		txtComment->Disable();
68 
69 	if (!connection->BackendMinimumVersion(7, 5))
70 		cbOwner->Disable();
71 
72 	if (conversion)
73 	{
74 		// edit mode
75 		cbSchema->Enable(connection->BackendMinimumVersion(9, 1));
76 		cbSourceEncoding->Append(conversion->GetForEncoding());
77 		cbSourceEncoding->SetSelection(0);
78 		cbTargetEncoding->Append(conversion->GetToEncoding());
79 		cbTargetEncoding->SetSelection(0);
80 
81 		cbFunction->Append(database->GetSchemaPrefix(conversion->GetProcNamespace()) + conversion->GetProc());
82 		cbFunction->SetSelection(0);
83 
84 		if (!connection->BackendMinimumVersion(7, 4))
85 			txtName->Disable();
86 		chkDefault->SetValue(conversion->GetDefaultConversion());
87 		cbSourceEncoding->Disable();
88 		cbTargetEncoding->Disable();
89 		cbFunction->Disable();
90 		chkDefault->Disable();
91 	}
92 	else
93 	{
94 		// create mode
95 
96 		wxString qry =
97 		    wxT("SELECT proname, nspname\n")
98 		    wxT("  FROM pg_proc p\n")
99 		    wxT("  JOIN pg_namespace n ON n.oid=pronamespace")
100 		    wxT("\n WHERE prorettype = ") + NumToStr(PGOID_TYPE_VOID) +
101 		    wxT("\n   AND proargtypes[0] = ") + NumToStr(PGOID_TYPE_INT4) +
102 		    wxT("\n   AND proargtypes[1] = ") + NumToStr(PGOID_TYPE_INT4) +
103 		    wxT("\n   AND proargtypes[2] = ") + NumToStr(PGOID_TYPE_CSTRING) +
104 		    wxT("\n   AND proargtypes[3] = ") + NumToStr(PGOID_TYPE_CSTRING) +
105 		    wxT("\n   AND proargtypes[4] = ") + NumToStr(PGOID_TYPE_INT4) +
106 		    wxT("\n   AND proargtypes[5] = 0");
107 
108 		pgSet *set = connection->ExecuteSet(qry);
109 		if (set)
110 		{
111 			while (!set->Eof())
112 			{
113 				functions.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname"))));
114 				cbFunction->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")));
115 
116 				set->MoveNext();
117 			}
118 			delete set;
119 		}
120 
121 		long encNo = 0;
122 		wxString encStr;
123 		do
124 		{
125 			encStr = connection->ExecuteScalar(
126 			             wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")"));
127 			if (!encStr.IsEmpty())
128 			{
129 				cbSourceEncoding->Append(encStr);
130 				cbTargetEncoding->Append(encStr);
131 			}
132 			encNo++;
133 		}
134 		while (!encStr.IsEmpty());
135 	}
136 
137 	return dlgProperty::Go(modal);
138 }
139 
140 
CreateObject(pgCollection * collection)141 pgObject *dlgConversion::CreateObject(pgCollection *collection)
142 {
143 	pgObject *obj = conversionFactory.CreateObjects(collection, 0,
144 	                wxT("\n AND conname = ") + qtDbString(GetName()));
145 
146 	return obj;
147 }
148 
149 
CheckChange()150 void dlgConversion::CheckChange()
151 {
152 	if (conversion)
153 	{
154 		EnableOK(txtName->GetValue() != conversion->GetName()
155 		         || cbSchema->GetValue() != conversion->GetSchema()->GetName()
156 		         || txtComment->GetValue() != conversion->GetComment()
157 		         || cbOwner->GetValue() != conversion->GetOwner());
158 	}
159 	else
160 	{
161 		bool enable = true;
162 		CheckValid(enable, !GetName().IsEmpty(), _("Please specify name."));
163 		CheckValid(enable, !cbSourceEncoding->GetValue().IsEmpty(), _("Please specify source encoding."));
164 		CheckValid(enable, !cbTargetEncoding->GetValue().IsEmpty(), _("Please specify target encoding."));
165 		CheckValid(enable, cbFunction->GetCurrentSelection() >= 0, _("Please specify conversion function."));
166 
167 		EnableOK(enable);
168 	}
169 }
170 
171 
172 
173 
GetSql()174 wxString dlgConversion::GetSql()
175 {
176 	wxString sql;
177 	wxString name;
178 
179 	if (conversion)
180 	{
181 		// edit mode
182 		name = GetName();
183 
184 		AppendNameChange(sql);
185 		AppendOwnerChange(sql, wxT("CONVERSION ") + schema->GetQuotedPrefix() + qtIdent(name));
186 
187 		if (cbSchema->GetValue() != conversion->GetSchema()->GetName())
188 		{
189 			sql += wxT("ALTER CONVERSION ") + qtIdent(conversion->GetSchema()->GetName()) + wxT(".") + qtIdent(name)
190 			       +  wxT("\n  SET SCHEMA ") + qtIdent(cbSchema->GetValue())
191 			       +  wxT(";\n");
192 		}
193 	}
194 	else
195 	{
196 		name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName());
197 
198 		// create mode
199 		sql = wxT("CREATE ");
200 		if (chkDefault->GetValue())
201 			sql += wxT("DEFAULT ");
202 		sql += wxT("CONVERSION ") + name
203 		       + wxT("\n   FOR ") + qtDbString(cbSourceEncoding->GetValue())
204 		       + wxT(" TO ") + qtDbString(cbTargetEncoding->GetValue())
205 		       + wxT("\n   FROM ") + functions.Item(cbFunction->GetCurrentSelection())
206 		       + wxT(";\n");
207 
208 		AppendOwnerNew(sql, wxT("CONVERSION ") + schema->GetQuotedPrefix() + qtIdent(name));
209 	}
210 	AppendComment(sql, wxT("CONVERSION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), conversion);
211 
212 	return sql;
213 }
214