1
//////////////////////////////////////////////////////////////////////////
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
8
//////////////////////////////////////////////////////////////////////////
12
#include "pgscript/objects/pgsString.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"
20
pgsString::pgsString(const wxString & data) :
21
pgsVariable(pgsVariable::pgsTString), m_data(data)
26
pgsString::~pgsString()
31
pgsVariable * pgsString::clone() const
33
return pnew pgsString(*this);
36
wxString pgsString::value() const
41
pgsOperand pgsString::eval(pgsVarMap & vars) const
46
pgsOperand pgsString::pgs_plus(const pgsVariable & rhs) const
50
return pnew pgsString(m_data + rhs.value());
54
throw pgsArithmeticException(m_data, rhs.value());
58
pgsOperand pgsString::pgs_minus(const pgsVariable & rhs) const
60
throw pgsArithmeticException(m_data, rhs.value());
63
pgsOperand pgsString::pgs_times(const pgsVariable & rhs) const
65
throw pgsArithmeticException(m_data, rhs.value());
68
pgsOperand pgsString::pgs_over(const pgsVariable & rhs) const
70
throw pgsArithmeticException(m_data, rhs.value());
73
pgsOperand pgsString::pgs_modulo(const pgsVariable & rhs) const
75
throw pgsArithmeticException(m_data, rhs.value());
78
pgsOperand pgsString::pgs_equal(const pgsVariable & rhs) const
82
return pnew pgsNumber(m_data == rhs.value() ? wxT("1") : wxT("0"));
86
throw pgsArithmeticException(m_data, rhs.value());
90
pgsOperand pgsString::pgs_different(const pgsVariable & rhs) const
94
return pnew pgsNumber(m_data != rhs.value() ? wxT("1") : wxT("0"));
98
throw pgsArithmeticException(m_data, rhs.value());
102
pgsOperand pgsString::pgs_greater(const pgsVariable & rhs) const
106
return pnew pgsNumber(m_data > rhs.value() ? wxT("1") : wxT("0"));
110
throw pgsArithmeticException(m_data, rhs.value());
114
pgsOperand pgsString::pgs_lower(const pgsVariable & rhs) const
118
return pnew pgsNumber(m_data < rhs.value() ? wxT("1") : wxT("0"));
122
throw pgsArithmeticException(m_data, rhs.value());
126
pgsOperand pgsString::pgs_lower_equal(const pgsVariable & rhs) const
130
return pnew pgsNumber(m_data <= rhs.value() ? wxT("1") : wxT("0"));
134
throw pgsArithmeticException(m_data, rhs.value());
138
pgsOperand pgsString::pgs_greater_equal(const pgsVariable & rhs) const
142
return pnew pgsNumber(m_data >= rhs.value() ? wxT("1") : wxT("0"));
146
throw pgsArithmeticException(m_data, rhs.value());
150
pgsOperand pgsString::pgs_not() const
152
wxString data = m_data.Strip(wxString::both);
153
return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT(""));
156
bool pgsString::pgs_is_true() const
158
wxString data = m_data.Strip(wxString::both);
159
return (!data.IsEmpty() ? true : false);
162
pgsOperand pgsString::pgs_almost_equal(const pgsVariable & rhs) const
166
return pnew pgsNumber(m_data.CmpNoCase(rhs.value()) == 0
167
? wxT("1") : wxT("0"));
171
throw pgsArithmeticException(m_data, rhs.value());
175
pgsNumber pgsString::number() const
177
wxString data = m_data.Strip(wxString::both);
178
pgsTypes type = pgsNumber::num_type(data);
182
return pgsNumber(data, pgsInt);
184
return pgsNumber(data, pgsReal);
186
throw pgsCastException(data, wxT("number"));
190
pgsRecord pgsString::record() const
194
// Try to find the representation of a record in the string
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);
203
size_t line_nb = 0, nb_of_columns = 0;
204
bool count_columns = true;
205
while (regex1.Matches(data))
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))
213
if (count_columns == true)
219
if (column_nb < nb_of_columns && rec != 0)
221
wxString value(regex2.GetMatch(line));
222
if (value.StartsWith(wxT("\""))
223
&& value.EndsWith(wxT("\"")))
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));
234
// This is a number or a string
235
pgsTypes type = pgsNumber::num_type(value);
239
rec->insert(line_nb, column_nb,
240
pnew pgsNumber(value, pgsInt));
243
rec->insert(line_nb, column_nb,
244
pnew pgsNumber(value, pgsReal));
247
rec->insert(line_nb, column_nb,
248
pnew pgsString(value));
256
regex2.ReplaceFirst(&line, wxT(""));
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)
264
count_columns = false;
265
rec = pnew pgsRecord(nb_of_columns);
269
regex1.ReplaceFirst(&data, wxT(""));
278
rec = pnew pgsRecord(1);
279
rec->insert(0, 0, this->clone());
282
pgsRecord ret_val(*rec);
287
pgsString pgsString::string() const
289
return pgsString(*this);