~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/pgscript/objects/pgsString.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// pgScript - PostgreSQL Tools
 
4
// RCS-ID:      $Id: pgsString.cpp 7758 2009-03-26 20:49:59Z dpage $
 
5
// Copyright (C) 2002 - 2009, The pgAdmin Development Team
 
6
// This software is released under the BSD Licence
 
7
//
 
8
//////////////////////////////////////////////////////////////////////////
 
9
 
 
10
 
 
11
#include "pgAdmin3.h"
 
12
#include "pgscript/objects/pgsString.h"
 
13
 
 
14
#include <wx/regex.h>
 
15
#include "pgscript/objects/pgsNumber.h"
 
16
#include "pgscript/objects/pgsRecord.h"
 
17
#include "pgscript/exceptions/pgsArithmeticException.h"
 
18
#include "pgscript/exceptions/pgsCastException.h"
 
19
 
 
20
pgsString::pgsString(const wxString & data) :
 
21
        pgsVariable(pgsVariable::pgsTString), m_data(data)
 
22
{
 
23
 
 
24
}
 
25
 
 
26
pgsString::~pgsString()
 
27
{
 
28
 
 
29
}
 
30
 
 
31
pgsVariable * pgsString::clone() const
 
32
{
 
33
        return pnew pgsString(*this);
 
34
}
 
35
 
 
36
wxString pgsString::value() const
 
37
{
 
38
        return m_data;
 
39
}
 
40
 
 
41
pgsOperand pgsString::eval(pgsVarMap & vars) const
 
42
{
 
43
        return this->clone();
 
44
}
 
45
 
 
46
pgsOperand pgsString::pgs_plus(const pgsVariable & rhs) const
 
47
{
 
48
        if (rhs.is_string())
 
49
        {
 
50
                return pnew pgsString(m_data + rhs.value());
 
51
        }
 
52
        else
 
53
        {
 
54
                throw pgsArithmeticException(m_data, rhs.value());
 
55
        }
 
56
}
 
57
 
 
58
pgsOperand pgsString::pgs_minus(const pgsVariable & rhs) const
 
59
{
 
60
        throw pgsArithmeticException(m_data, rhs.value());
 
61
}
 
62
 
 
63
pgsOperand pgsString::pgs_times(const pgsVariable & rhs) const
 
64
{
 
65
        throw pgsArithmeticException(m_data, rhs.value());
 
66
}
 
67
 
 
68
pgsOperand pgsString::pgs_over(const pgsVariable & rhs) const
 
69
{
 
70
        throw pgsArithmeticException(m_data, rhs.value());
 
71
}
 
72
 
 
73
pgsOperand pgsString::pgs_modulo(const pgsVariable & rhs) const
 
74
{
 
75
        throw pgsArithmeticException(m_data, rhs.value());
 
76
}
 
77
 
 
78
pgsOperand pgsString::pgs_equal(const pgsVariable & rhs) const
 
79
{
 
80
        if (rhs.is_string())
 
81
        {
 
82
                return pnew pgsNumber(m_data == rhs.value() ? wxT("1") : wxT("0"));
 
83
        }
 
84
        else
 
85
        {
 
86
                throw pgsArithmeticException(m_data, rhs.value());
 
87
        }
 
88
}
 
89
 
 
90
pgsOperand pgsString::pgs_different(const pgsVariable & rhs) const
 
91
{
 
92
        if (rhs.is_string())
 
93
        {
 
94
                return pnew pgsNumber(m_data != rhs.value() ? wxT("1") : wxT("0"));
 
95
        }
 
96
        else
 
97
        {
 
98
                throw pgsArithmeticException(m_data, rhs.value());
 
99
        }
 
100
}
 
101
 
 
102
pgsOperand pgsString::pgs_greater(const pgsVariable & rhs) const
 
103
{
 
104
        if (rhs.is_string())
 
105
        {
 
106
                return pnew pgsNumber(m_data > rhs.value() ? wxT("1") : wxT("0"));
 
107
        }
 
108
        else
 
109
        {
 
110
                throw pgsArithmeticException(m_data, rhs.value());
 
111
        }
 
112
}
 
113
 
 
114
pgsOperand pgsString::pgs_lower(const pgsVariable & rhs) const
 
115
{
 
116
        if (rhs.is_string())
 
117
        {
 
118
                return pnew pgsNumber(m_data < rhs.value() ? wxT("1") : wxT("0"));
 
119
        }
 
120
        else
 
121
        {
 
122
                throw pgsArithmeticException(m_data, rhs.value());
 
123
        }
 
124
}
 
125
 
 
126
pgsOperand pgsString::pgs_lower_equal(const pgsVariable & rhs) const
 
127
{
 
128
        if (rhs.is_string())
 
129
        {
 
130
                return pnew pgsNumber(m_data <= rhs.value() ? wxT("1") : wxT("0"));
 
131
        }
 
132
        else
 
133
        {
 
134
                throw pgsArithmeticException(m_data, rhs.value());
 
135
        }
 
136
}
 
137
 
 
138
pgsOperand pgsString::pgs_greater_equal(const pgsVariable & rhs) const
 
139
{
 
140
        if (rhs.is_string())
 
141
        {
 
142
                return pnew pgsNumber(m_data >= rhs.value() ? wxT("1") : wxT("0"));
 
143
        }
 
144
        else
 
145
        {
 
146
                throw pgsArithmeticException(m_data, rhs.value());
 
147
        }
 
148
}
 
149
 
 
150
pgsOperand pgsString::pgs_not() const
 
151
{
 
152
        wxString data = m_data.Strip(wxString::both);
 
153
        return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT(""));
 
154
}
 
155
 
 
156
bool pgsString::pgs_is_true() const
 
157
{
 
158
        wxString data = m_data.Strip(wxString::both);
 
159
        return (!data.IsEmpty() ? true : false);
 
160
}
 
161
 
 
162
pgsOperand pgsString::pgs_almost_equal(const pgsVariable & rhs) const
 
163
{
 
164
        if (rhs.is_string())
 
165
        {
 
166
                return pnew pgsNumber(m_data.CmpNoCase(rhs.value()) == 0
 
167
                                ? wxT("1") : wxT("0"));
 
168
        }
 
169
        else
 
170
        {
 
171
                throw pgsArithmeticException(m_data, rhs.value());
 
172
        }
 
173
}
 
174
 
 
175
pgsNumber pgsString::number() const
 
176
{
 
177
        wxString data = m_data.Strip(wxString::both);
 
178
        pgsTypes type = pgsNumber::num_type(data);
 
179
        switch (type)
 
180
        {
 
181
        case pgsTInt:
 
182
                return pgsNumber(data, pgsInt);
 
183
        case pgsTReal:
 
184
                return pgsNumber(data, pgsReal);
 
185
        default:
 
186
                throw pgsCastException(data, wxT("number"));
 
187
        }
 
188
}
 
189
 
 
190
pgsRecord pgsString::record() const
 
191
{
 
192
        pgsRecord * rec = 0;
 
193
        
 
194
        // Try to find the representation of a record in the string
 
195
        {
 
196
                wxString element(wxT("(\"([^\"\\\\]|\\\\.)*\")|((-|[a-zA-Z0-9\\+\\.])+)"));
 
197
                wxString data(m_data);
 
198
                wxRegEx regex1(wxString() << wxT("^[[:space:]]*\\([[:space:]]*(")
 
199
                                << element << wxT(")[[:space:]]*([,][[:space:]]*(")
 
200
                                << element << wxT(")[[:space:]]*)*\\)"), wxRE_DEFAULT | wxRE_ICASE);
 
201
                
 
202
                // Find each line
 
203
                size_t line_nb = 0, nb_of_columns = 0;
 
204
                bool count_columns = true;
 
205
                while (regex1.Matches(data))
 
206
                {
 
207
                        // Process that line: find each element
 
208
                        wxString line(regex1.GetMatch(data));
 
209
                        wxRegEx regex2(element);
 
210
                        size_t column_nb = 0;
 
211
                        while (regex2.Matches(line))
 
212
                        {
 
213
                                if (count_columns == true)
 
214
                                {
 
215
                                        ++nb_of_columns;
 
216
                                }
 
217
                                else
 
218
                                {
 
219
                                        if (column_nb < nb_of_columns && rec != 0)
 
220
                                        {
 
221
                                                wxString value(regex2.GetMatch(line));
 
222
                                                if (value.StartsWith(wxT("\""))
 
223
                                                                && value.EndsWith(wxT("\"")))
 
224
                                                {
 
225
                                                        // This is a string
 
226
                                                        value = value.Mid(1, value.Len() - 2);
 
227
                                                        value.Replace(wxT("\\\""), wxT("\""));
 
228
                                                        value.Replace(wxT("\\\\"), wxT("\\"));
 
229
                                                        rec->insert(line_nb, column_nb,
 
230
                                                                        pnew pgsString(value));
 
231
                                                }
 
232
                                                else
 
233
                                                {
 
234
                                                        // This is a number or a string
 
235
                                                        pgsTypes type = pgsNumber::num_type(value);
 
236
                                                        switch (type)
 
237
                                                        {
 
238
                                                        case pgsTInt:
 
239
                                                                rec->insert(line_nb, column_nb,
 
240
                                                                                pnew pgsNumber(value, pgsInt));
 
241
                                                                break;
 
242
                                                        case pgsTReal:
 
243
                                                                rec->insert(line_nb, column_nb,
 
244
                                                                                pnew pgsNumber(value, pgsReal));
 
245
                                                                break;
 
246
                                                        default:
 
247
                                                                rec->insert(line_nb, column_nb,
 
248
                                                                                pnew pgsString(value));
 
249
                                                                break;
 
250
                                                        }
 
251
                                                }
 
252
                                        }
 
253
                                        ++column_nb;
 
254
                                }
 
255
                                
 
256
                                regex2.ReplaceFirst(&line, wxT(""));
 
257
                        }
 
258
                        
 
259
                        // If it is the first loop we want to process this line a
 
260
                        // second time because the first one was meant to count
 
261
                        // the number of columns
 
262
                        if (count_columns == true)
 
263
                        {
 
264
                                count_columns = false;
 
265
                                rec = pnew pgsRecord(nb_of_columns);
 
266
                        }
 
267
                        else
 
268
                        {
 
269
                                regex1.ReplaceFirst(&data, wxT(""));
 
270
                                ++line_nb;
 
271
                        }
 
272
                }
 
273
        }
 
274
        
 
275
        // Process the case
 
276
        if (rec == 0)
 
277
        {
 
278
                rec = pnew pgsRecord(1);
 
279
                rec->insert(0, 0, this->clone());
 
280
        }
 
281
 
 
282
        pgsRecord ret_val(*rec);
 
283
        pdelete(rec);
 
284
        return ret_val;
 
285
}
 
286
 
 
287
pgsString pgsString::string() const
 
288
{
 
289
        return pgsString(*this);
 
290
}