pgsOperand pgsRecord::pgs_not() const { if (pgs_is_true()) { // A record with no line is false return pnew pgsRecord(count_columns()); } else { // A record with at least one line is true pgsRecord *copy = pnew pgsRecord(*this); copy->newline(); return copy; // Insert one line and return the record } }
pgsOperand pgsRecord::get_line(const USHORT &line) const { if (line < count_lines()) { pgsRecord *rec = pnew pgsRecord(count_columns()); rec->m_columns = this->m_columns; rec->newline(); rec->m_record[0] = this->m_record[line]; return rec; } else { return pnew pgsRecord(0); } }
void pgsDeclareRecordStmt::eval(pgsVarMap &vars) const { pgsRecord *rec = pnew pgsRecord(m_columns.size()); for (size_t i = 0; i < m_columns.GetCount(); i++) { rec->set_column_name(i, m_columns.Item(i)); } vars[m_rec] = rec; }
void pgsTestSuite::test_operator_number(void) { // From a number with a string { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsVariable * var1 = 0; var1 = pnew pgsString(wxT("5")); // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); pgsOperand op(pnew pgsNumber(wxT("0"))); TS_ASSERT((!(*op))->value() == wxT("1")); // [16] Almost equal try { (*var0 &= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number (integer) with a real number { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100"), pgsInt); pgsVariable * var1 = 0; var1 = pnew pgsNumber(wxT("5"), pgsReal); // [2] Addition TS_ASSERT((*var0 + *var1)->value() == wxT("105")); // [3] Subtraction TS_ASSERT((*var0 - *var1)->value() == wxT("95")); // [4] Multiplication TS_ASSERT((*var0 * *var1)->value() == wxT("500")); // [5] Division TS_ASSERT((*var0 / *var1)->value() == wxT("20")); // [6] Modulo TS_ASSERT((*var0 % *var1)->value() == wxT("0")); // [9] Equal TS_ASSERT((*var0 == *var1)->value() == wxT("0")); // [10] Different TS_ASSERT((*var0 != *var1)->value() == wxT("1")); // [11] Lower TS_ASSERT((*var0 < *var1)->value() == wxT("0")); // [12] Greater TS_ASSERT((*var0 > *var1)->value() == wxT("1")); // [13] Lower or equal TS_ASSERT((*var0 <= *var1)->value() == wxT("0")); // [14] Greater or equal TS_ASSERT((*var0 >= *var1)->value() == wxT("1")); // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); // [16] Almost equal TS_ASSERT((*var0 &= *var1)->value() == wxT("0")); // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with a record { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsRecord * rec = 0; rec = pnew pgsRecord(1); rec->insert(0, 0, pnew pgsString(wxT("5"))); pgsVariable * var1 = 0; var1 = rec; // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); // [16] Almost equal try { (*var0 &= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with a record { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsRecord * rec = 0; rec = pnew pgsRecord(1); rec->insert(0, 0, pnew pgsNumber(wxT("5"))); rec->insert(1, 0, pnew pgsNumber(wxT("1"))); pgsVariable * var1 = 0; var1 = rec; // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with a string generator { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsStringGen * gen = 0; gen = pnew pgsStringGen(10, 20); pgsVariable * var1 = 0; var1 = pnew pgsGenerator(pgsVariable::pgsTString, gen); // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with an integer generator { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsIntegerGen * gen = 0; gen = pnew pgsIntegerGen(5, 5); pgsVariable * var1 = 0; var1 = pnew pgsGenerator(pgsVariable::pgsTInt, gen); // [2] Addition TS_ASSERT((*var0 + *var1)->value() == wxT("105")); // [3] Subtraction TS_ASSERT((*var0 - *var1)->value() == wxT("95")); // [4] Multiplication TS_ASSERT((*var0 * *var1)->value() == wxT("500")); // [5] Division TS_ASSERT((*var0 / *var1)->value() == wxT("20")); // [6] Modulo TS_ASSERT((*var0 % *var1)->value() == wxT("0")); // [9] Equal TS_ASSERT((*var0 == *var1)->value() == wxT("0")); // [10] Different TS_ASSERT((*var0 != *var1)->value() == wxT("1")); // [11] Lower TS_ASSERT((*var0 < *var1)->value() == wxT("0")); // [12] Greater TS_ASSERT((*var0 > *var1)->value() == wxT("1")); // [13] Lower or equal TS_ASSERT((*var0 <= *var1)->value() == wxT("0")); // [14] Greater or equal TS_ASSERT((*var0 >= *var1)->value() == wxT("1")); // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); // [16] Almost equal TS_ASSERT((*var0 &= *var1)->value() == wxT("0")); // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } }
pgsRecord pgsRecord::record() const { return pgsRecord(*this); }
pgsVariable *pgsRecord::clone() const { return pnew pgsRecord(*this); }
pgsRecord pgsString::record() const { pgsRecord *rec = 0; // Try to find the representation of a record in the string { wxString element(wxT("(\"([^\"\\\\]|\\\\.)*\")|((-|[a-zA-Z0-9\\+\\.])+)")); wxString data(m_data); wxRegEx regex1(wxString() << wxT("^[[:space:]]*\\([[:space:]]*(") << element << wxT(")[[:space:]]*([,][[:space:]]*(") << element << wxT(")[[:space:]]*)*\\)"), wxRE_DEFAULT | wxRE_ICASE); // Find each line size_t line_nb = 0, nb_of_columns = 0; bool count_columns = true; while (regex1.Matches(data)) { // Process that line: find each element wxString line(regex1.GetMatch(data)); wxRegEx regex2(element); size_t column_nb = 0; while (regex2.Matches(line)) { if (count_columns == true) { ++nb_of_columns; } else { if (column_nb < nb_of_columns && rec != 0) { wxString value(regex2.GetMatch(line)); if (value.StartsWith(wxT("\"")) && value.EndsWith(wxT("\""))) { // This is a string value = value.Mid(1, value.Len() - 2); value.Replace(wxT("\\\""), wxT("\"")); value.Replace(wxT("\\\\"), wxT("\\")); rec->insert(line_nb, column_nb, pnew pgsString(value)); } else { // This is a number or a string pgsTypes type = pgsNumber::num_type(value); switch (type) { case pgsTInt: rec->insert(line_nb, column_nb, pnew pgsNumber(value, pgsInt)); break; case pgsTReal: rec->insert(line_nb, column_nb, pnew pgsNumber(value, pgsReal)); break; default: rec->insert(line_nb, column_nb, pnew pgsString(value)); break; } } } ++column_nb; } regex2.ReplaceFirst(&line, wxT("")); } // If it is the first loop we want to process this line a // second time because the first one was meant to count // the number of columns if (count_columns == true) { count_columns = false; rec = pnew pgsRecord(nb_of_columns); } else { regex1.ReplaceFirst(&data, wxT("")); ++line_nb; } } } // Process the case if (rec == 0) { rec = pnew pgsRecord(1); rec->insert(0, 0, this->clone()); } pgsRecord ret_val(*rec); pdelete(rec); return ret_val; }
pgsOperand pgsExecute::eval(pgsVarMap &vars) const { // Copy statement locally wxString stmt(m_query); // Build regular expressions wxRegEx identifier(wxT("([^\\])(@[a-zA-Z0-9_#@]+)")); wxRegEx escaped(wxT("\\\\(@|\\\\)")); // Backslash followed by @ or backslash wxASSERT(identifier.IsValid() && escaped.IsValid()); // Replace variables in statement while (identifier.Matches(stmt)) { wxString var = identifier.GetMatch(stmt, 2); wxString chr = identifier.GetMatch(stmt, 1); if (vars.find(var) != vars.end()) { wxString res = vars[var]->eval(vars)->value(); identifier.ReplaceFirst(&stmt, chr + pgsUtilities::escape_quotes(res)); } else { identifier.ReplaceFirst(&stmt, chr + wxT("\\\\") + var); } } escaped.ReplaceAll(&stmt, wxT("\\1")); // Perform operations only if we have a valid connection if (m_app != 0 && m_app->connection() != 0 && !m_app->TestDestroy()) { pgQueryThread thread(m_app->connection(), stmt); if (thread.Create() == wxTHREAD_NO_ERROR) { if (thread.Run() == wxTHREAD_NO_ERROR) { while (true) { if (m_app->TestDestroy()) // wxThread::TestDestroy() { thread.Delete(); break; } else if (thread.IsRunning()) { m_app->Yield(); m_app->Sleep(20); } else { thread.Wait(); break; } } if (thread.ReturnCode() != PGRES_COMMAND_OK && thread.ReturnCode() != PGRES_TUPLES_OK) { if (m_cout != 0) { m_app->LockOutput(); (*m_cout) << PGSOUTWARNING; wxString message(stmt + wxT("\n") + thread .GetMessagesAndClear().Strip(wxString::both)); wxRegEx multilf(wxT("(\n)+")); multilf.ReplaceAll(&message, wxT("\n")); message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTWARNING.Length())); (*m_cout) << message << wxT("\n"); m_app->UnlockOutput(); } } else if (!m_app->TestDestroy()) { if (m_cout != 0) { m_app->LockOutput(); (*m_cout) << PGSOUTQUERY; wxString message(thread.GetMessagesAndClear() .Strip(wxString::both)); if (!message.IsEmpty()) message = stmt + wxT("\n") + message; else message = stmt; wxRegEx multilf(wxT("(\n)+")); multilf.ReplaceAll(&message, wxT("\n")); message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTQUERY.Length())); (*m_cout) << message << wxT("\n"); m_app->UnlockOutput(); } pgsRecord *rec = 0; if (thread.DataValid()) { pgSet *set = thread.DataSet(); set->MoveFirst(); rec = pnew pgsRecord(set->NumCols()); wxArrayLong columns_int; // List of columns that contain integers wxArrayLong columns_real; // List of columns that contain reals for (long i = 0; i < set->NumCols(); i++) { rec->set_column_name(i, set->ColName(i)); wxString col_type = set->ColType(i); if (!col_type.CmpNoCase(wxT("bigint")) || !col_type.CmpNoCase(wxT("smallint")) || !col_type.CmpNoCase(wxT("integer"))) { columns_int.Add(i); } else if (!col_type.CmpNoCase(wxT("real")) || !col_type.CmpNoCase(wxT("double precision")) || !col_type.CmpNoCase(wxT("money")) || !col_type.CmpNoCase(wxT("numeric"))) { columns_real.Add(i); } } size_t line = 0; while (!set->Eof()) { for (long i = 0; i < set->NumCols(); i++) { wxString value = set->GetVal(i); if (columns_int.Index(i) != wxNOT_FOUND && pgsNumber::num_type(value) == pgsNumber::pgsTInt) { rec->insert(line, i, pnew pgsNumber(value, pgsInt)); } else if (columns_real.Index(i) != wxNOT_FOUND && pgsNumber::num_type(value) == pgsNumber::pgsTReal) { rec->insert(line, i, pnew pgsNumber(value, pgsReal)); } else { rec->insert(line, i, pnew pgsString(value)); } } set->MoveNext(); ++line; } } else { rec = pnew pgsRecord(1); rec->insert(0, 0, pnew pgsNumber(wxT("1"))); } return rec; } } else { wxLogError(wxT("PGSCRIPT: Cannot run query thread for the query:\n%s"), m_query.c_str()); } } else { wxLogError(wxT("PGSCRIPT: Cannot create query thread for the query:\n%s"), m_query.c_str()); } } // This must return a record whatever happens return pnew pgsRecord(1); }