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

« back to all changes in this revision

Viewing changes to pgadmin/dlg/dlgType.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
// dlgType.cpp - PostgreSQL TYPE Property
45
45
#define lstLabels               CTRL_LISTVIEW("lstLabels")
46
46
#define txtLabel                CTRL_TEXT("txtLabel")
47
47
#define btnAddMember            CTRL_BUTTON("btnAddMember")
 
48
#define btnChangeMember         CTRL_BUTTON("btnChangeMember")
48
49
#define btnRemoveMember         CTRL_BUTTON("btnRemoveMember")
49
 
#define btnAddLabel             CTRL_BUTTON("btnAddLabel")
 
50
#define btnAddAfterLabel        CTRL_BUTTON("btnAddAfterLabel")
 
51
#define btnAddBeforeLabel       CTRL_BUTTON("btnAddBeforeLabel")
50
52
#define btnRemoveLabel          CTRL_BUTTON("btnRemoveLabel")
51
53
#define pnlDefinition           CTRL_PANEL("pnlDefinition")
52
54
#define pnlDefinitionExtern     CTRL_PANEL("pnlDefinitionExtern")
53
55
#define pnlDefinitionComposite  CTRL_PANEL("pnlDefinitionComposite")
54
56
#define pnlDefinitionEnum       CTRL_PANEL("pnlDefinitionEnum")
 
57
#define chkCollatable           CTRL_CHECKBOX("chkCollatable")
 
58
#define cbCollation             CTRL_COMBOBOX("cbCollation")
55
59
 
56
60
 
57
61
BEGIN_EVENT_TABLE(dlgType, dlgTypeProperty)
58
 
    EVT_RADIOBOX(XRCID("rdbType"),                  dlgType::OnTypeChange)
59
 
 
60
 
    EVT_TEXT(XRCID("cbInput"),                      dlgProperty::OnChange)
61
 
    EVT_COMBOBOX(XRCID("cbInput"),                  dlgProperty::OnChange)
62
 
    EVT_TEXT(XRCID("cbOutput"),                     dlgProperty::OnChange)
63
 
    EVT_COMBOBOX(XRCID("cbOutput"),                 dlgProperty::OnChange)
64
 
    EVT_TEXT(XRCID("txtIntLength"),                 dlgProperty::OnChange)
65
 
    EVT_CHECKBOX(XRCID("chkVariable"),              dlgProperty::OnChange)
66
 
    
67
 
    EVT_BUTTON(XRCID("btnAddMember"),               dlgType::OnMemberAdd)
68
 
    EVT_BUTTON(XRCID("btnRemoveMember"),            dlgType::OnMemberRemove)
69
 
    EVT_BUTTON(XRCID("btnAddLabel"),                dlgType::OnLabelAdd)
70
 
    EVT_BUTTON(XRCID("btnRemoveLabel"),             dlgType::OnLabelRemove)
71
 
    EVT_LIST_ITEM_SELECTED(XRCID("lstMembers"),     dlgType::OnMemberSelChange)
72
 
    EVT_LIST_ITEM_SELECTED(XRCID("lstLabels"),      dlgType::OnLabelSelChange)
73
 
    EVT_TEXT(XRCID("cbDatatype"),                   dlgType::OnSelChangeTyp)
74
 
    EVT_COMBOBOX(XRCID("cbDatatype"),               dlgType::OnSelChangeTyp)
75
 
    EVT_TEXT(XRCID("txtMembername"),                dlgType::OnChangeMember)
76
 
    EVT_TEXT(XRCID("txtLength"),                    dlgType::OnSelChangeTypOrLen)
77
 
    EVT_TEXT(XRCID("txtPrecision"),                 dlgType::OnSelChangeTypOrLen)
 
62
        EVT_RADIOBOX(XRCID("rdbType"),                  dlgType::OnTypeChange)
 
63
 
 
64
        EVT_TEXT(XRCID("cbInput"),                      dlgProperty::OnChange)
 
65
        EVT_COMBOBOX(XRCID("cbInput"),                  dlgProperty::OnChange)
 
66
        EVT_TEXT(XRCID("cbOutput"),                     dlgProperty::OnChange)
 
67
        EVT_COMBOBOX(XRCID("cbOutput"),                 dlgProperty::OnChange)
 
68
        EVT_TEXT(XRCID("txtIntLength"),                 dlgProperty::OnChange)
 
69
        EVT_CHECKBOX(XRCID("chkVariable"),              dlgProperty::OnChange)
 
70
 
 
71
        EVT_BUTTON(XRCID("btnAddMember"),               dlgType::OnMemberAdd)
 
72
        EVT_BUTTON(XRCID("btnChangeMember"),            dlgType::OnMemberChange)
 
73
        EVT_BUTTON(XRCID("btnRemoveMember"),            dlgType::OnMemberRemove)
 
74
        EVT_BUTTON(XRCID("btnAddBeforeLabel"),          dlgType::OnLabelAddBefore)
 
75
        EVT_BUTTON(XRCID("btnAddAfterLabel"),           dlgType::OnLabelAddAfter)
 
76
        EVT_BUTTON(XRCID("btnRemoveLabel"),             dlgType::OnLabelRemove)
 
77
        EVT_LIST_ITEM_SELECTED(XRCID("lstMembers"),     dlgType::OnMemberSelChange)
 
78
        EVT_LIST_ITEM_SELECTED(XRCID("lstLabels"),      dlgType::OnLabelSelChange)
 
79
        EVT_TEXT(XRCID("cbDatatype"),                   dlgType::OnSelChangeTyp)
 
80
        EVT_COMBOBOX(XRCID("cbDatatype"),               dlgType::OnSelChangeTyp)
 
81
        EVT_TEXT(XRCID("txtMembername"),                dlgType::OnChangeMember)
 
82
        EVT_TEXT(XRCID("txtLength"),                    dlgType::OnSelChangeTypOrLen)
 
83
        EVT_TEXT(XRCID("txtPrecision"),                 dlgType::OnSelChangeTypOrLen)
78
84
END_EVENT_TABLE();
79
85
 
80
86
 
81
87
dlgProperty *pgTypeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
82
88
{
83
 
    return new dlgType(this, frame, (pgType*)node, (pgSchema*)parent);
 
89
        return new dlgType(this, frame, (pgType *)node, (pgSchema *)parent);
84
90
}
85
91
 
86
92
 
87
93
dlgType::dlgType(pgaFactory *f, frmMain *frame, pgType *node, pgSchema *sch)
88
 
: dlgTypeProperty(f, frame, wxT("dlgType"))
 
94
        : dlgTypeProperty(f, frame, wxT("dlgType"))
89
95
{
90
 
    type=node;
91
 
    schema=sch;
92
 
    lstMembers->CreateColumns(0, _("Member"), _("Data type"), -1);
93
 
    lstLabels->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, GetClientSize().GetWidth());
94
 
 
95
 
    wxNotifyEvent event;
96
 
    OnTypeChange(event);
 
96
        type = node;
 
97
        schema = sch;
 
98
        lstMembers->CreateColumns(0, _("Member"), _("Data type"), _("Collation"), -1);
 
99
        lstLabels->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, GetClientSize().GetWidth());
 
100
 
 
101
        cbStorage->Append(wxT("PLAIN"));
 
102
        cbStorage->Append(wxT("MAIN"));
 
103
        cbStorage->Append(wxT("EXTERNAL"));
 
104
        cbStorage->Append(wxT("EXTENDED"));
 
105
 
 
106
        queriesToBeSplitted = false;
 
107
 
 
108
        wxNotifyEvent event;
 
109
        OnTypeChange(event);
97
110
}
98
111
 
99
112
 
100
113
void dlgType::OnChangeMember(wxCommandEvent &ev)
101
114
{
102
 
    btnAddMember->Enable(!type
103
 
        && !txtMembername->GetValue().Strip(wxString::both).IsEmpty()
104
 
        && cbDatatype->GetGuessedSelection() >= 0);
 
115
        btnAddMember->Enable(
 
116
            ((type && connection->BackendMinimumVersion(9, 1)) || !type)
 
117
            && !txtMembername->GetValue().Strip(wxString::both).IsEmpty()
 
118
            && cbDatatype->GetGuessedSelection() >= 0);
 
119
        btnChangeMember->Enable(true);
105
120
}
106
121
 
107
122
void dlgType::showDefinition(int panel)
108
123
{
109
 
    pnlDefinitionExtern->Show(false);
110
 
    pnlDefinitionComposite->Show(false);
111
 
    pnlDefinitionEnum->Show(false);
112
 
 
113
 
    switch (panel)
114
 
    {
115
 
        case 0:
116
 
            pnlDefinitionComposite->Show(true);
117
 
            break;
118
 
        case 1:
119
 
            pnlDefinitionEnum->Show(true);
120
 
            break;
121
 
        case 2:
122
 
            pnlDefinitionExtern->Show(true);
123
 
            break;
124
 
    }
125
 
 
126
 
    pnlDefinitionComposite->GetParent()->Layout();
127
 
    // we don't need to call GetParent()->Layout() for all three panels
128
 
    // because they all share the same parent
 
124
        pnlDefinitionExtern->Show(false);
 
125
        pnlDefinitionComposite->Show(false);
 
126
        pnlDefinitionEnum->Show(false);
 
127
 
 
128
        switch (panel)
 
129
        {
 
130
                case 0:
 
131
                        pnlDefinitionComposite->Show(true);
 
132
                        break;
 
133
                case 1:
 
134
                        pnlDefinitionEnum->Show(true);
 
135
                        break;
 
136
                case 2:
 
137
                        pnlDefinitionExtern->Show(true);
 
138
                        break;
 
139
        }
 
140
 
 
141
        pnlDefinitionComposite->GetParent()->Layout();
 
142
        // we don't need to call GetParent()->Layout() for all three panels
 
143
        // because they all share the same parent
129
144
}
130
145
 
131
146
 
132
147
void dlgType::OnTypeChange(wxCommandEvent &ev)
133
148
{
134
 
    showDefinition(rdbType->GetSelection());
135
 
    
136
 
    CheckChange();
 
149
        showDefinition(rdbType->GetSelection());
 
150
 
 
151
        CheckChange();
137
152
}
138
153
 
139
154
 
140
155
pgObject *dlgType::GetObject()
141
156
{
142
 
    return type;
 
157
        return type;
143
158
}
144
159
 
145
160
 
146
161
int dlgType::Go(bool modal)
147
162
{
148
 
    pgSet *set;
149
 
 
150
 
    FillDatatype(cbDatatype, cbElement);
151
 
 
152
 
    if (type)
153
 
    {
154
 
        // Edit Mode
155
 
        txtName->Disable();
156
 
        rdbType->SetSelection(type->GetTypeClass());
157
 
        rdbType->Disable();
158
 
 
159
 
        showDefinition(type->GetTypeClass());
160
 
 
161
 
        cbInput->Append(type->GetInputFunction()); cbInput->SetSelection(0); cbInput->Disable();
162
 
        cbOutput->Append(type->GetOutputFunction()); cbOutput->SetSelection(0); cbOutput->Disable();
163
 
        cbReceive->Append(type->GetReceiveFunction()); cbReceive->SetSelection(0); cbReceive->Disable();
164
 
        cbSend->Append(type->GetSendFunction()); cbSend->SetSelection(0); cbSend->Disable();
165
 
        cbTypmodin->Append(type->GetTypmodinFunction()); cbTypmodin->SetSelection(0); cbTypmodin->Disable();
166
 
        cbTypmodout->Append(type->GetTypmodoutFunction()); cbTypmodout->SetSelection(0); cbTypmodout->Disable();
167
 
 
168
 
        chkVariable->SetValue(type->GetInternalLength() < 0); chkVariable->Disable();
169
 
        if (type->GetInternalLength() > 0)
170
 
            txtIntLength->SetValue(NumToStr(type->GetInternalLength())); 
171
 
        txtIntLength->Disable();
172
 
        txtDefault->SetValue(type->GetDefault()); txtDefault->Disable();
173
 
        cbElement->Append(type->GetElement()); cbElement->SetSelection(0); cbElement->Disable();
174
 
        txtDelimiter->SetValue(type->GetDelimiter()); txtDelimiter->Disable();
175
 
        chkByValue->SetValue(type->GetPassedByValue()); chkByValue->Disable();
176
 
        cbAlignment->SetValue(type->GetAlignment()); cbAlignment->Disable();
177
 
        cbStorage->SetValue(type->GetStorage()); cbStorage->Disable();
178
 
 
179
 
        txtMembername->Disable();
180
 
        btnAddMember->Disable();
181
 
        btnRemoveMember->Disable();
182
 
 
183
 
        txtLabel->Disable();
184
 
        btnAddLabel->Disable();
185
 
        btnRemoveLabel->Disable();
186
 
 
187
 
        wxArrayString elements=type->GetTypesArray();
188
 
        wxString fullType, typeName, typeLength, typePrecision;
189
 
        int pos;
190
 
        size_t i;
191
 
                for (i=0 ; i < elements.GetCount() ; i+=2)
192
 
        {
193
 
            lstMembers->AppendItem(0, elements.Item(i), elements.Item(i+1));
194
 
 
195
 
            fullType = elements.Item(i+1);
196
 
            typeName = fullType;
197
 
            typeLength = wxEmptyString;
198
 
            typePrecision = wxEmptyString;
199
 
 
200
 
            if (fullType.Find(wxT("(")) > 0)
201
 
            {
202
 
                // there is at least a length
203
 
                typeName = fullType.BeforeFirst('(');
204
 
                if (fullType.Find(wxT(",")) > 0)
205
 
                {
206
 
                    // there is also a precision
207
 
                    typeLength = fullType.AfterFirst('(').BeforeFirst(',');
208
 
                    typePrecision = fullType.AfterFirst(',').BeforeFirst(')');
209
 
                }
210
 
                else
211
 
                    typeLength = fullType.AfterFirst('(').BeforeFirst(')');
212
 
            }
213
 
 
214
 
            for (pos = 0; pos < cbDatatype->GetCount() - 1; pos++)
215
 
            {
216
 
                if (cbDatatype->GetString(pos) == typeName)
217
 
                {
218
 
                    memberTypes.Add(GetTypeInfo(pos));
219
 
                    break;
220
 
                }
221
 
            }
222
 
            memberLengths.Add(typeLength);
223
 
            memberPrecisions.Add(typePrecision);
224
 
        }
225
 
 
226
 
        cbDatatype->Disable();
227
 
        txtLength->Disable();
228
 
 
229
 
        // Load the enum labels
230
 
        elements=type->GetLabelArray();
231
 
                for (i=0 ; i < elements.GetCount() ; i++)
232
 
            lstLabels->AppendItem(0, elements.Item(i));
233
 
 
234
 
        if (!connection->BackendMinimumVersion(7, 5))
235
 
            cbOwner->Disable();
236
 
    }
237
 
    else
238
 
    {
239
 
        // Create mode
240
 
        cbOwner->Append(wxEmptyString);
241
 
        cbOwner->Disable();
242
 
 
243
 
        bool hasSendRcv = connection->BackendMinimumVersion(7, 4);
244
 
        bool hasTypmod = connection->BackendMinimumVersion(8, 3);
245
 
 
246
 
        if (hasSendRcv)
247
 
        {
248
 
            cbReceive->Append(wxEmptyString);
249
 
            cbSend->Append(wxEmptyString);
250
 
        }
251
 
        else
252
 
        {
253
 
            cbReceive->Disable();
254
 
            cbSend->Disable();
255
 
        }
256
 
 
257
 
        if (hasTypmod)
258
 
        {
259
 
            cbTypmodin->Append(wxEmptyString);
260
 
            cbTypmodout->Append(wxEmptyString);
261
 
        }
262
 
        else
263
 
        {
264
 
            cbTypmodin->Disable();
265
 
            cbTypmodout->Disable();
266
 
        }
267
 
 
268
 
        if (!connection->BackendMinimumVersion(8, 3))
269
 
            rdbType->Enable(TYPE_ENUM, false);
270
 
 
271
 
        set = connection->ExecuteSet(
272
 
            wxT("SELECT proname, nspname\n")
273
 
            wxT("  FROM (\n")
274
 
            wxT("        SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1\n")
275
 
            wxT("          FROM pg_proc p\n")
276
 
            wxT("          JOIN pg_namespace n ON n.oid=pronamespace\n")
277
 
            wxT("         GROUP BY proname, nspname\n")
278
 
            wxT("        HAVING count(proname) = 1   ) AS uniquefunc\n")
279
 
            wxT(" WHERE arg0 <> 0 AND arg1 = 0"));
280
 
        
281
 
        if (set)
282
 
        {
283
 
            while (!set->Eof())
284
 
            {
285
 
                wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
286
 
 
287
 
                cbInput->Append(pn);
288
 
                cbOutput->Append(pn);
289
 
                if (hasSendRcv)
290
 
                {
291
 
                    cbReceive->Append(pn);
292
 
                    cbSend->Append(pn);
293
 
                }
294
 
                if (hasTypmod)
295
 
                {
296
 
                    cbTypmodin->Append(pn);
297
 
                    cbTypmodout->Append(pn);
298
 
                }
299
 
                set->MoveNext();
300
 
            }
301
 
            delete set;
302
 
        }
303
 
 
304
 
        if (hasTypmod)
305
 
        {
306
 
            set = connection->ExecuteSet(
307
 
                wxT("SELECT proname, nspname\n")
308
 
                wxT("  FROM pg_proc p\n")
309
 
                wxT("  JOIN pg_namespace n ON n.oid=pronamespace\n")
310
 
                wxT("  WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='int4')")
311
 
                wxT("    AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='_cstring')")
312
 
                wxT("    AND proargtypes[1] IS NULL")
313
 
                wxT("  ORDER BY nspname, proname"));
314
 
 
315
 
            if (set)
316
 
            {
317
 
                while (!set->Eof())
318
 
                {
319
 
                    wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
320
 
 
321
 
                    cbTypmodin->Append(pn);
322
 
                    set->MoveNext();
323
 
                }
324
 
                delete set;
325
 
            }
326
 
 
327
 
            set = connection->ExecuteSet(
328
 
                wxT("SELECT proname, nspname\n")
329
 
                wxT("  FROM pg_proc p\n")
330
 
                wxT("  JOIN pg_namespace n ON n.oid=pronamespace\n")
331
 
                wxT("  WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='cstring')")
332
 
                wxT("    AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='int4')")
333
 
                wxT("    AND proargtypes[1] IS NULL")
334
 
                wxT("  ORDER BY nspname, proname"));
335
 
 
336
 
            if (set)
337
 
            {
338
 
                while (!set->Eof())
339
 
                {
340
 
                    wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
341
 
 
342
 
                    cbTypmodout->Append(pn);
343
 
                    set->MoveNext();
344
 
                }
345
 
                delete set;
346
 
            }
347
 
        }
348
 
 
349
 
        txtLength->SetValidator(numericValidator);
350
 
    }
351
 
    return dlgTypeProperty::Go(modal);
 
163
        pgSet *set;
 
164
 
 
165
        FillDatatype(cbDatatype, cbElement);
 
166
 
 
167
        if (connection->BackendMinimumVersion(9, 1))
 
168
        {
 
169
                // fill collation combobox
 
170
                cbCollation->Append(wxEmptyString);
 
171
                set = connection->ExecuteSet(
 
172
                          wxT("SELECT nspname, collname\n")
 
173
                          wxT("  FROM pg_collation c, pg_namespace n\n")
 
174
                          wxT("  WHERE c.collnamespace=n.oid\n")
 
175
                          wxT("  ORDER BY nspname, collname"));
 
176
                if (set)
 
177
                {
 
178
                        while (!set->Eof())
 
179
                        {
 
180
                                wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname")));
 
181
                                cbCollation->Append(name);
 
182
                                set->MoveNext();
 
183
                        }
 
184
                        delete set;
 
185
                }
 
186
                cbCollation->SetSelection(0);
 
187
        }
 
188
 
 
189
        if (type)
 
190
        {
 
191
                // Edit Mode
 
192
                txtName->Disable();
 
193
                rdbType->SetSelection(type->GetTypeClass());
 
194
                rdbType->Disable();
 
195
 
 
196
                showDefinition(type->GetTypeClass());
 
197
 
 
198
                cbInput->Append(type->GetInputFunction());
 
199
                cbInput->SetSelection(0);
 
200
                cbInput->Disable();
 
201
                cbOutput->Append(type->GetOutputFunction());
 
202
                cbOutput->SetSelection(0);
 
203
                cbOutput->Disable();
 
204
                cbReceive->Append(type->GetReceiveFunction());
 
205
                cbReceive->SetSelection(0);
 
206
                cbReceive->Disable();
 
207
                cbSend->Append(type->GetSendFunction());
 
208
                cbSend->SetSelection(0);
 
209
                cbSend->Disable();
 
210
                cbTypmodin->Append(type->GetTypmodinFunction());
 
211
                cbTypmodin->SetSelection(0);
 
212
                cbTypmodin->Disable();
 
213
                cbTypmodout->Append(type->GetTypmodoutFunction());
 
214
                cbTypmodout->SetSelection(0);
 
215
                cbTypmodout->Disable();
 
216
 
 
217
                chkVariable->SetValue(type->GetInternalLength() < 0);
 
218
                chkVariable->Disable();
 
219
                if (type->GetInternalLength() > 0)
 
220
                        txtIntLength->SetValue(NumToStr(type->GetInternalLength()));
 
221
                txtIntLength->Disable();
 
222
                txtDefault->SetValue(type->GetDefault());
 
223
                txtDefault->Disable();
 
224
                cbElement->Append(type->GetElement());
 
225
                cbElement->SetSelection(0);
 
226
                cbElement->Disable();
 
227
                txtDelimiter->SetValue(type->GetDelimiter());
 
228
                txtDelimiter->Disable();
 
229
                chkByValue->SetValue(type->GetPassedByValue());
 
230
                chkByValue->Disable();
 
231
                cbAlignment->SetValue(type->GetAlignment());
 
232
                cbAlignment->Disable();
 
233
                cbStorage->SetValue(type->GetStorage());
 
234
                cbStorage->Disable();
 
235
                chkCollatable->SetValue(type->GetCollatable());
 
236
                chkCollatable->Disable();
 
237
 
 
238
                bool changeok = connection->BackendMinimumVersion(9, 1);
 
239
                txtMembername->Enable(changeok);
 
240
                cbCollation->Enable(changeok);
 
241
                btnAddMember->Enable(changeok);
 
242
                btnChangeMember->Enable(false);
 
243
                btnRemoveMember->Enable(false);
 
244
 
 
245
                txtLabel->Enable(connection->BackendMinimumVersion(9, 1));
 
246
                btnAddBeforeLabel->Enable(connection->BackendMinimumVersion(9, 1));
 
247
                btnAddAfterLabel->Enable(connection->BackendMinimumVersion(9, 1));
 
248
                btnRemoveLabel->Disable();
 
249
 
 
250
                wxArrayString elements = type->GetTypesArray();
 
251
                wxString fullType, typeName, typeLength, typePrecision;
 
252
                size_t pos;
 
253
                size_t i;
 
254
                for (i = 0 ; i < elements.GetCount() ; i += 3)
 
255
                {
 
256
                        lstMembers->AppendItem(0, elements.Item(i), elements.Item(i + 1), elements.Item(i + 2));
 
257
 
 
258
                        fullType = elements.Item(i + 1);
 
259
                        typeName = fullType;
 
260
                        typeLength = wxEmptyString;
 
261
                        typePrecision = wxEmptyString;
 
262
 
 
263
                        if (fullType.Find(wxT("(")) > 0)
 
264
                        {
 
265
                                // there is at least a length
 
266
                                typeName = fullType.BeforeFirst('(');
 
267
                                if (fullType.Find(wxT(",")) > 0)
 
268
                                {
 
269
                                        // there is also a precision
 
270
                                        typeLength = fullType.AfterFirst('(').BeforeFirst(',');
 
271
                                        typePrecision = fullType.AfterFirst(',').BeforeFirst(')');
 
272
                                }
 
273
                                else
 
274
                                        typeLength = fullType.AfterFirst('(').BeforeFirst(')');
 
275
                        }
 
276
 
 
277
                        for (pos = 0; pos < cbDatatype->GetCount() - 1; pos++)
 
278
                        {
 
279
                                if (cbDatatype->GetString(pos) == typeName)
 
280
                                {
 
281
                                        memberTypes.Add(GetTypeInfo(pos));
 
282
                                        break;
 
283
                                }
 
284
                        }
 
285
                        memberLengths.Add(typeLength);
 
286
                        memberPrecisions.Add(typePrecision);
 
287
                        memberCollations.Add(elements.Item(i + 2));
 
288
                }
 
289
 
 
290
                cbDatatype->Enable(changeok);
 
291
                txtLength->Enable(changeok);
 
292
 
 
293
                // Load the enum labels
 
294
                elements = type->GetLabelArray();
 
295
                for (i = 0 ; i < elements.GetCount() ; i++)
 
296
                        lstLabels->AppendItem(0, elements.Item(i));
 
297
 
 
298
                if (!connection->BackendMinimumVersion(7, 5))
 
299
                        cbOwner->Disable();
 
300
        }
 
301
        else
 
302
        {
 
303
                // Create mode
 
304
                cbOwner->Append(wxEmptyString);
 
305
                cbOwner->Disable();
 
306
 
 
307
                bool hasSendRcv = connection->BackendMinimumVersion(7, 4);
 
308
                bool hasTypmod = connection->BackendMinimumVersion(8, 3);
 
309
 
 
310
                if (hasSendRcv)
 
311
                {
 
312
                        cbReceive->Append(wxEmptyString);
 
313
                        cbSend->Append(wxEmptyString);
 
314
                }
 
315
                else
 
316
                {
 
317
                        cbReceive->Disable();
 
318
                        cbSend->Disable();
 
319
                }
 
320
 
 
321
                if (hasTypmod)
 
322
                {
 
323
                        cbTypmodin->Append(wxEmptyString);
 
324
                        cbTypmodout->Append(wxEmptyString);
 
325
                }
 
326
                else
 
327
                {
 
328
                        cbTypmodin->Disable();
 
329
                        cbTypmodout->Disable();
 
330
                }
 
331
 
 
332
                if (!connection->BackendMinimumVersion(8, 3))
 
333
                        rdbType->Enable(TYPE_ENUM, false);
 
334
 
 
335
                chkCollatable->Enable(connection->BackendMinimumVersion(9, 1));
 
336
                cbCollation->Enable(connection->BackendMinimumVersion(9, 1));
 
337
 
 
338
                set = connection->ExecuteSet(
 
339
                          wxT("SELECT proname, nspname\n")
 
340
                          wxT("  FROM (\n")
 
341
                          wxT("        SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1\n")
 
342
                          wxT("          FROM pg_proc p\n")
 
343
                          wxT("          JOIN pg_namespace n ON n.oid=pronamespace\n")
 
344
                          wxT("         GROUP BY proname, nspname\n")
 
345
                          wxT("        HAVING count(proname) = 1   ) AS uniquefunc\n")
 
346
                          wxT(" WHERE arg0 <> 0 AND arg1 = 0"));
 
347
 
 
348
                if (set)
 
349
                {
 
350
                        while (!set->Eof())
 
351
                        {
 
352
                                wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
 
353
 
 
354
                                cbInput->Append(pn);
 
355
                                cbOutput->Append(pn);
 
356
                                if (hasSendRcv)
 
357
                                {
 
358
                                        cbReceive->Append(pn);
 
359
                                        cbSend->Append(pn);
 
360
                                }
 
361
                                if (hasTypmod)
 
362
                                {
 
363
                                        cbTypmodin->Append(pn);
 
364
                                        cbTypmodout->Append(pn);
 
365
                                }
 
366
                                set->MoveNext();
 
367
                        }
 
368
                        delete set;
 
369
                }
 
370
 
 
371
                if (hasTypmod)
 
372
                {
 
373
                        set = connection->ExecuteSet(
 
374
                                  wxT("SELECT proname, nspname\n")
 
375
                                  wxT("  FROM pg_proc p\n")
 
376
                                  wxT("  JOIN pg_namespace n ON n.oid=pronamespace\n")
 
377
                                  wxT("  WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='int4')")
 
378
                                  wxT("    AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='_cstring')")
 
379
                                  wxT("    AND proargtypes[1] IS NULL")
 
380
                                  wxT("  ORDER BY nspname, proname"));
 
381
 
 
382
                        if (set)
 
383
                        {
 
384
                                while (!set->Eof())
 
385
                                {
 
386
                                        wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
 
387
 
 
388
                                        cbTypmodin->Append(pn);
 
389
                                        set->MoveNext();
 
390
                                }
 
391
                                delete set;
 
392
                        }
 
393
 
 
394
                        set = connection->ExecuteSet(
 
395
                                  wxT("SELECT proname, nspname\n")
 
396
                                  wxT("  FROM pg_proc p\n")
 
397
                                  wxT("  JOIN pg_namespace n ON n.oid=pronamespace\n")
 
398
                                  wxT("  WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='cstring')")
 
399
                                  wxT("    AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='int4')")
 
400
                                  wxT("    AND proargtypes[1] IS NULL")
 
401
                                  wxT("  ORDER BY nspname, proname"));
 
402
 
 
403
                        if (set)
 
404
                        {
 
405
                                while (!set->Eof())
 
406
                                {
 
407
                                        wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"));
 
408
 
 
409
                                        cbTypmodout->Append(pn);
 
410
                                        set->MoveNext();
 
411
                                }
 
412
                                delete set;
 
413
                        }
 
414
                }
 
415
        }
 
416
 
 
417
        txtLength->SetValidator(numericValidator);
 
418
 
 
419
        return dlgTypeProperty::Go(modal);
352
420
}
353
421
 
354
422
 
355
423
void dlgType::OnSelChangeTyp(wxCommandEvent &ev)
356
424
{
357
 
    txtLength->SetValue(wxEmptyString);
358
 
    txtPrecision->SetValue(wxEmptyString);
359
 
    cbDatatype->GuessSelection(ev);
360
 
    OnSelChangeTypOrLen(ev);
 
425
        txtLength->SetValue(wxEmptyString);
 
426
        txtPrecision->SetValue(wxEmptyString);
 
427
        cbDatatype->GuessSelection(ev);
 
428
        cbCollation->SetValue(wxEmptyString);
 
429
        OnSelChangeTypOrLen(ev);
361
430
}
362
431
 
363
432
 
364
433
void dlgType::OnSelChangeTypOrLen(wxCommandEvent &ev)
365
434
{
366
 
    if (!type)
367
 
    {
368
 
        CheckLenEnable();
369
 
        txtLength->Enable(isVarLen);
370
 
        txtPrecision->Enable(isVarPrec);
371
 
        CheckChange();
372
 
        OnChangeMember(ev);
373
 
    }
 
435
        if ((type && connection->BackendMinimumVersion(9, 1)) || !type)
 
436
        {
 
437
                CheckLenEnable();
 
438
                txtLength->Enable(isVarLen);
 
439
                txtPrecision->Enable(isVarPrec);
 
440
                cbCollation->Enable(connection->BackendMinimumVersion(9, 1));
 
441
                CheckChange();
 
442
                OnChangeMember(ev);
 
443
        }
374
444
}
375
445
 
376
446
 
377
447
void dlgType::CheckChange()
378
448
{
379
 
    if (type)
380
 
    {
381
 
        EnableOK(txtComment->GetValue() != type->GetComment()
382
 
            || cbOwner->GetValue() != type->GetOwner());
383
 
    }
384
 
    else
385
 
    {
386
 
        wxString name=GetName();
387
 
 
388
 
        bool enable=true;
389
 
        CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
390
 
        CheckValid(enable, !name.StartsWith(wxT("_")), _("Name may not start with '_'."));
391
 
 
392
 
        if (rdbType->GetSelection() == TYPE_COMPOSITE)
393
 
        {
394
 
            CheckValid(enable, lstMembers->GetItemCount() > 1, _("Please specify at least two members."));
395
 
        }
396
 
        else if (rdbType->GetSelection() == TYPE_ENUM)
397
 
        {
398
 
            CheckValid(enable, lstLabels->GetItemCount() >= 1, _("Please specify at least one label."));
399
 
        }
400
 
        else
401
 
        {
402
 
            txtLength->Enable(!chkVariable->GetValue());
403
 
            CheckValid(enable, cbInput->GetCurrentSelection() >= 0, _("Please specify input conversion function."));
404
 
            CheckValid(enable, cbOutput->GetCurrentSelection() >= 0, _("Please specify output conversion function."));
405
 
            CheckValid(enable, chkVariable->GetValue() || StrToLong(txtLength->GetValue()) > 0, _("Please specify internal storage length."));
406
 
        }
407
 
        EnableOK(enable);
408
 
    }
 
449
        if (type)
 
450
        {
 
451
                EnableOK(txtComment->GetValue() != type->GetComment()
 
452
                         || cbOwner->GetValue() != type->GetOwner()
 
453
                         || (rdbType->GetSelection() == TYPE_COMPOSITE && GetSqlForTypes() != wxEmptyString)
 
454
                         || (GetSql().Length() > 0 && connection->BackendMinimumVersion(9, 1)));
 
455
        }
 
456
        else
 
457
        {
 
458
                wxString name = GetName();
 
459
 
 
460
                bool enable = true;
 
461
                CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
 
462
                CheckValid(enable, !name.StartsWith(wxT("_")), _("Name may not start with '_'."));
 
463
 
 
464
                if (rdbType->GetSelection() == TYPE_COMPOSITE)
 
465
                {
 
466
                        CheckValid(enable, lstMembers->GetItemCount() > 1, _("Please specify at least two members."));
 
467
                }
 
468
                else if (rdbType->GetSelection() == TYPE_ENUM)
 
469
                {
 
470
                        CheckValid(enable, lstLabels->GetItemCount() >= 1, _("Please specify at least one label."));
 
471
                }
 
472
                else
 
473
                {
 
474
                        txtLength->Enable(!chkVariable->GetValue());
 
475
                        CheckValid(enable, cbInput->GetCurrentSelection() >= 0, _("Please specify input conversion function."));
 
476
                        CheckValid(enable, cbOutput->GetCurrentSelection() >= 0, _("Please specify output conversion function."));
 
477
                        CheckValid(enable, chkVariable->GetValue() || StrToLong(txtLength->GetValue()) > 0, _("Please specify internal storage length."));
 
478
                }
 
479
                EnableOK(enable);
 
480
        }
409
481
}
410
482
 
411
483
 
412
484
void dlgType::OnMemberSelChange(wxListEvent &ev)
413
485
{
414
 
    long pos=lstMembers->GetSelection();
415
 
    if (pos >= 0)
416
 
    {
417
 
        txtMembername->SetValue(lstMembers->GetText(pos));
418
 
        cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':'));
419
 
        txtLength->SetValue(memberLengths.Item(pos));
420
 
        txtLength->Enable(!type && !txtLength->GetValue().IsEmpty());
421
 
        txtPrecision->SetValue(memberPrecisions.Item(pos));
422
 
        txtPrecision->Enable(!type && !txtPrecision->GetValue().IsEmpty());
423
 
    }
 
486
        long pos = lstMembers->GetSelection();
 
487
        if (pos >= 0)
 
488
        {
 
489
                txtMembername->SetValue(lstMembers->GetText(pos));
 
490
                cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':'));
 
491
                txtLength->SetValue(memberLengths.Item(pos));
 
492
                txtLength->Enable(((type && connection->BackendMinimumVersion(9, 1)) || !type) && !txtLength->GetValue().IsEmpty());
 
493
                txtPrecision->SetValue(memberPrecisions.Item(pos));
 
494
                txtPrecision->Enable(((type && connection->BackendMinimumVersion(9, 1)) || !type) && !txtPrecision->GetValue().IsEmpty());
 
495
                cbCollation->SetValue(memberCollations.Item(pos));
 
496
                cbCollation->Enable(connection->BackendMinimumVersion(9, 1));
 
497
                btnChangeMember->Enable((type && connection->BackendMinimumVersion(9, 1)) || !type);
 
498
                btnRemoveMember->Enable((type && connection->BackendMinimumVersion(9, 1)) || !type);
 
499
        }
424
500
}
425
501
 
426
502
 
427
503
void dlgType::OnMemberAdd(wxCommandEvent &ev)
428
504
{
429
 
    wxString name = txtMembername->GetValue().Strip(wxString::both);
430
 
    wxString type = cbDatatype->GetValue();
431
 
    wxString length = wxEmptyString;
432
 
    wxString precision = wxEmptyString;
433
 
 
434
 
    if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled())
435
 
       length = txtLength->GetValue();
436
 
    if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled())
437
 
       precision = txtPrecision->GetValue();
438
 
 
439
 
    if (!length.IsEmpty())
440
 
    {
441
 
        type += wxT("(") + length;
442
 
        if (!precision.IsEmpty())
443
 
            type += wxT(", ") + precision;
444
 
        type += wxT(")");
445
 
    }
446
 
 
447
 
    if (!name.IsEmpty())
448
 
    {
449
 
        long pos=lstMembers->FindItem(-1, name);
450
 
        if (pos < 0)
451
 
        {
452
 
            pos = lstMembers->GetItemCount();
453
 
            lstMembers->InsertItem(pos, name, 0);
454
 
            memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection()));
455
 
            memberLengths.Add(length);
456
 
            memberPrecisions.Add(precision);
457
 
        }
458
 
        else
459
 
        {
460
 
            memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos);
461
 
            memberLengths.Insert(length, pos);
462
 
            memberPrecisions.Insert(precision, pos);
463
 
            memberTypes.RemoveAt(pos+1);
464
 
            memberLengths.RemoveAt(pos+1);
465
 
            memberPrecisions.RemoveAt(pos+1);
466
 
        }
467
 
        lstMembers->SetItem(pos, 1, type);
468
 
    }
469
 
 
470
 
    CheckChange();
 
505
        wxString name = txtMembername->GetValue().Strip(wxString::both);
 
506
        wxString type = cbDatatype->GetValue();
 
507
        wxString length = wxEmptyString;
 
508
        wxString precision = wxEmptyString;
 
509
        wxString collation = wxEmptyString;
 
510
 
 
511
        if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled())
 
512
                length = txtLength->GetValue();
 
513
        if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled())
 
514
                precision = txtPrecision->GetValue();
 
515
        if (cbCollation->GetValue() != wxT("") && cbCollation->IsEnabled())
 
516
                collation = cbCollation->GetValue();
 
517
 
 
518
        if (!length.IsEmpty())
 
519
        {
 
520
                type += wxT("(") + length;
 
521
                if (!precision.IsEmpty())
 
522
                        type += wxT(",") + precision;
 
523
                type += wxT(")");
 
524
        }
 
525
 
 
526
        if (!name.IsEmpty())
 
527
        {
 
528
                size_t pos = lstMembers->GetItemCount();
 
529
                lstMembers->InsertItem(pos, name, 0);
 
530
                lstMembers->SetItem(pos, 1, type);
 
531
                lstMembers->SetItem(pos, 2, collation);
 
532
                memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection()));
 
533
                memberLengths.Add(length);
 
534
                memberPrecisions.Add(precision);
 
535
                memberCollations.Add(collation);
 
536
        }
 
537
 
 
538
        CheckChange();
 
539
}
 
540
 
 
541
 
 
542
void dlgType::OnMemberChange(wxCommandEvent &ev)
 
543
{
 
544
        wxString name = txtMembername->GetValue().Strip(wxString::both);
 
545
        wxString type = cbDatatype->GetValue();
 
546
        wxString length = wxEmptyString;
 
547
        wxString precision = wxEmptyString;
 
548
        wxString collation = wxEmptyString;
 
549
 
 
550
        if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled())
 
551
                length = txtLength->GetValue();
 
552
        if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled())
 
553
                precision = txtPrecision->GetValue();
 
554
        if (cbCollation->GetValue() != wxT("") && cbCollation->IsEnabled())
 
555
                collation = cbCollation->GetValue();
 
556
 
 
557
        if (!length.IsEmpty())
 
558
        {
 
559
                type += wxT("(") + length;
 
560
                if (!precision.IsEmpty())
 
561
                        type += wxT(",") + precision;
 
562
                type += wxT(")");
 
563
        }
 
564
 
 
565
        if (!name.IsEmpty())
 
566
        {
 
567
                long pos = lstMembers->GetFirstSelected();
 
568
                if (pos >= 0)
 
569
                {
 
570
                        lstMembers->SetItem(pos, 0, name);
 
571
                        lstMembers->SetItem(pos, 1, type);
 
572
                        lstMembers->SetItem(pos, 2, collation);
 
573
                        memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos);
 
574
                        memberLengths.Insert(length, pos);
 
575
                        memberPrecisions.Insert(precision, pos);
 
576
                        memberCollations.Insert(collation, pos);
 
577
                        memberTypes.RemoveAt(pos + 1);
 
578
                        memberLengths.RemoveAt(pos + 1);
 
579
                        memberPrecisions.RemoveAt(pos + 1);
 
580
                        memberCollations.RemoveAt(pos + 1);
 
581
                }
 
582
        }
 
583
 
 
584
        CheckChange();
471
585
}
472
586
 
473
587
 
474
588
void dlgType::OnMemberRemove(wxCommandEvent &ev)
475
589
{
476
 
    long pos=lstMembers->GetSelection();
 
590
        long pos = lstMembers->GetSelection();
477
591
 
478
 
    if (pos >= 0)
479
 
    {
480
 
        lstMembers->DeleteItem(pos);
481
 
        memberTypes.RemoveAt(pos);
482
 
        memberLengths.RemoveAt(pos);
483
 
        memberPrecisions.RemoveAt(pos);
484
 
    }
485
 
    CheckChange();
 
592
        if (pos >= 0)
 
593
        {
 
594
                lstMembers->DeleteItem(pos);
 
595
                memberTypes.RemoveAt(pos);
 
596
                memberLengths.RemoveAt(pos);
 
597
                memberPrecisions.RemoveAt(pos);
 
598
                memberCollations.RemoveAt(pos);
 
599
        }
 
600
        CheckChange();
486
601
}
487
602
 
488
603
 
489
604
void dlgType::OnLabelSelChange(wxListEvent &ev)
490
605
{
491
 
    long pos=lstLabels->GetSelection();
492
 
    if (pos >= 0)
493
 
    {
494
 
        txtLabel->SetValue(lstLabels->GetText(pos));
495
 
    }
496
 
}
497
 
 
498
 
 
499
 
void dlgType::OnLabelAdd(wxCommandEvent &ev)
500
 
{
501
 
    wxString label=txtLabel->GetValue().Strip(wxString::both);
502
 
 
503
 
    if (!label.IsEmpty())
504
 
    {
505
 
        long pos=lstLabels->FindItem(-1, label);
506
 
        if (pos < 0)
507
 
        {
508
 
            pos = lstLabels->GetItemCount();
509
 
            lstLabels->InsertItem(pos, label, 0);
510
 
        }
511
 
    }
512
 
    txtLabel->SetValue(wxEmptyString);
513
 
    CheckChange();
 
606
        long pos = lstLabels->GetSelection();
 
607
        if (pos >= 0)
 
608
        {
 
609
                txtLabel->SetValue(lstLabels->GetText(pos));
 
610
        }
 
611
}
 
612
 
 
613
 
 
614
void dlgType::OnLabelAddBefore(wxCommandEvent &ev)
 
615
{
 
616
        wxString label = txtLabel->GetValue().Strip(wxString::both);
 
617
 
 
618
        if (!label.IsEmpty())
 
619
        {
 
620
                long pos = lstLabels->FindItem(-1, label);
 
621
                if (pos < 0)
 
622
                {
 
623
                        if (lstLabels->GetFirstSelected() >= 0)
 
624
                                pos = lstLabels->GetFirstSelected();
 
625
                        else
 
626
                                pos = 0;
 
627
                        lstLabels->InsertItem(pos, label, 0);
 
628
                }
 
629
        }
 
630
        txtLabel->SetValue(wxEmptyString);
 
631
        CheckChange();
 
632
}
 
633
 
 
634
 
 
635
void dlgType::OnLabelAddAfter(wxCommandEvent &ev)
 
636
{
 
637
        wxString label = txtLabel->GetValue().Strip(wxString::both);
 
638
 
 
639
        if (!label.IsEmpty())
 
640
        {
 
641
                long pos = lstLabels->FindItem(-1, label);
 
642
                if (pos < 0)
 
643
                {
 
644
                        if (lstLabels->GetFirstSelected() >= 0)
 
645
                                pos = lstLabels->GetFirstSelected() + 1;
 
646
                        else
 
647
                                pos = lstLabels->GetItemCount();
 
648
                        lstLabels->InsertItem(pos, label, 0);
 
649
                }
 
650
        }
 
651
        txtLabel->SetValue(wxEmptyString);
 
652
        CheckChange();
514
653
}
515
654
 
516
655
 
517
656
void dlgType::OnLabelRemove(wxCommandEvent &ev)
518
657
{
519
 
    long pos=lstLabels->GetSelection();
520
 
 
521
 
    if (pos >= 0)
522
 
        lstLabels->DeleteItem(pos);
523
 
 
524
 
    CheckChange();
 
658
        long pos = lstLabels->GetSelection();
 
659
 
 
660
        if (pos >= 0)
 
661
                lstLabels->DeleteItem(pos);
 
662
 
 
663
        CheckChange();
525
664
}
526
665
 
527
666
 
528
667
pgObject *dlgType::CreateObject(pgCollection *collection)
529
668
{
530
 
    wxString name=GetName();
 
669
        wxString name = GetName();
531
670
 
532
 
    pgObject *obj=0; //pgType::ReadObjects(collection, 0, wxT("\n WHERE usename=") + qtDbString(name));
533
 
    return obj;
 
671
        pgObject *obj = 0; //pgType::ReadObjects(collection, 0, wxT("\n WHERE usename=") + qtDbString(name));
 
672
        return obj;
534
673
}
535
674
 
536
675
 
537
676
wxString dlgType::GetSql()
538
677
{
539
 
    wxString sql;
540
 
    
541
 
    if (type)
542
 
    {
543
 
        // Edit Mode
544
 
        AppendOwnerChange(sql, wxT("TYPE ") + type->GetQuotedFullIdentifier());
545
 
    }
546
 
    else
547
 
    {
548
 
        // Create Mode
549
 
        sql = wxT("CREATE TYPE ") + schema->GetQuotedPrefix() + qtIdent(GetName());
550
 
 
551
 
        if (rdbType->GetSelection() == TYPE_COMPOSITE)
552
 
        {
553
 
            sql += wxT(" AS\n   (");
554
 
 
555
 
            int i;
556
 
            for (i=0 ; i < lstMembers->GetItemCount() ; i++)
557
 
            {
558
 
                if (i)
559
 
                    sql += wxT(",\n    ");
560
 
                sql += qtIdent(lstMembers->GetItemText(i)) + wxT(" ")
561
 
                    + GetFullTypeName(i);
562
 
            }
563
 
        }
564
 
        else if (rdbType->GetSelection() == TYPE_ENUM)
565
 
        {
566
 
            sql += wxT(" AS ENUM\n   (");
567
 
 
568
 
            int i;
569
 
            for (i=0 ; i < lstLabels->GetItemCount() ; i++)
570
 
            {
571
 
                if (i)
572
 
                    sql += wxT(",\n    ");
573
 
                sql += connection->qtDbString(lstLabels->GetItemText(i));
574
 
            }
575
 
        }
576
 
        else
577
 
        {
578
 
            sql += wxT("\n   (INPUT=");
579
 
            AppendQuoted(sql, cbInput->GetValue());
580
 
            sql += wxT(", OUTPUT=");
581
 
            AppendQuoted(sql, cbOutput->GetValue());
582
 
 
583
 
            if (connection->BackendMinimumVersion(7, 4))
584
 
            {
585
 
                if (cbReceive->GetCurrentSelection() > 0 || cbSend->GetCurrentSelection() > 0)
586
 
                {
587
 
                    if (cbReceive->GetCurrentSelection() > 0)
588
 
                    {
589
 
                        sql += wxT(",\n   RECEIVE=");
590
 
                        AppendQuoted(sql, cbReceive->GetValue());
591
 
                        if (cbSend->GetCurrentSelection() > 0)
592
 
                        {
593
 
                            sql += wxT(", SEND=");
594
 
                            AppendQuoted(sql, cbSend->GetValue());
595
 
                        }
596
 
                    }
597
 
                    else
598
 
                    {
599
 
                        sql += wxT(",\n   SEND=");
600
 
                        AppendQuoted(sql, cbSend->GetValue());
601
 
                    }
602
 
                }
603
 
 
604
 
            }
605
 
            if (connection->BackendMinimumVersion(8, 3))
606
 
            {
607
 
                if (cbTypmodin->GetCurrentSelection() > 0 || cbTypmodout->GetCurrentSelection() > 0)
608
 
                {
609
 
                    if (cbTypmodin->GetCurrentSelection() > 0)
610
 
                    {
611
 
                        sql += wxT(",\n   TYPMOD_IN=");
612
 
                        AppendQuoted(sql, cbTypmodin->GetValue());
613
 
                        if (cbTypmodout->GetCurrentSelection() > 0)
614
 
                        {
615
 
                            sql += wxT(", TYPMOD_OUT=");
616
 
                            AppendQuoted(sql, cbTypmodout->GetValue());
617
 
                        }
618
 
                    }
619
 
                    else
620
 
                    {
621
 
                        sql += wxT(",\n   TYPMOD_OUT=");
622
 
                        AppendQuoted(sql, cbTypmodout->GetValue());
623
 
                    }
624
 
                }
625
 
 
626
 
            }
627
 
            sql += wxT(",\n    INTERNALLENGTH=");
628
 
            if (chkVariable->GetValue())
629
 
                sql += wxT("VARIABLE");
630
 
            else
631
 
                sql += txtLength->GetValue();
632
 
            AppendIfFilled(sql, wxT(",\n    DEFAULT="), txtDefault->GetValue());
633
 
            if (!cbElement->GetValue().IsEmpty())
634
 
            {
635
 
                sql += wxT(",\n    ELEMENT=");
636
 
                AppendQuoted(sql, cbElement->GetValue());
637
 
                AppendIfFilled(sql, wxT(", DELIMITER="), qtDbString(txtDelimiter->GetValue().Strip(wxString::both)));
638
 
            }
639
 
            if (chkByValue->GetValue())
640
 
                sql += wxT(",\n    PASSEDBYVALUE");
641
 
            AppendIfFilled(sql, wxT(",\n    ALIGNMENT="), cbAlignment->GetValue());
642
 
            AppendIfFilled(sql, wxT(",\n    STORAGE="), cbStorage->GetValue());
643
 
        }
644
 
 
645
 
        sql += wxT(");\n");
646
 
    }
647
 
    AppendComment(sql, wxT("TYPE"), schema, type);
648
 
 
649
 
    return sql;
 
678
        wxString sql, direction;
 
679
        size_t existingitems_index, listitems_index, offset;
 
680
 
 
681
        if (type)
 
682
        {
 
683
                // Edit Mode
 
684
                AppendOwnerChange(sql, wxT("TYPE ") + type->GetQuotedFullIdentifier());
 
685
                sql += GetSqlForTypes();
 
686
                if (rdbType->GetSelection() == TYPE_ENUM && connection->BackendMinimumVersion(9, 1))
 
687
                {
 
688
                        wxArrayString elements = type->GetLabelArray();
 
689
                        existingitems_index = 0;
 
690
                        for (listitems_index = 0 ; listitems_index < (size_t)lstLabels->GetItemCount() ; listitems_index++)
 
691
                        {
 
692
                                if (existingitems_index >= elements.GetCount() || lstLabels->GetItemText(listitems_index) != elements.Item(existingitems_index))
 
693
                                {
 
694
                                        queriesToBeSplitted = true;
 
695
                                        if (listitems_index == 0)
 
696
                                        {
 
697
                                                direction = wxT("BEFORE");
 
698
                                                offset = 0;
 
699
                                        }
 
700
                                        else
 
701
                                        {
 
702
                                                direction = wxT("AFTER");
 
703
                                                offset = -1;
 
704
                                        }
 
705
 
 
706
                                        sql += wxT("ALTER TYPE ") + type->GetQuotedFullIdentifier()
 
707
                                               +  wxT(" ADD VALUE ") + connection->qtDbString(lstLabels->GetItemText(listitems_index))
 
708
                                               +  wxT(" ") + direction + wxT(" ")
 
709
                                               + connection->qtDbString(elements.Item(existingitems_index + offset))
 
710
                                               + wxT(";\n");
 
711
                                }
 
712
                                else
 
713
                                        existingitems_index++;
 
714
                        }
 
715
                }
 
716
        }
 
717
        else
 
718
        {
 
719
                // Create Mode
 
720
                sql = wxT("CREATE TYPE ") + schema->GetQuotedPrefix() + qtIdent(GetName());
 
721
 
 
722
                if (rdbType->GetSelection() == TYPE_COMPOSITE)
 
723
                {
 
724
                        sql += wxT(" AS\n   (");
 
725
 
 
726
                        int i;
 
727
                        for (i = 0 ; i < lstMembers->GetItemCount() ; i++)
 
728
                        {
 
729
                                if (i)
 
730
                                        sql += wxT(",\n    ");
 
731
                                sql += qtIdent(lstMembers->GetItemText(i)) + wxT(" ")
 
732
                                       + GetFullTypeName(i);
 
733
                        }
 
734
                }
 
735
                else if (rdbType->GetSelection() == TYPE_ENUM)
 
736
                {
 
737
                        sql += wxT(" AS ENUM\n   (");
 
738
 
 
739
                        int i;
 
740
                        for (i = 0 ; i < lstLabels->GetItemCount() ; i++)
 
741
                        {
 
742
                                if (i)
 
743
                                        sql += wxT(",\n    ");
 
744
                                sql += connection->qtDbString(lstLabels->GetItemText(i));
 
745
                        }
 
746
                }
 
747
                else
 
748
                {
 
749
                        sql += wxT("\n   (INPUT=");
 
750
                        AppendQuoted(sql, cbInput->GetValue());
 
751
                        sql += wxT(", OUTPUT=");
 
752
                        AppendQuoted(sql, cbOutput->GetValue());
 
753
 
 
754
                        if (connection->BackendMinimumVersion(7, 4))
 
755
                        {
 
756
                                if (cbReceive->GetCurrentSelection() > 0 || cbSend->GetCurrentSelection() > 0)
 
757
                                {
 
758
                                        if (cbReceive->GetCurrentSelection() > 0)
 
759
                                        {
 
760
                                                sql += wxT(",\n   RECEIVE=");
 
761
                                                AppendQuoted(sql, cbReceive->GetValue());
 
762
                                                if (cbSend->GetCurrentSelection() > 0)
 
763
                                                {
 
764
                                                        sql += wxT(", SEND=");
 
765
                                                        AppendQuoted(sql, cbSend->GetValue());
 
766
                                                }
 
767
                                        }
 
768
                                        else
 
769
                                        {
 
770
                                                sql += wxT(",\n   SEND=");
 
771
                                                AppendQuoted(sql, cbSend->GetValue());
 
772
                                        }
 
773
                                }
 
774
 
 
775
                        }
 
776
                        if (connection->BackendMinimumVersion(8, 3))
 
777
                        {
 
778
                                if (cbTypmodin->GetCurrentSelection() > 0 || cbTypmodout->GetCurrentSelection() > 0)
 
779
                                {
 
780
                                        if (cbTypmodin->GetCurrentSelection() > 0)
 
781
                                        {
 
782
                                                sql += wxT(",\n   TYPMOD_IN=");
 
783
                                                AppendQuoted(sql, cbTypmodin->GetValue());
 
784
                                                if (cbTypmodout->GetCurrentSelection() > 0)
 
785
                                                {
 
786
                                                        sql += wxT(", TYPMOD_OUT=");
 
787
                                                        AppendQuoted(sql, cbTypmodout->GetValue());
 
788
                                                }
 
789
                                        }
 
790
                                        else
 
791
                                        {
 
792
                                                sql += wxT(",\n   TYPMOD_OUT=");
 
793
                                                AppendQuoted(sql, cbTypmodout->GetValue());
 
794
                                        }
 
795
                                }
 
796
 
 
797
                        }
 
798
                        sql += wxT(",\n    INTERNALLENGTH=");
 
799
                        if (chkVariable->GetValue())
 
800
                                sql += wxT("VARIABLE");
 
801
                        else
 
802
                                sql += txtLength->GetValue();
 
803
                        AppendIfFilled(sql, wxT(",\n    DEFAULT="), txtDefault->GetValue());
 
804
                        if (!cbElement->GetValue().IsEmpty())
 
805
                        {
 
806
                                sql += wxT(",\n    ELEMENT=");
 
807
                                AppendQuoted(sql, cbElement->GetValue());
 
808
                                AppendIfFilled(sql, wxT(", DELIMITER="), qtDbString(txtDelimiter->GetValue().Strip(wxString::both)));
 
809
                        }
 
810
                        if (chkByValue->GetValue())
 
811
                                sql += wxT(",\n    PASSEDBYVALUE");
 
812
                        AppendIfFilled(sql, wxT(",\n    ALIGNMENT="), cbAlignment->GetValue());
 
813
                        AppendIfFilled(sql, wxT(",\n    STORAGE="), cbStorage->GetValue());
 
814
                        if (connection->BackendMinimumVersion(9, 1) && chkCollatable->GetValue())
 
815
                                sql += wxT(",\n    COLLATABLE=true");
 
816
                }
 
817
 
 
818
                sql += wxT(");\n");
 
819
        }
 
820
        AppendComment(sql, wxT("TYPE"), schema, type);
 
821
 
 
822
        return sql;
650
823
}
651
824
 
652
825
wxString dlgType::GetFullTypeName(int type)
653
826
{
654
 
    wxString typname = memberTypes.Item(type).AfterFirst(':');
655
 
 
656
 
    if (!memberLengths.Item(type).IsEmpty())
657
 
    {
658
 
        typname += wxT("(") + memberLengths.Item(type);
659
 
        if (!memberPrecisions.Item(type).IsEmpty())
660
 
            typname += wxT(", ") + memberPrecisions.Item(type);
661
 
        typname += wxT(")");
662
 
    }
663
 
 
664
 
    return typname;
665
 
}
666
 
 
 
827
        wxString typname = memberTypes.Item(type).AfterFirst(':');
 
828
 
 
829
        if (!memberLengths.Item(type).IsEmpty())
 
830
        {
 
831
                typname += wxT("(") + memberLengths.Item(type);
 
832
                if (!memberPrecisions.Item(type).IsEmpty())
 
833
                        typname += wxT(",") + memberPrecisions.Item(type);
 
834
                typname += wxT(")");
 
835
        }
 
836
        if (!memberPrecisions.Item(type).IsEmpty() && memberPrecisions.Item(type) != wxT("pg_catalog.\"default\""))
 
837
                typname += wxT(" COLLATE ") + memberCollations.Item(type);
 
838
 
 
839
        return typname;
 
840
}
 
841
 
 
842
wxString dlgType::GetSqlForTypes()
 
843
{
 
844
        wxString sql = wxEmptyString;
 
845
        wxString old_name, old_type, old_collation, new_name, new_type, new_collation;
 
846
        wxArrayString elements = type->GetTypesArray();
 
847
        bool modified = lstMembers->GetItemCount() * 3 != (int)elements.GetCount();
 
848
        size_t i;
 
849
 
 
850
        // Check if there is a change
 
851
        for (int i = 0 ; i < lstMembers->GetItemCount() && !modified; i++)
 
852
        {
 
853
                old_name = elements.Item(i * 3);
 
854
                old_type = elements.Item(i * 3 + 1);
 
855
                old_collation = elements.Item(i * 3 + 2);
 
856
                new_name = lstMembers->GetItemText(i);
 
857
                new_type = GetFullTypeName(i);
 
858
                new_collation = memberCollations.Item(i);
 
859
                modified = modified || old_name != new_name
 
860
                           || old_type != new_type
 
861
                           || old_collation != new_collation;
 
862
        }
 
863
 
 
864
        if (modified)
 
865
        {
 
866
                // Drop all old attributes
 
867
                for (i = 0 ; i < elements.GetCount() ; i += 3)
 
868
                {
 
869
                        old_name = elements.Item(i);
 
870
                        sql += wxT("ALTER TYPE ") + type->GetName() + wxT(" DROP ATTRIBUTE ") + old_name + wxT(";\n");
 
871
                }
 
872
 
 
873
                // Add all new attributes
 
874
                for (int i = 0 ; i < lstMembers->GetItemCount() ; i++)
 
875
                {
 
876
                        new_name = lstMembers->GetItemText(i);
 
877
                        new_type = GetFullTypeName(i);
 
878
                        new_collation = memberCollations.Item(i);
 
879
                        sql += wxT("ALTER TYPE ") + type->GetName() + wxT(" ADD ATTRIBUTE ")
 
880
                               + new_name + wxT(" ") + new_type;
 
881
                        if (!new_collation.IsEmpty() && new_collation != wxT("pg_catalog.\"default\""))
 
882
                                sql += wxT(" COLLATE ") + new_collation;
 
883
                        sql += wxT(";\n");
 
884
                }
 
885
        }
 
886
 
 
887
        return sql;
 
888
}