Exemple #1
0
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
	}
}
Exemple #2
0
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);
	}
}
Exemple #5
0
pgsRecord pgsRecord::record() const
{
	return pgsRecord(*this);
}
Exemple #6
0
pgsVariable *pgsRecord::clone() const
{
	return pnew pgsRecord(*this);
}
Exemple #7
0
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;
}
Exemple #8
0
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);
}