pgsOperand pgsRemoveLine::eval(pgsVarMap &vars) const { if (vars.find(m_rec) != vars.end() && vars[m_rec]->is_record()) { pgsRecord &rec = dynamic_cast<pgsRecord &>(*vars[m_rec]); // Evaluate parameter pgsOperand line(m_line->eval(vars)); if (line->is_integer()) { long aux_line; line->value().ToLong(&aux_line); if (!rec.remove_line(aux_line)) { throw pgsParameterException(wxString() << wxT("an error ") << wxT("occurred while executing ") << value()); } } else { throw pgsParameterException(wxString() << line->value() << wxT(" is not a valid line number")); } return vars[m_rec]; } else { throw pgsParameterException(wxString() << m_rec << wxT(" is not a record")); } }
void pgsProgram::dump(const pgsVarMap &vars) { pgsVarMap::const_iterator it; for (it = vars.begin(); it != vars.end(); it++) { wxLogMessage(wxString() << it->first << wxT(" -> ") << it->second->value()); } }
pgsOperand pgsIdent::eval(pgsVarMap &vars) const { if (vars.find(m_name) != vars.end()) { return vars[m_name]; } else if (m_name == m_now) { time_t now = wxDateTime::GetTimeNow(); return pnew pgsNumber(wxString() << now); } else { return pnew pgsString(wxT("")); } }
pgsOperand pgsColumns::eval(pgsVarMap & vars) const { if (vars.find(m_name) != vars.end()) { if (vars[m_name]->is_record()) { const pgsRecord & rec = dynamic_cast<const pgsRecord &>(*vars[m_name]); return pnew pgsNumber(wxString() << rec.count_columns(), pgsInt); } else { // Not a record: 1 line and 1 column return pnew pgsNumber(wxT("1"), pgsInt); } } else { // Does not exist: 0 line and 0 column return pnew pgsNumber(wxT("0"), pgsInt); } }
pgsOperand pgsIdentRecord::eval(pgsVarMap &vars) const { // Check whether the variable is a record if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) { // Get the operand as a record const pgsRecord &rec = dynamic_cast<const pgsRecord &>(*vars[m_name]); // Evaluate parameters pgsOperand line(m_line->eval(vars)); if (line->is_integer()) { long aux_line; line->value().ToLong(&aux_line); if (m_column != 0) { pgsOperand column(m_column->eval(vars)); if (column->is_integer()) { long aux_column; column->value().ToLong(&aux_column); return rec.get(aux_line, aux_column); } else if (column->is_string()) { return rec.get(aux_line, rec.get_column(column->value())); } } else { return rec.get_line(aux_line); } } } return pnew pgsString(wxT("")); }
pgsOperand pgsAssignToRecord::eval(pgsVarMap &vars) const { if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) { // Get the operand as a record pgsRecord &rec = dynamic_cast<pgsRecord &>(*vars[m_name]); // Get the value to assign pgsOperand var(m_var->eval(vars)); if (!var->is_record()) { // Evaluate parameters pgsOperand line(m_line->eval(vars)); pgsOperand column(m_column->eval(vars)); if (line->is_integer()) { long aux_line; line->value().ToLong(&aux_line); if (column->is_integer() || column->is_string()) { bool success = false; if (column->is_integer()) { long aux_column; column->value().ToLong(&aux_column); if (aux_column < rec.count_columns()) { success = rec.insert(aux_line, aux_column, var); } } else if (column->is_string()) { USHORT aux_column = rec.get_column(column->value()); if (aux_column < rec.count_columns()) { success = rec.insert(aux_line, aux_column, var); } } if (success == false) { throw pgsParameterException(wxString() << wxT("An error ") << wxT("occurred in record affectation: ") << value() << wxT("\n") << wxT("One possible reason is a ") << wxT("column index out of range")); } } else { throw pgsParameterException(wxString() << column->value() << wxT(" is not a valid column number/name")); } } else { throw pgsParameterException(wxString() << line->value() << wxT(" is not a valid line number")); } } else { throw pgsParameterException(wxString() << wxT("Cannot assign a record") << wxT(" into a record: right member is a record")); } } else { throw pgsParameterException(wxString() << m_name << wxT(" is not a record")); } return pgsIdentRecord(m_name, m_line->clone(), m_column->clone()).eval(vars); }
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); }