~ubuntu-branches/ubuntu/utopic/pgadmin3/utopic-proposed

« back to all changes in this revision

Viewing changes to pgadmin/dlg/dlgFunction.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2011-06-07 23:03:54 UTC
  • mfrom: (1.3.1 upstream) (13 sid)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20110607230354-3td4j9y71u4ahcvj
Tags: 1.14.0~beta1-1
* New upstream development release, adding Build-Depends on
  postgresql-server-dev-all >= 117~.
* Add Build-Depends on quilt, (un)patch to debian/rules and patch for fixing
  the include for kwlist.h in pgadmin/db/keywords.c.
* Add pg_config --includedir-server output to CPPFLAGS.
* Remove unrecognized configure options: --with-wx-config,
  --with-pgsql-include, --enable-gtk2, --enable-unicode.
* Clean up manually the files that are left behind after the broken
  distclean.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//////////////////////////////////////////////////////////////////////////
2
2
//
3
3
// pgAdmin III - PostgreSQL Tools
4
 
// 
5
 
// Copyright (C) 2002 - 2010, The pgAdmin Development Team
 
4
//
 
5
// Copyright (C) 2002 - 2011, The pgAdmin Development Team
6
6
// This software is released under the PostgreSQL Licence
7
7
//
8
8
// dlgFunction.cpp - PostgreSQL Function Property
67
67
#define TXTOBJ_LIB  wxT("$libdir/")
68
68
 
69
69
BEGIN_EVENT_TABLE(dlgFunction, dlgSecurityProperty)
70
 
    EVT_TEXT(XRCID("cbVolatility"),                 dlgProperty::OnChange)
71
 
    EVT_CHECKBOX(XRCID("chkStrict"),                dlgProperty::OnChange)
72
 
    EVT_CHECKBOX(XRCID("chkSecureDefiner"),         dlgProperty::OnChange)
73
 
    EVT_TEXT(XRCID("txtObjectFile"),                dlgProperty::OnChange)
74
 
    EVT_TEXT(XRCID("txtLinkSymbol"),                dlgProperty::OnChange)
75
 
    EVT_TEXT(XRCID("txtCost"),                      dlgProperty::OnChange)
76
 
    EVT_TEXT(XRCID("txtRows"),                      dlgProperty::OnChange)
77
 
    EVT_STC_MODIFIED(XRCID("txtSqlBox"),            dlgProperty::OnChangeStc)
78
 
 
79
 
    EVT_CHECKBOX(XRCID("chkSetof"),                 dlgFunction::OnChangeSetof)
80
 
    EVT_TEXT(XRCID("cbReturntype"),                 dlgFunction::OnChangeReturn)
81
 
    EVT_COMBOBOX(XRCID("cbReturntype"),             dlgFunction::OnChangeReturn)
82
 
    EVT_TEXT(XRCID("cbDatatype"),                   dlgFunction::OnSelChangeType)
83
 
    EVT_COMBOBOX(XRCID("cbDatatype"),               dlgFunction::OnSelChangeType)
84
 
    EVT_TEXT(XRCID("cbLanguage"),                   dlgFunction::OnSelChangeLanguage)
85
 
    EVT_COMBOBOX(XRCID("cbLanguage"),               dlgFunction::OnSelChangeLanguage)
86
 
 
87
 
    EVT_LIST_ITEM_SELECTED(XRCID("lstArguments"),   dlgFunction::OnSelChangeArg)
88
 
    EVT_TEXT(XRCID("txtArgName"),                   dlgFunction::OnChangeArgName)
89
 
    EVT_BUTTON(wxID_ADD,                            dlgFunction::OnAddArg)
90
 
    EVT_BUTTON(XRCID("wxID_CHANGE"),                dlgFunction::OnChangeArg)
91
 
    EVT_BUTTON(wxID_REMOVE,                         dlgFunction::OnRemoveArg)
92
 
 
93
 
    EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"),   dlgFunction::OnVarSelChange)
94
 
    EVT_BUTTON(XRCID("btnAddVar"),                  dlgFunction::OnVarAdd)
95
 
    EVT_BUTTON(XRCID("btnRemoveVar"),               dlgFunction::OnVarRemove)
96
 
    EVT_TEXT(XRCID("cbVarname"),                    dlgFunction::OnVarnameSelChange)
97
 
    EVT_COMBOBOX(XRCID("cbVarname"),                dlgFunction::OnVarnameSelChange)
98
 
    EVT_RADIOBUTTON(XRCID("rdbIn"),                 dlgFunction::OnChangeArgMode)
99
 
    EVT_RADIOBUTTON(XRCID("rdbOut"),                dlgFunction::OnChangeArgMode)
100
 
    EVT_RADIOBUTTON(XRCID("rdbInOut"),              dlgFunction::OnChangeArgMode)
101
 
    EVT_RADIOBUTTON(XRCID("rdbVariadic"),           dlgFunction::OnChangeArgMode)
102
 
    EVT_CHECKBOX(XRCID("chkWindow"),                dlgFunction::OnChangeWindow)
 
70
        EVT_TEXT(XRCID("cbVolatility"),                 dlgProperty::OnChange)
 
71
        EVT_CHECKBOX(XRCID("chkStrict"),                dlgProperty::OnChange)
 
72
        EVT_CHECKBOX(XRCID("chkSecureDefiner"),         dlgProperty::OnChange)
 
73
        EVT_TEXT(XRCID("txtObjectFile"),                dlgProperty::OnChange)
 
74
        EVT_TEXT(XRCID("txtLinkSymbol"),                dlgProperty::OnChange)
 
75
        EVT_TEXT(XRCID("txtCost"),                      dlgProperty::OnChange)
 
76
        EVT_TEXT(XRCID("txtRows"),                      dlgProperty::OnChange)
 
77
        EVT_STC_MODIFIED(XRCID("txtSqlBox"),            dlgProperty::OnChangeStc)
 
78
 
 
79
        EVT_CHECKBOX(XRCID("chkSetof"),                 dlgFunction::OnChangeSetof)
 
80
        EVT_TEXT(XRCID("cbReturntype"),                 dlgFunction::OnChangeReturn)
 
81
        EVT_COMBOBOX(XRCID("cbReturntype"),             dlgFunction::OnChangeReturn)
 
82
        EVT_TEXT(XRCID("cbDatatype"),                   dlgFunction::OnSelChangeType)
 
83
        EVT_COMBOBOX(XRCID("cbDatatype"),               dlgFunction::OnSelChangeType)
 
84
        EVT_TEXT(XRCID("cbLanguage"),                   dlgFunction::OnSelChangeLanguage)
 
85
        EVT_COMBOBOX(XRCID("cbLanguage"),               dlgFunction::OnSelChangeLanguage)
 
86
 
 
87
        EVT_LIST_ITEM_SELECTED(XRCID("lstArguments"),   dlgFunction::OnSelChangeArg)
 
88
        EVT_TEXT(XRCID("txtArgName"),                   dlgFunction::OnChangeArgName)
 
89
        EVT_BUTTON(wxID_ADD,                            dlgFunction::OnAddArg)
 
90
        EVT_BUTTON(XRCID("wxID_CHANGE"),                dlgFunction::OnChangeArg)
 
91
        EVT_BUTTON(wxID_REMOVE,                         dlgFunction::OnRemoveArg)
 
92
 
 
93
        EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"),   dlgFunction::OnVarSelChange)
 
94
        EVT_BUTTON(XRCID("btnAddVar"),                  dlgFunction::OnVarAdd)
 
95
        EVT_BUTTON(XRCID("btnRemoveVar"),               dlgFunction::OnVarRemove)
 
96
        EVT_TEXT(XRCID("cbVarname"),                    dlgFunction::OnVarnameSelChange)
 
97
        EVT_COMBOBOX(XRCID("cbVarname"),                dlgFunction::OnVarnameSelChange)
 
98
        EVT_RADIOBUTTON(XRCID("rdbIn"),                 dlgFunction::OnChangeArgMode)
 
99
        EVT_RADIOBUTTON(XRCID("rdbOut"),                dlgFunction::OnChangeArgMode)
 
100
        EVT_RADIOBUTTON(XRCID("rdbInOut"),              dlgFunction::OnChangeArgMode)
 
101
        EVT_RADIOBUTTON(XRCID("rdbVariadic"),           dlgFunction::OnChangeArgMode)
 
102
        EVT_CHECKBOX(XRCID("chkWindow"),                dlgFunction::OnChangeWindow)
103
103
#ifdef __WXMAC__
104
 
    EVT_SIZE(                                       dlgFunction::OnChangeSize)
 
104
        EVT_SIZE(                                       dlgFunction::OnChangeSize)
105
105
#endif
106
 
    EVT_BUTTON(wxID_APPLY,                          dlgFunction::OnApply)
 
106
        EVT_BUTTON(wxID_APPLY,                          dlgFunction::OnApply)
107
107
END_EVENT_TABLE();
108
108
 
109
109
 
110
110
dlgProperty *pgFunctionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
111
111
{
112
 
    pgSchema *sch;
113
 
 
114
 
    if (parent->GetMetaType() == PGM_TRIGGER)
115
 
        sch = parent->GetSchema();
116
 
    else
117
 
        sch = (pgSchema*)parent;
118
 
 
119
 
    return new dlgFunction(this, frame, (pgFunction*)node, sch);
 
112
        pgSchema *sch;
 
113
 
 
114
        if (parent->GetMetaType() == PGM_TRIGGER)
 
115
                sch = parent->GetSchema();
 
116
        else
 
117
                sch = (pgSchema *)parent;
 
118
 
 
119
        return new dlgFunction(this, frame, (pgFunction *)node, sch);
120
120
}
121
121
 
122
122
 
123
123
dlgFunction::dlgFunction(pgaFactory *f, frmMain *frame, pgFunction *node, pgSchema *sch)
124
 
: dlgSecurityProperty(f, frame, node, wxT("dlgFunction"), wxT("EXECUTE"), "X"),
125
 
  isEdbWrapped( false )
 
124
        : dlgSecurityProperty(f, frame, node, wxT("dlgFunction"), wxT("EXECUTE"), "X"),
 
125
          isEdbWrapped( false )
126
126
{
127
 
    schema=sch;
128
 
    function=node;
129
 
    isProcedure = false;
130
 
 
131
 
    txtArguments->Disable();
132
 
 
133
 
    bool bVal;
134
 
    settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false);
135
 
    if (!bVal)
136
 
    {
137
 
        txtSqlBox->SetMarginType(1, wxSTC_MARGIN_NUMBER);
138
 
        txtSqlBox->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x);
139
 
    }
140
 
 
141
 
    btnAdd->Disable();
142
 
    btnRemove->Disable();
143
 
    btnChange->Disable();
144
 
 
145
 
    lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1);
146
 
    chkValue->Hide();
 
127
        schema = sch;
 
128
        function = node;
 
129
        isProcedure = false;
 
130
 
 
131
        txtArguments->Disable();
 
132
 
 
133
        bool bVal;
 
134
        settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false);
 
135
        if (!bVal)
 
136
        {
 
137
                txtSqlBox->SetMarginType(1, wxSTC_MARGIN_NUMBER);
 
138
                txtSqlBox->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x);
 
139
        }
 
140
 
 
141
        btnAdd->Disable();
 
142
        btnRemove->Disable();
 
143
        btnChange->Disable();
 
144
 
 
145
        lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1);
 
146
        chkValue->Hide();
147
147
}
148
148
 
149
149
 
150
150
 
151
151
dlgProperty *pgProcedureFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
152
152
{
153
 
    return new dlgProcedure(this, frame, (pgFunction*)node, (pgSchema*)parent);
 
153
        return new dlgProcedure(this, frame, (pgFunction *)node, (pgSchema *)parent);
154
154
}
155
155
 
156
156
dlgProcedure::dlgProcedure(pgaFactory *f, frmMain *frame, pgFunction *node, pgSchema *sch)
157
 
: dlgFunction(f, frame, node, sch)
 
157
        : dlgFunction(f, frame, node, sch)
158
158
{
159
 
    isProcedure = true;
 
159
        isProcedure = true;
160
160
}
161
161
 
162
162
pgObject *dlgFunction::GetObject()
163
163
{
164
 
    return function;
 
164
        return function;
165
165
}
166
166
 
167
167
 
168
168
int dlgFunction::Go(bool modal)
169
169
{
170
 
    isBackendMinVer84 = connection->BackendMinimumVersion(8, 4);
171
 
 
172
 
    if (function)
173
 
    {
174
 
        rdbIn->Disable();
175
 
        rdbOut->Disable();
176
 
        rdbInOut->Disable();
177
 
        rdbVariadic->Disable();
178
 
        isProcedure = function->GetIsProcedure();
179
 
    }
180
 
    else
181
 
        cbOwner->Append(wxEmptyString);
182
 
 
183
 
    if (!isBackendMinVer84)
184
 
        txtArgDefVal->Disable();
185
 
 
186
 
    AddGroups(cbOwner);
187
 
    AddUsers(cbOwner);
188
 
 
189
 
    lstArguments->AddColumn(_("Type"), 60);
190
 
    lstArguments->AddColumn(_("Mode"), 40);
191
 
    lstArguments->AddColumn(_("Name"), 60);
192
 
    lstArguments->AddColumn(_("Default Value"), 60);
193
 
 
194
 
    if (!connection->BackendMinimumVersion(8, 0))
195
 
        cbOwner->Disable();
196
 
 
197
 
    if (!connection->BackendMinimumVersion(8, 3))
198
 
        txtCost->Disable();
199
 
 
200
 
    txtRows->Disable();
201
 
 
202
 
    if (!connection->BackendMinimumVersion(8, 0))
203
 
        txtArgName->Disable();
204
 
 
205
 
    // Window function can not be modified
206
 
    // Disable it for editing
207
 
    if (function || !isBackendMinVer84)
208
 
        chkWindow->Disable();
209
 
 
210
 
    if (isProcedure)
211
 
    {
212
 
        if (function && !connection->EdbMinimumVersion(8, 2))
213
 
            txtName->Disable();
214
 
        cbOwner->Disable();
215
 
        cbLanguage->Disable();
216
 
        chkStrict->Disable();
217
 
        chkWindow->Disable();
218
 
        chkSecureDefiner->Disable();
219
 
        chkSetof->Disable();
220
 
        cbVolatility->Disable();
221
 
        cbReturntype->Disable();
222
 
        txtCost->Disable();
223
 
        txtRows->Disable();
224
 
    }
225
 
    else
226
 
    {
227
 
        if (!connection->BackendMinimumVersion(8, 1))
228
 
        {
229
 
            rdbIn->SetValue(true);
230
 
            rdbIn->Disable();
231
 
            rdbOut->Disable();
232
 
            rdbInOut->Disable();
233
 
        }
234
 
 
235
 
        if (!isBackendMinVer84)
236
 
        {
237
 
            rdbVariadic->Disable();
238
 
        }
239
 
    }
240
 
 
241
 
    pgSet *lang=connection->ExecuteSet(wxT("SELECT lanname FROM pg_language"));
242
 
    if (lang)
243
 
    {
244
 
        while (!lang->Eof())
245
 
        {
246
 
            wxString language=lang->GetVal(0);
247
 
            if (factory == &triggerFunctionFactory)
248
 
            {
249
 
                if (language.IsSameAs(wxT("SQL"), false) ||
250
 
                    language.IsSameAs(wxT("edbspl"), false))
251
 
                {
252
 
                    lang->MoveNext();
253
 
                    continue;
254
 
                }
255
 
            }
256
 
            cbLanguage->Append(language);
257
 
            lang->MoveNext();
258
 
        }
259
 
        delete lang;
260
 
    }
261
 
 
262
 
    if (connection->BackendMinimumVersion(8, 3))
263
 
    {
264
 
        pgSet *set;
265
 
        set=connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n")
266
 
                wxT("  FROM pg_settings WHERE context in ('user', 'superuser')"));
267
 
        if (set)
268
 
        {
269
 
            while (!set->Eof())
270
 
            {
271
 
                cbVarname->Append(set->GetVal(0));
272
 
                varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + 
273
 
                            set->GetVal(wxT("min_val")) + wxT(" ") +
274
 
                            set->GetVal(wxT("max_val")));
275
 
                set->MoveNext();
276
 
            }
277
 
            delete set;
278
 
 
279
 
            cbVarname->SetSelection(0);
280
 
            SetupVarEditor(0);
281
 
        }
282
 
 
283
 
    }
284
 
    else
285
 
    {
286
 
        btnAddVar->Disable();
287
 
        btnRemoveVar->Disable();
288
 
        cbVarname->Disable();
289
 
        txtValue->Disable();
290
 
        chkValue->Disable();
291
 
    }
292
 
 
293
 
    if (function)
294
 
    {
295
 
        // edit mode
296
 
 
297
 
        if (factory != &triggerFunctionFactory)
298
 
        {
299
 
            wxArrayString argTypes = function->GetArgTypesArray();
300
 
            wxArrayString argNames = function->GetArgNamesArray();
301
 
            wxArrayString argModes = function->GetArgModesArray();
302
 
            wxArrayString argDefs  = function->GetArgDefsArray();
303
 
 
304
 
            for (unsigned int i=0; i<argTypes.Count(); i++)
305
 
            {
306
 
                if (argModes[i] != wxT("TABLE"))
307
 
                {
308
 
                    if (isBackendMinVer84)
309
 
                        lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i], (argDefs.Count() > i ? argDefs[i] : wxString(wxEmptyString)));
310
 
                    else
311
 
                        lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i]);
312
 
                }
313
 
            }
314
 
        }
315
 
 
316
 
        txtArguments->SetValue(function->GetArgListWithNames());
317
 
        cbReturntype->Append(function->GetReturnType());
318
 
        cbReturntype->SetValue(function->GetReturnType());
319
 
 
320
 
        cbLanguage->SetValue(function->GetLanguage());
321
 
        cbVolatility->SetValue(function->GetVolatility());
322
 
 
323
 
        chkSetof->SetValue(function->GetReturnAsSet());
324
 
        chkStrict->SetValue(function->GetIsStrict());
 
170
        isBackendMinVer84 = connection->BackendMinimumVersion(8, 4);
 
171
 
 
172
        if (function)
 
173
        {
 
174
                rdbIn->Disable();
 
175
                rdbOut->Disable();
 
176
                rdbInOut->Disable();
 
177
                rdbVariadic->Disable();
 
178
                isProcedure = function->GetIsProcedure();
 
179
        }
 
180
        else
 
181
                cbOwner->Append(wxEmptyString);
 
182
 
 
183
        if (!isBackendMinVer84)
 
184
                txtArgDefVal->Disable();
 
185
 
 
186
        AddGroups(cbOwner);
 
187
        AddUsers(cbOwner);
 
188
 
 
189
        lstArguments->AddColumn(_("Type"), 60);
 
190
        lstArguments->AddColumn(_("Mode"), 40);
 
191
        lstArguments->AddColumn(_("Name"), 60);
 
192
        lstArguments->AddColumn(_("Default Value"), 60);
 
193
 
 
194
        if (!connection->BackendMinimumVersion(8, 0))
 
195
                cbOwner->Disable();
 
196
 
 
197
        if (!connection->BackendMinimumVersion(8, 3))
 
198
                txtCost->Disable();
 
199
 
 
200
        txtRows->Disable();
 
201
 
 
202
        if (!connection->BackendMinimumVersion(8, 0))
 
203
                txtArgName->Disable();
 
204
 
 
205
        // Window function can not be modified
 
206
        // Disable it for editing
 
207
        if (function || !isBackendMinVer84)
 
208
                chkWindow->Disable();
 
209
 
 
210
        if (isProcedure)
 
211
        {
 
212
                if (function && !connection->EdbMinimumVersion(8, 2))
 
213
                        txtName->Disable();
 
214
                cbOwner->Disable();
 
215
                cbLanguage->Disable();
 
216
                chkStrict->Disable();
 
217
                chkWindow->Disable();
 
218
                chkSecureDefiner->Disable();
 
219
                chkSetof->Disable();
 
220
                cbVolatility->Disable();
 
221
                cbReturntype->Disable();
 
222
                txtCost->Disable();
 
223
                txtRows->Disable();
 
224
        }
 
225
        else
 
226
        {
 
227
                if (!connection->BackendMinimumVersion(8, 1))
 
228
                {
 
229
                        rdbIn->SetValue(true);
 
230
                        rdbIn->Disable();
 
231
                        rdbOut->Disable();
 
232
                        rdbInOut->Disable();
 
233
                }
 
234
 
 
235
                if (!isBackendMinVer84)
 
236
                {
 
237
                        rdbVariadic->Disable();
 
238
                }
 
239
        }
 
240
 
 
241
        pgSet *lang = connection->ExecuteSet(wxT("SELECT lanname FROM pg_language"));
 
242
        if (lang)
 
243
        {
 
244
                while (!lang->Eof())
 
245
                {
 
246
                        wxString language = lang->GetVal(0);
 
247
                        if (factory == &triggerFunctionFactory)
 
248
                        {
 
249
                                if (language.IsSameAs(wxT("SQL"), false) ||
 
250
                                        language.IsSameAs(wxT("edbspl"), false))
 
251
                                {
 
252
                                        lang->MoveNext();
 
253
                                        continue;
 
254
                                }
 
255
                        }
 
256
                        cbLanguage->Append(language);
 
257
                        lang->MoveNext();
 
258
                }
 
259
                delete lang;
 
260
        }
 
261
 
 
262
        if (connection->BackendMinimumVersion(8, 3))
 
263
        {
 
264
                pgSet *set;
 
265
                set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n")
 
266
                                             wxT("  FROM pg_settings WHERE context in ('user', 'superuser')"));
 
267
                if (set)
 
268
                {
 
269
                        while (!set->Eof())
 
270
                        {
 
271
                                cbVarname->Append(set->GetVal(0));
 
272
                                varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") +
 
273
                                            set->GetVal(wxT("min_val")) + wxT(" ") +
 
274
                                            set->GetVal(wxT("max_val")));
 
275
                                set->MoveNext();
 
276
                        }
 
277
                        delete set;
 
278
 
 
279
                        cbVarname->SetSelection(0);
 
280
                        SetupVarEditor(0);
 
281
                }
 
282
 
 
283
        }
 
284
        else
 
285
        {
 
286
                btnAddVar->Disable();
 
287
                btnRemoveVar->Disable();
 
288
                cbVarname->Disable();
 
289
                txtValue->Disable();
 
290
                chkValue->Disable();
 
291
        }
 
292
 
 
293
        if (function)
 
294
        {
 
295
                // edit mode
 
296
 
 
297
                if (factory != &triggerFunctionFactory)
 
298
                {
 
299
                        wxArrayString argTypes = function->GetArgTypesArray();
 
300
                        wxArrayString argNames = function->GetArgNamesArray();
 
301
                        wxArrayString argModes = function->GetArgModesArray();
 
302
                        wxArrayString argDefs  = function->GetArgDefsArray();
 
303
 
 
304
                        for (unsigned int i = 0; i < argTypes.Count(); i++)
 
305
                        {
 
306
                                if (argModes[i] != wxT("TABLE"))
 
307
                                {
 
308
                                        if (isBackendMinVer84)
 
309
                                                lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i], (argDefs.Count() > i ? argDefs[i] : wxString(wxEmptyString)));
 
310
                                        else
 
311
                                                lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i]);
 
312
                                }
 
313
                        }
 
314
                }
 
315
 
 
316
                txtArguments->SetValue(function->GetArgListWithNames());
 
317
                cbReturntype->Append(function->GetReturnType());
 
318
                cbReturntype->SetValue(function->GetReturnType());
 
319
 
 
320
                cbLanguage->SetValue(function->GetLanguage());
 
321
                cbVolatility->SetValue(function->GetVolatility());
 
322
 
 
323
                chkSetof->SetValue(function->GetReturnAsSet());
 
324
                chkStrict->SetValue(function->GetIsStrict());
325
325
                if (connection->BackendMinimumVersion(8, 4))
326
 
                chkWindow->SetValue(function->GetIsWindow());
327
 
        chkSecureDefiner->SetValue(function->GetSecureDefiner());
328
 
 
329
 
        if (function->GetLanguage().IsSameAs(wxT("C"), false))
330
 
        {
331
 
            txtObjectFile->SetValue(function->GetBin());
332
 
            txtLinkSymbol->SetValue(function->GetSource());
333
 
        }
334
 
        else
335
 
            txtSqlBox->SetText(function->GetSource());
336
 
 
337
 
        if (!connection->BackendMinimumVersion(7, 4))
338
 
            txtName->Disable();
339
 
 
340
 
        if (connection->BackendMinimumVersion(8, 3))
341
 
        {
342
 
            txtCost->SetValue(NumToStr(function->GetCost()));
343
 
            if (function->GetReturnAsSet())
344
 
            {
345
 
                txtRows->SetValue(NumToStr(function->GetRows()));
346
 
                txtRows->Enable();
347
 
            }
348
 
            else
349
 
                txtRows->Disable();
350
 
        }
351
 
 
352
 
        size_t index;
353
 
        for (index = 0 ; index < function->GetConfigList().GetCount() ; index++)
354
 
        {
355
 
            wxString item=function->GetConfigList().Item(index);
356
 
            lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('='));
357
 
        }
358
 
 
359
 
        cbReturntype->Disable();
360
 
        chkSetof->Disable();
361
 
        cbDatatype->Disable();
362
 
        // Editing paramter for wrapped functions is not allowed
363
 
        // It will anyway throw an error, if we try to edit the paramter list
364
 
        if ( connection->GetIsEdb() &&
365
 
             function->GetSource().Trim(false).StartsWith( wxT( "$__EDBwrapped__$" )))
366
 
        {
367
 
            isEdbWrapped = true;
368
 
            cbDatatype->Disable();
369
 
            rdbIn->Disable();
370
 
            rdbOut->Disable();
371
 
            rdbInOut->Disable();
372
 
            rdbVariadic->Disable();
373
 
            txtArgName->Disable();
374
 
            txtArgDefVal->Disable();
375
 
            btnAdd->Disable();
376
 
            btnChange->Disable();
377
 
            btnRemove->Disable();
378
 
        }
379
 
    }
380
 
    else
381
 
    {
382
 
        wxString restrict;
383
 
        // create mode
384
 
        restrict = wxT("(typtype IN ('b', 'c', 'd', 'p') AND typname NOT IN ('any', 'trigger', 'language_handler'))");
385
 
        if (!settings->GetShowSystemObjects()) 
386
 
            restrict += wxT(" AND nspname NOT LIKE 'pg_toast%' AND nspname NOT LIKE 'pg_temp%'");
387
 
 
388
 
        DatatypeReader tr(database, restrict);
389
 
        while (tr.HasMore())
390
 
        {
391
 
            pgDatatype dt=tr.GetDatatype();
392
 
 
393
 
            typOids.Add(tr.GetOidStr());
394
 
            types.Add(dt.QuotedFullName());
395
 
 
396
 
            cbDatatype->Append(dt.FullName());
397
 
            if (factory != &triggerFunctionFactory)
398
 
                cbReturntype->Append(dt.FullName());
399
 
            tr.MoveNext();
400
 
        }
401
 
 
402
 
        long sel;
403
 
        if (factory == &triggerFunctionFactory)
404
 
        {
405
 
            cbReturntype->Append(wxT("trigger"));
406
 
            cbReturntype->SetSelection(0);
407
 
            cbReturntype->Disable();
408
 
            lstArguments->Disable();
409
 
            cbDatatype->Disable();
410
 
            txtArgName->Disable();
411
 
            sel=cbLanguage->FindString(wxT("c"));
412
 
        }
413
 
        else if (isProcedure)
414
 
            sel=cbLanguage->FindString(wxT("edbspl"));
415
 
        else
416
 
            sel=cbLanguage->FindString(wxT("sql"));
417
 
 
418
 
        if (sel >= 0)
419
 
            cbLanguage->SetSelection(sel);
420
 
        txtObjectFile->SetValue(TXTOBJ_LIB);
421
 
    }
422
 
 
423
 
    wxNotifyEvent event;
424
 
    OnSelChangeLanguage(event);
425
 
 
426
 
    return dlgSecurityProperty::Go(modal);
 
326
                        chkWindow->SetValue(function->GetIsWindow());
 
327
                chkSecureDefiner->SetValue(function->GetSecureDefiner());
 
328
 
 
329
                if (function->GetLanguage().IsSameAs(wxT("C"), false))
 
330
                {
 
331
                        txtObjectFile->SetValue(function->GetBin());
 
332
                        txtLinkSymbol->SetValue(function->GetSource());
 
333
                }
 
334
                else
 
335
                        txtSqlBox->SetText(function->GetSource());
 
336
 
 
337
                if (!connection->BackendMinimumVersion(7, 4))
 
338
                        txtName->Disable();
 
339
 
 
340
                if (connection->BackendMinimumVersion(8, 3))
 
341
                {
 
342
                        txtCost->SetValue(NumToStr(function->GetCost()));
 
343
                        if (function->GetReturnAsSet())
 
344
                        {
 
345
                                txtRows->SetValue(NumToStr(function->GetRows()));
 
346
                                txtRows->Enable();
 
347
                        }
 
348
                        else
 
349
                                txtRows->Disable();
 
350
                }
 
351
 
 
352
                size_t index;
 
353
                for (index = 0 ; index < function->GetConfigList().GetCount() ; index++)
 
354
                {
 
355
                        wxString item = function->GetConfigList().Item(index);
 
356
                        lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('='));
 
357
                }
 
358
 
 
359
                cbReturntype->Disable();
 
360
                chkSetof->Disable();
 
361
                cbDatatype->Disable();
 
362
                // Editing paramter for wrapped functions is not allowed
 
363
                // It will anyway throw an error, if we try to edit the paramter list
 
364
                if ( connection->GetIsEdb() &&
 
365
                        function->GetSource().Trim(false).StartsWith( wxT( "$__EDBwrapped__$" )))
 
366
                {
 
367
                        isEdbWrapped = true;
 
368
                        cbDatatype->Disable();
 
369
                        rdbIn->Disable();
 
370
                        rdbOut->Disable();
 
371
                        rdbInOut->Disable();
 
372
                        rdbVariadic->Disable();
 
373
                        txtArgName->Disable();
 
374
                        txtArgDefVal->Disable();
 
375
                        btnAdd->Disable();
 
376
                        btnChange->Disable();
 
377
                        btnRemove->Disable();
 
378
                }
 
379
        }
 
380
        else
 
381
        {
 
382
                wxString restrict;
 
383
                // create mode
 
384
                restrict = wxT("(typtype IN ('b', 'c', 'd', 'p') AND typname NOT IN ('any', 'trigger', 'language_handler'))");
 
385
                if (!settings->GetShowSystemObjects())
 
386
                        restrict += wxT(" AND nspname NOT LIKE 'pg_toast%' AND nspname NOT LIKE 'pg_temp%'");
 
387
 
 
388
                DatatypeReader tr(database, restrict);
 
389
                while (tr.HasMore())
 
390
                {
 
391
                        pgDatatype dt = tr.GetDatatype();
 
392
 
 
393
                        typOids.Add(tr.GetOidStr());
 
394
                        types.Add(dt.QuotedFullName());
 
395
 
 
396
                        cbDatatype->Append(dt.FullName());
 
397
                        if (factory != &triggerFunctionFactory)
 
398
                                cbReturntype->Append(dt.FullName());
 
399
                        tr.MoveNext();
 
400
                }
 
401
 
 
402
                long sel;
 
403
                if (factory == &triggerFunctionFactory)
 
404
                {
 
405
                        cbReturntype->Append(wxT("trigger"));
 
406
                        cbReturntype->SetSelection(0);
 
407
                        cbReturntype->Disable();
 
408
                        lstArguments->Disable();
 
409
                        cbDatatype->Disable();
 
410
                        txtArgName->Disable();
 
411
                        sel = cbLanguage->FindString(wxT("c"));
 
412
                }
 
413
                else if (isProcedure)
 
414
                        sel = cbLanguage->FindString(wxT("edbspl"));
 
415
                else
 
416
                        sel = cbLanguage->FindString(wxT("sql"));
 
417
 
 
418
                if (sel >= 0)
 
419
                        cbLanguage->SetSelection(sel);
 
420
                txtObjectFile->SetValue(TXTOBJ_LIB);
 
421
        }
 
422
 
 
423
        wxNotifyEvent event;
 
424
        OnSelChangeLanguage(event);
 
425
 
 
426
        return dlgSecurityProperty::Go(modal);
427
427
}
428
428
 
429
429
#ifdef __WXMAC__
430
430
void dlgFunction::OnChangeSize(wxSizeEvent &ev)
431
431
{
432
 
    lstArguments->SetSize(wxDefaultCoord, wxDefaultCoord,
433
 
        ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
434
 
    lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord,
435
 
        ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
436
 
    dlgSecurityProperty::OnChangeSize(ev);
 
432
        lstArguments->SetSize(wxDefaultCoord, wxDefaultCoord,
 
433
                              ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
 
434
        lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord,
 
435
                              ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350);
 
436
        dlgSecurityProperty::OnChangeSize(ev);
437
437
}
438
438
#endif
439
439
 
440
440
 
441
441
void dlgFunction::OnVarnameSelChange(wxCommandEvent &ev)
442
442
{
443
 
    int sel=cbVarname->GuessSelection(ev);
 
443
        int sel = cbVarname->GuessSelection(ev);
444
444
 
445
 
    SetupVarEditor(sel);
 
445
        SetupVarEditor(sel);
446
446
}
447
447
 
448
448
void dlgFunction::SetupVarEditor(int var)
449
449
{
450
 
    if (var >= 0 && varInfo.Count() > 0)
451
 
    {
452
 
        wxStringTokenizer vals(varInfo.Item(var));
453
 
        wxString typ=vals.GetNextToken();
 
450
        if (var >= 0 && varInfo.Count() > 0)
 
451
        {
 
452
                wxStringTokenizer vals(varInfo.Item(var));
 
453
                wxString typ = vals.GetNextToken();
454
454
 
455
 
        if (typ == wxT("bool"))
456
 
        {
457
 
            txtValue->Hide();
458
 
            chkValue->Show();
459
 
            chkValue->GetParent()->Layout();
460
 
        }
461
 
        else
462
 
        {
463
 
            chkValue->Hide();
464
 
            txtValue->Show();
465
 
            txtValue->GetParent()->Layout();
466
 
            if (typ == wxT("string") || typ == wxT("enum"))
467
 
                txtValue->SetValidator(wxTextValidator());
468
 
            else
469
 
                txtValue->SetValidator(numericValidator);
470
 
        }
471
 
    }
 
455
                if (typ == wxT("bool"))
 
456
                {
 
457
                        txtValue->Hide();
 
458
                        chkValue->Show();
 
459
                        chkValue->GetParent()->Layout();
 
460
                }
 
461
                else
 
462
                {
 
463
                        chkValue->Hide();
 
464
                        txtValue->Show();
 
465
                        txtValue->GetParent()->Layout();
 
466
                        if (typ == wxT("string") || typ == wxT("enum"))
 
467
                                txtValue->SetValidator(wxTextValidator());
 
468
                        else
 
469
                                txtValue->SetValidator(numericValidator);
 
470
                }
 
471
        }
472
472
}
473
473
 
474
474
void dlgFunction::OnVarSelChange(wxListEvent &ev)
475
475
{
476
 
    long pos=lstVariables->GetSelection();
477
 
    if (pos >= 0)
478
 
    {
479
 
        wxString value=lstVariables->GetText(pos, 1);
480
 
        cbVarname->SetValue(lstVariables->GetText(pos));
481
 
 
482
 
 
483
 
        // We used to raise an OnVarnameSelChange() event here, but
484
 
        // at this point the combo box hasn't necessarily updated.
485
 
        int sel = cbVarname->FindString(lstVariables->GetText(pos));
486
 
        SetupVarEditor(sel);
487
 
 
488
 
        txtValue->SetValue(value);
489
 
        chkValue->SetValue(value == wxT("on"));
490
 
    }
 
476
        long pos = lstVariables->GetSelection();
 
477
        if (pos >= 0)
 
478
        {
 
479
                wxString value = lstVariables->GetText(pos, 1);
 
480
                cbVarname->SetValue(lstVariables->GetText(pos));
 
481
 
 
482
 
 
483
                // We used to raise an OnVarnameSelChange() event here, but
 
484
                // at this point the combo box hasn't necessarily updated.
 
485
                int sel = cbVarname->FindString(lstVariables->GetText(pos));
 
486
                SetupVarEditor(sel);
 
487
 
 
488
                txtValue->SetValue(value);
 
489
                chkValue->SetValue(value == wxT("on"));
 
490
        }
491
491
}
492
492
 
493
493
 
494
494
 
495
495
void dlgFunction::OnVarAdd(wxCommandEvent &ev)
496
496
{
497
 
    wxString name=cbVarname->GetValue();
498
 
    wxString value;
499
 
    if (chkValue->IsShown())
500
 
        value = chkValue->GetValue() ? wxT("on") : wxT("off");
501
 
    else
502
 
        value = txtValue->GetValue().Strip(wxString::both);
503
 
 
504
 
    if (value.IsEmpty())
505
 
        value = wxT("DEFAULT");
506
 
 
507
 
    if (!name.IsEmpty())
508
 
    {
509
 
        long pos=lstVariables->FindItem(-1, name);
510
 
        if (pos < 0)
511
 
        {
512
 
            pos = lstVariables->GetItemCount();
513
 
            lstVariables->InsertItem(pos, name, 0);
514
 
        }
515
 
        lstVariables->SetItem(pos, 1, value);
516
 
    }
517
 
    CheckChange();
 
497
        wxString name = cbVarname->GetValue();
 
498
        wxString value;
 
499
        if (chkValue->IsShown())
 
500
                value = chkValue->GetValue() ? wxT("on") : wxT("off");
 
501
        else
 
502
                value = txtValue->GetValue().Strip(wxString::both);
 
503
 
 
504
        if (value.IsEmpty())
 
505
                value = wxT("DEFAULT");
 
506
 
 
507
        if (!name.IsEmpty())
 
508
        {
 
509
                long pos = lstVariables->FindItem(-1, name);
 
510
                if (pos < 0)
 
511
                {
 
512
                        pos = lstVariables->GetItemCount();
 
513
                        lstVariables->InsertItem(pos, name, 0);
 
514
                }
 
515
                lstVariables->SetItem(pos, 1, value);
 
516
        }
 
517
        CheckChange();
518
518
}
519
519
 
520
520
 
521
521
void dlgFunction::OnVarRemove(wxCommandEvent &ev)
522
522
{
523
 
    if (lstVariables->GetSelection() == wxNOT_FOUND)
524
 
        return;
525
 
    lstVariables->DeleteCurrentItem();
526
 
    CheckChange();
 
523
        if (lstVariables->GetSelection() == wxNOT_FOUND)
 
524
                return;
 
525
        lstVariables->DeleteCurrentItem();
 
526
        CheckChange();
527
527
}
528
528
 
529
529
 
530
530
pgObject *dlgFunction::CreateObject(pgCollection *collection)
531
531
{
532
 
    wxString sql=wxT(" WHERE proname=") + qtDbString(GetName()) +
533
 
        wxT("\n   AND pronamespace=") + schema->GetOidStr();
534
 
 
535
 
    long argCount;
536
 
    for (argCount=0 ; argCount < (int)argOids.GetCount() ; argCount++)
537
 
        sql += wxT("\n   AND proargtypes[") + NumToStr(argCount) + wxT("] = ") + argOids.Item(argCount);
538
 
 
539
 
    sql += wxT("\n   AND proargtypes[") + NumToStr(argCount) + wxT("] = 0\n");
540
 
 
541
 
    pgObject *obj=functionFactory.AppendFunctions(collection, collection->GetSchema(), 0, sql);
542
 
    return obj;
 
532
        wxString sql = wxT(" WHERE proname=") + qtDbString(GetName()) +
 
533
                       wxT("\n   AND pronamespace=") + schema->GetOidStr();
 
534
 
 
535
        long argCount;
 
536
        for (argCount = 0 ; argCount < (int)argOids.GetCount() ; argCount++)
 
537
                sql += wxT("\n   AND proargtypes[") + NumToStr(argCount) + wxT("] = ") + argOids.Item(argCount);
 
538
 
 
539
        sql += wxT("\n   AND proargtypes[") + NumToStr(argCount) + wxT("] = 0\n");
 
540
 
 
541
        pgObject *obj = functionFactory.AppendFunctions(collection, collection->GetSchema(), 0, sql);
 
542
        return obj;
543
543
}
544
544
 
545
545
 
546
546
void dlgFunction::CheckChange()
547
547
{
548
 
    wxString name=GetName();
549
 
    bool isC=cbLanguage->GetValue().IsSameAs(wxT("C"), false);
550
 
    bool enable=true, didChange=true;
551
 
 
552
 
    CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
553
 
    if (!isProcedure)
554
 
        CheckValid(enable, cbReturntype->GetValue().Trim() != wxEmptyString, _("Please select return type."));
555
 
 
556
 
    if (!(isProcedure && connection->GetIsEdb()))
557
 
        CheckValid(enable, cbLanguage->GetGuessedSelection() >= 0, _("Please select language."));
558
 
 
559
 
    if (isC)
560
 
    {
561
 
        wxString objfile=txtObjectFile->GetValue();
562
 
        CheckValid(enable, !objfile.IsEmpty() && objfile != TXTOBJ_LIB, _("Please specify object library."));
563
 
    }
564
 
    else
565
 
    {
566
 
        CheckValid(enable, !txtSqlBox->GetText().IsEmpty(), _("Please enter function source code."));
567
 
    }
568
 
 
569
 
    if (function && enable)
570
 
    {
571
 
        EnableOK(!GetSql().IsEmpty());
572
 
    }
573
 
    else
574
 
    {
575
 
        EnableOK(enable && didChange);
576
 
    }
 
548
        wxString name = GetName();
 
549
        bool isC = cbLanguage->GetValue().IsSameAs(wxT("C"), false);
 
550
        bool enable = true, didChange = true;
 
551
 
 
552
        CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
 
553
        if (!isProcedure)
 
554
                CheckValid(enable, cbReturntype->GetValue().Trim() != wxEmptyString, _("Please select return type."));
 
555
 
 
556
        if (!(isProcedure && connection->GetIsEdb()))
 
557
                CheckValid(enable, cbLanguage->GetGuessedSelection() >= 0, _("Please select language."));
 
558
 
 
559
        if (isC)
 
560
        {
 
561
                wxString objfile = txtObjectFile->GetValue();
 
562
                CheckValid(enable, !objfile.IsEmpty() && objfile != TXTOBJ_LIB, _("Please specify object library."));
 
563
        }
 
564
        else
 
565
        {
 
566
                CheckValid(enable, !txtSqlBox->GetText().IsEmpty(), _("Please enter function source code."));
 
567
        }
 
568
 
 
569
        if (function && enable)
 
570
        {
 
571
                EnableOK(!GetSql().IsEmpty());
 
572
        }
 
573
        else
 
574
        {
 
575
                EnableOK(enable && didChange);
 
576
        }
577
577
}
578
578
 
579
579
bool dlgFunction::IsUpToDate()
583
583
        else
584
584
                return true;
585
585
}
586
 
  
 
586
 
587
587
void dlgFunction::OnApply(wxCommandEvent &ev)
588
588
{
589
 
    dlgProperty::OnApply(ev);
 
589
        dlgProperty::OnApply(ev);
590
590
 
591
 
    wxString sql = wxT("SELECT xmin FROM pg_proc WHERE oid = ") + function->GetOidStr();
 
591
        wxString sql = wxT("SELECT xmin FROM pg_proc WHERE oid = ") + function->GetOidStr();
592
592
        function->iSetXid(StrToOid(connection->ExecuteScalar(sql)));
593
593
}
594
594
 
595
595
void dlgFunction::OnSelChangeLanguage(wxCommandEvent &ev)
596
596
{
597
 
    bool isC=(cbLanguage->GetValue().IsSameAs(wxT("C"), false));
598
 
 
599
 
    stObjectFile->Show(isC);
600
 
    txtObjectFile->Show(isC);
601
 
    stLinkSymbol->Show(isC);
602
 
    txtLinkSymbol->Show(isC);
603
 
    txtSqlBox->Show(!isC);
604
 
 
605
 
    txtSqlBox->GetContainingSizer()->Layout();
606
 
 
607
 
    CheckChange();
 
597
        bool isC = (cbLanguage->GetValue().IsSameAs(wxT("C"), false));
 
598
 
 
599
        stObjectFile->Show(isC);
 
600
        txtObjectFile->Show(isC);
 
601
        stLinkSymbol->Show(isC);
 
602
        txtLinkSymbol->Show(isC);
 
603
        txtSqlBox->Show(!isC);
 
604
 
 
605
        txtSqlBox->GetContainingSizer()->Layout();
 
606
 
 
607
        CheckChange();
608
608
}
609
609
 
610
610
 
611
611
void dlgFunction::OnSelChangeArg(wxListEvent &ev)
612
612
{
613
 
    int row=lstArguments->GetSelection();
614
 
    if (row >= 0)
615
 
    {
616
 
        cbDatatype->SetValue(lstArguments->GetText(row, 0));
617
 
        wxString mode = lstArguments->GetText(row, 1);
618
 
        if (mode == wxT("IN"))
619
 
            rdbIn->SetValue(true);
620
 
        else if (mode == wxT("OUT"))
621
 
            rdbOut->SetValue(true);
622
 
        else if (mode == wxT("IN OUT") || mode == wxT("INOUT"))
623
 
            rdbInOut->SetValue(true);
624
 
        else if (mode == wxT("VARIADIC"))
625
 
            rdbVariadic->SetValue(true);
626
 
        txtArgName->SetValue(lstArguments->GetText(row, 2));
627
 
        if (isBackendMinVer84)
628
 
        {
629
 
            txtArgDefVal->SetValue(lstArguments->GetText(row, 3));
630
 
            txtArgDefVal->Enable(mode == wxT("IN") || mode.IsEmpty());
631
 
        }
 
613
        int row = lstArguments->GetSelection();
 
614
        if (row >= 0)
 
615
        {
 
616
                cbDatatype->SetValue(lstArguments->GetText(row, 0));
 
617
                wxString mode = lstArguments->GetText(row, 1);
 
618
                if (mode == wxT("IN"))
 
619
                        rdbIn->SetValue(true);
 
620
                else if (mode == wxT("OUT"))
 
621
                        rdbOut->SetValue(true);
 
622
                else if (mode == wxT("IN OUT") || mode == wxT("INOUT"))
 
623
                        rdbInOut->SetValue(true);
 
624
                else if (mode == wxT("VARIADIC"))
 
625
                        rdbVariadic->SetValue(true);
 
626
                txtArgName->SetValue(lstArguments->GetText(row, 2));
 
627
                if (isBackendMinVer84)
 
628
                {
 
629
                        txtArgDefVal->SetValue(lstArguments->GetText(row, 3));
 
630
                        txtArgDefVal->Enable(mode == wxT("IN") || mode.IsEmpty());
 
631
                }
632
632
 
633
 
        wxCommandEvent ev;
634
 
        OnChangeArgName(ev);
635
 
    }
 
633
                wxCommandEvent ev;
 
634
                OnChangeArgName(ev);
 
635
        }
636
636
}
637
637
 
638
638
 
639
639
void dlgFunction::OnChangeReturn(wxCommandEvent &ev)
640
640
{
641
 
    cbReturntype->GuessSelection(ev);
642
 
    CheckChange();
 
641
        cbReturntype->GuessSelection(ev);
 
642
        CheckChange();
643
643
}
644
644
 
645
645
 
646
646
void dlgFunction::OnChangeSetof(wxCommandEvent &ev)
647
647
{
648
 
    if (chkSetof->GetValue() && connection->BackendMinimumVersion(8, 3) && !isProcedure)
649
 
        txtRows->Enable();
650
 
    else
651
 
        txtRows->Disable();
 
648
        if (chkSetof->GetValue() && connection->BackendMinimumVersion(8, 3) && !isProcedure)
 
649
                txtRows->Enable();
 
650
        else
 
651
                txtRows->Disable();
652
652
 
653
 
    CheckChange();
 
653
        CheckChange();
654
654
}
655
655
 
656
656
 
657
657
void dlgFunction::OnSelChangeType(wxCommandEvent &ev)
658
658
{
659
 
    cbDatatype->GuessSelection(ev);
660
 
    OnChangeArgName(ev);
 
659
        cbDatatype->GuessSelection(ev);
 
660
        OnChangeArgName(ev);
661
661
}
662
662
 
663
663
 
664
664
void dlgFunction::OnChangeArgName(wxCommandEvent &ev)
665
665
{
666
 
    int argNameRow=-1;
667
 
    if (!txtArgName->GetValue().IsEmpty())
668
 
        argNameRow = lstArguments->FindItem(-1, txtArgName->GetValue());
669
 
 
670
 
    int pos=lstArguments->GetSelection();
671
 
 
672
 
    bool typeValid = (function != 0 || cbDatatype->GetGuessedSelection() >= 0);
673
 
 
674
 
    // EDBWrapped function does not allow modification in parameter list
675
 
    btnChange->Enable(pos >= 0 && typeValid && !isEdbWrapped);
676
 
    if (!function)
677
 
    {
678
 
        // EDBWrapped function does not allow modification in parameter list
679
 
        btnAdd->Enable(argNameRow < 0 && typeValid && !isEdbWrapped);
680
 
        btnRemove->Enable(pos >= 0 && !isEdbWrapped);
681
 
    }
 
666
        int argNameRow = -1;
 
667
        if (!txtArgName->GetValue().IsEmpty())
 
668
                argNameRow = lstArguments->FindItem(-1, txtArgName->GetValue());
 
669
 
 
670
        int pos = lstArguments->GetSelection();
 
671
 
 
672
        bool typeValid = (function != 0 || cbDatatype->GetGuessedSelection() >= 0);
 
673
 
 
674
        // EDBWrapped function does not allow modification in parameter list
 
675
        btnChange->Enable(pos >= 0 && typeValid && !isEdbWrapped);
 
676
        if (!function)
 
677
        {
 
678
                // EDBWrapped function does not allow modification in parameter list
 
679
                btnAdd->Enable(argNameRow < 0 && typeValid && !isEdbWrapped);
 
680
                btnRemove->Enable(pos >= 0 && !isEdbWrapped);
 
681
        }
682
682
}
683
683
 
684
684
void dlgFunction::OnChangeArgMode(wxCommandEvent &ev)
685
685
{
686
 
    // Do nothing, if Default value for function parameter not supported
687
 
    if (!isBackendMinVer84)
688
 
        return;
 
686
        // Do nothing, if Default value for function parameter not supported
 
687
        if (!isBackendMinVer84)
 
688
                return;
689
689
 
690
 
    // Only IN parameter supports default value
691
 
    if (!rdbIn->GetValue())
692
 
    {
693
 
        txtArgDefVal->SetValue(wxEmptyString);
694
 
        txtArgDefVal->Enable(false);
695
 
    }
696
 
    else
697
 
    {
698
 
        // EDBWrapped function does not allow modification in parameter list
699
 
        txtArgDefVal->Enable(true && !isEdbWrapped);
700
 
    }
 
690
        // Only IN parameter supports default value
 
691
        if (!rdbIn->GetValue())
 
692
        {
 
693
                txtArgDefVal->SetValue(wxEmptyString);
 
694
                txtArgDefVal->Enable(false);
 
695
        }
 
696
        else
 
697
        {
 
698
                // EDBWrapped function does not allow modification in parameter list
 
699
                txtArgDefVal->Enable(true && !isEdbWrapped);
 
700
        }
701
701
}
702
702
 
703
703
void dlgFunction::OnChangeArg(wxCommandEvent &ev)
704
704
{
705
 
    if (GetSelectedDirection() == wxT("VARIADIC") && 
706
 
        !cbDatatype->GetValue().EndsWith(wxT("[]")))
707
 
    {
708
 
        wxLogError(_("Only array types can be VARIADIC."));
709
 
        return;
710
 
    }
711
 
 
712
 
    int row=lstArguments->GetSelection();
713
 
 
714
 
    if (row >= 0)
715
 
    {
716
 
        lstArguments->SetItem(row, 0, cbDatatype->GetValue());
717
 
        lstArguments->SetItem(row, 1, GetSelectedDirection());
718
 
        lstArguments->SetItem(row, 2, txtArgName->GetValue());
719
 
        if (isBackendMinVer84)
720
 
            lstArguments->SetItem(row, 3, txtArgDefVal->GetValue());
721
 
 
722
 
        if (!function)
723
 
            argOids.Item(row) = typOids.Item(cbDatatype->GetGuessedSelection());
724
 
        txtArguments->SetValue(GetArgs());
725
 
    }
726
 
    OnChangeArgName(ev);
727
 
    CheckChange();
 
705
        if (GetSelectedDirection() == wxT("VARIADIC") &&
 
706
                !cbDatatype->GetValue().EndsWith(wxT("[]")))
 
707
        {
 
708
                wxLogError(_("Only array types can be VARIADIC."));
 
709
                return;
 
710
        }
 
711
 
 
712
        int row = lstArguments->GetSelection();
 
713
 
 
714
        if (row >= 0)
 
715
        {
 
716
                lstArguments->SetItem(row, 0, cbDatatype->GetValue());
 
717
                lstArguments->SetItem(row, 1, GetSelectedDirection());
 
718
                lstArguments->SetItem(row, 2, txtArgName->GetValue());
 
719
                if (isBackendMinVer84)
 
720
                        lstArguments->SetItem(row, 3, txtArgDefVal->GetValue());
 
721
 
 
722
                if (!function)
 
723
                        argOids.Item(row) = typOids.Item(cbDatatype->GetGuessedSelection());
 
724
                txtArguments->SetValue(GetArgs());
 
725
        }
 
726
        OnChangeArgName(ev);
 
727
        CheckChange();
728
728
}
729
729
 
730
730
 
731
731
void dlgFunction::OnAddArg(wxCommandEvent &ev)
732
732
{
733
 
    if (GetSelectedDirection() == wxT("VARIADIC") && 
734
 
        !cbDatatype->GetValue().EndsWith(wxT("[]")))
735
 
    {
736
 
        wxLogError(_("Only array types can be VARIADIC."));
737
 
        return;
738
 
    }
739
 
 
740
 
    lstArguments->AppendItem(-1, cbDatatype->GetValue(), GetSelectedDirection(), txtArgName->GetValue(), txtArgDefVal->GetValue().Trim());
741
 
 
742
 
    if (!function)
743
 
        argOids.Add(typOids.Item(cbDatatype->GetGuessedSelection()));
744
 
 
745
 
    txtArguments->SetValue(GetArgs());
746
 
    OnChangeArgName(ev);
 
733
        if (GetSelectedDirection() == wxT("VARIADIC") &&
 
734
                !cbDatatype->GetValue().EndsWith(wxT("[]")))
 
735
        {
 
736
                wxLogError(_("Only array types can be VARIADIC."));
 
737
                return;
 
738
        }
 
739
 
 
740
        lstArguments->AppendItem(-1, cbDatatype->GetValue(), GetSelectedDirection(), txtArgName->GetValue(), txtArgDefVal->GetValue().Trim());
 
741
 
 
742
        if (!function)
 
743
                argOids.Add(typOids.Item(cbDatatype->GetGuessedSelection()));
 
744
 
 
745
        txtArguments->SetValue(GetArgs());
 
746
        OnChangeArgName(ev);
747
747
}
748
748
 
749
749
 
750
750
void dlgFunction::OnRemoveArg(wxCommandEvent &ev)
751
751
{
752
 
    unsigned int sel=lstArguments->GetSelection();
753
 
    argOids.RemoveAt(sel);
754
 
    lstArguments->DeleteItem(sel);
755
 
    btnRemove->Disable();
756
 
    txtArguments->SetValue(GetArgs());
757
 
    OnChangeArgName(ev);
 
752
        unsigned int sel = lstArguments->GetSelection();
 
753
        argOids.RemoveAt(sel);
 
754
        lstArguments->DeleteItem(sel);
 
755
        btnRemove->Disable();
 
756
        txtArguments->SetValue(GetArgs());
 
757
        OnChangeArgName(ev);
758
758
}
759
759
 
760
760
wxString dlgFunction::GetSelectedDirection()
761
761
{
762
 
    if (rdbIn->GetValue())
763
 
        return wxT("IN");
764
 
    else if (rdbOut->GetValue())
765
 
        return wxT("OUT");
766
 
    else if (rdbInOut->GetValue())
767
 
    {
768
 
        if (isProcedure)
769
 
            return wxT("IN OUT");
770
 
        else
771
 
            return wxT("INOUT");
772
 
    }
773
 
    else if (rdbVariadic->GetValue())
774
 
        return wxT("VARIADIC");
775
 
    else
776
 
        return wxEmptyString;
 
762
        if (rdbIn->GetValue())
 
763
                return wxT("IN");
 
764
        else if (rdbOut->GetValue())
 
765
                return wxT("OUT");
 
766
        else if (rdbInOut->GetValue())
 
767
        {
 
768
                if (isProcedure)
 
769
                        return wxT("IN OUT");
 
770
                else
 
771
                        return wxT("INOUT");
 
772
        }
 
773
        else if (rdbVariadic->GetValue())
 
774
                return wxT("VARIADIC");
 
775
        else
 
776
                return wxEmptyString;
777
777
}
778
778
 
779
779
 
780
780
wxString dlgFunction::GetArgs(const bool withNames, const bool inOnly)
781
781
{
782
 
    wxString args;
783
 
    bool isEdbspl = cbLanguage->GetValue() == wxT("edbspl");
784
 
 
785
 
    for (int i=0; i < lstArguments->GetItemCount(); i++)
786
 
    {
787
 
        if (!isEdbspl && inOnly && lstArguments->GetText(i, 1) == wxT("OUT"))
788
 
            continue;
789
 
 
790
 
        if (i && !args.IsEmpty() && !args.EndsWith(wxT(", ")))
791
 
            args += wxT(", ");
792
 
 
793
 
        if (isProcedure)
794
 
        {
795
 
            if (withNames && lstArguments->GetText(i, 2) != wxEmptyString)
796
 
                args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" ");
797
 
 
798
 
            // edbspl functions should list OUT params, but only by type.
799
 
            if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT"))
800
 
            {
801
 
                if (lstArguments->GetText(i, 1) != wxEmptyString)
802
 
                    args += lstArguments->GetText(i, 1) + wxT(" ");
803
 
            }
804
 
                
805
 
            args += lstArguments->GetText(i, 0);
806
 
        }
807
 
        else
808
 
        {
809
 
            // edbspl functions should list OUT params, but only by type.
810
 
            if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT"))
811
 
            {
812
 
                if (connection->BackendMinimumVersion(8, 1) && lstArguments->GetText(i, 1) != wxEmptyString)
813
 
                    args += lstArguments->GetText(i, 1) + wxT(" ");
814
 
            }
815
 
 
816
 
            if (connection->BackendMinimumVersion(8, 0) && withNames && lstArguments->GetText(i, 2) != wxEmptyString)
817
 
                args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" ");
818
 
 
819
 
            args += lstArguments->GetText(i, 0);
820
 
        }
821
 
        if (isBackendMinVer84 && !lstArguments->GetText(i, 3).IsEmpty())
822
 
           args += wxT(" DEFAULT ") + lstArguments->GetText(i, 3);
823
 
    }
824
 
 
825
 
    return args;
 
782
        wxString args;
 
783
        bool isEdbspl = cbLanguage->GetValue() == wxT("edbspl");
 
784
 
 
785
        for (int i = 0; i < lstArguments->GetItemCount(); i++)
 
786
        {
 
787
                if (!isEdbspl && inOnly && lstArguments->GetText(i, 1) == wxT("OUT"))
 
788
                        continue;
 
789
 
 
790
                if (i && !args.IsEmpty() && !args.EndsWith(wxT(", ")))
 
791
                        args += wxT(", ");
 
792
 
 
793
                if (isProcedure)
 
794
                {
 
795
                        if (withNames && lstArguments->GetText(i, 2) != wxEmptyString)
 
796
                                args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" ");
 
797
 
 
798
                        // edbspl functions should list OUT params, but only by type.
 
799
                        // although this is not true for EDB AS90 onwards..
 
800
                        if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT") ||
 
801
                                connection->EdbMinimumVersion(9, 0))
 
802
                        {
 
803
                                if (lstArguments->GetText(i, 1) != wxEmptyString)
 
804
                                        args += lstArguments->GetText(i, 1) + wxT(" ");
 
805
                        }
 
806
 
 
807
                        args += lstArguments->GetText(i, 0);
 
808
                }
 
809
                else
 
810
                {
 
811
                        // edbspl functions should list OUT params, but only by type.
 
812
                        // although this is not true for EDB AS90 onwards..
 
813
                        if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT") ||
 
814
                                connection->EdbMinimumVersion(9, 0))
 
815
                        {
 
816
                                if (connection->BackendMinimumVersion(8, 1) && lstArguments->GetText(i, 1) != wxEmptyString)
 
817
                                        args += lstArguments->GetText(i, 1) + wxT(" ");
 
818
                        }
 
819
 
 
820
                        if (connection->BackendMinimumVersion(8, 0) && withNames && lstArguments->GetText(i, 2) != wxEmptyString)
 
821
                                args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" ");
 
822
 
 
823
                        args += lstArguments->GetText(i, 0);
 
824
                }
 
825
                if (isBackendMinVer84 && !lstArguments->GetText(i, 3).IsEmpty())
 
826
                        args += wxT(" DEFAULT ") + lstArguments->GetText(i, 3);
 
827
        }
 
828
 
 
829
        return args;
826
830
}
827
831
 
828
832
 
829
833
wxString dlgFunction::GetSql()
830
834
{
831
 
    wxString sql;
832
 
    wxString name=GetName();
833
 
    wxString objType;
834
 
    if (isProcedure)
835
 
        objType = wxT("PROCEDURE ");
836
 
    else
837
 
        objType = wxT("FUNCTION ");
838
 
 
839
 
    bool isC=cbLanguage->GetValue().IsSameAs(wxT("C"), false);
840
 
    bool didChange = !function
841
 
                || cbLanguage->GetValue() != function->GetLanguage()
842
 
        || cbVolatility->GetValue() != function->GetVolatility()
843
 
        || chkSecureDefiner->GetValue() != function->GetSecureDefiner()
844
 
        || chkStrict->GetValue() != function->GetIsStrict()
845
 
        || cbOwner->GetValue() != function->GetOwner()
846
 
        || GetArgs() != function->GetArgListWithNames()
847
 
        || (isC && (txtObjectFile->GetValue() != function->GetBin() || txtLinkSymbol->GetValue() != function->GetSource()))
848
 
        || (!isC && txtSqlBox->GetText() != function->GetSource());
849
 
 
850
 
    if (connection->BackendMinimumVersion(8, 3))
851
 
    {
852
 
        didChange = (didChange ||
853
 
            txtCost->GetValue() != NumToStr(function->GetCost()) ||
854
 
            (chkSetof->GetValue() && txtRows->GetValue() != NumToStr(function->GetRows())));
855
 
    }
856
 
 
857
 
    if (function)
858
 
    {
859
 
        // edit mode
860
 
        if (name != function->GetName())
861
 
        {
862
 
            if (!isProcedure)
863
 
                sql = wxT("ALTER FUNCTION ") + function->GetQuotedFullIdentifier() 
864
 
                                             + wxT("(") + function->GetArgSigList() + wxT(")")
865
 
                                             + wxT(" RENAME TO ") + qtIdent(name) + wxT(";\n");
866
 
            else
867
 
                sql = wxT("ALTER PROCEDURE ") + function->GetQuotedFullIdentifier() 
868
 
                    + wxT(" RENAME TO ") + qtIdent(name) + wxT(";\n");
869
 
        }
870
 
 
871
 
        if (didChange)
872
 
            sql += wxT("CREATE OR REPLACE ") + objType;
873
 
    }
874
 
    else
875
 
    {
876
 
        // create mode
877
 
        sql = wxT("CREATE " ) + objType;
878
 
    }
879
 
 
880
 
    if (didChange)
881
 
    {
882
 
        if (isProcedure && GetArgs().IsEmpty())
883
 
        {
884
 
            sql += schema->GetQuotedPrefix() + qtIdent(GetName());
885
 
        }
886
 
        else
887
 
        {
888
 
            sql += schema->GetQuotedPrefix() + qtIdent(GetName()) 
889
 
                + wxT("(") + GetArgs() + wxT(")");
890
 
        }
891
 
 
892
 
        if (!isProcedure)
893
 
        {
894
 
            sql += wxT(" RETURNS ");
895
 
            if (chkSetof->GetValue() && !cbReturntype->GetValue().StartsWith(wxT("TABLE")))
896
 
                sql += wxT("SETOF ");
897
 
 
898
 
            sql += cbReturntype->GetValue();
899
 
        }
900
 
 
901
 
        sql += wxT(" AS\n");
902
 
 
903
 
        if (isProcedure)
904
 
        {
905
 
            sql += txtSqlBox->GetText();
906
 
            sql = sql.Trim(true);
907
 
            if (!sql.EndsWith(wxT(";")))
908
 
                sql += wxT(";\n");
909
 
            else
910
 
                sql += wxT("\n");
911
 
        }
912
 
        else
913
 
        {
914
 
            if (cbLanguage->GetValue().IsSameAs(wxT("C"), false))
915
 
            {
916
 
                sql += qtDbString(txtObjectFile->GetValue());
917
 
                if (!txtLinkSymbol->GetValue().IsEmpty())
918
 
                    sql += wxT(", ") + qtDbString(txtLinkSymbol->GetValue());
919
 
            }
920
 
            else
921
 
            {
922
 
                if (connection->BackendMinimumVersion(7, 5))
923
 
                    sql += qtDbStringDollar(txtSqlBox->GetText());
924
 
                else
925
 
                    sql += qtDbString(txtSqlBox->GetText());
926
 
            }
927
 
 
928
 
            sql += wxT("\nLANGUAGE ") + cbLanguage->GetValue();
929
 
            if (chkWindow->GetValue())
930
 
                sql += wxT(" WINDOW ");
931
 
            else
932
 
                sql += wxT(" ");
933
 
            sql +=  cbVolatility->GetValue();
934
 
            if (chkStrict->GetValue())
935
 
                sql += wxT(" STRICT");
936
 
            if (chkSecureDefiner->GetValue())
937
 
                sql += wxT(" SECURITY DEFINER");
938
 
 
939
 
            // PostgreSQL 8.3+ cost/row estimations
940
 
            if (connection->BackendMinimumVersion(8, 3))
941
 
            {
942
 
                if (txtCost->GetValue().Length() > 0)
943
 
                    sql += wxT("\nCOST ") + txtCost->GetValue();
944
 
 
945
 
                if (chkSetof->GetValue() && txtRows->GetValue().Length() > 0)
946
 
                    sql += wxT("\nROWS ") + txtRows->GetValue();
947
 
            }
948
 
 
949
 
            sql += wxT(";\n");
950
 
        }
951
 
    }
952
 
 
953
 
    name = schema->GetQuotedPrefix() + qtIdent(name) 
954
 
         + wxT("(") + GetArgs(false, true) + wxT(")");
955
 
 
956
 
    if (function)
957
 
    {
958
 
        if (cbOwner->GetValue() != function->GetOwner())
959
 
            sql += wxT("ALTER FUNCTION ") + name
960
 
                +  wxT(" OWNER TO ") + qtIdent(cbOwner->GetValue())
961
 
                + wxT(";\n");    
962
 
    }
963
 
    else
964
 
    {
965
 
        if (cbOwner->GetCurrentSelection() > 0)
966
 
            AppendOwnerNew(sql,wxT("FUNCTION ") + name);
967
 
    }
968
 
 
969
 
    if (isProcedure)
970
 
        sql += GetGrant(wxT("X"), wxT("PROCEDURE ") + name);
971
 
    else
972
 
    {
973
 
        wxArrayString vars;
974
 
        size_t index;
975
 
 
976
 
        if (function)
977
 
        {
978
 
            for (index = 0 ; index < function->GetConfigList().GetCount() ; index++)
979
 
                vars.Add(function->GetConfigList().Item(index));
980
 
        }
981
 
 
982
 
        int cnt=lstVariables->GetItemCount();
983
 
        int pos;
984
 
 
985
 
        // check for changed or added vars
986
 
        for (pos=0 ; pos < cnt ; pos++)
987
 
        {
988
 
            wxString newVar=lstVariables->GetText(pos);
989
 
            wxString newVal=lstVariables->GetText(pos, 1);
990
 
 
991
 
            wxString oldVal;
992
 
 
993
 
            for (index=0 ; index < vars.GetCount() ; index++)
994
 
            {
995
 
                wxString var=vars.Item(index);
996
 
                if (var.BeforeFirst('=').IsSameAs(newVar, false))
997
 
                {
998
 
                    oldVal = var.Mid(newVar.Length()+1);
999
 
                    vars.RemoveAt(index);
1000
 
                    break;
1001
 
                }
1002
 
            }
1003
 
                        
1004
 
            // Reset the vars if they've changed, or the function definition has
1005
 
            // changed, which will remove them all :-(
1006
 
            if ((oldVal != newVal) || didChange)  
1007
 
            {
1008
 
                if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces"))
1009
 
                    sql += wxT("ALTER FUNCTION ") + name
1010
 
                        +  wxT(" SET ") + newVar
1011
 
                        +  wxT("='") + newVal
1012
 
                        +  wxT("';\n");
1013
 
                else
1014
 
                    sql += wxT("ALTER FUNCTION ") + name
1015
 
                        +  wxT(" SET ") + newVar
1016
 
                        +  wxT("=") + newVal
1017
 
                        +  wxT(";\n");
1018
 
            }
1019
 
        }
1020
 
        
1021
 
        // check for removed vars
1022
 
        for (pos=0 ; pos < (int)vars.GetCount() ; pos++)
1023
 
        {
1024
 
            sql += wxT("ALTER FUNCTION ") + name
1025
 
                +  wxT(" RESET ") + vars.Item(pos).BeforeFirst('=')
1026
 
                + wxT(";\n");
1027
 
        }
1028
 
 
1029
 
        sql += GetGrant(wxT("X"), wxT("FUNCTION ") + name);
1030
 
    }
1031
 
 
1032
 
    if (isProcedure)
1033
 
        AppendComment(sql, wxT("PROCEDURE ") + schema->GetQuotedPrefix() + qtIdent(GetName()), function);
1034
 
    else
1035
 
        AppendComment(sql, wxT("FUNCTION ") + name, function);
1036
 
 
1037
 
    return sql;
 
835
        wxString sql;
 
836
        wxString name = GetName();
 
837
        wxString objType;
 
838
        if (isProcedure)
 
839
                objType = wxT("PROCEDURE ");
 
840
        else
 
841
                objType = wxT("FUNCTION ");
 
842
 
 
843
        bool isC = cbLanguage->GetValue().IsSameAs(wxT("C"), false);
 
844
        bool didChange = !function
 
845
                         || cbLanguage->GetValue() != function->GetLanguage()
 
846
                         || cbVolatility->GetValue() != function->GetVolatility()
 
847
                         || chkSecureDefiner->GetValue() != function->GetSecureDefiner()
 
848
                         || chkStrict->GetValue() != function->GetIsStrict()
 
849
                         || cbOwner->GetValue() != function->GetOwner()
 
850
                         || GetArgs() != function->GetArgListWithNames()
 
851
                         || (isC && (txtObjectFile->GetValue() != function->GetBin() || txtLinkSymbol->GetValue() != function->GetSource()))
 
852
                         || (!isC && txtSqlBox->GetText() != function->GetSource());
 
853
 
 
854
        if (connection->BackendMinimumVersion(8, 3))
 
855
        {
 
856
                didChange = (didChange ||
 
857
                             txtCost->GetValue() != NumToStr(function->GetCost()) ||
 
858
                             (chkSetof->GetValue() && txtRows->GetValue() != NumToStr(function->GetRows())));
 
859
        }
 
860
 
 
861
        if (function)
 
862
        {
 
863
                // edit mode
 
864
                if (name != function->GetName())
 
865
                {
 
866
                        if (!isProcedure)
 
867
                                sql = wxT("ALTER FUNCTION ") + function->GetQuotedFullIdentifier()
 
868
                                      + wxT("(") + function->GetArgSigList() + wxT(")")
 
869
                                      + wxT(" RENAME TO ") + qtIdent(name) + wxT(";\n");
 
870
                        else
 
871
                                sql = wxT("ALTER PROCEDURE ") + function->GetQuotedFullIdentifier()
 
872
                                      + wxT(" RENAME TO ") + qtIdent(name) + wxT(";\n");
 
873
                }
 
874
 
 
875
                if (didChange)
 
876
                        sql += wxT("CREATE OR REPLACE ") + objType;
 
877
        }
 
878
        else
 
879
        {
 
880
                // create mode
 
881
                sql = wxT("CREATE " ) + objType;
 
882
        }
 
883
 
 
884
        if (didChange)
 
885
        {
 
886
                if (isProcedure && GetArgs().IsEmpty())
 
887
                {
 
888
                        sql += schema->GetQuotedPrefix() + qtIdent(GetName());
 
889
                }
 
890
                else
 
891
                {
 
892
                        sql += schema->GetQuotedPrefix() + qtIdent(GetName())
 
893
                               + wxT("(") + GetArgs() + wxT(")");
 
894
                }
 
895
 
 
896
                if (!isProcedure)
 
897
                {
 
898
                        sql += wxT(" RETURNS ");
 
899
                        if (chkSetof->GetValue() && !cbReturntype->GetValue().StartsWith(wxT("TABLE")))
 
900
                                sql += wxT("SETOF ");
 
901
 
 
902
                        sql += cbReturntype->GetValue();
 
903
                }
 
904
 
 
905
                sql += wxT(" AS\n");
 
906
 
 
907
                if (isProcedure)
 
908
                {
 
909
                        sql += txtSqlBox->GetText();
 
910
                        sql = sql.Trim(true);
 
911
                        if (!sql.EndsWith(wxT(";")))
 
912
                                sql += wxT(";\n");
 
913
                        else
 
914
                                sql += wxT("\n");
 
915
                }
 
916
                else
 
917
                {
 
918
                        if (cbLanguage->GetValue().IsSameAs(wxT("C"), false))
 
919
                        {
 
920
                                sql += qtDbString(txtObjectFile->GetValue());
 
921
                                if (!txtLinkSymbol->GetValue().IsEmpty())
 
922
                                        sql += wxT(", ") + qtDbString(txtLinkSymbol->GetValue());
 
923
                        }
 
924
                        else
 
925
                        {
 
926
                                if (connection->BackendMinimumVersion(7, 5))
 
927
                                        sql += qtDbStringDollar(txtSqlBox->GetText());
 
928
                                else
 
929
                                        sql += qtDbString(txtSqlBox->GetText());
 
930
                        }
 
931
 
 
932
                        sql += wxT("\nLANGUAGE ") + cbLanguage->GetValue();
 
933
                        if (chkWindow->GetValue())
 
934
                                sql += wxT(" WINDOW ");
 
935
                        else
 
936
                                sql += wxT(" ");
 
937
                        sql +=  cbVolatility->GetValue();
 
938
                        if (chkStrict->GetValue())
 
939
                                sql += wxT(" STRICT");
 
940
                        if (chkSecureDefiner->GetValue())
 
941
                                sql += wxT(" SECURITY DEFINER");
 
942
 
 
943
                        // PostgreSQL 8.3+ cost/row estimations
 
944
                        if (connection->BackendMinimumVersion(8, 3))
 
945
                        {
 
946
                                if (txtCost->GetValue().Length() > 0)
 
947
                                        sql += wxT("\nCOST ") + txtCost->GetValue();
 
948
 
 
949
                                if (chkSetof->GetValue() && txtRows->GetValue().Length() > 0)
 
950
                                        sql += wxT("\nROWS ") + txtRows->GetValue();
 
951
                        }
 
952
 
 
953
                        sql += wxT(";\n");
 
954
                }
 
955
        }
 
956
 
 
957
        name = schema->GetQuotedPrefix() + qtIdent(name)
 
958
               + wxT("(") + GetArgs(false, true) + wxT(")");
 
959
 
 
960
        if (function)
 
961
        {
 
962
                if (cbOwner->GetValue() != function->GetOwner())
 
963
                        sql += wxT("ALTER FUNCTION ") + name
 
964
                               +  wxT(" OWNER TO ") + qtIdent(cbOwner->GetValue())
 
965
                               + wxT(";\n");
 
966
        }
 
967
        else
 
968
        {
 
969
                if (cbOwner->GetCurrentSelection() > 0)
 
970
                        AppendOwnerNew(sql, wxT("FUNCTION ") + name);
 
971
        }
 
972
 
 
973
        if (isProcedure)
 
974
                sql += GetGrant(wxT("X"), wxT("PROCEDURE ") + name);
 
975
        else
 
976
        {
 
977
                wxArrayString vars;
 
978
                size_t index;
 
979
 
 
980
                if (function)
 
981
                {
 
982
                        for (index = 0 ; index < function->GetConfigList().GetCount() ; index++)
 
983
                                vars.Add(function->GetConfigList().Item(index));
 
984
                }
 
985
 
 
986
                int cnt = lstVariables->GetItemCount();
 
987
                int pos;
 
988
 
 
989
                // check for changed or added vars
 
990
                for (pos = 0 ; pos < cnt ; pos++)
 
991
                {
 
992
                        wxString newVar = lstVariables->GetText(pos);
 
993
                        wxString newVal = lstVariables->GetText(pos, 1);
 
994
 
 
995
                        wxString oldVal;
 
996
 
 
997
                        for (index = 0 ; index < vars.GetCount() ; index++)
 
998
                        {
 
999
                                wxString var = vars.Item(index);
 
1000
                                if (var.BeforeFirst('=').IsSameAs(newVar, false))
 
1001
                                {
 
1002
                                        oldVal = var.Mid(newVar.Length() + 1);
 
1003
                                        vars.RemoveAt(index);
 
1004
                                        break;
 
1005
                                }
 
1006
                        }
 
1007
 
 
1008
                        // Reset the vars if they've changed, or the function definition has
 
1009
                        // changed, which will remove them all :-(
 
1010
                        if ((oldVal != newVal) || didChange)
 
1011
                        {
 
1012
                                if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces"))
 
1013
                                        sql += wxT("ALTER FUNCTION ") + name
 
1014
                                               +  wxT(" SET ") + newVar
 
1015
                                               +  wxT("='") + newVal
 
1016
                                               +  wxT("';\n");
 
1017
                                else
 
1018
                                        sql += wxT("ALTER FUNCTION ") + name
 
1019
                                               +  wxT(" SET ") + newVar
 
1020
                                               +  wxT("=") + newVal
 
1021
                                               +  wxT(";\n");
 
1022
                        }
 
1023
                }
 
1024
 
 
1025
                // check for removed vars
 
1026
                for (pos = 0 ; pos < (int)vars.GetCount() ; pos++)
 
1027
                {
 
1028
                        sql += wxT("ALTER FUNCTION ") + name
 
1029
                               +  wxT(" RESET ") + vars.Item(pos).BeforeFirst('=')
 
1030
                               + wxT(";\n");
 
1031
                }
 
1032
 
 
1033
                sql += GetGrant(wxT("X"), wxT("FUNCTION ") + name);
 
1034
        }
 
1035
 
 
1036
        if (isProcedure)
 
1037
                AppendComment(sql, wxT("PROCEDURE ") + schema->GetQuotedPrefix() + qtIdent(GetName()), function);
 
1038
        else
 
1039
                AppendComment(sql, wxT("FUNCTION ") + name, function);
 
1040
 
 
1041
        return sql;
1038
1042
}
1039
1043
 
1040
1044
 
1041
1045
void dlgFunction::OnChangeWindow(wxCommandEvent &ev)
1042
1046
{
1043
 
    CheckChange();
 
1047
        CheckChange();
1044
1048
}
1045
1049