mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 14:15:49 -06:00
support PG11
Поддержка PostgreSQL 11 только для Windows
This commit is contained in:
commit
4af765213c
1765 changed files with 407959 additions and 0 deletions
10
pgscript/README
Normal file
10
pgscript/README
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
Please refer to xtra/pgscript/doc/developers.html for the pgScript developer
|
||||
documentation.
|
||||
|
||||
parser.sh must be called for regenerating Flex and Bison source files because it
|
||||
does some more processing than just executing Bison and Flex: it replaces some
|
||||
headers and add other ones.
|
||||
|
||||
Please use Flex 2.5.33 otherwise the pgadmin/include/pgscript/FlexLexer.h file
|
||||
will not be valid. If you use a different version from 2.5.33 you need to copy FlexLexer.h that comes along with your Flex distribution to
|
||||
pgadmin/include/pgscript.
|
||||
24
pgscript/exceptions/module.mk
Normal file
24
pgscript/exceptions/module.mk
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/pgscript/exceptions/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
pgscript/exceptions/pgsArithmeticException.cpp \
|
||||
pgscript/exceptions/pgsAssertException.cpp \
|
||||
pgscript/exceptions/pgsBreakException.cpp \
|
||||
pgscript/exceptions/pgsCastException.cpp \
|
||||
pgscript/exceptions/pgsContinueException.cpp \
|
||||
pgscript/exceptions/pgsException.cpp \
|
||||
pgscript/exceptions/pgsInterruptException.cpp \
|
||||
pgscript/exceptions/pgsParameterException.cpp
|
||||
|
||||
EXTRA_DIST += \
|
||||
pgscript/exceptions/module.mk
|
||||
|
||||
30
pgscript/exceptions/pgsArithmeticException.cpp
Normal file
30
pgscript/exceptions/pgsArithmeticException.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsArithmeticException.h"
|
||||
|
||||
pgsArithmeticException::pgsArithmeticException(const wxString &left, const wxString &right) :
|
||||
pgsException(), m_left(left), m_right(right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsArithmeticException::~pgsArithmeticException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsArithmeticException::message() const
|
||||
{
|
||||
return wxString() << PGSOUTEXCEPTION <<
|
||||
wxString::Format(_("Arithmetic Exception - Operation impossible between '%s' and '%s'"),
|
||||
m_left.c_str(), m_right.c_str());
|
||||
}
|
||||
28
pgscript/exceptions/pgsAssertException.cpp
Normal file
28
pgscript/exceptions/pgsAssertException.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsAssertException.h"
|
||||
|
||||
pgsAssertException::pgsAssertException(const wxString &message) :
|
||||
m_message(message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsAssertException::~pgsAssertException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsAssertException::message() const
|
||||
{
|
||||
return wxString() << PGSOUTEXCEPTION << _("Assert Exception - ") << m_message;
|
||||
}
|
||||
28
pgscript/exceptions/pgsBreakException.cpp
Normal file
28
pgscript/exceptions/pgsBreakException.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsBreakException.h"
|
||||
|
||||
pgsBreakException::pgsBreakException() :
|
||||
pgsException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsBreakException::~pgsBreakException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsBreakException::message() const
|
||||
{
|
||||
return wxT("BREAK");
|
||||
}
|
||||
30
pgscript/exceptions/pgsCastException.cpp
Normal file
30
pgscript/exceptions/pgsCastException.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsCastException.h"
|
||||
|
||||
pgsCastException::pgsCastException(const wxString &value, const wxString &type) :
|
||||
pgsException(), m_value(value), m_type(type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsCastException::~pgsCastException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsCastException::message() const
|
||||
{
|
||||
return wxString() << PGSOUTEXCEPTION <<
|
||||
wxString::Format(_("Cast Exception - Cannot convert '%s' to '%s'"),
|
||||
m_value.c_str(), m_type.c_str());
|
||||
}
|
||||
28
pgscript/exceptions/pgsContinueException.cpp
Normal file
28
pgscript/exceptions/pgsContinueException.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsContinueException.h"
|
||||
|
||||
pgsContinueException::pgsContinueException() :
|
||||
pgsException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsContinueException::~pgsContinueException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsContinueException::message() const
|
||||
{
|
||||
return wxT("CONTINUE");
|
||||
}
|
||||
22
pgscript/exceptions/pgsException.cpp
Normal file
22
pgscript/exceptions/pgsException.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsException.h"
|
||||
|
||||
pgsException::pgsException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsException::~pgsException()
|
||||
{
|
||||
|
||||
}
|
||||
28
pgscript/exceptions/pgsInterruptException.cpp
Normal file
28
pgscript/exceptions/pgsInterruptException.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/exceptions/pgsInterruptException.h"
|
||||
|
||||
pgsInterruptException::pgsInterruptException() :
|
||||
pgsException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsInterruptException::~pgsInterruptException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsInterruptException::message() const
|
||||
{
|
||||
return wxString() << PGSOUTEXCEPTION << _("pgScript interrupted");
|
||||
}
|
||||
35
pgscript/exceptions/pgsParameterException.cpp
Normal file
35
pgscript/exceptions/pgsParameterException.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "utils/misc.h"
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
|
||||
pgsParameterException::pgsParameterException(const wxString &message) :
|
||||
pgsException(), m_message(message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsParameterException::~pgsParameterException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const wxString pgsParameterException::message() const
|
||||
{
|
||||
wxString message(m_message);
|
||||
message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTEXCEPTION.Length()));
|
||||
message.Prepend(wxT(">> "));
|
||||
message.Prepend(generate_spaces(PGSOUTEXCEPTION.Length()));
|
||||
return wxString() << PGSOUTEXCEPTION <<
|
||||
wxString::Format(_("Parameter Exception - Some parameters are invalid:\n%s"),
|
||||
message.c_str());
|
||||
}
|
||||
53
pgscript/expressions/module.mk
Normal file
53
pgscript/expressions/module.mk
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/pgscript/expressions/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
pgscript/expressions/pgsAnd.cpp \
|
||||
pgscript/expressions/pgsAssign.cpp \
|
||||
pgscript/expressions/pgsAssignToRecord.cpp \
|
||||
pgscript/expressions/pgsCast.cpp \
|
||||
pgscript/expressions/pgsColumns.cpp \
|
||||
pgscript/expressions/pgsDifferent.cpp \
|
||||
pgscript/expressions/pgsEqual.cpp \
|
||||
pgscript/expressions/pgsExecute.cpp \
|
||||
pgscript/expressions/pgsExpression.cpp \
|
||||
pgscript/expressions/pgsGenDate.cpp \
|
||||
pgscript/expressions/pgsGenDateTime.cpp \
|
||||
pgscript/expressions/pgsGenDictionary.cpp \
|
||||
pgscript/expressions/pgsGenInt.cpp \
|
||||
pgscript/expressions/pgsGenReal.cpp \
|
||||
pgscript/expressions/pgsGenReference.cpp \
|
||||
pgscript/expressions/pgsGenRegex.cpp \
|
||||
pgscript/expressions/pgsGenString.cpp \
|
||||
pgscript/expressions/pgsGenTime.cpp \
|
||||
pgscript/expressions/pgsGreater.cpp \
|
||||
pgscript/expressions/pgsGreaterEqual.cpp \
|
||||
pgscript/expressions/pgsIdent.cpp \
|
||||
pgscript/expressions/pgsIdentRecord.cpp \
|
||||
pgscript/expressions/pgsLines.cpp \
|
||||
pgscript/expressions/pgsLower.cpp \
|
||||
pgscript/expressions/pgsLowerEqual.cpp \
|
||||
pgscript/expressions/pgsMinus.cpp \
|
||||
pgscript/expressions/pgsModulo.cpp \
|
||||
pgscript/expressions/pgsNegate.cpp \
|
||||
pgscript/expressions/pgsNot.cpp \
|
||||
pgscript/expressions/pgsOperation.cpp \
|
||||
pgscript/expressions/pgsOr.cpp \
|
||||
pgscript/expressions/pgsOver.cpp \
|
||||
pgscript/expressions/pgsParenthesis.cpp \
|
||||
pgscript/expressions/pgsPlus.cpp \
|
||||
pgscript/expressions/pgsRemoveLine.cpp \
|
||||
pgscript/expressions/pgsTimes.cpp \
|
||||
pgscript/expressions/pgsTrim.cpp
|
||||
|
||||
EXTRA_DIST += \
|
||||
pgscript/expressions/module.mk
|
||||
|
||||
57
pgscript/expressions/pgsAnd.cpp
Normal file
57
pgscript/expressions/pgsAnd.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsAnd.h"
|
||||
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
|
||||
pgsAnd::pgsAnd(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsAnd::~pgsAnd()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsAnd::clone() const
|
||||
{
|
||||
return pnew pgsAnd(*this);
|
||||
}
|
||||
|
||||
pgsAnd::pgsAnd(const pgsAnd &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsAnd &pgsAnd::operator =(const pgsAnd &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsAnd::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" AND ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsAnd::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return pnew pgsNumber(wxString() << (m_left->eval(vars)->pgs_is_true()
|
||||
&& m_right->eval(vars)->pgs_is_true()), pgsInt);
|
||||
}
|
||||
59
pgscript/expressions/pgsAssign.cpp
Normal file
59
pgscript/expressions/pgsAssign.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsAssign.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsAssign::pgsAssign(const wxString &name, const pgsExpression *var) :
|
||||
pgsExpression(), m_name(name), m_var(var)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsAssign::~pgsAssign()
|
||||
{
|
||||
pdelete(m_var);
|
||||
}
|
||||
|
||||
pgsExpression *pgsAssign::clone() const
|
||||
{
|
||||
return pnew pgsAssign(*this);
|
||||
}
|
||||
|
||||
pgsAssign::pgsAssign(const pgsAssign &that) :
|
||||
pgsExpression(that), m_name(that.m_name)
|
||||
{
|
||||
m_var = that.m_var->clone();
|
||||
}
|
||||
|
||||
pgsAssign &pgsAssign::operator =(const pgsAssign &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
m_name = that.m_name;
|
||||
pdelete(m_var);
|
||||
m_var = that.m_var->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsAssign::value() const
|
||||
{
|
||||
return wxString() << wxT("SET ") << m_name << wxT(" = ") << m_var->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsAssign::eval(pgsVarMap &vars) const
|
||||
{
|
||||
vars[m_name] = m_var->eval(vars);
|
||||
return vars[m_name];
|
||||
}
|
||||
138
pgscript/expressions/pgsAssignToRecord.cpp
Normal file
138
pgscript/expressions/pgsAssignToRecord.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsAssignToRecord.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/expressions/pgsIdentRecord.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
|
||||
pgsAssignToRecord::pgsAssignToRecord(const wxString &name, const pgsExpression *line,
|
||||
const pgsExpression *column, const pgsExpression *var) :
|
||||
pgsAssign(name, var), m_line(line), m_column(column)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsAssignToRecord::~pgsAssignToRecord()
|
||||
{
|
||||
pdelete(m_line);
|
||||
pdelete(m_column);
|
||||
}
|
||||
|
||||
pgsExpression *pgsAssignToRecord::clone() const
|
||||
{
|
||||
return pnew pgsAssignToRecord(*this);
|
||||
}
|
||||
|
||||
pgsAssignToRecord::pgsAssignToRecord(const pgsAssignToRecord &that) :
|
||||
pgsAssign(that)
|
||||
{
|
||||
m_line = that.m_line->clone();
|
||||
m_column = that.m_column->clone();
|
||||
}
|
||||
|
||||
pgsAssignToRecord &pgsAssignToRecord::operator =(const pgsAssignToRecord &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsAssign::operator=(that);
|
||||
pdelete(m_line);
|
||||
pdelete(m_column);
|
||||
m_line = that.m_line->clone();
|
||||
m_column = that.m_column->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsAssignToRecord::value() const
|
||||
{
|
||||
return wxString() << wxT("SET ") << m_name << wxT("[") << m_line->value()
|
||||
<< wxT("]") << wxT("[") << m_column->value() << wxT("]")
|
||||
<< wxT(" = ") << m_var->value();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
100
pgscript/expressions/pgsCast.cpp
Normal file
100
pgscript/expressions/pgsCast.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsCast.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
|
||||
#include "pgscript/parser.tab.hh"
|
||||
typedef pgscript::pgsParser::token token;
|
||||
|
||||
pgsCast::pgsCast(const int &cast_type, const pgsExpression *var) :
|
||||
pgsExpression(), m_cast_type(cast_type), m_var(var)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsCast::~pgsCast()
|
||||
{
|
||||
pdelete(m_var);
|
||||
}
|
||||
|
||||
pgsExpression *pgsCast::clone() const
|
||||
{
|
||||
return pnew pgsCast(*this);
|
||||
}
|
||||
|
||||
pgsCast::pgsCast(const pgsCast &that) :
|
||||
pgsExpression(that), m_cast_type(that.m_cast_type)
|
||||
{
|
||||
m_var = that.m_var->clone();
|
||||
}
|
||||
|
||||
pgsCast &pgsCast::operator =(const pgsCast &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
m_cast_type = that.m_cast_type;
|
||||
pdelete(m_var);
|
||||
m_var = that.m_var->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsCast::value() const
|
||||
{
|
||||
wxString cast_type;
|
||||
|
||||
switch (m_cast_type)
|
||||
{
|
||||
case token::PGS_INTEGER:
|
||||
cast_type = wxT("integer");
|
||||
break;
|
||||
case token::PGS_REAL:
|
||||
cast_type = wxT("real");
|
||||
break;
|
||||
case token::PGS_RECORD:
|
||||
cast_type = wxT("record");
|
||||
break;
|
||||
case token::PGS_STRING:
|
||||
cast_type = wxT("string");
|
||||
break;
|
||||
default:
|
||||
cast_type = wxT("unknown");
|
||||
break;
|
||||
}
|
||||
return wxString() << wxT("CAST (") << m_var->value() << wxT(" AS ")
|
||||
<< cast_type.Upper() << wxT(") ");
|
||||
}
|
||||
|
||||
pgsOperand pgsCast::eval(pgsVarMap &vars) const
|
||||
{
|
||||
pgsOperand var = m_var->eval(vars);
|
||||
MAPM num;
|
||||
|
||||
switch (m_cast_type)
|
||||
{
|
||||
case token::PGS_INTEGER:
|
||||
num = pgsMapm::pgs_str_mapm(var->number().value());
|
||||
num = pgsMapm::pgs_mapm_round(num);
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num, true), pgsInt);
|
||||
case token::PGS_REAL:
|
||||
return pnew pgsNumber(var->number().value(), pgsReal);
|
||||
case token::PGS_RECORD:
|
||||
return var->record().clone();
|
||||
case token::PGS_STRING:
|
||||
return var->string().clone();
|
||||
default:
|
||||
return var->clone();
|
||||
}
|
||||
}
|
||||
58
pgscript/expressions/pgsColumns.cpp
Normal file
58
pgscript/expressions/pgsColumns.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsColumns.h"
|
||||
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
|
||||
pgsColumns::pgsColumns(const wxString &name) :
|
||||
pgsExpression(), m_name(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsColumns::~pgsColumns()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsColumns::clone() const
|
||||
{
|
||||
return pnew pgsColumns(*this);
|
||||
}
|
||||
|
||||
wxString pgsColumns::value() const
|
||||
{
|
||||
return wxString() << wxT("COLUMNS(") << m_name << 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);
|
||||
}
|
||||
}
|
||||
60
pgscript/expressions/pgsDifferent.cpp
Normal file
60
pgscript/expressions/pgsDifferent.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsDifferent.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsDifferent::pgsDifferent(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsDifferent::~pgsDifferent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsDifferent::clone() const
|
||||
{
|
||||
return pnew pgsDifferent(*this);
|
||||
}
|
||||
|
||||
pgsDifferent::pgsDifferent(const pgsDifferent &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsDifferent &pgsDifferent::operator =(const pgsDifferent &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsDifferent::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" <> ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsDifferent::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left != *right);
|
||||
}
|
||||
65
pgscript/expressions/pgsEqual.cpp
Normal file
65
pgscript/expressions/pgsEqual.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsEqual.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsEqual::pgsEqual(const pgsExpression *left, const pgsExpression *right,
|
||||
bool case_sensitive) :
|
||||
pgsOperation(left, right), m_case_sensitive(case_sensitive)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsEqual::~pgsEqual()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsEqual::clone() const
|
||||
{
|
||||
return pnew pgsEqual(*this);
|
||||
}
|
||||
|
||||
pgsEqual::pgsEqual(const pgsEqual &that) :
|
||||
pgsOperation(that), m_case_sensitive(that.m_case_sensitive)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsEqual &pgsEqual::operator =(const pgsEqual &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
const pgsEqual *p = dynamic_cast<const pgsEqual *>(&that);
|
||||
m_case_sensitive = (p != 0) ?
|
||||
p->m_case_sensitive : true;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsEqual::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << (m_case_sensitive ? wxT(" = ")
|
||||
: wxT(" ~= ")) << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsEqual::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (m_case_sensitive ? (*left == *right) : (*left &= *right));
|
||||
}
|
||||
230
pgscript/expressions/pgsExecute.cpp
Normal file
230
pgscript/expressions/pgsExecute.cpp
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsExecute.h"
|
||||
|
||||
#include <wx/regex.h>
|
||||
#include "db/pgConn.h"
|
||||
#include "db/pgQueryThread.h"
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
#include "pgscript/utilities/pgsUtilities.h"
|
||||
#include "pgscript/utilities/pgsThread.h"
|
||||
|
||||
pgsExecute::pgsExecute(const wxString &query, pgsOutputStream *cout,
|
||||
pgsThread *app) :
|
||||
pgsExpression(), m_query(query), m_cout(cout), m_app(app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExecute::~pgsExecute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsExecute::clone() const
|
||||
{
|
||||
return pnew pgsExecute(*this);
|
||||
}
|
||||
|
||||
pgsExecute &pgsExecute::operator=(const pgsExecute &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
m_query = that.m_query;
|
||||
m_app = that.m_app;
|
||||
m_query = that.m_query;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsExecute::value() const
|
||||
{
|
||||
return m_query;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
23
pgscript/expressions/pgsExpression.cpp
Normal file
23
pgscript/expressions/pgsExpression.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsExpression.h"
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsExpression::pgsExpression()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression::~pgsExpression()
|
||||
{
|
||||
|
||||
}
|
||||
123
pgscript/expressions/pgsGenDate.cpp
Normal file
123
pgscript/expressions/pgsGenDate.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenDate.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsDateGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenDate::pgsGenDate(const pgsExpression *min, const pgsExpression *max,
|
||||
const pgsExpression *sequence, const pgsExpression *seed) :
|
||||
pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenDate::~pgsGenDate()
|
||||
{
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenDate::clone() const
|
||||
{
|
||||
return pnew pgsGenDate(*this);
|
||||
}
|
||||
|
||||
pgsGenDate::pgsGenDate(const pgsGenDate &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenDate &pgsGenDate::operator =(const pgsGenDate &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenDate::value() const
|
||||
{
|
||||
return wxString() << wxT("date[ min = ") << m_min->value() << wxT(" max = ")
|
||||
<< m_max->value() << wxT(" sequence = ") << m_sequence->value()
|
||||
<< wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenDate::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand min(m_min->eval(vars));
|
||||
pgsOperand max(m_max->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (min->is_string() && max->is_string() && sequence->is_integer()
|
||||
&& seed->is_integer())
|
||||
{
|
||||
wxDateTime aux_min, aux_max;
|
||||
if (aux_min.ParseDate(min->value()) != 0 && aux_max.ParseDate(max->value()) != 0
|
||||
&& aux_min.IsValid() && aux_max.IsValid())
|
||||
{
|
||||
long aux_sequence, aux_seed;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString,
|
||||
pnew pgsDateGen(aux_min, aux_max, aux_sequence != 0, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin and/or max dates are not valid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!min->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin should be a string"));
|
||||
}
|
||||
else if (!max->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmax should be a string"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
123
pgscript/expressions/pgsGenDateTime.cpp
Normal file
123
pgscript/expressions/pgsGenDateTime.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenDateTime.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsDateTimeGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenDateTime::pgsGenDateTime(const pgsExpression *min, const pgsExpression *max,
|
||||
const pgsExpression *sequence, const pgsExpression *seed) :
|
||||
pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenDateTime::~pgsGenDateTime()
|
||||
{
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenDateTime::clone() const
|
||||
{
|
||||
return pnew pgsGenDateTime(*this);
|
||||
}
|
||||
|
||||
pgsGenDateTime::pgsGenDateTime(const pgsGenDateTime &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenDateTime &pgsGenDateTime::operator =(const pgsGenDateTime &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenDateTime::value() const
|
||||
{
|
||||
return wxString() << wxT("date_time[ min = ") << m_min->value() << wxT(" max = ")
|
||||
<< m_max->value() << wxT(" sequence = ") << m_sequence->value()
|
||||
<< wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenDateTime::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand min(m_min->eval(vars));
|
||||
pgsOperand max(m_max->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (min->is_string() && max->is_string() && sequence->is_integer()
|
||||
&& seed->is_integer())
|
||||
{
|
||||
wxDateTime aux_min, aux_max;
|
||||
if (aux_min.ParseDateTime(min->value()) != 0 && aux_max.ParseDateTime(max->value()) != 0
|
||||
&& aux_min.IsValid() && aux_max.IsValid())
|
||||
{
|
||||
long aux_sequence, aux_seed;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString,
|
||||
pnew pgsDateTimeGen(aux_min, aux_max, aux_sequence != 0, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin and/or max datetimes are not valid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!min->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin should be a string"));
|
||||
}
|
||||
else if (!max->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmax should be a string"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
126
pgscript/expressions/pgsGenDictionary.cpp
Normal file
126
pgscript/expressions/pgsGenDictionary.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenDictionary.h"
|
||||
|
||||
#include <wx/filename.h>
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsDictionaryGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenDictionary::pgsGenDictionary(const pgsExpression *file_path, const pgsExpression *sequence,
|
||||
const pgsExpression *seed, const pgsExpression *wx_conv) :
|
||||
pgsExpression(), m_file_path(file_path), m_sequence(sequence), m_seed(seed),
|
||||
m_wx_conv(wx_conv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenDictionary::~pgsGenDictionary()
|
||||
{
|
||||
pdelete(m_file_path);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
pdelete(m_wx_conv);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenDictionary::clone() const
|
||||
{
|
||||
return pnew pgsGenDictionary(*this);
|
||||
}
|
||||
|
||||
pgsGenDictionary::pgsGenDictionary(const pgsGenDictionary &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_file_path = that.m_file_path->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
m_wx_conv = that.m_wx_conv->clone();
|
||||
}
|
||||
|
||||
pgsGenDictionary &pgsGenDictionary::operator =(const pgsGenDictionary &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_file_path);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
pdelete(m_wx_conv);
|
||||
m_file_path = that.m_file_path->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
m_wx_conv = that.m_wx_conv->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenDictionary::value() const
|
||||
{
|
||||
return wxString() << wxT("file[ file = ") << m_file_path->value() << wxT(" sequence = ")
|
||||
<< m_sequence->value() << wxT(" seed = ") << m_seed->value()
|
||||
<< wxT(" encoding = ") << m_wx_conv->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenDictionary::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand file_path(m_file_path->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
pgsOperand wx_conv(m_wx_conv->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (file_path->is_string() && sequence->is_integer() && seed->is_integer()
|
||||
&& wx_conv->is_string())
|
||||
{
|
||||
wxFileName file(file_path->value());
|
||||
if (file.FileExists() && file.IsFileReadable())
|
||||
{
|
||||
long aux_sequence, aux_seed;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString,
|
||||
pnew pgsDictionaryGen(file_path->value(), aux_sequence != 0,
|
||||
aux_seed, wxCSConv(wx_conv->value())));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nFile <") << file_path->value()
|
||||
<< wxT("> does not exist"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!file_path->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nfile should be a string"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else if (!seed->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nencoding should be a string"));
|
||||
}
|
||||
}
|
||||
}
|
||||
114
pgscript/expressions/pgsGenInt.cpp
Normal file
114
pgscript/expressions/pgsGenInt.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenInt.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsDictionaryGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenInt::pgsGenInt(const pgsExpression *min, const pgsExpression *max,
|
||||
const pgsExpression *sequence, const pgsExpression *seed) :
|
||||
pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenInt::~pgsGenInt()
|
||||
{
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenInt::clone() const
|
||||
{
|
||||
return pnew pgsGenInt(*this);
|
||||
}
|
||||
|
||||
pgsGenInt::pgsGenInt(const pgsGenInt &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenInt &pgsGenInt::operator =(const pgsGenInt &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenInt::value() const
|
||||
{
|
||||
return wxString() << wxT("integer[ min = ") << m_min->value() << wxT(" max = ")
|
||||
<< m_max->value() << wxT(" sequence = ") << m_sequence->value()
|
||||
<< wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenInt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand min(m_min->eval(vars));
|
||||
pgsOperand max(m_max->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (min->is_integer() && max->is_integer() && sequence->is_integer()
|
||||
&& seed->is_integer())
|
||||
{
|
||||
long aux_sequence, aux_seed;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTInt,
|
||||
pnew pgsIntegerGen(pgsVariable::num(min), pgsVariable::num(max),
|
||||
aux_sequence != 0, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!min->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin should be an integer"));
|
||||
}
|
||||
else if (!max->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmax should be an integer"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
128
pgscript/expressions/pgsGenReal.cpp
Normal file
128
pgscript/expressions/pgsGenReal.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenReal.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsRealGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenReal::pgsGenReal(const pgsExpression *min, const pgsExpression *max,
|
||||
const pgsExpression *precision, const pgsExpression *sequence,
|
||||
const pgsExpression *seed) :
|
||||
pgsExpression(), m_min(min), m_max(max), m_precision(precision),
|
||||
m_sequence(sequence), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenReal::~pgsGenReal()
|
||||
{
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_precision);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenReal::clone() const
|
||||
{
|
||||
return pnew pgsGenReal(*this);
|
||||
}
|
||||
|
||||
pgsGenReal::pgsGenReal(const pgsGenReal &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_precision = that.m_precision->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenReal &pgsGenReal::operator =(const pgsGenReal &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_precision);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_precision = that.m_precision->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenReal::value() const
|
||||
{
|
||||
return wxString() << wxT("real[ min = ") << m_min->value() << wxT(" max = ")
|
||||
<< m_max->value() << wxT(" precision = ") << m_precision->value()
|
||||
<< wxT(" sequence = ") << m_sequence->value() << wxT(" seed = ")
|
||||
<< m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenReal::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand min(m_min->eval(vars));
|
||||
pgsOperand max(m_max->eval(vars));
|
||||
pgsOperand precision(m_precision->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (min->is_number() && max->is_number() && sequence->is_integer()
|
||||
&& seed->is_integer() && precision->is_integer())
|
||||
{
|
||||
long aux_sequence, aux_seed, aux_precision;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
precision->value().ToLong(&aux_precision);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTReal,
|
||||
pnew pgsRealGen(pgsVariable::num(min), pgsVariable::num(max), aux_precision,
|
||||
aux_sequence != 0, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!min->is_number())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin should be a number"));
|
||||
}
|
||||
else if (!max->is_number())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmax should be a number"));
|
||||
}
|
||||
else if (!precision->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nprecision should be an integer"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
131
pgscript/expressions/pgsGenReference.cpp
Normal file
131
pgscript/expressions/pgsGenReference.cpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenReference.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsReferenceGen.h"
|
||||
#include "pgscript/expressions/pgsExecute.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenReference::pgsGenReference(const pgsExpression *table, const pgsExpression *column,
|
||||
const pgsExpression *sequence, const pgsExpression *seed, pgsThread *app) :
|
||||
pgsExpression(), m_table(table), m_column(column), m_sequence(sequence),
|
||||
m_seed(seed), m_app(app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenReference::~pgsGenReference()
|
||||
{
|
||||
pdelete(m_table);
|
||||
pdelete(m_column);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenReference::clone() const
|
||||
{
|
||||
return pnew pgsGenReference(*this);
|
||||
}
|
||||
|
||||
pgsGenReference::pgsGenReference(const pgsGenReference &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_table = that.m_table->clone();
|
||||
m_column = that.m_column->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
m_app = that.m_app;
|
||||
}
|
||||
|
||||
pgsGenReference &pgsGenReference::operator =(const pgsGenReference &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_table);
|
||||
pdelete(m_column);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
m_table = that.m_table->clone();
|
||||
m_column = that.m_column->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
m_app = that.m_app;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenReference::value() const
|
||||
{
|
||||
return wxString() << wxT("reference[ table = ") << m_table->value()
|
||||
<< wxT(" column = ") << m_column->value() << wxT(" sequence = ")
|
||||
<< m_sequence->value() << wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenReference::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand table(m_table->eval(vars));
|
||||
pgsOperand column(m_column->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (table->is_string() && !table->value().IsEmpty() && column->is_string()
|
||||
&& !column->value().IsEmpty() && sequence->is_integer()
|
||||
&& seed->is_integer())
|
||||
{
|
||||
// Check wheter the table and the column do exist
|
||||
pgsOperand result = pgsExecute(wxString() << wxT("SELECT 1 FROM ")
|
||||
<< table->value() << wxT(" WHERE ") << column->value()
|
||||
<< wxT(" = ") << column->value(), 0, m_app).eval(vars);
|
||||
if (result->pgs_is_true())
|
||||
{
|
||||
long aux_sequence, aux_seed;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString,
|
||||
pnew pgsReferenceGen(m_app, table->value(),
|
||||
column->value(), aux_sequence != 0, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\ntable/column does not exist"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!table->is_string() || table->value().IsEmpty())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\ntable should be a non-empty string"));
|
||||
}
|
||||
else if (!column->is_string() || column->value().IsEmpty())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\ncolumn should be a non-empty string"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
98
pgscript/expressions/pgsGenRegex.cpp
Normal file
98
pgscript/expressions/pgsGenRegex.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenRegex.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsRegexGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenRegex::pgsGenRegex(const pgsExpression *regex, const pgsExpression *seed) :
|
||||
pgsExpression(), m_regex(regex), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenRegex::~pgsGenRegex()
|
||||
{
|
||||
pdelete(m_regex);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenRegex::clone() const
|
||||
{
|
||||
return pnew pgsGenRegex(*this);
|
||||
}
|
||||
|
||||
pgsGenRegex::pgsGenRegex(const pgsGenRegex &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_regex = that.m_regex->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenRegex &pgsGenRegex::operator =(const pgsGenRegex &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_regex);
|
||||
pdelete(m_seed);
|
||||
m_regex = that.m_regex->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenRegex::value() const
|
||||
{
|
||||
return wxString() << wxT("string[ regex = ") << m_regex->value()
|
||||
<< wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenRegex::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand regex(m_regex->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (regex->is_string() && seed->is_integer())
|
||||
{
|
||||
long aux_seed;
|
||||
seed->value().ToLong(&aux_seed);
|
||||
pgsRegexGen *gen = pnew pgsRegexGen(regex->value(), aux_seed);
|
||||
if (!gen->is_valid())
|
||||
{
|
||||
pdelete(gen);
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nregex is not a valid regular expression"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString, gen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!regex->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nregex should be a string"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
115
pgscript/expressions/pgsGenString.cpp
Normal file
115
pgscript/expressions/pgsGenString.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenString.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsStringGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenString::pgsGenString(const pgsExpression *min, const pgsExpression *max,
|
||||
const pgsExpression *nb_words, const pgsExpression *seed) :
|
||||
pgsExpression(), m_min(min), m_max(max), m_nb_words(nb_words), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenString::~pgsGenString()
|
||||
{
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_nb_words);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenString::clone() const
|
||||
{
|
||||
return pnew pgsGenString(*this);
|
||||
}
|
||||
|
||||
pgsGenString::pgsGenString(const pgsGenString &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_nb_words = that.m_nb_words->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenString &pgsGenString::operator =(const pgsGenString &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_nb_words);
|
||||
pdelete(m_seed);
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_nb_words = that.m_nb_words->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenString::value() const
|
||||
{
|
||||
return wxString() << wxT("string[ min = ") << m_min->value() << wxT(" max = ")
|
||||
<< m_max->value() << wxT(" nb_words = ") << m_nb_words->value()
|
||||
<< wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenString::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand min(m_min->eval(vars));
|
||||
pgsOperand max(m_max->eval(vars));
|
||||
pgsOperand nb_words(m_nb_words->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (min->is_integer() && max->is_integer() && nb_words->is_integer()
|
||||
&& seed->is_integer())
|
||||
{
|
||||
long aux_min, aux_max, aux_nb_words, aux_seed;
|
||||
min->value().ToLong(&aux_min);
|
||||
max->value().ToLong(&aux_max);
|
||||
nb_words->value().ToLong(&aux_nb_words);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString,
|
||||
pnew pgsStringGen(aux_min, aux_max, aux_nb_words, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!min->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin should be an integer"));
|
||||
}
|
||||
else if (!max->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmax should be an integer"));
|
||||
}
|
||||
else if (!nb_words->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nnb_words should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
123
pgscript/expressions/pgsGenTime.cpp
Normal file
123
pgscript/expressions/pgsGenTime.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGenTime.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/generators/pgsTimeGen.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
pgsGenTime::pgsGenTime(const pgsExpression *min, const pgsExpression *max,
|
||||
const pgsExpression *sequence, const pgsExpression *seed) :
|
||||
pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenTime::~pgsGenTime()
|
||||
{
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
}
|
||||
|
||||
pgsExpression *pgsGenTime::clone() const
|
||||
{
|
||||
return pnew pgsGenTime(*this);
|
||||
}
|
||||
|
||||
pgsGenTime::pgsGenTime(const pgsGenTime &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
|
||||
pgsGenTime &pgsGenTime::operator =(const pgsGenTime &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_min);
|
||||
pdelete(m_max);
|
||||
pdelete(m_sequence);
|
||||
pdelete(m_seed);
|
||||
m_min = that.m_min->clone();
|
||||
m_max = that.m_max->clone();
|
||||
m_sequence = that.m_sequence->clone();
|
||||
m_seed = that.m_seed->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGenTime::value() const
|
||||
{
|
||||
return wxString() << wxT("time[ min = ") << m_min->value() << wxT(" max = ")
|
||||
<< m_max->value() << wxT(" sequence = ") << m_sequence->value()
|
||||
<< wxT(" seed = ") << m_seed->value() << wxT(" ]");
|
||||
}
|
||||
|
||||
pgsOperand pgsGenTime::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate parameters
|
||||
pgsOperand min(m_min->eval(vars));
|
||||
pgsOperand max(m_max->eval(vars));
|
||||
pgsOperand sequence(m_sequence->eval(vars));
|
||||
pgsOperand seed(m_seed->eval(vars));
|
||||
|
||||
// Check parameters and create the generator
|
||||
if (min->is_string() && max->is_string() && sequence->is_integer()
|
||||
&& seed->is_integer())
|
||||
{
|
||||
wxDateTime aux_min, aux_max;
|
||||
if (aux_min.ParseTime(min->value()) != 0 && aux_max.ParseTime(max->value()) != 0
|
||||
&& aux_min.IsValid() && aux_max.IsValid())
|
||||
{
|
||||
long aux_sequence, aux_seed;
|
||||
sequence->value().ToLong(&aux_sequence);
|
||||
seed->value().ToLong(&aux_seed);
|
||||
return pnew pgsGenerator(pgsVariable::pgsTString,
|
||||
pnew pgsTimeGen(aux_min, aux_max, aux_sequence != 0, aux_seed));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin and/or max times are not valid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deal with errors
|
||||
if (!min->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmin should be a string"));
|
||||
}
|
||||
else if (!max->is_string())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nmax should be a string"));
|
||||
}
|
||||
else if (!sequence->is_integer())
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nsequence should be an integer"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsParameterException(wxString() << value()
|
||||
<< wxT(":\nseed should be an integer"));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
pgscript/expressions/pgsGreater.cpp
Normal file
60
pgscript/expressions/pgsGreater.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGreater.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsGreater::pgsGreater(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGreater::~pgsGreater()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsGreater::clone() const
|
||||
{
|
||||
return pnew pgsGreater(*this);
|
||||
}
|
||||
|
||||
pgsGreater::pgsGreater(const pgsGreater &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGreater &pgsGreater::operator =(const pgsGreater &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGreater::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" > ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsGreater::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left > *right);
|
||||
}
|
||||
60
pgscript/expressions/pgsGreaterEqual.cpp
Normal file
60
pgscript/expressions/pgsGreaterEqual.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsGreaterEqual.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsGreaterEqual::pgsGreaterEqual(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGreaterEqual::~pgsGreaterEqual()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsGreaterEqual::clone() const
|
||||
{
|
||||
return pnew pgsGreaterEqual(*this);
|
||||
}
|
||||
|
||||
pgsGreaterEqual::pgsGreaterEqual(const pgsGreaterEqual &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGreaterEqual &pgsGreaterEqual::operator =(const pgsGreaterEqual &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsGreaterEqual::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" >= ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsGreaterEqual::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left >= *right);
|
||||
}
|
||||
56
pgscript/expressions/pgsIdent.cpp
Normal file
56
pgscript/expressions/pgsIdent.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsIdent.h"
|
||||
|
||||
#include <wx/datetime.h>
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
|
||||
const wxString pgsIdent::m_now = wxT("@NOW");
|
||||
|
||||
pgsIdent::pgsIdent(const wxString &name) :
|
||||
pgsExpression(), m_name(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsIdent::~pgsIdent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsIdent::clone() const
|
||||
{
|
||||
return pnew pgsIdent(*this);
|
||||
}
|
||||
|
||||
wxString pgsIdent::value() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
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(""));
|
||||
}
|
||||
}
|
||||
103
pgscript/expressions/pgsIdentRecord.cpp
Normal file
103
pgscript/expressions/pgsIdentRecord.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsIdentRecord.h"
|
||||
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
|
||||
pgsIdentRecord::pgsIdentRecord(const wxString &name, const pgsExpression *line,
|
||||
const pgsExpression *column) :
|
||||
pgsIdent(name), m_line(line), m_column(column)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsIdentRecord::~pgsIdentRecord()
|
||||
{
|
||||
pdelete(m_line);
|
||||
pdelete(m_column);
|
||||
}
|
||||
|
||||
pgsExpression *pgsIdentRecord::clone() const
|
||||
{
|
||||
return pnew pgsIdentRecord(*this);
|
||||
}
|
||||
|
||||
pgsIdentRecord::pgsIdentRecord(const pgsIdentRecord &that) :
|
||||
pgsIdent(that)
|
||||
{
|
||||
m_line = that.m_line->clone();
|
||||
m_column = that.m_column != 0 ? that.m_column->clone() : 0;
|
||||
}
|
||||
|
||||
pgsIdentRecord &pgsIdentRecord::operator=(const pgsIdentRecord &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsIdent::operator=(that);
|
||||
pdelete(m_line);
|
||||
pdelete(m_column);
|
||||
m_line = that.m_line->clone();
|
||||
m_column = that.m_column != 0 ? that.m_column->clone() : 0;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsIdentRecord::value() const
|
||||
{
|
||||
wxString result;
|
||||
result << m_name << wxT("[") << m_line->value() << wxT("]");
|
||||
if (m_column != 0)
|
||||
{
|
||||
result << wxT("[") << m_column->value() << wxT("]");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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(""));
|
||||
}
|
||||
58
pgscript/expressions/pgsLines.cpp
Normal file
58
pgscript/expressions/pgsLines.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsLines.h"
|
||||
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
|
||||
pgsLines::pgsLines(const wxString &name) :
|
||||
pgsExpression(), m_name(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsLines::~pgsLines()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsLines::clone() const
|
||||
{
|
||||
return pnew pgsLines(*this);
|
||||
}
|
||||
|
||||
wxString pgsLines::value() const
|
||||
{
|
||||
return wxString() << wxT("LINES(") << m_name << wxT(")");
|
||||
}
|
||||
|
||||
pgsOperand pgsLines::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_lines(), 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);
|
||||
}
|
||||
}
|
||||
60
pgscript/expressions/pgsLower.cpp
Normal file
60
pgscript/expressions/pgsLower.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsLower.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsLower::pgsLower(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsLower::~pgsLower()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsLower::clone() const
|
||||
{
|
||||
return pnew pgsLower(*this);
|
||||
}
|
||||
|
||||
pgsLower::pgsLower(const pgsLower &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsLower &pgsLower::operator =(const pgsLower &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsLower::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" < ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsLower::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left < *right);
|
||||
}
|
||||
61
pgscript/expressions/pgsLowerEqual.cpp
Normal file
61
pgscript/expressions/pgsLowerEqual.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsLowerEqual.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsLowerEqual::pgsLowerEqual(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsLowerEqual::~pgsLowerEqual()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsLowerEqual::clone() const
|
||||
{
|
||||
return pnew pgsLowerEqual(*this);
|
||||
}
|
||||
|
||||
pgsLowerEqual::pgsLowerEqual(const pgsLowerEqual &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsLowerEqual &pgsLowerEqual::operator =(const pgsLowerEqual &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsLowerEqual::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" <= ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsLowerEqual::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left <= *right);
|
||||
}
|
||||
60
pgscript/expressions/pgsMinus.cpp
Normal file
60
pgscript/expressions/pgsMinus.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsMinus.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsMinus::pgsMinus(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsMinus::~pgsMinus()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsMinus::clone() const
|
||||
{
|
||||
return pnew pgsMinus(*this);
|
||||
}
|
||||
|
||||
pgsMinus::pgsMinus(const pgsMinus &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsMinus &pgsMinus::operator =(const pgsMinus &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsMinus::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" - ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsMinus::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left - *right);
|
||||
}
|
||||
60
pgscript/expressions/pgsModulo.cpp
Normal file
60
pgscript/expressions/pgsModulo.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsModulo.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsModulo::pgsModulo(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsModulo::~pgsModulo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsModulo::clone() const
|
||||
{
|
||||
return pnew pgsModulo(*this);
|
||||
}
|
||||
|
||||
pgsModulo::pgsModulo(const pgsModulo &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsModulo &pgsModulo::operator =(const pgsModulo &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsModulo::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" % ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsModulo::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left % *right);
|
||||
}
|
||||
60
pgscript/expressions/pgsNegate.cpp
Normal file
60
pgscript/expressions/pgsNegate.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsNegate.h"
|
||||
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
|
||||
pgsNegate::pgsNegate(const pgsExpression *left) :
|
||||
pgsOperation(left, 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNegate::~pgsNegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsNegate::clone() const
|
||||
{
|
||||
return pnew pgsNegate(*this);
|
||||
}
|
||||
|
||||
pgsNegate::pgsNegate(const pgsNegate &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNegate &pgsNegate::operator =(const pgsNegate &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsNegate::value() const
|
||||
{
|
||||
return wxString() << wxT("-") << m_left->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsNegate::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(pnew pgsNumber(wxT("0"), pgsInt));
|
||||
pgsOperand right(m_left->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left - *right);
|
||||
}
|
||||
59
pgscript/expressions/pgsNot.cpp
Normal file
59
pgscript/expressions/pgsNot.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsNot.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsNot::pgsNot(const pgsExpression *left) :
|
||||
pgsOperation(left, 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNot::~pgsNot()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsNot::clone() const
|
||||
{
|
||||
return pnew pgsNot(*this);
|
||||
}
|
||||
|
||||
pgsNot::pgsNot(const pgsNot &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNot &pgsNot::operator =(const pgsNot &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsNot::value() const
|
||||
{
|
||||
return wxString() << wxT("NOT ") << m_left->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsNot::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (!(*left));
|
||||
}
|
||||
46
pgscript/expressions/pgsOperation.cpp
Normal file
46
pgscript/expressions/pgsOperation.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsOperation.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsOperation::pgsOperation(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsExpression(), m_left(left), m_right(right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsOperation::~pgsOperation()
|
||||
{
|
||||
pdelete(m_left);
|
||||
pdelete(m_right);
|
||||
}
|
||||
|
||||
pgsOperation::pgsOperation(const pgsOperation &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_left = that.m_left->clone();
|
||||
m_right = that.m_right != 0 ? that.m_right->clone() : 0;
|
||||
}
|
||||
|
||||
pgsOperation &pgsOperation::operator =(const pgsOperation &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_left);
|
||||
pdelete(m_right);
|
||||
m_left = that.m_left->clone();
|
||||
m_right = that.m_right != 0 ? that.m_right->clone() : 0;
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
56
pgscript/expressions/pgsOr.cpp
Normal file
56
pgscript/expressions/pgsOr.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsOr.h"
|
||||
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
|
||||
pgsOr::pgsOr(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsOr::~pgsOr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsOr::clone() const
|
||||
{
|
||||
return pnew pgsOr(*this);
|
||||
}
|
||||
|
||||
pgsOr::pgsOr(const pgsOr &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsOr &pgsOr::operator =(const pgsOr &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsOr::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" OR ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsOr::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return pnew pgsNumber(wxString() << (m_left->eval(vars)->pgs_is_true()
|
||||
|| m_right->eval(vars)->pgs_is_true()), pgsInt);
|
||||
}
|
||||
60
pgscript/expressions/pgsOver.cpp
Normal file
60
pgscript/expressions/pgsOver.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsOver.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsOver::pgsOver(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsOver::~pgsOver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsOver::clone() const
|
||||
{
|
||||
return pnew pgsOver(*this);
|
||||
}
|
||||
|
||||
pgsOver::pgsOver(const pgsOver &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsOver &pgsOver::operator =(const pgsOver &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsOver::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" / ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsOver::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left / *right);
|
||||
}
|
||||
59
pgscript/expressions/pgsParenthesis.cpp
Normal file
59
pgscript/expressions/pgsParenthesis.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsParenthesis.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsParenthesis::pgsParenthesis(const pgsExpression *left) :
|
||||
pgsOperation(left, 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsParenthesis::~pgsParenthesis()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsParenthesis::clone() const
|
||||
{
|
||||
return pnew pgsParenthesis(*this);
|
||||
}
|
||||
|
||||
pgsParenthesis::pgsParenthesis(const pgsParenthesis &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsParenthesis &pgsParenthesis::operator =(const pgsParenthesis &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsParenthesis::value() const
|
||||
{
|
||||
return wxString() << wxT("(") << m_left->value() << wxT(")");
|
||||
}
|
||||
|
||||
pgsOperand pgsParenthesis::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return left;
|
||||
}
|
||||
60
pgscript/expressions/pgsPlus.cpp
Normal file
60
pgscript/expressions/pgsPlus.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsPlus.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsPlus::pgsPlus(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsPlus::~pgsPlus()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsPlus::clone() const
|
||||
{
|
||||
return pnew pgsPlus(*this);
|
||||
}
|
||||
|
||||
pgsPlus::pgsPlus(const pgsPlus &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsPlus &pgsPlus::operator =(const pgsPlus &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsPlus::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" + ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsPlus::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left + *right);
|
||||
}
|
||||
89
pgscript/expressions/pgsRemoveLine.cpp
Normal file
89
pgscript/expressions/pgsRemoveLine.cpp
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsRemoveLine.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsParameterException.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
|
||||
pgsRemoveLine::pgsRemoveLine(const wxString &rec, const pgsExpression *line) :
|
||||
pgsExpression(), m_rec(rec), m_line(line)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsRemoveLine::~pgsRemoveLine()
|
||||
{
|
||||
pdelete(m_line);
|
||||
}
|
||||
|
||||
pgsExpression *pgsRemoveLine::clone() const
|
||||
{
|
||||
return pnew pgsRemoveLine(*this);
|
||||
}
|
||||
|
||||
pgsRemoveLine::pgsRemoveLine(const pgsRemoveLine &that) :
|
||||
pgsExpression(that), m_rec(that.m_rec)
|
||||
{
|
||||
m_line = that.m_line->clone();
|
||||
}
|
||||
|
||||
pgsRemoveLine &pgsRemoveLine::operator =(const pgsRemoveLine &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
m_rec = that.m_rec;
|
||||
pdelete(m_line);
|
||||
m_line = that.m_line->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsRemoveLine::value() const
|
||||
{
|
||||
return wxString() << wxT("RMLINE(") << m_rec << wxT("[")
|
||||
<< m_line->value() << wxT("])");
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
60
pgscript/expressions/pgsTimes.cpp
Normal file
60
pgscript/expressions/pgsTimes.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsTimes.h"
|
||||
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsTimes::pgsTimes(const pgsExpression *left, const pgsExpression *right) :
|
||||
pgsOperation(left, right)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsTimes::~pgsTimes()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpression *pgsTimes::clone() const
|
||||
{
|
||||
return pnew pgsTimes(*this);
|
||||
}
|
||||
|
||||
pgsTimes::pgsTimes(const pgsTimes &that) :
|
||||
pgsOperation(that)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsTimes &pgsTimes::operator =(const pgsTimes &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsOperation::operator=(that);
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
wxString pgsTimes::value() const
|
||||
{
|
||||
return wxString() << m_left->value() << wxT(" * ") << m_right->value();
|
||||
}
|
||||
|
||||
pgsOperand pgsTimes::eval(pgsVarMap &vars) const
|
||||
{
|
||||
// Evaluate operands
|
||||
pgsOperand left(m_left->eval(vars));
|
||||
pgsOperand right(m_right->eval(vars));
|
||||
|
||||
// Return the result
|
||||
return (*left **right);
|
||||
}
|
||||
57
pgscript/expressions/pgsTrim.cpp
Normal file
57
pgscript/expressions/pgsTrim.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/expressions/pgsTrim.h"
|
||||
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
|
||||
pgsTrim::pgsTrim(const pgsExpression *exp) :
|
||||
pgsExpression(), m_exp(exp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsTrim::~pgsTrim()
|
||||
{
|
||||
pdelete(m_exp);
|
||||
}
|
||||
|
||||
pgsTrim::pgsTrim(const pgsTrim &that) :
|
||||
pgsExpression(that)
|
||||
{
|
||||
m_exp = that.m_exp->clone();
|
||||
}
|
||||
|
||||
pgsTrim &pgsTrim::operator=(const pgsTrim &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsExpression::operator=(that);
|
||||
pdelete(m_exp);
|
||||
m_exp = that.m_exp->clone();
|
||||
}
|
||||
return (*this);
|
||||
}
|
||||
|
||||
pgsExpression *pgsTrim::clone() const
|
||||
{
|
||||
return pnew pgsTrim(*this);
|
||||
}
|
||||
|
||||
wxString pgsTrim::value() const
|
||||
{
|
||||
return wxString() << wxT("TRIM(") << m_exp->value() << wxT(")");
|
||||
}
|
||||
|
||||
pgsOperand pgsTrim::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return pnew pgsString(m_exp->eval(vars)->value().Strip(wxString::both));
|
||||
}
|
||||
27
pgscript/generators/module.mk
Normal file
27
pgscript/generators/module.mk
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/pgscript/generators/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
pgscript/generators/pgsDateGen.cpp \
|
||||
pgscript/generators/pgsDateTimeGen.cpp \
|
||||
pgscript/generators/pgsDictionaryGen.cpp \
|
||||
pgscript/generators/pgsIntegerGen.cpp \
|
||||
pgscript/generators/pgsNumberGen.cpp \
|
||||
pgscript/generators/pgsObjectGen.cpp \
|
||||
pgscript/generators/pgsRealGen.cpp \
|
||||
pgscript/generators/pgsReferenceGen.cpp \
|
||||
pgscript/generators/pgsRegexGen.cpp \
|
||||
pgscript/generators/pgsStringGen.cpp \
|
||||
pgscript/generators/pgsTimeGen.cpp
|
||||
|
||||
EXTRA_DIST += \
|
||||
pgscript/generators/module.mk
|
||||
|
||||
47
pgscript/generators/pgsDateGen.cpp
Normal file
47
pgscript/generators/pgsDateGen.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsDateGen.h"
|
||||
|
||||
pgsDateGen::pgsDateGen(wxDateTime min, wxDateTime max, const bool &sequence,
|
||||
const long &seed) :
|
||||
pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max),
|
||||
m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min),
|
||||
m_range(m_max.Subtract(m_min).GetDays()), m_sequence(sequence)
|
||||
{
|
||||
m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, m_range, is_sequence(),
|
||||
m_seed));
|
||||
}
|
||||
|
||||
bool pgsDateGen::is_sequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
wxString pgsDateGen::random()
|
||||
{
|
||||
wxDateSpan date_span(0, 0, 0, m_randomizer->random_long());
|
||||
wxDateTime aux_min(m_min);
|
||||
aux_min.Add(date_span);
|
||||
wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min));
|
||||
wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max));
|
||||
return aux_min.FormatISODate();
|
||||
}
|
||||
|
||||
pgsDateGen::~pgsDateGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsDateGen *pgsDateGen::clone()
|
||||
{
|
||||
return pnew pgsDateGen(*this);
|
||||
}
|
||||
62
pgscript/generators/pgsDateTimeGen.cpp
Normal file
62
pgscript/generators/pgsDateTimeGen.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsDateTimeGen.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
pgsDateTimeGen::pgsDateTimeGen(wxDateTime min, wxDateTime max,
|
||||
const bool &sequence, const long &seed) :
|
||||
pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max),
|
||||
m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min),
|
||||
m_range(m_max.Subtract(m_min).GetSeconds()), m_sequence(sequence)
|
||||
{
|
||||
m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, std::string(m_range
|
||||
.ToString().mb_str()).c_str(), is_sequence(), m_seed));
|
||||
}
|
||||
|
||||
bool pgsDateTimeGen::is_sequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
wxString pgsDateTimeGen::random()
|
||||
{
|
||||
// Get a random number representing seconds
|
||||
MAPM result = pgsMapm::pgs_str_mapm(m_randomizer->random()), quot, rem;
|
||||
|
||||
// Use hours and seconds for avoiding overflows of seconds
|
||||
result.integer_div_rem(3600, quot, rem);
|
||||
long hours, seconds;
|
||||
pgsMapm::pgs_mapm_str(quot, true).ToLong(&hours);
|
||||
pgsMapm::pgs_mapm_str(rem, true).ToLong(&seconds);
|
||||
wxTimeSpan time_span(hours, 0, seconds, 0);
|
||||
|
||||
// Add the TimeSpan to the MinDate
|
||||
wxDateTime aux_min(m_min);
|
||||
aux_min.Add(time_span);
|
||||
|
||||
// Post conditions
|
||||
wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min));
|
||||
wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max));
|
||||
|
||||
return aux_min.Format(wxT("%Y-%m-%d %H:%M:%S"));
|
||||
}
|
||||
|
||||
pgsDateTimeGen::~pgsDateTimeGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsDateTimeGen *pgsDateTimeGen::clone()
|
||||
{
|
||||
return pnew pgsDateTimeGen(*this);
|
||||
}
|
||||
99
pgscript/generators/pgsDictionaryGen.cpp
Normal file
99
pgscript/generators/pgsDictionaryGen.cpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsDictionaryGen.h"
|
||||
|
||||
#include <wx/txtstrm.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <wx/filename.h>
|
||||
|
||||
pgsDictionaryGen::pgsDictionaryGen(const wxString &file_path,
|
||||
const bool &sequence, const long &seed, wxCSConv conv) :
|
||||
pgsObjectGen(seed), m_file_path(file_path), m_conv(conv)
|
||||
{
|
||||
m_nb_lines = this->count_lines();
|
||||
m_randomizer = pgsRandomizer(pnew pgsIntegerGen(1, m_nb_lines,
|
||||
sequence, seed));
|
||||
}
|
||||
|
||||
wxString pgsDictionaryGen::random()
|
||||
{
|
||||
return this->get_line(m_randomizer->random_long());
|
||||
}
|
||||
|
||||
pgsDictionaryGen::~pgsDictionaryGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsDictionaryGen *pgsDictionaryGen::clone()
|
||||
{
|
||||
return pnew pgsDictionaryGen(*this);
|
||||
}
|
||||
|
||||
const long &pgsDictionaryGen::nb_lines() const
|
||||
{
|
||||
return m_nb_lines;
|
||||
}
|
||||
|
||||
long pgsDictionaryGen::count_lines()
|
||||
{
|
||||
long result = 0;
|
||||
|
||||
wxFileName file_path(m_file_path);
|
||||
if (file_path.FileExists() && file_path.IsFileReadable())
|
||||
{
|
||||
wxFFileInputStream input(m_file_path);
|
||||
if (input.IsOk())
|
||||
{
|
||||
#if wxUSE_UNICODE
|
||||
wxTextInputStream text(input, wxT(" \t"), m_conv);
|
||||
#else
|
||||
wxTextInputStream text(input, wxT(" \t"));
|
||||
#endif
|
||||
wxString line;
|
||||
while (!(line = text.ReadLine()).IsEmpty() && !input.Eof())
|
||||
{
|
||||
++result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result < 0) result = 0;
|
||||
wxASSERT(result >= 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
wxString pgsDictionaryGen::get_line(long line_nb)
|
||||
{
|
||||
long current_line = 1;
|
||||
|
||||
if (m_nb_lines > 0)
|
||||
{
|
||||
wxFFileInputStream input(m_file_path);
|
||||
if (input.IsOk())
|
||||
{
|
||||
#if wxUSE_UNICODE
|
||||
wxTextInputStream text(input, wxT(" \t"), m_conv);
|
||||
#else
|
||||
wxTextInputStream text(input, wxT(" \t"));
|
||||
#endif
|
||||
while (current_line < line_nb && !input.Eof())
|
||||
{
|
||||
text.ReadLine();
|
||||
++current_line;
|
||||
}
|
||||
return text.ReadLine();
|
||||
}
|
||||
}
|
||||
|
||||
return wxString();
|
||||
}
|
||||
174
pgscript/generators/pgsIntegerGen.cpp
Normal file
174
pgscript/generators/pgsIntegerGen.cpp
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsIntegerGen.h"
|
||||
|
||||
pgsIntegerGen::pgsSequentialIntGen::pgsSequentialIntGen(const MAPM &range,
|
||||
const long &seed) :
|
||||
pgsNumberGen(range), m_state(seed), m_m(2), m_remainder(m_range)
|
||||
{
|
||||
MAPM _2 = 2;
|
||||
while (m_m < m_range)
|
||||
{
|
||||
m_m = m_m * _2;
|
||||
}
|
||||
m_buffer.Alloc(BUFFER_SIZE);
|
||||
}
|
||||
|
||||
MAPM pgsIntegerGen::pgsSequentialIntGen::random()
|
||||
{
|
||||
// Bufferizer BUFFER_SIZE values in the vector
|
||||
if (m_buffer.GetCount() == 0)
|
||||
{
|
||||
// Calculate the number of elements to bufferize
|
||||
MAPM min = wxMin(m_remainder, MAPM(BUFFER_SIZE));
|
||||
|
||||
// Generate those elements
|
||||
for (MAPM i = 0; i < min; i = i + 1)
|
||||
{
|
||||
do
|
||||
{
|
||||
m_state = (m_state * arg_a);
|
||||
m_state = (m_state + arg_c) % m_m;
|
||||
}
|
||||
while (m_state >= m_range);
|
||||
m_buffer.Add(m_state);
|
||||
m_remainder -= 1;
|
||||
}
|
||||
|
||||
class pgsRandInt
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
long m_state;
|
||||
|
||||
public:
|
||||
|
||||
pgsRandInt(long n)
|
||||
: m_state(n)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
long rand()
|
||||
{
|
||||
m_state = (1103515245L * m_state + 12345L) % 2147483647L;
|
||||
return m_state;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Shuffle the vector of generated values
|
||||
pgsRandInt rand_int(BUFFER_SIZE);
|
||||
for (size_t i = 0; i < m_buffer.GetCount(); i++)
|
||||
{
|
||||
size_t r = i + (rand_int.rand() % (m_buffer.GetCount() - i));
|
||||
const MAPM a = m_buffer.Item(i);
|
||||
m_buffer.Item(i) = m_buffer.Item(r);
|
||||
m_buffer.Item(r) = a;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_remainder == 0)
|
||||
{
|
||||
m_remainder = m_range;
|
||||
}
|
||||
|
||||
// Take the last bufferized value
|
||||
MAPM data = m_buffer.Last();
|
||||
m_buffer.RemoveAt(m_buffer.GetCount() - 1);
|
||||
|
||||
// Return random value
|
||||
return data;
|
||||
}
|
||||
|
||||
pgsIntegerGen::pgsSequentialIntGen::~pgsSequentialIntGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNumberGen *pgsIntegerGen::pgsSequentialIntGen::clone()
|
||||
{
|
||||
return pnew pgsIntegerGen::pgsSequentialIntGen(*this);
|
||||
}
|
||||
|
||||
const MAPM pgsIntegerGen::pgsSequentialIntGen::arg_a = 5;
|
||||
const MAPM pgsIntegerGen::pgsSequentialIntGen::arg_c = 1;
|
||||
|
||||
pgsIntegerGen::pgsNormalIntGen::pgsNormalIntGen(const MAPM &range,
|
||||
const long &seed) :
|
||||
pgsNumberGen(range), m_state(seed), m_top(arg_m - 1)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
random(); // Beginning of the sequence is garbage
|
||||
}
|
||||
|
||||
MAPM pgsIntegerGen::pgsNormalIntGen::random()
|
||||
{
|
||||
m_state = (m_state * arg_a);
|
||||
m_state = (m_state + arg_c) % arg_m;
|
||||
return (m_state * m_range).div(m_top);
|
||||
}
|
||||
|
||||
pgsIntegerGen::pgsNormalIntGen::~pgsNormalIntGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNumberGen *pgsIntegerGen::pgsNormalIntGen::clone()
|
||||
{
|
||||
return pnew pgsIntegerGen::pgsNormalIntGen(*this);
|
||||
}
|
||||
|
||||
const MAPM pgsIntegerGen::pgsNormalIntGen::arg_a = 16807L;
|
||||
const MAPM pgsIntegerGen::pgsNormalIntGen::arg_c = 0;
|
||||
const MAPM pgsIntegerGen::pgsNormalIntGen::arg_m = 2147483647L;
|
||||
|
||||
pgsIntegerGen::pgsIntegerGen(const MAPM &min, const MAPM &max,
|
||||
const bool &sequence, const long &seed) :
|
||||
pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)),
|
||||
m_range(m_max - m_min + 1), m_sequence(sequence)
|
||||
{
|
||||
m_randomizer = is_sequence()
|
||||
? pgsRandomizer(pnew pgsSequentialIntGen(m_range, m_seed))
|
||||
: pgsRandomizer(pnew pgsNormalIntGen(m_range, m_seed));
|
||||
}
|
||||
|
||||
bool pgsIntegerGen::is_sequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
wxString pgsIntegerGen::random()
|
||||
{
|
||||
MAPM data = m_randomizer->random();
|
||||
data = data + m_min;
|
||||
wxASSERT(data >= m_min && data <= m_max);
|
||||
return pgsMapm::pgs_mapm_str(data);
|
||||
}
|
||||
|
||||
long pgsIntegerGen::random_long()
|
||||
{
|
||||
long result;
|
||||
random().ToLong(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
pgsIntegerGen::~pgsIntegerGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsIntegerGen *pgsIntegerGen::clone()
|
||||
{
|
||||
return pnew pgsIntegerGen(*this);
|
||||
}
|
||||
23
pgscript/generators/pgsNumberGen.cpp
Normal file
23
pgscript/generators/pgsNumberGen.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsNumberGen.h"
|
||||
|
||||
pgsNumberGen::pgsNumberGen(const MAPM &range) :
|
||||
m_range(range)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNumberGen::~pgsNumberGen()
|
||||
{
|
||||
|
||||
}
|
||||
23
pgscript/generators/pgsObjectGen.cpp
Normal file
23
pgscript/generators/pgsObjectGen.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsObjectGen.h"
|
||||
|
||||
pgsObjectGen::pgsObjectGen(const long &seed) :
|
||||
m_seed(seed == 0 ? 1 : seed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsObjectGen::~pgsObjectGen()
|
||||
{
|
||||
|
||||
}
|
||||
48
pgscript/generators/pgsRealGen.cpp
Normal file
48
pgscript/generators/pgsRealGen.cpp
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsRealGen.h"
|
||||
|
||||
pgsRealGen::pgsRealGen(const MAPM &min, const MAPM &max,
|
||||
const UCHAR &precision, const bool &sequence, const long &seed) :
|
||||
pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)),
|
||||
m_range(m_max - m_min), m_sequence(sequence)
|
||||
{
|
||||
m_pow = MAPM(10).pow(MAPM(precision));
|
||||
m_int_max = pgsMapm::pgs_mapm_round(m_range * m_pow) + 1;
|
||||
|
||||
m_randomizer = is_sequence()
|
||||
? pgsRandomizer(pnew pgsIntegerGen::pgsSequentialIntGen(m_int_max, m_seed))
|
||||
: pgsRandomizer(pnew pgsIntegerGen::pgsNormalIntGen(m_int_max, m_seed));
|
||||
}
|
||||
|
||||
bool pgsRealGen::is_sequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
wxString pgsRealGen::random()
|
||||
{
|
||||
MAPM data = m_randomizer->random() / m_pow;
|
||||
data = data + m_min;
|
||||
wxASSERT(data >= m_min && data <= m_max);
|
||||
return pgsMapm::pgs_mapm_str(data);
|
||||
}
|
||||
|
||||
pgsRealGen::~pgsRealGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsRealGen *pgsRealGen::clone()
|
||||
{
|
||||
return pnew pgsRealGen(*this);
|
||||
}
|
||||
76
pgscript/generators/pgsReferenceGen.cpp
Normal file
76
pgscript/generators/pgsReferenceGen.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsReferenceGen.h"
|
||||
|
||||
#include "pgscript/expressions/pgsExecute.h"
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/utilities/pgsThread.h"
|
||||
|
||||
pgsReferenceGen::pgsReferenceGen(pgsThread *app, const wxString &table,
|
||||
const wxString &column, const bool &sequence, const long &seed) :
|
||||
pgsObjectGen(seed), m_app(app), m_table(table), m_column(column),
|
||||
m_sequence(sequence)
|
||||
{
|
||||
// We need an empty symbol table for calling pgsExecute.eval(...)
|
||||
pgsVarMap vars;
|
||||
|
||||
// Count the number of lines in the table
|
||||
pgsOperand result = pgsExecute(wxString() << wxT("SELECT count(*) FROM ")
|
||||
<< m_table, 0, m_app).eval(vars);
|
||||
wxASSERT(result->is_record());
|
||||
wxString value = result->value();
|
||||
if (!value.IsEmpty())
|
||||
{
|
||||
m_nb_rows = pgsMapm::pgs_str_mapm(result->number().value());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nb_rows = 0;
|
||||
}
|
||||
wxLogScriptVerbose(wxT("REFGEN: Number of rows in %s: %s"), m_table.c_str(),
|
||||
pgsMapm::pgs_mapm_str(m_nb_rows).c_str());
|
||||
|
||||
// Create an integer generator with that number of lines
|
||||
m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, m_nb_rows - 1,
|
||||
is_sequence(), m_seed));
|
||||
}
|
||||
|
||||
bool pgsReferenceGen::is_sequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
wxString pgsReferenceGen::random()
|
||||
{
|
||||
// We need an empty symbol table for calling pgsExecute.eval(...)
|
||||
pgsVarMap vars;
|
||||
|
||||
// Choose one line
|
||||
pgsOperand result = pgsExecute(wxString() << wxT("SELECT ") << m_column
|
||||
<< wxT(" FROM ") << m_table << wxT(" LIMIT 1 OFFSET ")
|
||||
<< m_randomizer->random(), 0, m_app).eval(vars);
|
||||
wxASSERT(result->is_record());
|
||||
|
||||
// Return the result as a single value
|
||||
return dynamic_cast<const pgsRecord &>(*result).get(0, 0)->value();
|
||||
}
|
||||
|
||||
pgsReferenceGen::~pgsReferenceGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsReferenceGen *pgsReferenceGen::clone()
|
||||
{
|
||||
return pnew pgsReferenceGen(*this);
|
||||
}
|
||||
309
pgscript/generators/pgsRegexGen.cpp
Normal file
309
pgscript/generators/pgsRegexGen.cpp
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsRegexGen.h"
|
||||
|
||||
#include <wx/sstream.h>
|
||||
#include <wx/regex.h>
|
||||
#include <wx/xml/xml.h>
|
||||
|
||||
#include <wx/arrimpl.cpp>
|
||||
WX_DEFINE_OBJARRAY(pgsVectorStringGen);
|
||||
|
||||
pgsRegexGen::pgsRegex::pgsRegex(const pgsVectorChar &characters,
|
||||
const long &first, const long &second) :
|
||||
m_characters(characters), m_first(wxMin(first, second)),
|
||||
m_second(wxMax(first, second))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsRegexGen::pgsRegex::pgsRegex() :
|
||||
m_characters(pgsVectorChar()), m_first(0), m_second(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsRegexGen::pgsRegex::~pgsRegex()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsRegexGen::pgsRegex *pgsRegexGen::pgsRegex::clone()
|
||||
{
|
||||
return pnew pgsRegexGen::pgsRegex(*this);
|
||||
}
|
||||
|
||||
void pgsRegexGen::pgsRegex::set_characters(const pgsVectorChar &characters)
|
||||
{
|
||||
m_characters = characters;
|
||||
}
|
||||
|
||||
void pgsRegexGen::pgsRegex::add_character(const wxChar &c)
|
||||
{
|
||||
m_characters.Add(c);
|
||||
}
|
||||
|
||||
void pgsRegexGen::pgsRegex::set_first(const long &first)
|
||||
{
|
||||
m_first = first;
|
||||
m_second = first;
|
||||
}
|
||||
|
||||
void pgsRegexGen::pgsRegex::set_second(const long &second)
|
||||
{
|
||||
long first = m_first;
|
||||
m_first = wxMin(first, second);
|
||||
m_second = wxMax(first, second);
|
||||
}
|
||||
|
||||
const pgsVectorChar &pgsRegexGen::pgsRegex::get_characters() const
|
||||
{
|
||||
return m_characters;
|
||||
}
|
||||
|
||||
const long &pgsRegexGen::pgsRegex::get_first() const
|
||||
{
|
||||
return m_first;
|
||||
}
|
||||
|
||||
const long &pgsRegexGen::pgsRegex::get_second() const
|
||||
{
|
||||
return m_second;
|
||||
}
|
||||
|
||||
pgsRegexGen::pgsRegexGen(const wxString ®ex, const long &seed) :
|
||||
pgsObjectGen(seed), m_regex(regex), m_valid(true), m_string_gens(pgsVectorStringGen())
|
||||
{
|
||||
wxLogScriptVerbose(wxT("REGEXGEN: %s"), m_regex.c_str());
|
||||
|
||||
// Transform regular expression into XML structure
|
||||
bool escape = false, first_regex = true, list = false;
|
||||
wxString result = wxT("<regexpressions>\n");
|
||||
size_t i = 0;
|
||||
while (i < m_regex.Length())
|
||||
{
|
||||
if (escape)
|
||||
{
|
||||
if (list == true)
|
||||
{
|
||||
result.Append(espace_xml_char(m_regex[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!first_regex)
|
||||
result.Append(wxT(" </regex>\n"));
|
||||
else
|
||||
first_regex = false;
|
||||
result.Append(wxT(" <regex>\n <characters>"));
|
||||
result.Append(espace_xml_char(m_regex[i]));
|
||||
result.Append(wxT("</characters>\n"));
|
||||
}
|
||||
escape = false;
|
||||
}
|
||||
else if (list == true && m_regex[i] == wxT('-'))
|
||||
{
|
||||
if ((i + 1) < m_regex.Length())
|
||||
{
|
||||
result.Append(char_range(m_regex[i - 1], m_regex[i + 1]));
|
||||
}
|
||||
}
|
||||
else if (m_regex[i] == wxT('['))
|
||||
{
|
||||
if (!first_regex)
|
||||
result.Append(wxT(" </regex>\n"));
|
||||
else
|
||||
first_regex = false;
|
||||
result.Append(wxT(" <regex>\n <characters>"));
|
||||
list = true;
|
||||
}
|
||||
else if (m_regex[i] == wxT(']'))
|
||||
{
|
||||
result.Append(wxT("</characters>\n"));
|
||||
list = false;
|
||||
}
|
||||
else if (m_regex[i] == wxT('{'))
|
||||
{
|
||||
result.Append(wxT(" <range>"));
|
||||
list = true;
|
||||
}
|
||||
else if (m_regex[i] == wxT('}'))
|
||||
{
|
||||
result.Append(wxT("</range>\n"));
|
||||
list = false;
|
||||
}
|
||||
else if (m_regex[i] == wxT('\\'))
|
||||
{
|
||||
escape = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list == true)
|
||||
{
|
||||
result.Append(espace_xml_char(m_regex[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!first_regex)
|
||||
result.Append(wxT(" </regex>\n"));
|
||||
else
|
||||
first_regex = false;
|
||||
result.Append(wxT(" <regex>\n <characters>"));
|
||||
result.Append(espace_xml_char(m_regex[i]));
|
||||
result.Append(wxT("</characters>\n"));
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
if (result != wxT("<regexpressions>\n"))
|
||||
result.Append(wxT(" </regex>\n"));
|
||||
result.Append(wxT("</regexpressions>\n"));
|
||||
|
||||
wxLogScriptVerbose(wxT("REGEXGEN: %s"), result.c_str());
|
||||
|
||||
// Load this XML structure with the wxXmlDocument from wxWidgets
|
||||
wxStringInputStream input(result);
|
||||
wxXmlDocument doc;
|
||||
if (!doc.Load(input, wxT("UTF-8"), wxXMLDOC_KEEP_WHITESPACE_NODES))
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start processing the XML file
|
||||
if (doc.GetRoot()->GetName() != wxT("regexpressions"))
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Go through XML nodes
|
||||
wxXmlNode *xml_regexpressions = doc.GetRoot()->GetChildren();
|
||||
while (xml_regexpressions && m_valid)
|
||||
{
|
||||
if (xml_regexpressions->GetName() == wxT("regex"))
|
||||
{
|
||||
wxXmlNode *xml_regex = xml_regexpressions->GetChildren();
|
||||
|
||||
pgsRegex regex;
|
||||
regex.set_first(1);
|
||||
|
||||
while (xml_regex && m_valid)
|
||||
{
|
||||
if (xml_regex->GetName() == wxT("characters"))
|
||||
{
|
||||
wxString content = xml_regex->GetNodeContent();
|
||||
for (size_t i = 0; i < content.Length(); i++)
|
||||
{
|
||||
regex.add_character(content[i]);
|
||||
}
|
||||
}
|
||||
else if (xml_regex->GetName() == wxT("range"))
|
||||
{
|
||||
wxString content = xml_regex->GetNodeContent();
|
||||
wxRegEx ex(wxT("^([0-9]+)(,([0-9]+))?$"));
|
||||
wxASSERT(ex.IsValid());
|
||||
if (ex.Matches(content))
|
||||
{
|
||||
long min;
|
||||
ex.GetMatch(content, 1).ToLong(&min);
|
||||
regex.set_first(min);
|
||||
wxString smax = ex.GetMatch(content, 3);
|
||||
if (!smax.IsEmpty())
|
||||
{
|
||||
long max;
|
||||
smax.ToLong(&max);
|
||||
regex.set_second(max);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
xml_regex = xml_regex->GetNext();
|
||||
}
|
||||
|
||||
m_string_gens.Add(pgsStringGen(regex.get_first(),
|
||||
regex.get_second(), 1, seed,
|
||||
regex.get_characters()));
|
||||
}
|
||||
|
||||
xml_regexpressions = xml_regexpressions->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxString pgsRegexGen::random()
|
||||
{
|
||||
wxString result;
|
||||
for (size_t i = 0; i < string_gens_size(); i++)
|
||||
{
|
||||
result.Append(m_string_gens.Item(i).random());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const pgsVectorStringGen &pgsRegexGen::string_gens() const
|
||||
{
|
||||
return m_string_gens;
|
||||
}
|
||||
|
||||
size_t pgsRegexGen::string_gens_size() const
|
||||
{
|
||||
return m_string_gens.size();
|
||||
}
|
||||
|
||||
const bool &pgsRegexGen::is_valid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
wxString pgsRegexGen::espace_xml_char(const wxChar &c)
|
||||
{
|
||||
if (c == wxT('<'))
|
||||
return wxT("<");
|
||||
else if (c == wxT('&'))
|
||||
return wxT("&");
|
||||
else if (c == wxT('>'))
|
||||
return wxT(">");
|
||||
else if (c == wxT('"'))
|
||||
return wxT(""");
|
||||
else if (c == wxT('\''))
|
||||
return wxT("'");
|
||||
else return wxString(c);
|
||||
}
|
||||
|
||||
wxString pgsRegexGen::char_range(const wxChar &b, const wxChar &c)
|
||||
{
|
||||
wxChar min = wxMin(b, c);
|
||||
++min;
|
||||
wxChar max = wxMax(b, c);
|
||||
wxString result;
|
||||
for (wxChar i = min; i < max; i++)
|
||||
{
|
||||
result.Append(espace_xml_char(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pgsRegexGen::~pgsRegexGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsRegexGen *pgsRegexGen::clone()
|
||||
{
|
||||
return pnew pgsRegexGen(*this);
|
||||
}
|
||||
83
pgscript/generators/pgsStringGen.cpp
Normal file
83
pgscript/generators/pgsStringGen.cpp
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsStringGen.h"
|
||||
|
||||
#include <wx/arrimpl.cpp>
|
||||
WX_DEFINE_OBJARRAY(pgsVectorChar);
|
||||
|
||||
pgsStringGen::pgsStringGen(USHORT w_size_min, USHORT w_size_max,
|
||||
const UCHAR &nb_words, const long &seed, pgsVectorChar characters) :
|
||||
pgsObjectGen(seed), m_nb_words(nb_words), m_characters(characters)
|
||||
{
|
||||
init_characters(); // Initialize vector if it is empty
|
||||
|
||||
const USHORT w_size_aux = w_size_min;
|
||||
w_size_min = wxMin(w_size_aux, w_size_max);
|
||||
w_size_max = wxMax(w_size_aux, w_size_max);
|
||||
|
||||
size_t char_count = m_characters.GetCount();
|
||||
m_w_size_randomizer = pgsRandomizer(pnew pgsIntegerGen(w_size_min,
|
||||
w_size_max, false, seed));
|
||||
m_letter_randomizer = pgsRandomizer(pnew pgsIntegerGen(0,
|
||||
wx_static_cast(long, char_count) - 1, false, seed));
|
||||
}
|
||||
|
||||
wxString pgsStringGen::random()
|
||||
{
|
||||
wxString str_result;
|
||||
long w_size;
|
||||
|
||||
for (UCHAR i = 0; i < m_nb_words; i++)
|
||||
{
|
||||
w_size = m_w_size_randomizer->random_long();
|
||||
for (long j = 0; j < w_size; j++)
|
||||
{
|
||||
str_result.Append(m_characters
|
||||
.Item(m_letter_randomizer->random_long()), 1);
|
||||
}
|
||||
if (w_size > 0 && m_nb_words != (i + 1))
|
||||
{
|
||||
str_result.Append(wxT(' '), 1);
|
||||
}
|
||||
}
|
||||
|
||||
return str_result;
|
||||
}
|
||||
|
||||
pgsStringGen::~pgsStringGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pgsStringGen::init_characters()
|
||||
{
|
||||
if (m_characters.size() == 0)
|
||||
{
|
||||
for (char c = '0'; c <= '9'; c++)
|
||||
{
|
||||
m_characters.push_back(c);
|
||||
}
|
||||
for (char c = 'A'; c <= 'Z'; c++)
|
||||
{
|
||||
m_characters.push_back(c);
|
||||
}
|
||||
for (char c = 'a'; c <= 'z'; c++)
|
||||
{
|
||||
m_characters.push_back(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pgsStringGen *pgsStringGen::clone()
|
||||
{
|
||||
return pnew pgsStringGen(*this);
|
||||
}
|
||||
52
pgscript/generators/pgsTimeGen.cpp
Normal file
52
pgscript/generators/pgsTimeGen.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/generators/pgsTimeGen.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
pgsTimeGen::pgsTimeGen(wxDateTime min, wxDateTime max, const bool &sequence,
|
||||
const long &seed) :
|
||||
pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max),
|
||||
m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min),
|
||||
m_range(m_max.Subtract(m_min).GetSeconds()), m_sequence(sequence)
|
||||
{
|
||||
m_min.SetYear(1970); // We know this date is not a DST date
|
||||
m_min.SetMonth(wxDateTime::Jan);
|
||||
m_min.SetDay(1);
|
||||
m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, std::string(m_range
|
||||
.ToString().mb_str()).c_str(), is_sequence(), m_seed));
|
||||
}
|
||||
|
||||
bool pgsTimeGen::is_sequence() const
|
||||
{
|
||||
return m_sequence;
|
||||
}
|
||||
|
||||
wxString pgsTimeGen::random()
|
||||
{
|
||||
wxTimeSpan time_span(0, 0, m_randomizer->random_long(), 0);
|
||||
wxDateTime aux_min(m_min);
|
||||
aux_min.Add(time_span);
|
||||
wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min));
|
||||
wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max));
|
||||
return aux_min.FormatISOTime();
|
||||
}
|
||||
|
||||
pgsTimeGen::~pgsTimeGen()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsTimeGen *pgsTimeGen::clone()
|
||||
{
|
||||
return pnew pgsTimeGen(*this);
|
||||
}
|
||||
2696
pgscript/lex.pgs.cc
Normal file
2696
pgscript/lex.pgs.cc
Normal file
File diff suppressed because it is too large
Load diff
29
pgscript/module.mk
Normal file
29
pgscript/module.mk
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/pgscript/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
pgscript/pgsApplication.cpp \
|
||||
pgscript/lex.pgs.cc \
|
||||
pgscript/parser.tab.cc
|
||||
|
||||
EXTRA_DIST += \
|
||||
pgscript/module.mk \
|
||||
pgscript/parser.sh \
|
||||
pgscript/pgsParser.yy \
|
||||
pgscript/pgsScanner.ll \
|
||||
pgscript/README
|
||||
|
||||
include pgscript/exceptions/module.mk
|
||||
include pgscript/expressions/module.mk
|
||||
include pgscript/generators/module.mk
|
||||
include pgscript/objects/module.mk
|
||||
include pgscript/statements/module.mk
|
||||
include pgscript/utilities/module.mk
|
||||
21
pgscript/objects/module.mk
Normal file
21
pgscript/objects/module.mk
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/pgscript/objects/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
pgscript/objects/pgsGenerator.cpp \
|
||||
pgscript/objects/pgsNumber.cpp \
|
||||
pgscript/objects/pgsRecord.cpp \
|
||||
pgscript/objects/pgsString.cpp \
|
||||
pgscript/objects/pgsVariable.cpp
|
||||
|
||||
EXTRA_DIST += \
|
||||
pgscript/objects/module.mk
|
||||
|
||||
154
pgscript/objects/pgsGenerator.cpp
Normal file
154
pgscript/objects/pgsGenerator.cpp
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/objects/pgsGenerator.h"
|
||||
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
#include "pgscript/exceptions/pgsCastException.h"
|
||||
|
||||
pgsGenerator::pgsGenerator(const pgsTypes &generator_type,
|
||||
pgsObjectGen *randomizer) :
|
||||
pgsVariable(generator_type), m_randomizer(randomizer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsGenerator::~pgsGenerator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsVariable *pgsGenerator::clone() const
|
||||
{
|
||||
return pnew pgsGenerator(*this);
|
||||
}
|
||||
|
||||
wxString pgsGenerator::value() const
|
||||
{
|
||||
return m_randomizer->random();
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::operand() const
|
||||
{
|
||||
switch (type())
|
||||
{
|
||||
case pgsTInt:
|
||||
return pnew pgsNumber(value(), pgsInt);
|
||||
case pgsTReal:
|
||||
return pnew pgsNumber(value(), pgsReal);
|
||||
default:
|
||||
return pnew pgsString(value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return this->clone();
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_plus(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() + rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_minus(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() - rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_times(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() * rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_over(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() / rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_modulo(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() % rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() == rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_different(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() != rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_greater(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() > rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_lower(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() < rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_lower_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() <= rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_greater_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() >= rhs;
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_not() const
|
||||
{
|
||||
return !(*operand());
|
||||
}
|
||||
|
||||
bool pgsGenerator::pgs_is_true() const
|
||||
{
|
||||
return operand()->pgs_is_true();
|
||||
}
|
||||
|
||||
pgsOperand pgsGenerator::pgs_almost_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
return *operand() &= rhs;
|
||||
}
|
||||
|
||||
pgsNumber pgsGenerator::number() const
|
||||
{
|
||||
wxString data = value().Strip(wxString::both);
|
||||
pgsTypes type = pgsNumber::num_type(data);
|
||||
switch (type)
|
||||
{
|
||||
case pgsTInt:
|
||||
return pgsNumber(data, pgsInt);
|
||||
case pgsTReal:
|
||||
return pgsNumber(data, pgsReal);
|
||||
default:
|
||||
throw pgsCastException(data, wxT("number"));
|
||||
}
|
||||
}
|
||||
|
||||
pgsRecord pgsGenerator::record() const
|
||||
{
|
||||
pgsRecord rec(1);
|
||||
rec.insert(0, 0, operand());
|
||||
return rec;
|
||||
}
|
||||
|
||||
pgsString pgsGenerator::string() const
|
||||
{
|
||||
return pgsString(value());
|
||||
}
|
||||
286
pgscript/objects/pgsNumber.cpp
Normal file
286
pgscript/objects/pgsNumber.cpp
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
|
||||
#include <wx/regex.h>
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
#include "pgscript/exceptions/pgsArithmeticException.h"
|
||||
#include "pgscript/exceptions/pgsCastException.h"
|
||||
|
||||
#define PGS_INTEGER_FORM_1 wxT("^[+-]?[0-9]+$")
|
||||
#define PGS_REAL_FORM_1 wxT("^[+-]?[0-9]+[Ee][+-]?[0-9]+$")
|
||||
#define PGS_REAL_FORM_2 wxT("^[+-]?[0-9]*[.][0-9]+([Ee][+-]?[0-9]+)?$")
|
||||
#define PGS_REAL_FORM_3 wxT("^[+-]?[0-9]+[.][0-9]*([Ee][+-]?[0-9]+)?$")
|
||||
|
||||
pgsNumber::pgsNumber(const wxString &data, const bool &is_real) :
|
||||
pgsVariable(!is_real ? pgsVariable::pgsTInt : pgsVariable::pgsTReal),
|
||||
m_data(data.Strip(wxString::both))
|
||||
{
|
||||
wxASSERT(is_valid());
|
||||
}
|
||||
|
||||
bool pgsNumber::is_valid() const
|
||||
{
|
||||
pgsTypes type = num_type(m_data);
|
||||
return (type == pgsTInt) || (type == pgsTReal && is_real());
|
||||
}
|
||||
|
||||
pgsNumber::~pgsNumber()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsNumber::pgsNumber(const pgsNumber &that) :
|
||||
pgsVariable(that), m_data(that.m_data)
|
||||
{
|
||||
wxASSERT(is_valid());
|
||||
}
|
||||
|
||||
pgsNumber &pgsNumber::operator =(const pgsNumber &that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
pgsVariable::operator=(that);
|
||||
m_data = that.m_data;
|
||||
}
|
||||
|
||||
wxASSERT(is_valid());
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
pgsVariable *pgsNumber::clone() const
|
||||
{
|
||||
return pnew pgsNumber(*this);
|
||||
}
|
||||
|
||||
wxString pgsNumber::value() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return this->clone();
|
||||
}
|
||||
|
||||
pgsVariable::pgsTypes pgsNumber::num_type(const wxString &num)
|
||||
{
|
||||
if (wxRegEx(PGS_INTEGER_FORM_1).Matches(num))
|
||||
{
|
||||
return pgsTInt;
|
||||
}
|
||||
else if (( wxRegEx(PGS_REAL_FORM_1).Matches(num)
|
||||
|| wxRegEx(PGS_REAL_FORM_2).Matches(num)
|
||||
|| wxRegEx(PGS_REAL_FORM_3).Matches(num)))
|
||||
{
|
||||
return pgsTReal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return pgsTString;
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_plus(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data)
|
||||
+ num(rhs.value())), is_real() || rhs.is_real());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_minus(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data)
|
||||
- num(rhs.value())), is_real() || rhs.is_real());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_times(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data)
|
||||
* num(rhs.value())), is_real() || rhs.is_real());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_over(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
if (num(rhs.value()) != 0)
|
||||
{
|
||||
if (is_real() || rhs.is_real())
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data)
|
||||
/ num(rhs.value())), is_real() || rhs.is_real());
|
||||
else
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data)
|
||||
.div(num(rhs.value()))), is_real() || rhs.is_real());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_modulo(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
if (num(rhs.value()) != 0)
|
||||
{
|
||||
return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data)
|
||||
% num(rhs.value())), is_real() || rhs.is_real());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) == num(rhs.value())
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_different(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) != num(rhs.value())
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_greater(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) > num(rhs.value())
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_lower(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) < num(rhs.value())
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_lower_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) <= num(rhs.value())
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_greater_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_number())
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) >= num(rhs.value())
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_not() const
|
||||
{
|
||||
return pnew pgsNumber(num(m_data) == 0 ? wxT("1") : wxT("0"));
|
||||
}
|
||||
|
||||
bool pgsNumber::pgs_is_true() const
|
||||
{
|
||||
return (num(m_data) != 0 ? true : false);
|
||||
}
|
||||
|
||||
pgsOperand pgsNumber::pgs_almost_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
return pgs_equal(rhs);
|
||||
}
|
||||
|
||||
pgsNumber pgsNumber::number() const
|
||||
{
|
||||
return pgsNumber(*this);
|
||||
}
|
||||
|
||||
pgsRecord pgsNumber::record() const
|
||||
{
|
||||
pgsRecord rec(1);;
|
||||
rec.insert(0, 0, this->clone());
|
||||
return rec;
|
||||
}
|
||||
|
||||
pgsString pgsNumber::string() const
|
||||
{
|
||||
return pgsString(m_data);
|
||||
}
|
||||
509
pgscript/objects/pgsRecord.cpp
Normal file
509
pgscript/objects/pgsRecord.cpp
Normal file
|
|
@ -0,0 +1,509 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
|
||||
#include "pgscript/expressions/pgsEqual.h"
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
#include "pgscript/exceptions/pgsArithmeticException.h"
|
||||
#include "pgscript/exceptions/pgsCastException.h"
|
||||
|
||||
#include <wx/arrimpl.cpp>
|
||||
|
||||
WX_DEFINE_OBJARRAY(pgsVectorRecordLine);
|
||||
WX_DEFINE_OBJARRAY(pgsVectorRecord);
|
||||
|
||||
pgsRecord::pgsRecord(const USHORT &nb_columns) :
|
||||
pgsVariable(pgsVariable::pgsTRecord)
|
||||
{
|
||||
m_columns.SetCount(nb_columns);
|
||||
}
|
||||
|
||||
pgsRecord::~pgsRecord()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsVariable *pgsRecord::clone() const
|
||||
{
|
||||
return pnew pgsRecord(*this);
|
||||
}
|
||||
|
||||
wxString pgsRecord::value() const
|
||||
{
|
||||
wxString data;
|
||||
pgsVarMap vars;
|
||||
|
||||
// Go through each line and enclose it into braces
|
||||
for (USHORT i = 0; i < count_lines(); i++)
|
||||
{
|
||||
data += wxT("(");
|
||||
|
||||
// Go through each column and separate them with commas
|
||||
for (USHORT j = 0; j < count_columns(); j++)
|
||||
{
|
||||
wxString elm(m_record[i][j]->eval(vars)->value());
|
||||
if (!m_record[i][j]->is_number())
|
||||
{
|
||||
elm.Replace(wxT("\\"), wxT("\\\\"));
|
||||
elm.Replace(wxT("\""), wxT("\\\""));
|
||||
elm = wxT("\"") + elm + wxT("\"");
|
||||
}
|
||||
data += elm + (j != count_columns() - 1 ? wxT(",") : wxT(""));
|
||||
}
|
||||
|
||||
data += (i == count_lines() - 1) ? wxT(")") : wxT(")\n");
|
||||
}
|
||||
|
||||
// Return the string representation of the record
|
||||
return data;
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return this->clone();
|
||||
}
|
||||
|
||||
USHORT pgsRecord::count_lines() const
|
||||
{
|
||||
return m_record.GetCount();
|
||||
}
|
||||
|
||||
USHORT pgsRecord::count_columns() const
|
||||
{
|
||||
return m_columns.GetCount();
|
||||
}
|
||||
|
||||
bool pgsRecord::insert(const USHORT &line, const USHORT &column,
|
||||
pgsOperand value)
|
||||
{
|
||||
// Add lines to match the line number provided
|
||||
for (USHORT i = count_lines(); i <= line; i++)
|
||||
{
|
||||
newline();
|
||||
}
|
||||
|
||||
// Cannot insert if column is invalid
|
||||
if (column >= count_columns())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Insert the value at line.column
|
||||
else
|
||||
{
|
||||
m_record[line][column] = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::get(const USHORT &line,
|
||||
const USHORT &column) const
|
||||
{
|
||||
if (line < count_lines() && column < count_columns())
|
||||
{
|
||||
return m_record[line][column];
|
||||
}
|
||||
else
|
||||
{
|
||||
return pnew pgsString(wxT(""));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
bool pgsRecord::set_column_name(const USHORT &column, wxString name)
|
||||
{
|
||||
// Column number must be valid
|
||||
if (column >= count_columns())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Column name must not exist
|
||||
// Column name must not be empty
|
||||
name = name.Strip(wxString::both).Lower();
|
||||
if (m_columns.Index(name) != wxNOT_FOUND || name.IsEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the column name
|
||||
m_columns[column] = name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
USHORT pgsRecord::get_column(wxString name) const
|
||||
{
|
||||
name = name.Strip(wxString::both).Lower();
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
return count_columns();
|
||||
}
|
||||
for (USHORT i = 0; i < count_columns(); i++)
|
||||
{
|
||||
if (m_columns[i] == name)
|
||||
return i;
|
||||
}
|
||||
return count_columns();
|
||||
}
|
||||
|
||||
bool pgsRecord::remove_line(const USHORT &line)
|
||||
{
|
||||
if (line < count_lines())
|
||||
{
|
||||
m_record.RemoveAt(line);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pgsRecord::newline()
|
||||
{
|
||||
// Insert a line
|
||||
m_record.Add(pgsVectorRecordLine());
|
||||
// Initialize each column of the line with an empty string
|
||||
for (USHORT i = 0; i < count_columns(); i++)
|
||||
{
|
||||
m_record.Last().Add(pnew pgsString(wxT("")));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pgsRecord::valid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pgsRecord::operator==(const pgsRecord &rhs) const
|
||||
{
|
||||
// Test the number of lines
|
||||
if (this->count_lines() != rhs.count_lines())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return records_equal(*this, rhs, true);
|
||||
}
|
||||
|
||||
bool pgsRecord::operator!=(const pgsRecord &rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
bool pgsRecord::operator<(const pgsRecord &rhs) const
|
||||
{
|
||||
// Test the number of lines
|
||||
if (this->count_lines() >= rhs.count_lines())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return records_equal(*this, rhs, true);
|
||||
}
|
||||
|
||||
bool pgsRecord::operator>(const pgsRecord &rhs) const
|
||||
{
|
||||
return (rhs < *this);
|
||||
}
|
||||
|
||||
bool pgsRecord::operator<=(const pgsRecord &rhs) const
|
||||
{
|
||||
// Test the number of lines
|
||||
if (this->count_lines() > rhs.count_lines())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return records_equal(*this, rhs, true);
|
||||
}
|
||||
|
||||
bool pgsRecord::operator>=(const pgsRecord &rhs) const
|
||||
{
|
||||
return (rhs <= *this);
|
||||
}
|
||||
|
||||
bool pgsRecord::almost_equal(const pgsRecord &rhs) const
|
||||
{
|
||||
// Test the number of lines
|
||||
if (this->count_lines() != rhs.count_lines())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return records_equal(*this, rhs, false);
|
||||
}
|
||||
|
||||
bool pgsRecord::records_equal(const pgsRecord &lhs, const pgsRecord &rhs,
|
||||
bool case_sensitive) const
|
||||
{
|
||||
// Test the number of columns
|
||||
if (lhs.count_columns() != rhs.count_columns())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test each line
|
||||
wxArrayInt seen;
|
||||
for (USHORT i = 0; i < lhs.count_lines(); i++)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
// Test if the line of lhs matches with an unseen line of rhs
|
||||
for (USHORT j = 0; result == false && j < rhs.count_lines(); j++)
|
||||
{
|
||||
int k = wx_static_cast(int, j);
|
||||
if (seen.Index(k) == wxNOT_FOUND
|
||||
&& lines_equal(lhs.m_record[i], rhs.m_record[j],
|
||||
case_sensitive))
|
||||
{
|
||||
result = true;
|
||||
seen.push_back(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is not OK... Continue with the next element
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // End of the test
|
||||
}
|
||||
|
||||
bool pgsRecord::lines_equal(const pgsVectorRecordLine &lhs,
|
||||
const pgsVectorRecordLine &rhs, bool case_sensitive) const
|
||||
{
|
||||
pgsVarMap vars;
|
||||
|
||||
// Both lines must have the same number of columns
|
||||
if (lhs.GetCount() != rhs.GetCount())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test each element (column) of the line
|
||||
for (USHORT j = 0; j < wx_static_cast(USHORT, lhs.GetCount()); j++)
|
||||
{
|
||||
// Test if the two elements are equal
|
||||
pgsEqual test(lhs[j]->string().clone(), rhs[j]->string().clone(),
|
||||
case_sensitive);
|
||||
if (test.eval(vars)->value() == wxT("1"))
|
||||
{
|
||||
// lhs == rhs: continue
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// lhs != rhs: lines are not equal
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_plus(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_minus(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_times(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_over(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_modulo(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(*this == rhs_op ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_different(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(*this != rhs_op ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_greater(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(*this > rhs_op ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_lower(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(*this < rhs_op ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_lower_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(*this <= rhs_op ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_greater_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(*this >= rhs_op ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
bool pgsRecord::pgs_is_true() const
|
||||
{
|
||||
return (count_lines() > 0 ? true : false);
|
||||
}
|
||||
|
||||
pgsOperand pgsRecord::pgs_almost_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_record())
|
||||
{
|
||||
const pgsRecord &rhs_op = dynamic_cast<const pgsRecord &>(rhs);
|
||||
return pnew pgsNumber(this->almost_equal(rhs_op) ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(value(), rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsNumber pgsRecord::number() const
|
||||
{
|
||||
wxString data = value().Strip(wxString::both);
|
||||
|
||||
if (data.StartsWith(wxT("(")))
|
||||
{
|
||||
data = data.Mid(1);
|
||||
}
|
||||
|
||||
if (data.EndsWith(wxT(")")))
|
||||
{
|
||||
data = data.Mid(0, data.Len() - 1);
|
||||
}
|
||||
|
||||
pgsTypes type = pgsNumber::num_type(data);
|
||||
switch (type)
|
||||
{
|
||||
case pgsTInt:
|
||||
return pgsNumber(data, pgsInt);
|
||||
case pgsTReal:
|
||||
return pgsNumber(data, pgsReal);
|
||||
default:
|
||||
throw pgsCastException(data, wxT("number"));
|
||||
}
|
||||
}
|
||||
|
||||
pgsRecord pgsRecord::record() const
|
||||
{
|
||||
return pgsRecord(*this);
|
||||
}
|
||||
|
||||
pgsString pgsRecord::string() const
|
||||
{
|
||||
return pgsString(value());
|
||||
}
|
||||
290
pgscript/objects/pgsString.cpp
Normal file
290
pgscript/objects/pgsString.cpp
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
|
||||
#include <wx/regex.h>
|
||||
#include "pgscript/objects/pgsNumber.h"
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
#include "pgscript/exceptions/pgsArithmeticException.h"
|
||||
#include "pgscript/exceptions/pgsCastException.h"
|
||||
|
||||
pgsString::pgsString(const wxString &data) :
|
||||
pgsVariable(pgsVariable::pgsTString), m_data(data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsString::~pgsString()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsVariable *pgsString::clone() const
|
||||
{
|
||||
return pnew pgsString(*this);
|
||||
}
|
||||
|
||||
wxString pgsString::value() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
pgsOperand pgsString::eval(pgsVarMap &vars) const
|
||||
{
|
||||
return this->clone();
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_plus(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsString(m_data + rhs.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_minus(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_times(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_over(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_modulo(const pgsVariable &rhs) const
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data == rhs.value() ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_different(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data != rhs.value() ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_greater(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data > rhs.value() ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_lower(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data < rhs.value() ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_lower_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data <= rhs.value() ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_greater_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data >= rhs.value() ? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_not() const
|
||||
{
|
||||
wxString data = m_data.Strip(wxString::both);
|
||||
return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT(""));
|
||||
}
|
||||
|
||||
bool pgsString::pgs_is_true() const
|
||||
{
|
||||
wxString data = m_data.Strip(wxString::both);
|
||||
return (!data.IsEmpty() ? true : false);
|
||||
}
|
||||
|
||||
pgsOperand pgsString::pgs_almost_equal(const pgsVariable &rhs) const
|
||||
{
|
||||
if (rhs.is_string())
|
||||
{
|
||||
return pnew pgsNumber(m_data.CmpNoCase(rhs.value()) == 0
|
||||
? wxT("1") : wxT("0"));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw pgsArithmeticException(m_data, rhs.value());
|
||||
}
|
||||
}
|
||||
|
||||
pgsNumber pgsString::number() const
|
||||
{
|
||||
wxString data = m_data.Strip(wxString::both);
|
||||
pgsTypes type = pgsNumber::num_type(data);
|
||||
switch (type)
|
||||
{
|
||||
case pgsTInt:
|
||||
return pgsNumber(data, pgsInt);
|
||||
case pgsTReal:
|
||||
return pgsNumber(data, pgsReal);
|
||||
default:
|
||||
throw pgsCastException(data, wxT("number"));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pgsString pgsString::string() const
|
||||
{
|
||||
return pgsString(*this);
|
||||
}
|
||||
128
pgscript/objects/pgsVariable.cpp
Normal file
128
pgscript/objects/pgsVariable.cpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/objects/pgsVariable.h"
|
||||
|
||||
pgsVariable::pgsVariable(const pgsTypes &type) :
|
||||
pgsExpression(), m_type(type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsVariable::~pgsVariable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MAPM pgsVariable::num(const pgsOperand &var)
|
||||
{
|
||||
return pgsMapm::pgs_str_mapm(var->value());
|
||||
}
|
||||
|
||||
MAPM pgsVariable::num(const wxString &var)
|
||||
{
|
||||
return pgsMapm::pgs_str_mapm(var);
|
||||
}
|
||||
|
||||
bool pgsVariable::is_number() const
|
||||
{
|
||||
return is_integer() || is_real();
|
||||
}
|
||||
|
||||
bool pgsVariable::is_integer() const
|
||||
{
|
||||
return m_type == pgsTInt;
|
||||
}
|
||||
|
||||
bool pgsVariable::is_real() const
|
||||
{
|
||||
return m_type == pgsTReal;
|
||||
}
|
||||
|
||||
bool pgsVariable::is_string() const
|
||||
{
|
||||
return m_type == pgsTString;
|
||||
}
|
||||
|
||||
bool pgsVariable::is_record() const
|
||||
{
|
||||
return m_type == pgsTRecord;
|
||||
}
|
||||
|
||||
const pgsVariable::pgsTypes &pgsVariable::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
pgsOperand operator+(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_plus(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator-(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_minus(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator*(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_times(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator/(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_over(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator%(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_modulo(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator==(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_equal(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator!=(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_different(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator<(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_lower(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator>(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_greater(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator<=(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_lower_equal(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator>=(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_greater_equal(rhs);
|
||||
}
|
||||
|
||||
pgsOperand operator!(const pgsVariable &lhs)
|
||||
{
|
||||
return lhs.pgs_not();
|
||||
}
|
||||
|
||||
pgsOperand operator&=(const pgsVariable &lhs, const pgsVariable &rhs)
|
||||
{
|
||||
return lhs.pgs_almost_equal(rhs);
|
||||
}
|
||||
80
pgscript/parser.sh
Normal file
80
pgscript/parser.sh
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/sh
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# parser.sh - Runs Flex and Bison and processes the generated files
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
# Directory containing pgScript includes (relative to the src directory)
|
||||
INCLUDEDIR="include/pgscript"
|
||||
# Directory containing pgScript sources (relative to the src directory)
|
||||
SOURCEDIR="pgscript"
|
||||
# Headers generated by Bison that need to be moved to ${INCLUDEDIR}
|
||||
FILESTOMOVE=( "location.hh" "parser.tab.hh" "position.hh" "stack.hh" )
|
||||
|
||||
# Flex destination
|
||||
LEXER="pgscript/lex.pgs.cc"
|
||||
# A temporary file
|
||||
AUX="pgscript/auxfile"
|
||||
# Bison destination
|
||||
PARSER="pgscript/parser.tab.cc"
|
||||
|
||||
#######################################################################
|
||||
|
||||
# Find the current directory
|
||||
THISDIR=`dirname $0`
|
||||
PREVDIR="$PWD"
|
||||
|
||||
# Go to the directory on top of the script directory
|
||||
echo -n "cd ${THISDIR}/.. ... "
|
||||
cd "${THISDIR}/.."
|
||||
echo "done"
|
||||
pwd
|
||||
echo ""
|
||||
|
||||
# Generate Bison file
|
||||
echo -n "+ Generating Bison output... "
|
||||
bison -o"${PARSER}" "${SOURCEDIR}/pgsParser.yy"
|
||||
echo "done"
|
||||
|
||||
# Generate Flex file
|
||||
echo -n "+ Generating Flex output... "
|
||||
flex -o"${LEXER}" "${SOURCEDIR}/pgsScanner.ll"
|
||||
echo "done"
|
||||
|
||||
# Add pgAdmin3.h include at the beginning and change <FlexLexer.h> to
|
||||
# "pgscript/FlexLexer.h" for the Flex output
|
||||
echo -n "+ Processing Flex output... "
|
||||
cat "${LEXER}" | awk 'BEGIN {print "#include \"pgAdmin3.h\"\n\n"}{print $0}' \
|
||||
| sed -e 's/<FlexLexer\.h>/"pgscript\/FlexLexer\.h"/g' > "${AUX}"
|
||||
mv -f "${AUX}" "${LEXER}"
|
||||
echo "done"
|
||||
|
||||
# Add pgAdmin3.h include at the beginning and a pragma and change
|
||||
# "parser.tab.hh" to "pgscript/parser.tab.hh" to the Bison output
|
||||
echo -n "+ Processing Bison output... "
|
||||
cat "${PARSER}" | awk 'BEGIN {print "#include \"pgAdmin3.h\"\n#if _MSC_VER > 1000\n#pragma warning(disable: 4800)\n#endif\n"}{print $0}' | \
|
||||
sed -e 's/"parser.tab.hh"/"pgscript\/parser\.tab\.hh"/g' > "${AUX}"
|
||||
sleep 1
|
||||
mv -f "${AUX}" "${PARSER}"
|
||||
echo "done"
|
||||
|
||||
# Move Bison include files to the include directory
|
||||
echo + "Moving Bison header files... "
|
||||
for file in ${FILESTOMOVE[@]}
|
||||
do
|
||||
echo " + mv ${SOURCEDIR}/${file} ${INCLUDEDIR}/${file}"
|
||||
mv "${SOURCEDIR}/${file}" "${INCLUDEDIR}/${file}"
|
||||
done
|
||||
echo "... done"
|
||||
|
||||
# Go back to the previous directory
|
||||
echo ""
|
||||
echo -n "cd $PREVDIR ... "
|
||||
cd "$PREVDIR"
|
||||
echo "done"
|
||||
2703
pgscript/parser.tab.cc
Normal file
2703
pgscript/parser.tab.cc
Normal file
File diff suppressed because it is too large
Load diff
215
pgscript/pgsApplication.cpp
Normal file
215
pgscript/pgsApplication.cpp
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/pgsApplication.h"
|
||||
|
||||
#include "db/pgConn.h"
|
||||
#include "pgscript/expressions/pgsAssign.h"
|
||||
#include "pgscript/expressions/pgsIdent.h"
|
||||
#include "pgscript/objects/pgsString.h"
|
||||
#include "pgscript/utilities/pgsThread.h"
|
||||
|
||||
pgsApplication::pgsApplication(const wxString &host, const wxString &database,
|
||||
const wxString &user, const wxString &password, int port) :
|
||||
m_mutex(1, 1), m_stream(1, 1), m_connection(pnew pgConn(host, wxEmptyString, wxEmptyString, database, user,
|
||||
password, port)), m_defined_conn(true), m_thread(0), m_caller(0)
|
||||
{
|
||||
if (m_connection->GetStatus() != PGCONN_OK)
|
||||
{
|
||||
wxLogError(wxT("PGSCRIPT: Cannot connect to database %s:%d/%s with ")
|
||||
wxT("credentials '%s'/'%s'"), host.c_str(), port, database.c_str(),
|
||||
user.c_str(), password.c_str());
|
||||
}
|
||||
|
||||
wxLogScript(wxT("Application created"));
|
||||
}
|
||||
|
||||
pgsApplication::pgsApplication(pgConn *connection) :
|
||||
m_mutex(1, 1), m_stream(1, 1), m_connection(connection),
|
||||
m_defined_conn(false), m_thread(0), m_caller(0)
|
||||
{
|
||||
wxLogScript(wxT("Application created"));
|
||||
}
|
||||
|
||||
pgsApplication::~pgsApplication()
|
||||
{
|
||||
if (m_defined_conn)
|
||||
{
|
||||
pdelete(m_connection);
|
||||
}
|
||||
|
||||
wxLogScript(wxT("Application destroyed"));
|
||||
}
|
||||
|
||||
bool pgsApplication::ParseFile(const wxString &file, pgsOutputStream &out,
|
||||
wxMBConv *conv)
|
||||
{
|
||||
if (!IsRunning())
|
||||
{
|
||||
m_last_error_line = -1;
|
||||
m_thread = new pgsThread(m_vars, m_mutex, m_connection,
|
||||
file, out, *this, conv);
|
||||
return RunThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool pgsApplication::ParseString(const wxString &string,
|
||||
pgsOutputStream &out)
|
||||
{
|
||||
if (!IsRunning())
|
||||
{
|
||||
m_last_error_line = -1;
|
||||
m_thread = new pgsThread(m_vars, m_mutex, m_connection,
|
||||
string, out, *this);
|
||||
return RunThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool pgsApplication::RunThread()
|
||||
{
|
||||
bool created = false;
|
||||
|
||||
if (m_thread != 0 && m_thread->Create() == wxTHREAD_NO_ERROR)
|
||||
{
|
||||
m_thread->SetPriority(WXTHREAD_MIN_PRIORITY);
|
||||
|
||||
if (m_thread->Run() == wxTHREAD_NO_ERROR)
|
||||
{
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (created)
|
||||
{
|
||||
wxLogScript(wxT("Running..."));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError(wxT("PGSCRIPT: Thread error"));
|
||||
pdelete(m_thread);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool pgsApplication::IsRunning()
|
||||
{
|
||||
if (m_mutex.TryWait() == wxSEMA_NO_ERROR)
|
||||
{
|
||||
m_mutex.Post();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void pgsApplication::Wait()
|
||||
{
|
||||
if (IsRunning())
|
||||
{
|
||||
wxLogScript(wxT("Waiting for pgScript"));
|
||||
m_mutex.Wait();
|
||||
m_mutex.Post();
|
||||
}
|
||||
}
|
||||
|
||||
void pgsApplication::Terminate()
|
||||
{
|
||||
if (IsRunning())
|
||||
{
|
||||
wxLogScript(wxT("Deleting pgScript"));
|
||||
m_thread->Delete();
|
||||
}
|
||||
}
|
||||
|
||||
void pgsApplication::Complete()
|
||||
{
|
||||
// If last_error_line() == -1 then there was no error
|
||||
// Else get the line number where the error occurred
|
||||
m_last_error_line = m_thread->last_error_line();
|
||||
|
||||
#if !defined(PGSCLI)
|
||||
if (m_caller != 0)
|
||||
{
|
||||
wxCommandEvent resultEvent(wxEVT_COMMAND_MENU_SELECTED, m_event_id);
|
||||
|
||||
#if wxCHECK_VERSION(2, 9, 0)
|
||||
m_caller->GetEventHandler()->AddPendingEvent(resultEvent);
|
||||
#else
|
||||
m_caller->AddPendingEvent(resultEvent);
|
||||
#endif
|
||||
}
|
||||
#endif // PGSCLI
|
||||
|
||||
wxLogScript(wxT("Execution completed"));
|
||||
}
|
||||
|
||||
void pgsApplication::SetConnection(pgConn *conn)
|
||||
{
|
||||
if (m_defined_conn)
|
||||
{
|
||||
pdelete(m_connection);
|
||||
m_defined_conn = false;
|
||||
}
|
||||
|
||||
m_connection = conn;
|
||||
}
|
||||
|
||||
void pgsApplication::ClearSymbols()
|
||||
{
|
||||
if (!IsRunning())
|
||||
{
|
||||
m_vars.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(PGSCLI)
|
||||
void pgsApplication::SetCaller(wxWindow *caller, long event_id)
|
||||
{
|
||||
m_caller = caller;
|
||||
m_event_id = event_id;
|
||||
}
|
||||
#endif // PGSCLI
|
||||
|
||||
bool pgsApplication::IsConnectionValid() const
|
||||
{
|
||||
return (m_connection->GetStatus() == PGCONN_OK);
|
||||
}
|
||||
|
||||
void pgsApplication::LockOutput()
|
||||
{
|
||||
m_stream.Wait();
|
||||
}
|
||||
|
||||
void pgsApplication::UnlockOutput()
|
||||
{
|
||||
m_stream.Post();
|
||||
}
|
||||
|
||||
bool pgsApplication::errorOccurred() const
|
||||
{
|
||||
return (m_last_error_line != -1);
|
||||
}
|
||||
|
||||
int pgsApplication::errorLine() const
|
||||
{
|
||||
return m_last_error_line;
|
||||
}
|
||||
1045
pgscript/pgsParser.yy
Normal file
1045
pgscript/pgsParser.yy
Normal file
File diff suppressed because it is too large
Load diff
421
pgscript/pgsScanner.ll
Normal file
421
pgscript/pgsScanner.ll
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
L [a-zA-Z_@#]
|
||||
D [0-9]
|
||||
E [e-eE-E][+-]?{D}+
|
||||
|
||||
%{ /*** C/C++ Declarations ***/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pgscript/pgScript.h"
|
||||
#include "pgscript/parser.tab.hh"
|
||||
#include "pgscript/utilities/pgsScanner.h"
|
||||
|
||||
/* Import the parser's token type into a local typedef */
|
||||
typedef pgscript::pgsParser::token token;
|
||||
typedef pgscript::pgsParser::token_type token_type;
|
||||
|
||||
/* Work around an incompatibility in flex (at least versions 2.5.31 through
|
||||
* 2.5.33): it generates code that does not conform to C89. See Debian bug
|
||||
* 333231 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */
|
||||
#undef yywrap
|
||||
#define yywrap() 1
|
||||
|
||||
/* By default yylex returns int, we use token_type. Unfortunately yyterminate
|
||||
* by default returns 0, which is not of token_type. */
|
||||
#define yyterminate() return token::PGS_END
|
||||
|
||||
/* This disables inclusion of unistd.h, which is not available under Visual C++
|
||||
* on Win32. The C++ scanner uses STL streams instead. */
|
||||
#define YY_NO_UNISTD_H
|
||||
|
||||
%}
|
||||
|
||||
/*** Flex Declarations and Options ***/
|
||||
|
||||
/* Enable C++ scanner class generation */
|
||||
%option c++
|
||||
|
||||
/* Change the name of the scanner class. Results in "pgsFlexLexer" */
|
||||
%option prefix="pgs"
|
||||
|
||||
/* Case insensitive */
|
||||
%option case-insensitive
|
||||
|
||||
/* The manual says "somewhat more optimized" */
|
||||
%option batch
|
||||
|
||||
/* Prevent isatty warning in VC++ */
|
||||
%option never-interactive
|
||||
|
||||
/* For using start conditions */
|
||||
%option stack
|
||||
|
||||
/* No support for include files is planned */
|
||||
%option noyywrap
|
||||
|
||||
/* The following paragraph suffices to track locations accurately. Each time
|
||||
* yylex is invoked, the begin position is moved onto the end position. */
|
||||
%{
|
||||
#define YY_USER_ACTION yylloc->columns(yyleng);
|
||||
%}
|
||||
|
||||
%x SC_COMMENT
|
||||
%x SC_QUERY
|
||||
%x SC_DOLLAR
|
||||
%x SC_STRING
|
||||
|
||||
%% /*** Regular Expressions Part ***/
|
||||
|
||||
/* Code to place at the beginning of yylex() */
|
||||
%{
|
||||
// Reset location
|
||||
yylloc->step();
|
||||
%}
|
||||
|
||||
<INITIAL,SC_QUERY>"--".*$ { /* Ignore SQL comment */ }
|
||||
<INITIAL>"/*" { comment_caller = INITIAL; BEGIN(SC_COMMENT); }
|
||||
<SC_QUERY>"/*" { comment_caller = SC_QUERY; BEGIN(SC_COMMENT); }
|
||||
|
||||
<INITIAL>{
|
||||
"WHILE" { return token::PGS_WHILE; }
|
||||
"BREAK" { return token::PGS_BREAK; }
|
||||
"RETURN" { return token::PGS_RETURN; }
|
||||
"CONTINUE" { return token::PGS_CONTINUE; }
|
||||
"IF" { return token::PGS_IF; }
|
||||
"ELSE" { return token::PGS_ELSE; }
|
||||
"WAITFOR" { return token::PGS_WAITFOR; }
|
||||
"AS" { return token::PGS_AS; }
|
||||
|
||||
"ASSERT" { return token::PGS_ASSERT; }
|
||||
"GO" { /* Ignore it */ }
|
||||
"PRINT" { return token::PGS_PRINT; }
|
||||
|
||||
"COLUMNS" { return token::PGS_CNT_COLUMNS; }
|
||||
"LINES" { return token::PGS_CNT_LINES; }
|
||||
"TRIM" { return token::PGS_TRIM; }
|
||||
"RMLINE" { return token::PGS_RM_LINE; }
|
||||
"CAST" { return token::PGS_CAST; }
|
||||
|
||||
"RECORD" { return token::PGS_RECORD; }
|
||||
|
||||
"INTEGER" { return token::PGS_INTEGER; }
|
||||
"REAL" { return token::PGS_REAL; }
|
||||
"STRING" { return token::PGS_STRING; }
|
||||
"REGEX" { return token::PGS_REGEX; }
|
||||
"FILE" { return token::PGS_FILE; }
|
||||
"DATE" { return token::PGS_DATE; }
|
||||
"TIME" { return token::PGS_TIME; }
|
||||
"DATETIME" { return token::PGS_DATE_TIME; }
|
||||
"REFERENCE" { return token::PGS_REFERENCE; }
|
||||
|
||||
|
||||
"SET"[ \t]+"@" { unput('@'); yylloc->end.columns(-1);
|
||||
return token::PGS_SET_ASSIGN; }
|
||||
"DECLARE"[ \t]+"@" { unput('@'); yylloc->end.columns(-1);
|
||||
return token::PGS_DECLARE_ASSGN; }
|
||||
|
||||
"BEGIN" { /* Block opening */ return token::PGS_OPEN; }
|
||||
"END" { /* Block closing */ return token::PGS_CLOSE; }
|
||||
|
||||
"@"({L}|{D})* { yylval->str = pnew wxString(yytext, m_conv);
|
||||
return token::PGS_IDENTIFIER; }
|
||||
|
||||
{D}+ { yylval->str = pnew wxString(yytext, m_conv);
|
||||
return token::PGS_VAL_INT; }
|
||||
|
||||
{D}*"."{D}+({E})? { yylval->str = pnew wxString(yytext, m_conv);
|
||||
return token::PGS_VAL_REAL; }
|
||||
{D}+{E} { yylval->str = pnew wxString(yytext, m_conv);
|
||||
return token::PGS_VAL_REAL; }
|
||||
{D}+"."{D}*({E})? { yylval->str = pnew wxString(yytext, m_conv);
|
||||
return token::PGS_VAL_REAL; }
|
||||
|
||||
"AND" { return token::PGS_AND_OP; }
|
||||
"OR" { return token::PGS_OR_OP; }
|
||||
"<=" { return token::PGS_LE_OP; }
|
||||
">=" { return token::PGS_GE_OP; }
|
||||
"=" { return token::PGS_EQ_OP; }
|
||||
"~=" { return token::PGS_AE_OP; }
|
||||
"<>" { return token::PGS_NE_OP; }
|
||||
";" { return wx_static_cast(token_type, ';'); }
|
||||
("{"|"<%") { return wx_static_cast(token_type, '{'); }
|
||||
("}"|"%>") { return wx_static_cast(token_type, '}'); }
|
||||
":" { return wx_static_cast(token_type, ':'); }
|
||||
"(" { return wx_static_cast(token_type, '('); }
|
||||
")" { return wx_static_cast(token_type, ')'); }
|
||||
("["|"<:") { return wx_static_cast(token_type, '['); }
|
||||
("]"|":>") { return wx_static_cast(token_type, ']'); }
|
||||
"." { return wx_static_cast(token_type, '.'); }
|
||||
"," { return wx_static_cast(token_type, ','); }
|
||||
"NOT" { return token::PGS_NOT_OP; }
|
||||
"-" { return wx_static_cast(token_type, '-'); }
|
||||
"+" { return wx_static_cast(token_type, '+'); }
|
||||
"*" { return wx_static_cast(token_type, '*'); }
|
||||
"/" { return wx_static_cast(token_type, '/'); }
|
||||
"%" { return wx_static_cast(token_type, '%'); }
|
||||
"<" { return wx_static_cast(token_type, '<'); }
|
||||
">" { return wx_static_cast(token_type, '>'); }
|
||||
|
||||
"'" { string_caller = INITIAL; BEGIN(SC_STRING); }
|
||||
|
||||
"ABORT" { query += yytext; query_token = token::PGS_ABORT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"ALTER" { query += yytext; query_token = token::PGS_ALTER;
|
||||
BEGIN(SC_QUERY); }
|
||||
"ANALYZE" { query += yytext; query_token = token::PGS_ANALYZE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"BEGIN"[ \t]+"TRAN" { query += yytext; query_token = token::PGS_BEGIN;
|
||||
BEGIN(SC_QUERY); }
|
||||
"BEGIN"[ \t]+"WORK" { query += yytext; query_token = token::PGS_BEGIN;
|
||||
BEGIN(SC_QUERY); }
|
||||
"CHECKPOINT" { query += yytext; query_token = token::PGS_CHECKPOINT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"CLOSE" { query += yytext; query_token = token::PGS_CLOSE_ST;
|
||||
BEGIN(SC_QUERY); }
|
||||
"CLUSTER" { query += yytext; query_token = token::PGS_CLUSTER;
|
||||
BEGIN(SC_QUERY); }
|
||||
"COMMENT" { query += yytext; query_token = token::PGS_COMMENT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"COMMIT" { query += yytext; query_token = token::PGS_COMMIT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"COPY" { query += yytext; query_token = token::PGS_COPY;
|
||||
BEGIN(SC_QUERY); }
|
||||
"CREATE" { query += yytext; query_token = token::PGS_CREATE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"DEALLOCATE" { query += yytext; query_token = token::PGS_DEALLOCATE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"DECLARE" { query += yytext; query_token = token::PGS_DECLARE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"DELETE" { query += yytext; query_token = token::PGS_DELETE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"DISCARD" { query += yytext; query_token = token::PGS_DISCARD;
|
||||
BEGIN(SC_QUERY); }
|
||||
"DROP" { query += yytext; query_token = token::PGS_DROP;
|
||||
BEGIN(SC_QUERY); }
|
||||
"END"[ \t]+"TRANS" { query += yytext; query_token = token::PGS_END_ST;
|
||||
BEGIN(SC_QUERY); }
|
||||
"END"[ \t]+"WORK" { query += yytext; query_token = token::PGS_END_ST;
|
||||
BEGIN(SC_QUERY); }
|
||||
"EXECUTE" { query += yytext; query_token = token::PGS_EXECUTE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"EXPLAIN" { query += yytext; query_token = token::PGS_EXPLAIN;
|
||||
BEGIN(SC_QUERY); }
|
||||
"FETCH" { query += yytext; query_token = token::PGS_FETCH;
|
||||
BEGIN(SC_QUERY); }
|
||||
"GRANT" { query += yytext; query_token = token::PGS_GRANT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"INSERT" { query += yytext; query_token = token::PGS_INSERT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"LISTEN" { query += yytext; query_token = token::PGS_LISTEN;
|
||||
BEGIN(SC_QUERY); }
|
||||
"LOAD" { query += yytext; query_token = token::PGS_LOAD;
|
||||
BEGIN(SC_QUERY); }
|
||||
"LOCK" { query += yytext; query_token = token::PGS_LOCK;
|
||||
BEGIN(SC_QUERY); }
|
||||
"MOVE" { query += yytext; query_token = token::PGS_MOVE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"NOTIFY" { query += yytext; query_token = token::PGS_NOTIFY;
|
||||
BEGIN(SC_QUERY); }
|
||||
"PREPARE" { query += yytext; query_token = token::PGS_PREPARE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"REASSIGN" { query += yytext; query_token = token::PGS_REASSIGN;
|
||||
BEGIN(SC_QUERY); }
|
||||
"REINDEX" { query += yytext; query_token = token::PGS_REINDEX;
|
||||
BEGIN(SC_QUERY); }
|
||||
"RELEASE" { query += yytext; query_token = token::PGS_RELEASE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"RESET" { query += yytext; query_token = token::PGS_RESET;
|
||||
BEGIN(SC_QUERY); }
|
||||
"REVOKE" { query += yytext; query_token = token::PGS_REVOKE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"ROLLBACK" { query += yytext; query_token = token::PGS_ROLLBACK;
|
||||
BEGIN(SC_QUERY); }
|
||||
"SAVEPOINT" { query += yytext; query_token = token::PGS_SAVEPOINT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"SELECT" { query += yytext; query_token = token::PGS_SELECT;
|
||||
BEGIN(SC_QUERY); }
|
||||
"SET" { query += yytext; query_token = token::PGS_SET;
|
||||
BEGIN(SC_QUERY); }
|
||||
"SHOW" { query += yytext; query_token = token::PGS_SHOW;
|
||||
BEGIN(SC_QUERY); }
|
||||
"START" { query += yytext; query_token = token::PGS_START;
|
||||
BEGIN(SC_QUERY); }
|
||||
"TRUNCATE" { query += yytext; query_token = token::PGS_TRUNCATE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"UNLISTEN" { query += yytext; query_token = token::PGS_UNLISTEN;
|
||||
BEGIN(SC_QUERY); }
|
||||
"UPDATE" { query += yytext; query_token = token::PGS_UPDATE;
|
||||
BEGIN(SC_QUERY); }
|
||||
"VACUUM" { query += yytext; query_token = token::PGS_VACUUM;
|
||||
BEGIN(SC_QUERY); }
|
||||
"VALUES" { query += yytext; query_token = token::PGS_VALUES;
|
||||
BEGIN(SC_QUERY); }
|
||||
|
||||
[ \t\v\f]+ { }
|
||||
\r { yylloc->step(); }
|
||||
\n { yylloc->lines(yyleng); yylloc->step(); }
|
||||
. { return token::PGS_UNKNOWN; }
|
||||
}
|
||||
|
||||
<SC_QUERY>{
|
||||
"'" { query += yytext; string_caller = SC_QUERY; BEGIN(SC_STRING); }
|
||||
\$({L}|{D})*\$ { query += yytext; dollar = yytext; BEGIN(SC_DOLLAR); }
|
||||
";" { yylval->str = pnew wxString(query.c_str(), m_conv);
|
||||
query.clear(); unput(';'); yylloc->end.columns(-1);
|
||||
BEGIN(INITIAL); m_parent = 0; return query_token; }
|
||||
"(" { ++m_parent; query += yytext; }
|
||||
")" {
|
||||
--m_parent;
|
||||
if (m_parent == -1)
|
||||
{
|
||||
yylval->str = pnew wxString(query.c_str(), m_conv);
|
||||
query.clear(); unput(')'); yylloc->end.columns(-1);
|
||||
BEGIN(INITIAL); m_parent = 0; return query_token;
|
||||
}
|
||||
else
|
||||
{
|
||||
query += yytext;
|
||||
}
|
||||
}
|
||||
\r { query += yytext; yylloc->step(); }
|
||||
\n { query += yytext; yylloc->lines(yyleng); yylloc->step(); }
|
||||
<<EOF>> { yylval->str = pnew wxString(query.c_str(), m_conv);
|
||||
query.clear(); m_parent = 0; return query_token; }
|
||||
. { yylloc->columns(columns(*yytext)); query += yytext; }
|
||||
}
|
||||
|
||||
<SC_DOLLAR>{
|
||||
\$({L}|{D})*\$ { query += yytext;
|
||||
if (std::string(yytext) == dollar) BEGIN(SC_QUERY); }
|
||||
\r { query += yytext; yylloc->step(); }
|
||||
\n { query += yytext; yylloc->lines(yyleng); yylloc->step(); }
|
||||
<<EOF>> { query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv);
|
||||
query.clear(); m_parent = 0; return query_token; }
|
||||
. { yylloc->columns(columns(*yytext)); query += yytext; }
|
||||
}
|
||||
|
||||
<SC_COMMENT>{
|
||||
"*/" { BEGIN(comment_caller); }
|
||||
\r { yylloc->step(); }
|
||||
\n { yylloc->lines(yyleng); yylloc->step(); }
|
||||
. { yylloc->columns(columns(*yytext)); }
|
||||
}
|
||||
|
||||
<SC_STRING>{
|
||||
"''" {
|
||||
if (string_caller == SC_QUERY)
|
||||
query += yytext;
|
||||
else
|
||||
str += "'";
|
||||
}
|
||||
\\. {
|
||||
if (string_caller == SC_QUERY)
|
||||
query += yytext;
|
||||
else
|
||||
str += *(yytext + 1);
|
||||
yylloc->columns(columns(*(yytext + 1)));
|
||||
}
|
||||
"'" {
|
||||
if (string_caller == SC_QUERY)
|
||||
{
|
||||
query += yytext;
|
||||
BEGIN(string_caller);
|
||||
}
|
||||
else
|
||||
{
|
||||
yylval->str = pnew wxString(str.c_str(), m_conv);
|
||||
str.clear();
|
||||
BEGIN(string_caller);
|
||||
return token::PGS_VAL_STR;
|
||||
}
|
||||
}
|
||||
\r {
|
||||
if (string_caller == SC_QUERY)
|
||||
query += yytext;
|
||||
else
|
||||
str += yytext;
|
||||
yylloc->step();
|
||||
}
|
||||
\n {
|
||||
if (string_caller == SC_QUERY)
|
||||
query += yytext;
|
||||
else
|
||||
str += yytext;
|
||||
yylloc->lines(yyleng); yylloc->step();
|
||||
}
|
||||
<<EOF>> {
|
||||
if (string_caller == SC_QUERY)
|
||||
{
|
||||
query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv);
|
||||
query.clear(); m_parent = 0; return query_token;
|
||||
}
|
||||
else
|
||||
{
|
||||
yylval->str = pnew wxString(str.c_str(), m_conv);
|
||||
str.clear();
|
||||
BEGIN(string_caller);
|
||||
return token::PGS_VAL_STR;
|
||||
}
|
||||
}
|
||||
. {
|
||||
if (string_caller == SC_QUERY)
|
||||
query += yytext;
|
||||
else
|
||||
str += yytext;
|
||||
yylloc->columns(columns(*yytext));
|
||||
}
|
||||
}
|
||||
|
||||
%% /*** Additional Code ***/
|
||||
|
||||
namespace pgscript
|
||||
{
|
||||
|
||||
pgsScanner::pgsScanner(wxMBConv & conv, std::istream * in, std::ostream * out) :
|
||||
pgsFlexLexer(in, out), m_parent(0), m_conv(conv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsScanner::~pgsScanner()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pgsScanner::set_debug(bool b)
|
||||
{
|
||||
yy_flex_debug = b;
|
||||
}
|
||||
|
||||
int pgsScanner::columns(const char & c)
|
||||
{
|
||||
if ((c & 0xF0) == 0xF0) // 4 bytes
|
||||
return -3;
|
||||
else if ((c & 0xE0) == 0xE0) // 3 bytes
|
||||
return -2;
|
||||
else if ((c & 0xC0) == 0xC0) // 2 bytes
|
||||
return -1;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* This implementation of pgsFlexLexer::yylex() is required to fill the
|
||||
* vtable of the class pgsFlexLexer. We define the scanner's main yylex
|
||||
* function via YY_DECL to reside in the pgsScanner class instead. */
|
||||
|
||||
#ifdef yylex
|
||||
#undef yylex
|
||||
#endif
|
||||
|
||||
int pgsFlexLexer::yylex()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
27
pgscript/statements/module.mk
Normal file
27
pgscript/statements/module.mk
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#######################################################################
|
||||
#
|
||||
# pgAdmin III - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
# module.mk - pgadmin/pgscript/statements/ Makefile fragment
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
pgadmin3_SOURCES += \
|
||||
pgscript/statements/pgsAssertStmt.cpp \
|
||||
pgscript/statements/pgsBreakStmt.cpp \
|
||||
pgscript/statements/pgsContinueStmt.cpp \
|
||||
pgscript/statements/pgsDeclareRecordStmt.cpp \
|
||||
pgscript/statements/pgsExpressionStmt.cpp \
|
||||
pgscript/statements/pgsIfStmt.cpp \
|
||||
pgscript/statements/pgsPrintStmt.cpp \
|
||||
pgscript/statements/pgsProgram.cpp \
|
||||
pgscript/statements/pgsStmt.cpp \
|
||||
pgscript/statements/pgsStmtList.cpp \
|
||||
pgscript/statements/pgsWhileStmt.cpp
|
||||
|
||||
EXTRA_DIST += \
|
||||
pgscript/statements/module.mk
|
||||
|
||||
34
pgscript/statements/pgsAssertStmt.cpp
Normal file
34
pgscript/statements/pgsAssertStmt.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsAssertStmt.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsAssertException.h"
|
||||
|
||||
pgsAssertStmt::pgsAssertStmt(const pgsExpression *cond, pgsThread *app) :
|
||||
pgsStmt(app), m_cond(cond)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsAssertStmt::~pgsAssertStmt()
|
||||
{
|
||||
pdelete(m_cond);
|
||||
}
|
||||
|
||||
void pgsAssertStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
pgsOperand result = m_cond->eval(vars);
|
||||
if (!result->pgs_is_true())
|
||||
{
|
||||
throw pgsAssertException(m_cond->value());
|
||||
}
|
||||
}
|
||||
30
pgscript/statements/pgsBreakStmt.cpp
Normal file
30
pgscript/statements/pgsBreakStmt.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsBreakStmt.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsBreakException.h"
|
||||
|
||||
pgsBreakStmt::pgsBreakStmt(pgsThread *app) :
|
||||
pgsStmt(app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsBreakStmt::~pgsBreakStmt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pgsBreakStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
throw pgsBreakException();
|
||||
}
|
||||
30
pgscript/statements/pgsContinueStmt.cpp
Normal file
30
pgscript/statements/pgsContinueStmt.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsContinueStmt.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsContinueException.h"
|
||||
|
||||
pgsContinueStmt::pgsContinueStmt(pgsThread *app) :
|
||||
pgsStmt(app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsContinueStmt::~pgsContinueStmt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pgsContinueStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
throw pgsContinueException();
|
||||
}
|
||||
36
pgscript/statements/pgsDeclareRecordStmt.cpp
Normal file
36
pgscript/statements/pgsDeclareRecordStmt.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsDeclareRecordStmt.h"
|
||||
|
||||
#include "pgscript/objects/pgsRecord.h"
|
||||
|
||||
pgsDeclareRecordStmt::pgsDeclareRecordStmt(const wxString &rec,
|
||||
const wxArrayString &columns, pgsThread *app) :
|
||||
pgsStmt(app), m_rec(rec), m_columns(columns)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsDeclareRecordStmt::~pgsDeclareRecordStmt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
28
pgscript/statements/pgsExpressionStmt.cpp
Normal file
28
pgscript/statements/pgsExpressionStmt.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsExpressionStmt.h"
|
||||
|
||||
pgsExpressionStmt::pgsExpressionStmt(const pgsExpression *var, pgsThread *app) :
|
||||
pgsStmt(app), m_var(var)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsExpressionStmt::~pgsExpressionStmt()
|
||||
{
|
||||
pdelete(m_var)
|
||||
}
|
||||
|
||||
void pgsExpressionStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
m_var->eval(vars);
|
||||
}
|
||||
39
pgscript/statements/pgsIfStmt.cpp
Normal file
39
pgscript/statements/pgsIfStmt.cpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsIfStmt.h"
|
||||
|
||||
pgsIfStmt::pgsIfStmt(const pgsExpression *cond, const pgsStmt *stmt_list_if,
|
||||
const pgsStmt *stmt_list_else, pgsThread *app) :
|
||||
pgsStmt(app), m_cond(cond), m_stmt_list_if(stmt_list_if),
|
||||
m_stmt_list_else(stmt_list_else)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsIfStmt::~pgsIfStmt()
|
||||
{
|
||||
pdelete(m_cond);
|
||||
pdelete(m_stmt_list_if);
|
||||
pdelete(m_stmt_list_else);
|
||||
}
|
||||
|
||||
void pgsIfStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
if (m_cond->eval(vars)->pgs_is_true())
|
||||
{
|
||||
m_stmt_list_if->eval(vars);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_stmt_list_else->eval(vars);
|
||||
}
|
||||
}
|
||||
56
pgscript/statements/pgsPrintStmt.cpp
Normal file
56
pgscript/statements/pgsPrintStmt.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsPrintStmt.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsException.h"
|
||||
#include "pgscript/utilities/pgsThread.h"
|
||||
#include "pgscript/utilities/pgsUtilities.h"
|
||||
|
||||
pgsPrintStmt::pgsPrintStmt(const pgsExpression *var, pgsOutputStream &cout,
|
||||
pgsThread *app) :
|
||||
pgsStmt(app), m_var(var), m_cout(cout)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsPrintStmt::~pgsPrintStmt()
|
||||
{
|
||||
pdelete(m_var);
|
||||
}
|
||||
|
||||
void pgsPrintStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->LockOutput();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_cout << PGSOUTPGSCRIPT << wx_static_cast(const wxString,
|
||||
m_var->eval(vars)->value()) << wxT("\n");
|
||||
}
|
||||
catch (const pgsException &)
|
||||
{
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->UnlockOutput();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->UnlockOutput();
|
||||
}
|
||||
}
|
||||
63
pgscript/statements/pgsProgram.cpp
Normal file
63
pgscript/statements/pgsProgram.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsProgram.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsException.h"
|
||||
#include "pgscript/statements/pgsStmtList.h"
|
||||
|
||||
pgsProgram::pgsProgram(pgsVarMap &vars) :
|
||||
m_vars(vars)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsProgram::~pgsProgram()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pgsProgram::dump()
|
||||
{
|
||||
dump(m_vars);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
void pgsProgram::eval(pgsStmtList *stmt_list)
|
||||
{
|
||||
wxLogScript(wxT("Entering program"));
|
||||
|
||||
try
|
||||
{
|
||||
stmt_list->eval(m_vars);
|
||||
}
|
||||
catch (const pgsException &)
|
||||
{
|
||||
|
||||
}
|
||||
catch (const std::exception &)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsStmtList::m_exception_thrown = false;
|
||||
|
||||
wxLogScript(wxT("Leaving program"));
|
||||
}
|
||||
33
pgscript/statements/pgsStmt.cpp
Normal file
33
pgscript/statements/pgsStmt.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsStmt.h"
|
||||
|
||||
pgsStmt::pgsStmt(pgsThread *app) :
|
||||
m_line(0), m_app(app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsStmt::~pgsStmt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void pgsStmt::set_position(int line)
|
||||
{
|
||||
m_line = line;
|
||||
}
|
||||
|
||||
int pgsStmt::line() const
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
115
pgscript/statements/pgsStmtList.cpp
Normal file
115
pgscript/statements/pgsStmtList.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsStmtList.h"
|
||||
|
||||
#include <typeinfo>
|
||||
#include "pgscript/exceptions/pgsBreakException.h"
|
||||
#include "pgscript/exceptions/pgsContinueException.h"
|
||||
#include "pgscript/exceptions/pgsInterruptException.h"
|
||||
#include "pgscript/utilities/pgsThread.h"
|
||||
#include "pgscript/utilities/pgsUtilities.h"
|
||||
|
||||
#include <wx/listimpl.cpp>
|
||||
WX_DEFINE_LIST(pgsListStmt);
|
||||
|
||||
bool pgsStmtList::m_exception_thrown = false;
|
||||
|
||||
pgsStmtList::pgsStmtList(pgsOutputStream &cout, pgsThread *app) :
|
||||
pgsStmt(app), m_cout(cout)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsStmtList::~pgsStmtList()
|
||||
{
|
||||
pgsListStmt::iterator it;
|
||||
for (it = m_stmt_list.begin(); it != m_stmt_list.end(); it++)
|
||||
{
|
||||
pdelete(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void pgsStmtList::eval(pgsVarMap &vars) const
|
||||
{
|
||||
pgsListStmt::const_iterator it;
|
||||
for (it = m_stmt_list.begin(); it != m_stmt_list.end(); it++)
|
||||
{
|
||||
pgsStmt *current = *it;
|
||||
|
||||
try
|
||||
{
|
||||
current->eval(vars);
|
||||
|
||||
if (m_app != 0 && m_app->TestDestroy())
|
||||
throw pgsInterruptException();
|
||||
}
|
||||
catch (const pgsException &e)
|
||||
{
|
||||
if (!m_exception_thrown && (typeid(e) != typeid(pgsBreakException))
|
||||
&& (typeid(e) != typeid(pgsContinueException)))
|
||||
{
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->LockOutput();
|
||||
m_app->last_error_line(current->line());
|
||||
}
|
||||
|
||||
m_cout << wx_static_cast(const wxString, e.message())
|
||||
<< wxT(" on line ") << current->line() << wxT("\n");
|
||||
m_exception_thrown = true;
|
||||
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->UnlockOutput();
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
if (!m_exception_thrown)
|
||||
{
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->LockOutput();
|
||||
m_app->last_error_line(current->line());
|
||||
}
|
||||
|
||||
m_cout << PGSOUTERROR << _("Unknown exception:\n")
|
||||
<< wx_static_cast(const wxString,
|
||||
wxString(e.what(), wxConvUTF8));
|
||||
m_exception_thrown = true;
|
||||
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->UnlockOutput();
|
||||
}
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
||||
if (m_app != 0)
|
||||
{
|
||||
m_app->Yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pgsStmtList::insert_front(pgsStmt *stmt)
|
||||
{
|
||||
m_stmt_list.push_front(stmt);
|
||||
}
|
||||
|
||||
void pgsStmtList::insert_back(pgsStmt *stmt)
|
||||
{
|
||||
m_stmt_list.push_back(stmt);
|
||||
}
|
||||
56
pgscript/statements/pgsWhileStmt.cpp
Normal file
56
pgscript/statements/pgsWhileStmt.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgScript - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2002 - 2016, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/statements/pgsWhileStmt.h"
|
||||
|
||||
#include "pgscript/exceptions/pgsBreakException.h"
|
||||
#include "pgscript/exceptions/pgsContinueException.h"
|
||||
#include "pgscript/exceptions/pgsInterruptException.h"
|
||||
#include "pgscript/utilities/pgsThread.h"
|
||||
|
||||
pgsWhileStmt::pgsWhileStmt(const pgsExpression *cond, const pgsStmt *stmt_list,
|
||||
pgsThread *app) :
|
||||
pgsStmt(app), m_cond(cond), m_stmt_list(stmt_list)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pgsWhileStmt::~pgsWhileStmt()
|
||||
{
|
||||
pdelete(m_cond);
|
||||
pdelete(m_stmt_list);
|
||||
}
|
||||
|
||||
void pgsWhileStmt::eval(pgsVarMap &vars) const
|
||||
{
|
||||
loop:
|
||||
if (m_cond->eval(vars)->pgs_is_true())
|
||||
{
|
||||
try
|
||||
{
|
||||
m_stmt_list->eval(vars);
|
||||
}
|
||||
catch (const pgsBreakException &)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
catch (const pgsContinueException &)
|
||||
{
|
||||
|
||||
}
|
||||
if (m_app != 0 && m_app->TestDestroy())
|
||||
throw pgsInterruptException();
|
||||
|
||||
goto loop;
|
||||
}
|
||||
end:
|
||||
;
|
||||
}
|
||||
154
pgscript/utilities/m_apm/mapm5sin.cpp
Normal file
154
pgscript/utilities/m_apm/mapm5sin.cpp
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm5sin.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the functions that implement the sin (5x)
|
||||
* and cos (4x) multiple angle relations
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
void M_5x_sin(M_APM r, int places, M_APM x)
|
||||
{
|
||||
M_APM tmp8, tmp9;
|
||||
|
||||
tmp8 = M_get_stack_var();
|
||||
tmp9 = M_get_stack_var();
|
||||
|
||||
m_apm_multiply(tmp9, x, MM_5x_125R); /* 1 / (5*5*5) */
|
||||
M_raw_sin(tmp8, (places + 6), tmp9);
|
||||
M_5x_do_it(tmp9, (places + 4), tmp8);
|
||||
M_5x_do_it(tmp8, (places + 4), tmp9);
|
||||
M_5x_do_it(r, places, tmp8);
|
||||
|
||||
M_restore_stack(2);
|
||||
}
|
||||
/****************************************************************************/
|
||||
void M_4x_cos(M_APM r, int places, M_APM x)
|
||||
{
|
||||
M_APM tmp8, tmp9;
|
||||
|
||||
tmp8 = M_get_stack_var();
|
||||
tmp9 = M_get_stack_var();
|
||||
|
||||
/*
|
||||
* if |x| >= 1.0 use multiple angle identity 4 times
|
||||
* if |x| < 1.0 use multiple angle identity 3 times
|
||||
*/
|
||||
|
||||
if (x->m_apm_exponent > 0)
|
||||
{
|
||||
m_apm_multiply(tmp9, x, MM_5x_256R); /* 1 / (4*4*4*4) */
|
||||
M_raw_cos(tmp8, (places + 8), tmp9);
|
||||
M_4x_do_it(tmp9, (places + 8), tmp8);
|
||||
M_4x_do_it(tmp8, (places + 6), tmp9);
|
||||
M_4x_do_it(tmp9, (places + 4), tmp8);
|
||||
M_4x_do_it(r, places, tmp9);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_apm_multiply(tmp9, x, MM_5x_64R); /* 1 / (4*4*4) */
|
||||
M_raw_cos(tmp8, (places + 6), tmp9);
|
||||
M_4x_do_it(tmp9, (places + 4), tmp8);
|
||||
M_4x_do_it(tmp8, (places + 4), tmp9);
|
||||
M_4x_do_it(r, places, tmp8);
|
||||
}
|
||||
|
||||
M_restore_stack(2);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* calculate the multiple angle identity for sin (5x)
|
||||
*
|
||||
* sin (5x) == 16 * sin^5 (x) - 20 * sin^3 (x) + 5 * sin(x)
|
||||
*/
|
||||
void M_5x_do_it(M_APM rr, int places, M_APM xx)
|
||||
{
|
||||
M_APM tmp0, tmp1, t2, t3, t5;
|
||||
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
t2 = M_get_stack_var();
|
||||
t3 = M_get_stack_var();
|
||||
t5 = M_get_stack_var();
|
||||
|
||||
m_apm_multiply(tmp1, xx, xx);
|
||||
m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */
|
||||
|
||||
m_apm_multiply(tmp1, t2, xx);
|
||||
m_apm_round(t3, (places + 4), tmp1); /* x ^ 3 */
|
||||
|
||||
m_apm_multiply(t5, t2, t3); /* x ^ 5 */
|
||||
|
||||
m_apm_multiply(tmp0, xx, MM_Five);
|
||||
m_apm_multiply(tmp1, t5, MM_5x_Sixteen);
|
||||
m_apm_add(t2, tmp0, tmp1);
|
||||
m_apm_multiply(tmp1, t3, MM_5x_Twenty);
|
||||
m_apm_subtract(tmp0, t2, tmp1);
|
||||
|
||||
m_apm_round(rr, places, tmp0);
|
||||
M_restore_stack(5);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* calculate the multiple angle identity for cos (4x)
|
||||
*
|
||||
* cos (4x) == 8 * [ cos^4 (x) - cos^2 (x) ] + 1
|
||||
*/
|
||||
void M_4x_do_it(M_APM rr, int places, M_APM xx)
|
||||
{
|
||||
M_APM tmp0, tmp1, t2, t4;
|
||||
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
t2 = M_get_stack_var();
|
||||
t4 = M_get_stack_var();
|
||||
|
||||
m_apm_multiply(tmp1, xx, xx);
|
||||
m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */
|
||||
m_apm_multiply(t4, t2, t2); /* x ^ 4 */
|
||||
|
||||
m_apm_subtract(tmp0, t4, t2);
|
||||
m_apm_multiply(tmp1, tmp0, MM_5x_Eight);
|
||||
m_apm_add(tmp0, MM_One, tmp1);
|
||||
m_apm_round(rr, places, tmp0);
|
||||
M_restore_stack(4);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* compute r = sqrt(1 - a ^ 2).
|
||||
*/
|
||||
void M_cos_to_sin(M_APM r, int places, M_APM a)
|
||||
{
|
||||
M_APM tmp1, tmp2;
|
||||
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
|
||||
m_apm_multiply(tmp1, a, a);
|
||||
m_apm_subtract(tmp2, MM_One, tmp1);
|
||||
m_apm_sqrt(r, places, tmp2);
|
||||
M_restore_stack(2);
|
||||
}
|
||||
/****************************************************************************/
|
||||
329
pgscript/utilities/m_apm/mapm_add.cpp
Normal file
329
pgscript/utilities/m_apm/mapm_add.cpp
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_add.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the functions that implement the sin (5x)
|
||||
* and cos (4x) multiple angle relations
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
static M_APM M_work1 = NULL;
|
||||
static M_APM M_work2 = NULL;
|
||||
static int M_add_firsttime = TRUE;
|
||||
|
||||
/****************************************************************************/
|
||||
void M_free_all_add()
|
||||
{
|
||||
if (M_add_firsttime == FALSE)
|
||||
{
|
||||
m_apm_free(M_work1);
|
||||
m_apm_free(M_work2);
|
||||
M_add_firsttime = TRUE;
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_add(M_APM r, M_APM a, M_APM b)
|
||||
{
|
||||
int j, carry, sign, aexp, bexp, adigits, bdigits;
|
||||
|
||||
if (M_add_firsttime)
|
||||
{
|
||||
M_add_firsttime = FALSE;
|
||||
M_work1 = m_apm_init();
|
||||
M_work2 = m_apm_init();
|
||||
}
|
||||
|
||||
if (a->m_apm_sign == 0)
|
||||
{
|
||||
m_apm_copy(r, b);
|
||||
return;
|
||||
}
|
||||
|
||||
if (b->m_apm_sign == 0)
|
||||
{
|
||||
m_apm_copy(r, a);
|
||||
return;
|
||||
}
|
||||
|
||||
if (a->m_apm_sign == 1 && b->m_apm_sign == -1)
|
||||
{
|
||||
b->m_apm_sign = 1;
|
||||
m_apm_subtract(r, a, b);
|
||||
b->m_apm_sign = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (a->m_apm_sign == -1 && b->m_apm_sign == 1)
|
||||
{
|
||||
a->m_apm_sign = 1;
|
||||
m_apm_subtract(r, b, a);
|
||||
a->m_apm_sign = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
sign = a->m_apm_sign; /* signs are the same, result will be same */
|
||||
|
||||
aexp = a->m_apm_exponent;
|
||||
bexp = b->m_apm_exponent;
|
||||
|
||||
m_apm_copy(M_work1, a);
|
||||
m_apm_copy(M_work2, b);
|
||||
|
||||
/*
|
||||
* scale by at least 1 factor of 10 in case the MSB carrys
|
||||
*/
|
||||
|
||||
if (aexp == bexp)
|
||||
{
|
||||
M_apm_scale(M_work1, 2); /* shift 2 digits == 1 byte for efficiency */
|
||||
M_apm_scale(M_work2, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aexp > bexp)
|
||||
{
|
||||
M_apm_scale(M_work1, 2);
|
||||
M_apm_scale(M_work2, (aexp + 2 - bexp));
|
||||
}
|
||||
else /* aexp < bexp */
|
||||
{
|
||||
M_apm_scale(M_work2, 2);
|
||||
M_apm_scale(M_work1, (bexp + 2 - aexp));
|
||||
}
|
||||
}
|
||||
|
||||
adigits = M_work1->m_apm_datalength;
|
||||
bdigits = M_work2->m_apm_datalength;
|
||||
|
||||
if (adigits >= bdigits)
|
||||
{
|
||||
m_apm_copy(r, M_work1);
|
||||
j = (bdigits + 1) >> 1;
|
||||
carry = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
j--;
|
||||
r->m_apm_data[j] += carry + M_work2->m_apm_data[j];
|
||||
|
||||
if (r->m_apm_data[j] >= 100)
|
||||
{
|
||||
r->m_apm_data[j] -= 100;
|
||||
carry = 1;
|
||||
}
|
||||
else
|
||||
carry = 0;
|
||||
|
||||
if (j == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_apm_copy(r, M_work2);
|
||||
j = (adigits + 1) >> 1;
|
||||
carry = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
j--;
|
||||
r->m_apm_data[j] += carry + M_work1->m_apm_data[j];
|
||||
|
||||
if (r->m_apm_data[j] >= 100)
|
||||
{
|
||||
r->m_apm_data[j] -= 100;
|
||||
carry = 1;
|
||||
}
|
||||
else
|
||||
carry = 0;
|
||||
|
||||
if (j == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r->m_apm_sign = sign;
|
||||
|
||||
M_apm_normalize(r);
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_subtract(M_APM r, M_APM a, M_APM b)
|
||||
{
|
||||
int itmp, j, flag, icompare, sign, aexp, bexp,
|
||||
borrow, adigits, bdigits;
|
||||
|
||||
if (M_add_firsttime)
|
||||
{
|
||||
M_add_firsttime = FALSE;
|
||||
M_work1 = m_apm_init();
|
||||
M_work2 = m_apm_init();
|
||||
}
|
||||
|
||||
if (b->m_apm_sign == 0)
|
||||
{
|
||||
m_apm_copy(r, a);
|
||||
return;
|
||||
}
|
||||
|
||||
if (a->m_apm_sign == 0)
|
||||
{
|
||||
m_apm_copy(r, b);
|
||||
r->m_apm_sign = -(r->m_apm_sign);
|
||||
return;
|
||||
}
|
||||
|
||||
if (a->m_apm_sign == 1 && b->m_apm_sign == -1)
|
||||
{
|
||||
b->m_apm_sign = 1;
|
||||
m_apm_add(r, a, b);
|
||||
b->m_apm_sign = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (a->m_apm_sign == -1 && b->m_apm_sign == 1)
|
||||
{
|
||||
b->m_apm_sign = -1;
|
||||
m_apm_add(r, a, b);
|
||||
b->m_apm_sign = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* now, the signs are the same */
|
||||
/* make a positive working copy */
|
||||
|
||||
m_apm_absolute_value(M_work1, a);
|
||||
m_apm_absolute_value(M_work2, b);
|
||||
|
||||
/* are they the same?? if so, the result is zero */
|
||||
|
||||
if ((icompare = m_apm_compare(M_work1, M_work2)) == 0)
|
||||
{
|
||||
M_set_to_zero(r);
|
||||
return;
|
||||
}
|
||||
|
||||
if (icompare == 1) /* |a| > |b| (do A-B) */
|
||||
{
|
||||
flag = TRUE;
|
||||
sign = a->m_apm_sign;
|
||||
}
|
||||
else /* |b| > |a| (do B-A) */
|
||||
{
|
||||
flag = FALSE;
|
||||
sign = -(a->m_apm_sign);
|
||||
}
|
||||
|
||||
aexp = M_work1->m_apm_exponent;
|
||||
bexp = M_work2->m_apm_exponent;
|
||||
|
||||
if (aexp > bexp)
|
||||
M_apm_scale(M_work2, (aexp - bexp));
|
||||
|
||||
if (aexp < bexp)
|
||||
M_apm_scale(M_work1, (bexp - aexp));
|
||||
|
||||
adigits = M_work1->m_apm_datalength;
|
||||
bdigits = M_work2->m_apm_datalength;
|
||||
|
||||
if (adigits > bdigits)
|
||||
M_apm_pad(M_work2, adigits);
|
||||
|
||||
if (adigits < bdigits)
|
||||
M_apm_pad(M_work1, bdigits);
|
||||
|
||||
if (flag) /* perform A-B, M_work1 - M_work2 */
|
||||
{
|
||||
m_apm_copy(r, M_work1);
|
||||
j = (r->m_apm_datalength + 1) >> 1;
|
||||
borrow = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
j--;
|
||||
itmp = (int)r->m_apm_data[j] - ((int)M_work2->m_apm_data[j] + borrow);
|
||||
|
||||
if (itmp >= 0)
|
||||
{
|
||||
r->m_apm_data[j] = (UCHAR)itmp;
|
||||
borrow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->m_apm_data[j] = (UCHAR)(100 + itmp);
|
||||
borrow = 1;
|
||||
}
|
||||
|
||||
if (j == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* perform B-A, M_work2 - M_work1 */
|
||||
{
|
||||
m_apm_copy(r, M_work2);
|
||||
j = (r->m_apm_datalength + 1) >> 1;
|
||||
borrow = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
j--;
|
||||
itmp = (int)r->m_apm_data[j] - ((int)M_work1->m_apm_data[j] + borrow);
|
||||
|
||||
if (itmp >= 0)
|
||||
{
|
||||
r->m_apm_data[j] = (UCHAR)itmp;
|
||||
borrow = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r->m_apm_data[j] = (UCHAR)(100 + itmp);
|
||||
borrow = 1;
|
||||
}
|
||||
|
||||
if (j == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r->m_apm_sign = sign;
|
||||
|
||||
M_apm_normalize(r);
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
MAPM operator+(const MAPM &a, const MAPM &b)
|
||||
{
|
||||
MAPM ret;
|
||||
m_apm_add(ret.val(), a.cval(), b.cval());
|
||||
return ret;
|
||||
}
|
||||
MAPM operator-(const MAPM &a, const MAPM &b)
|
||||
{
|
||||
MAPM ret;
|
||||
m_apm_subtract(ret.val(), a.cval(), b.cval());
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
161
pgscript/utilities/m_apm/mapm_cpi.cpp
Normal file
161
pgscript/utilities/m_apm/mapm_cpi.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_cpi.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the PI related functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* check if our local copy of PI is precise enough
|
||||
* for our purpose. if not, calculate PI so it's
|
||||
* as precise as desired, accurate to 'places' decimal
|
||||
* places.
|
||||
*/
|
||||
void M_check_PI_places(int places)
|
||||
{
|
||||
int dplaces;
|
||||
|
||||
dplaces = places + 2;
|
||||
|
||||
if (dplaces > MM_lc_PI_digits)
|
||||
{
|
||||
MM_lc_PI_digits = dplaces + 2;
|
||||
|
||||
/* compute PI using the AGM (see right below) */
|
||||
|
||||
M_calculate_PI_AGM(MM_lc_PI, (dplaces + 5));
|
||||
|
||||
m_apm_multiply(MM_lc_HALF_PI, MM_0_5, MM_lc_PI);
|
||||
m_apm_multiply(MM_lc_2_PI, MM_Two, MM_lc_PI);
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* Calculate PI using the AGM (Arithmetic-Geometric Mean)
|
||||
*
|
||||
* Init : A0 = 1
|
||||
* B0 = 1 / sqrt(2)
|
||||
* Sum = 1
|
||||
*
|
||||
* Iterate: n = 1...
|
||||
*
|
||||
*
|
||||
* A = 0.5 * [ A + B ]
|
||||
* n n-1 n-1
|
||||
*
|
||||
*
|
||||
* B = sqrt [ A * B ]
|
||||
* n n-1 n-1
|
||||
*
|
||||
*
|
||||
*
|
||||
* C = 0.5 * [ A - B ]
|
||||
* n n-1 n-1
|
||||
*
|
||||
*
|
||||
* 2 n+1
|
||||
* Sum = Sum - C * 2
|
||||
* n
|
||||
*
|
||||
*
|
||||
* At the end when C is 'small enough' :
|
||||
* n
|
||||
*
|
||||
* 2
|
||||
* PI = 4 * A / Sum
|
||||
* n+1
|
||||
*
|
||||
* -OR-
|
||||
*
|
||||
* 2
|
||||
* PI = ( A + B ) / Sum
|
||||
* n n
|
||||
*
|
||||
*/
|
||||
void M_calculate_PI_AGM(M_APM outv, int places)
|
||||
{
|
||||
M_APM tmp1, tmp2, a0, b0, c0, a1, b1, sum, pow_2;
|
||||
int dplaces, nn;
|
||||
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
a0 = M_get_stack_var();
|
||||
b0 = M_get_stack_var();
|
||||
c0 = M_get_stack_var();
|
||||
a1 = M_get_stack_var();
|
||||
b1 = M_get_stack_var();
|
||||
sum = M_get_stack_var();
|
||||
pow_2 = M_get_stack_var();
|
||||
|
||||
dplaces = places + 16;
|
||||
|
||||
m_apm_copy(a0, MM_One);
|
||||
m_apm_copy(sum, MM_One);
|
||||
m_apm_copy(pow_2, MM_Four);
|
||||
m_apm_sqrt(b0, dplaces, MM_0_5); /* sqrt(0.5) */
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_add(tmp1, a0, b0);
|
||||
m_apm_multiply(a1, MM_0_5, tmp1);
|
||||
|
||||
m_apm_multiply(tmp1, a0, b0);
|
||||
m_apm_sqrt(b1, dplaces, tmp1);
|
||||
|
||||
m_apm_subtract(tmp1, a0, b0);
|
||||
m_apm_multiply(c0, MM_0_5, tmp1);
|
||||
|
||||
/*
|
||||
* the net 'PI' calculated from this iteration will
|
||||
* be accurate to ~4 X the value of (c0)'s exponent.
|
||||
* this was determined experimentally.
|
||||
*/
|
||||
|
||||
nn = -4 * c0->m_apm_exponent;
|
||||
|
||||
m_apm_multiply(tmp1, c0, c0);
|
||||
m_apm_multiply(tmp2, tmp1, pow_2);
|
||||
m_apm_subtract(tmp1, sum, tmp2);
|
||||
m_apm_round(sum, dplaces, tmp1);
|
||||
|
||||
if (nn >= dplaces)
|
||||
break;
|
||||
|
||||
m_apm_copy(a0, a1);
|
||||
m_apm_copy(b0, b1);
|
||||
|
||||
m_apm_multiply(tmp1, pow_2, MM_Two);
|
||||
m_apm_copy(pow_2, tmp1);
|
||||
}
|
||||
|
||||
m_apm_add(tmp1, a1, b1);
|
||||
m_apm_multiply(tmp2, tmp1, tmp1);
|
||||
m_apm_divide(tmp1, dplaces, tmp2, sum);
|
||||
m_apm_round(outv, places, tmp1);
|
||||
|
||||
M_restore_stack(9);
|
||||
}
|
||||
/****************************************************************************/
|
||||
300
pgscript/utilities/m_apm/mapm_div.cpp
Normal file
300
pgscript/utilities/m_apm/mapm_div.cpp
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_div.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the basic division functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
static M_APM M_div_worka;
|
||||
static M_APM M_div_workb;
|
||||
static M_APM M_div_tmp7;
|
||||
static M_APM M_div_tmp8;
|
||||
static M_APM M_div_tmp9;
|
||||
|
||||
static int M_div_firsttime = TRUE;
|
||||
|
||||
/****************************************************************************/
|
||||
void M_free_all_div()
|
||||
{
|
||||
if (M_div_firsttime == FALSE)
|
||||
{
|
||||
m_apm_free(M_div_worka);
|
||||
m_apm_free(M_div_workb);
|
||||
m_apm_free(M_div_tmp7);
|
||||
m_apm_free(M_div_tmp8);
|
||||
m_apm_free(M_div_tmp9);
|
||||
|
||||
M_div_firsttime = TRUE;
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_integer_div_rem(M_APM qq, M_APM rr, M_APM aa, M_APM bb)
|
||||
{
|
||||
m_apm_integer_divide(qq, aa, bb);
|
||||
m_apm_multiply(M_div_tmp7, qq, bb);
|
||||
m_apm_subtract(rr, aa, M_div_tmp7);
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_integer_divide(M_APM rr, M_APM aa, M_APM bb)
|
||||
{
|
||||
/*
|
||||
* we must use this divide function since the
|
||||
* faster divide function using the reciprocal
|
||||
* will round the result (possibly changing
|
||||
* nnm.999999... --> nn(m+1).0000 which would
|
||||
* invalidate the 'integer_divide' goal).
|
||||
*/
|
||||
|
||||
M_apm_sdivide(rr, 4, aa, bb);
|
||||
|
||||
if (rr->m_apm_exponent <= 0) /* result is 0 */
|
||||
{
|
||||
M_set_to_zero(rr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rr->m_apm_datalength > rr->m_apm_exponent)
|
||||
{
|
||||
rr->m_apm_datalength = rr->m_apm_exponent;
|
||||
M_apm_normalize(rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
void M_apm_sdivide(M_APM r, int places, M_APM a, M_APM b)
|
||||
{
|
||||
int j, k, m, b0, sign, nexp, indexr, icompare, iterations;
|
||||
long trial_numer;
|
||||
void *vp;
|
||||
|
||||
if (M_div_firsttime)
|
||||
{
|
||||
M_div_firsttime = FALSE;
|
||||
|
||||
M_div_worka = m_apm_init();
|
||||
M_div_workb = m_apm_init();
|
||||
M_div_tmp7 = m_apm_init();
|
||||
M_div_tmp8 = m_apm_init();
|
||||
M_div_tmp9 = m_apm_init();
|
||||
}
|
||||
|
||||
sign = a->m_apm_sign * b->m_apm_sign;
|
||||
|
||||
if (sign == 0) /* one number is zero, result is zero */
|
||||
{
|
||||
if (b->m_apm_sign == 0)
|
||||
{
|
||||
M_apm_log_error_msg(M_APM_RETURN, "\'M_apm_sdivide\', Divide by 0");
|
||||
}
|
||||
|
||||
M_set_to_zero(r);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Knuth step D1. Since base = 100, base / 2 = 50.
|
||||
* (also make the working copies positive)
|
||||
*/
|
||||
|
||||
if (b->m_apm_data[0] >= 50)
|
||||
{
|
||||
m_apm_absolute_value(M_div_worka, a);
|
||||
m_apm_absolute_value(M_div_workb, b);
|
||||
}
|
||||
else /* 'normal' step D1 */
|
||||
{
|
||||
k = 100 / (b->m_apm_data[0] + 1);
|
||||
m_apm_set_long(M_div_tmp9, (long)k);
|
||||
|
||||
m_apm_multiply(M_div_worka, M_div_tmp9, a);
|
||||
m_apm_multiply(M_div_workb, M_div_tmp9, b);
|
||||
|
||||
M_div_worka->m_apm_sign = 1;
|
||||
M_div_workb->m_apm_sign = 1;
|
||||
}
|
||||
|
||||
/* setup trial denominator for step D3 */
|
||||
|
||||
b0 = 100 * (int)M_div_workb->m_apm_data[0];
|
||||
|
||||
if (M_div_workb->m_apm_datalength >= 3)
|
||||
b0 += M_div_workb->m_apm_data[1];
|
||||
|
||||
nexp = M_div_worka->m_apm_exponent - M_div_workb->m_apm_exponent;
|
||||
|
||||
if (nexp > 0)
|
||||
iterations = nexp + places + 1;
|
||||
else
|
||||
iterations = places + 1;
|
||||
|
||||
k = (iterations + 1) >> 1; /* required size of result, in bytes */
|
||||
|
||||
if (k > r->m_apm_malloclength)
|
||||
{
|
||||
if ((vp = MAPM_REALLOC(r->m_apm_data, (k + 32))) == NULL)
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_sdivide\', Out of memory");
|
||||
}
|
||||
|
||||
r->m_apm_malloclength = k + 28;
|
||||
r->m_apm_data = (UCHAR *)vp;
|
||||
}
|
||||
|
||||
/* clear the exponent in the working copies */
|
||||
|
||||
M_div_worka->m_apm_exponent = 0;
|
||||
M_div_workb->m_apm_exponent = 0;
|
||||
|
||||
/* if numbers are equal, ratio == 1.00000... */
|
||||
|
||||
if ((icompare = m_apm_compare(M_div_worka, M_div_workb)) == 0)
|
||||
{
|
||||
iterations = 1;
|
||||
r->m_apm_data[0] = 10;
|
||||
nexp++;
|
||||
}
|
||||
else /* ratio not 1, do the real division */
|
||||
{
|
||||
if (icompare == 1) /* numerator > denominator */
|
||||
{
|
||||
nexp++; /* to adjust the final exponent */
|
||||
M_div_worka->m_apm_exponent += 1; /* multiply numerator by 10 */
|
||||
}
|
||||
else /* numerator < denominator */
|
||||
{
|
||||
M_div_worka->m_apm_exponent += 2; /* multiply numerator by 100 */
|
||||
}
|
||||
|
||||
indexr = 0;
|
||||
m = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/*
|
||||
* Knuth step D3. Only use the 3rd -> 6th digits if the number
|
||||
* actually has that many digits.
|
||||
*/
|
||||
|
||||
trial_numer = 10000L * (long)M_div_worka->m_apm_data[0];
|
||||
|
||||
if (M_div_worka->m_apm_datalength >= 5)
|
||||
{
|
||||
trial_numer += 100 * M_div_worka->m_apm_data[1]
|
||||
+ M_div_worka->m_apm_data[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (M_div_worka->m_apm_datalength >= 3)
|
||||
trial_numer += 100 * M_div_worka->m_apm_data[1];
|
||||
}
|
||||
|
||||
j = (int)(trial_numer / b0);
|
||||
|
||||
/*
|
||||
* Since the library 'normalizes' all the results, we need
|
||||
* to look at the exponent of the number to decide if we
|
||||
* have a lead in 0n or 00.
|
||||
*/
|
||||
|
||||
if ((k = 2 - M_div_worka->m_apm_exponent) > 0)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
j /= 10;
|
||||
if (--k == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == 100) /* qhat == base ?? */
|
||||
j = 99; /* if so, decrease by 1 */
|
||||
|
||||
m_apm_set_long(M_div_tmp8, (long)j);
|
||||
m_apm_multiply(M_div_tmp7, M_div_tmp8, M_div_workb);
|
||||
|
||||
/*
|
||||
* Compare our q-hat (j) against the desired number.
|
||||
* j is either correct, 1 too large, or 2 too large
|
||||
* per Theorem B on pg 272 of Art of Compter Programming,
|
||||
* Volume 2, 3rd Edition.
|
||||
*
|
||||
* The above statement is only true if using the 2 leading
|
||||
* digits of the numerator and the leading digit of the
|
||||
* denominator. Since we are using the (3) leading digits
|
||||
* of the numerator and the (2) leading digits of the
|
||||
* denominator, we eliminate the case where our q-hat is
|
||||
* 2 too large, (and q-hat being 1 too large is quite remote).
|
||||
*/
|
||||
|
||||
if (m_apm_compare(M_div_tmp7, M_div_worka) == 1)
|
||||
{
|
||||
j--;
|
||||
m_apm_subtract(M_div_tmp8, M_div_tmp7, M_div_workb);
|
||||
m_apm_copy(M_div_tmp7, M_div_tmp8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we know q-hat is correct, step D6 is unnecessary.
|
||||
*
|
||||
* Store q-hat, step D5. Since D6 is unnecessary, we can
|
||||
* do D5 before D4 and decide if we are done.
|
||||
*/
|
||||
|
||||
r->m_apm_data[indexr++] = (UCHAR)j; /* j == 'qhat' */
|
||||
m += 2;
|
||||
|
||||
if (m >= iterations)
|
||||
break;
|
||||
|
||||
/* step D4 */
|
||||
|
||||
m_apm_subtract(M_div_tmp9, M_div_worka, M_div_tmp7);
|
||||
|
||||
/*
|
||||
* if the subtraction yields zero, the division is exact
|
||||
* and we are done early.
|
||||
*/
|
||||
|
||||
if (M_div_tmp9->m_apm_sign == 0)
|
||||
{
|
||||
iterations = m;
|
||||
break;
|
||||
}
|
||||
|
||||
/* multiply by 100 and re-save */
|
||||
M_div_tmp9->m_apm_exponent += 2;
|
||||
m_apm_copy(M_div_worka, M_div_tmp9);
|
||||
}
|
||||
}
|
||||
|
||||
r->m_apm_sign = sign;
|
||||
r->m_apm_exponent = nexp;
|
||||
r->m_apm_datalength = iterations;
|
||||
|
||||
M_apm_normalize(r);
|
||||
}
|
||||
/****************************************************************************/
|
||||
294
pgscript/utilities/m_apm/mapm_exp.cpp
Normal file
294
pgscript/utilities/m_apm/mapm_exp.cpp
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_exp.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the EXP function.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
static M_APM MM_exp_log2R;
|
||||
static M_APM MM_exp_512R;
|
||||
static int MM_firsttime1 = TRUE;
|
||||
|
||||
/****************************************************************************/
|
||||
void M_free_all_exp()
|
||||
{
|
||||
if (MM_firsttime1 == FALSE)
|
||||
{
|
||||
m_apm_free(MM_exp_log2R);
|
||||
m_apm_free(MM_exp_512R);
|
||||
|
||||
MM_firsttime1 = TRUE;
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_exp(M_APM r, int places, M_APM x)
|
||||
{
|
||||
M_APM tmp7, tmp8, tmp9;
|
||||
int dplaces, nn, ii;
|
||||
|
||||
if (MM_firsttime1)
|
||||
{
|
||||
MM_firsttime1 = FALSE;
|
||||
|
||||
MM_exp_log2R = m_apm_init();
|
||||
MM_exp_512R = m_apm_init();
|
||||
|
||||
m_apm_set_string(MM_exp_log2R, "1.44269504089"); /* ~ 1 / log(2) */
|
||||
m_apm_set_string(MM_exp_512R, "1.953125E-3"); /* 1 / 512 */
|
||||
}
|
||||
|
||||
tmp7 = M_get_stack_var();
|
||||
tmp8 = M_get_stack_var();
|
||||
tmp9 = M_get_stack_var();
|
||||
|
||||
if (x->m_apm_sign == 0) /* if input == 0, return '1' */
|
||||
{
|
||||
m_apm_copy(r, MM_One);
|
||||
M_restore_stack(3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (x->m_apm_exponent <= -3) /* already small enough so call _raw directly */
|
||||
{
|
||||
M_raw_exp(tmp9, (places + 6), x);
|
||||
m_apm_round(r, places, tmp9);
|
||||
M_restore_stack(3);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
From David H. Bailey's MPFUN Fortran package :
|
||||
|
||||
exp (t) = (1 + r + r^2 / 2! + r^3 / 3! + r^4 / 4! ...) ^ q * 2 ^ n
|
||||
|
||||
where q = 256, r = t' / q, t' = t - n Log(2) and where n is chosen so
|
||||
that -0.5 Log(2) < t' <= 0.5 Log(2). Reducing t mod Log(2) and
|
||||
dividing by 256 insures that -0.001 < r <= 0.001, which accelerates
|
||||
convergence in the above series.
|
||||
|
||||
I use q = 512 and also limit how small 'r' can become. The 'r' used
|
||||
here is limited in magnitude from 1.95E-4 < |r| < 1.35E-3. Forcing
|
||||
'r' into a narrow range keeps the algorithm 'well behaved'.
|
||||
|
||||
( the range is [0.1 / 512] to [log(2) / 512] )
|
||||
*/
|
||||
|
||||
if (M_exp_compute_nn(&nn, tmp7, x) != 0)
|
||||
{
|
||||
M_apm_log_error_msg(M_APM_RETURN,
|
||||
"\'m_apm_exp\', Input too large, Overflow");
|
||||
|
||||
M_set_to_zero(r);
|
||||
M_restore_stack(3);
|
||||
return;
|
||||
}
|
||||
|
||||
dplaces = places + 8;
|
||||
|
||||
/* check to make sure our log(2) is accurate enough */
|
||||
|
||||
M_check_log_places(dplaces);
|
||||
|
||||
m_apm_multiply(tmp8, tmp7, MM_lc_log2);
|
||||
m_apm_subtract(tmp7, x, tmp8);
|
||||
|
||||
/*
|
||||
* guarantee that |tmp7| is between 0.1 and 0.9999999....
|
||||
* (in practice, the upper limit only reaches log(2), 0.693... )
|
||||
*/
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (tmp7->m_apm_sign != 0)
|
||||
{
|
||||
if (tmp7->m_apm_exponent == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp7->m_apm_sign >= 0)
|
||||
{
|
||||
nn++;
|
||||
m_apm_subtract(tmp8, tmp7, MM_lc_log2);
|
||||
m_apm_copy(tmp7, tmp8);
|
||||
}
|
||||
else
|
||||
{
|
||||
nn--;
|
||||
m_apm_add(tmp8, tmp7, MM_lc_log2);
|
||||
m_apm_copy(tmp7, tmp8);
|
||||
}
|
||||
}
|
||||
|
||||
m_apm_multiply(tmp9, tmp7, MM_exp_512R);
|
||||
|
||||
/* perform the series expansion ... */
|
||||
|
||||
M_raw_exp(tmp8, dplaces, tmp9);
|
||||
|
||||
/*
|
||||
* raise result to the 512 power
|
||||
*
|
||||
* note : x ^ 512 = (((x ^ 2) ^ 2) ^ 2) ... 9 times
|
||||
*/
|
||||
|
||||
ii = 9;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_multiply(tmp9, tmp8, tmp8);
|
||||
m_apm_round(tmp8, dplaces, tmp9);
|
||||
|
||||
if (--ii == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* now compute 2 ^ N */
|
||||
|
||||
m_apm_integer_pow(tmp7, dplaces, MM_Two, nn);
|
||||
|
||||
m_apm_multiply(tmp9, tmp7, tmp8);
|
||||
m_apm_round(r, places, tmp9);
|
||||
|
||||
M_restore_stack(3); /* restore the 3 locals we used here */
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
compute int *n = round_to_nearest_int(a / log(2))
|
||||
M_APM b = MAPM version of *n
|
||||
|
||||
returns 0: OK
|
||||
-1, 1: failure
|
||||
*/
|
||||
int M_exp_compute_nn(int *n, M_APM b, M_APM a)
|
||||
{
|
||||
M_APM tmp0, tmp1;
|
||||
void *vp;
|
||||
char *cp, sbuf[48];
|
||||
int kk;
|
||||
|
||||
*n = 0;
|
||||
vp = NULL;
|
||||
cp = sbuf;
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
|
||||
/* find 'n' and convert it to a normal C int */
|
||||
/* we just need an approx 1/log(2) for this calculation */
|
||||
|
||||
m_apm_multiply(tmp1, a, MM_exp_log2R);
|
||||
|
||||
/* round to the nearest int */
|
||||
|
||||
if (tmp1->m_apm_sign >= 0)
|
||||
{
|
||||
m_apm_add(tmp0, tmp1, MM_0_5);
|
||||
m_apm_floor(tmp1, tmp0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_apm_subtract(tmp0, tmp1, MM_0_5);
|
||||
m_apm_ceil(tmp1, tmp0);
|
||||
}
|
||||
|
||||
kk = tmp1->m_apm_exponent;
|
||||
if (kk >= 42)
|
||||
{
|
||||
if ((vp = (void *)MAPM_MALLOC((kk + 16) * sizeof(char))) == NULL)
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL, "\'M_exp_compute_nn\', Out of memory");
|
||||
}
|
||||
|
||||
cp = (char *)vp;
|
||||
}
|
||||
|
||||
m_apm_to_integer_string(cp, tmp1);
|
||||
*n = atoi(cp);
|
||||
|
||||
m_apm_set_long(b, (long)(*n));
|
||||
|
||||
kk = m_apm_compare(b, tmp1);
|
||||
|
||||
if (vp != NULL)
|
||||
MAPM_FREE(vp);
|
||||
|
||||
M_restore_stack(2);
|
||||
return(kk);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
calculate the exponential function using the following series :
|
||||
|
||||
x^2 x^3 x^4 x^5
|
||||
exp(x) == 1 + x + --- + --- + --- + --- ...
|
||||
2! 3! 4! 5!
|
||||
|
||||
*/
|
||||
void M_raw_exp(M_APM rr, int places, M_APM xx)
|
||||
{
|
||||
M_APM tmp0, digit, term;
|
||||
int tolerance, local_precision, prev_exp;
|
||||
long m1;
|
||||
|
||||
tmp0 = M_get_stack_var();
|
||||
term = M_get_stack_var();
|
||||
digit = M_get_stack_var();
|
||||
|
||||
local_precision = places + 8;
|
||||
tolerance = -(places + 4);
|
||||
prev_exp = 0;
|
||||
|
||||
m_apm_add(rr, MM_One, xx);
|
||||
m_apm_copy(term, xx);
|
||||
|
||||
m1 = 2L;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_set_long(digit, m1);
|
||||
m_apm_multiply(tmp0, term, xx);
|
||||
m_apm_divide(term, local_precision, tmp0, digit);
|
||||
m_apm_add(tmp0, rr, term);
|
||||
m_apm_copy(rr, tmp0);
|
||||
|
||||
if ((term->m_apm_exponent < tolerance) || (term->m_apm_sign == 0))
|
||||
break;
|
||||
|
||||
if (m1 != 2L)
|
||||
{
|
||||
local_precision = local_precision + term->m_apm_exponent - prev_exp;
|
||||
|
||||
if (local_precision < 20)
|
||||
local_precision = 20;
|
||||
}
|
||||
|
||||
prev_exp = term->m_apm_exponent;
|
||||
m1++;
|
||||
}
|
||||
|
||||
M_restore_stack(3); /* restore the 3 locals we used here */
|
||||
}
|
||||
/****************************************************************************/
|
||||
55
pgscript/utilities/m_apm/mapm_fam.cpp
Normal file
55
pgscript/utilities/m_apm/mapm_fam.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_fam.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the free all memory and similiar functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
void m_apm_free_all_mem()
|
||||
{
|
||||
M_free_all_add(); /* call each module which has statically declared data */
|
||||
M_free_all_div();
|
||||
M_free_all_exp();
|
||||
|
||||
#ifndef NO_FFT_MULTIPLY
|
||||
M_free_all_fft();
|
||||
#endif
|
||||
|
||||
M_free_all_pow();
|
||||
M_free_all_rnd();
|
||||
M_free_all_set();
|
||||
M_free_all_cnst();
|
||||
M_free_all_fmul();
|
||||
M_free_all_stck();
|
||||
M_free_all_util();
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_trim_mem_usage()
|
||||
{
|
||||
m_apm_free_all_mem();
|
||||
m_apm_free(m_apm_init());
|
||||
}
|
||||
/****************************************************************************/
|
||||
953
pgscript/utilities/m_apm/mapm_fft.cpp
Normal file
953
pgscript/utilities/m_apm/mapm_fft.cpp
Normal file
|
|
@ -0,0 +1,953 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_fft.c
|
||||
*
|
||||
* This FFT (Fast Fourier Transform) is from Takuya OOURA
|
||||
*
|
||||
* Copyright(C) 1996-1999 Takuya OOURA
|
||||
* email: ooura@mmm.t.u-tokyo.ac.jp
|
||||
*
|
||||
* See full FFT documentation below ... (MCR)
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the FFT based FAST MULTIPLICATION function
|
||||
* as well as its support functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
#ifndef MM_PI_2
|
||||
#define MM_PI_2 1.570796326794896619231321691639751442098584699687
|
||||
#endif
|
||||
|
||||
#ifndef WR5000 /* cos(MM_PI_2*0.5000) */
|
||||
#define WR5000 0.707106781186547524400844362104849039284835937688
|
||||
#endif
|
||||
|
||||
#ifndef RDFT_LOOP_DIV /* control of the RDFT's speed & tolerance */
|
||||
#define RDFT_LOOP_DIV 64
|
||||
#endif
|
||||
|
||||
extern void M_fast_mul_fft(UCHAR *, UCHAR *, UCHAR *, int);
|
||||
|
||||
extern void M_rdft(int, int, double *);
|
||||
extern void M_bitrv2(int, double *);
|
||||
extern void M_cftfsub(int, double *);
|
||||
extern void M_cftbsub(int, double *);
|
||||
extern void M_rftfsub(int, double *);
|
||||
extern void M_rftbsub(int, double *);
|
||||
extern void M_cft1st(int, double *);
|
||||
extern void M_cftmdl(int, int, double *);
|
||||
|
||||
static double *M_aa_array, *M_bb_array;
|
||||
static int M_size = -1;
|
||||
|
||||
static char *M_fft_error_msg = (char *)"\'M_fast_mul_fft\', Out of memory";
|
||||
|
||||
/****************************************************************************/
|
||||
void M_free_all_fft()
|
||||
{
|
||||
if (M_size > 0)
|
||||
{
|
||||
MAPM_FREE(M_aa_array);
|
||||
MAPM_FREE(M_bb_array);
|
||||
M_size = -1;
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* multiply 'uu' by 'vv' with nbytes each
|
||||
* yielding a 2*nbytes result in 'ww'.
|
||||
* each byte contains a base 100 'digit',
|
||||
* i.e.: range from 0-99.
|
||||
*
|
||||
* MSB LSB
|
||||
*
|
||||
* uu,vv [0] [1] [2] ... [N-1]
|
||||
* ww [0] [1] [2] ... [2N-1]
|
||||
*/
|
||||
|
||||
void M_fast_mul_fft(UCHAR *ww, UCHAR *uu, UCHAR *vv, int nbytes)
|
||||
{
|
||||
int mflag, i, j, nn2, nn;
|
||||
double carry, nnr, dtemp, *a, *b;
|
||||
UCHAR *w0;
|
||||
unsigned long ul;
|
||||
|
||||
if (M_size < 0) /* if first time in, setup working arrays */
|
||||
{
|
||||
if (M_get_sizeof_int() == 2) /* if still using 16 bit compilers */
|
||||
M_size = 516;
|
||||
else
|
||||
M_size = 8200;
|
||||
|
||||
M_aa_array = (double *)MAPM_MALLOC(M_size * sizeof(double));
|
||||
M_bb_array = (double *)MAPM_MALLOC(M_size * sizeof(double));
|
||||
|
||||
if ((M_aa_array == NULL) || (M_bb_array == NULL))
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL, M_fft_error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
nn = nbytes;
|
||||
nn2 = nbytes >> 1;
|
||||
|
||||
if (nn > M_size)
|
||||
{
|
||||
mflag = TRUE;
|
||||
|
||||
a = (double *)MAPM_MALLOC((nn + 8) * sizeof(double));
|
||||
b = (double *)MAPM_MALLOC((nn + 8) * sizeof(double));
|
||||
|
||||
if ((a == NULL) || (b == NULL))
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL, M_fft_error_msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mflag = FALSE;
|
||||
|
||||
a = M_aa_array;
|
||||
b = M_bb_array;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert normal base 100 MAPM numbers to base 10000
|
||||
* for the FFT operation.
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
for (j = 0; j < nn2; j++)
|
||||
{
|
||||
a[j] = (double)((int)uu[i] * 100 + uu[i + 1]);
|
||||
b[j] = (double)((int)vv[i] * 100 + vv[i + 1]);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
/* zero fill the second half of the arrays */
|
||||
|
||||
for (j = nn2; j < nn; j++)
|
||||
{
|
||||
a[j] = 0.0;
|
||||
b[j] = 0.0;
|
||||
}
|
||||
|
||||
/* perform the forward Fourier transforms for both numbers */
|
||||
|
||||
M_rdft(nn, 1, a);
|
||||
M_rdft(nn, 1, b);
|
||||
|
||||
/* perform the convolution ... */
|
||||
|
||||
b[0] *= a[0];
|
||||
b[1] *= a[1];
|
||||
|
||||
for (j = 3; j <= nn; j += 2)
|
||||
{
|
||||
dtemp = b[j - 1];
|
||||
b[j - 1] = dtemp * a[j - 1] - b[j] * a[j];
|
||||
b[j] = dtemp * a[j] + b[j] * a[j - 1];
|
||||
}
|
||||
|
||||
/* perform the inverse transform on the result */
|
||||
|
||||
M_rdft(nn, -1, b);
|
||||
|
||||
/* perform a final pass to release all the carries */
|
||||
/* we are still in base 10000 at this point */
|
||||
|
||||
carry = 0.0;
|
||||
j = nn;
|
||||
nnr = 2.0 / (double)nn;
|
||||
|
||||
while (1)
|
||||
{
|
||||
dtemp = b[--j] * nnr + carry + 0.5;
|
||||
ul = (unsigned long)(dtemp * 1.0E-4);
|
||||
carry = (double)ul;
|
||||
b[j] = dtemp - carry * 10000.0;
|
||||
|
||||
if (j == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy result to our destination after converting back to base 100 */
|
||||
|
||||
w0 = ww;
|
||||
M_get_div_rem((int)ul, w0, (w0 + 1));
|
||||
|
||||
for (j = 0; j <= (nn - 2); j++)
|
||||
{
|
||||
w0 += 2;
|
||||
M_get_div_rem((int)b[j], w0, (w0 + 1));
|
||||
}
|
||||
|
||||
if (mflag)
|
||||
{
|
||||
MAPM_FREE(b);
|
||||
MAPM_FREE(a);
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* The following info is from Takuya OOURA's documentation :
|
||||
*
|
||||
* NOTE : MAPM only uses the 'RDFT' function (as well as the
|
||||
* functions RDFT calls). All the code from here down
|
||||
* in this file is from Takuya OOURA. The only change I
|
||||
* made was to add 'M_' in front of all the functions
|
||||
* I used. This was to guard against any possible
|
||||
* name collisions in the future.
|
||||
*
|
||||
* MCR 06 July 2000
|
||||
*
|
||||
*
|
||||
* General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package
|
||||
*
|
||||
* Description:
|
||||
* A package to calculate Discrete Fourier/Cosine/Sine Transforms of
|
||||
* 1-dimensional sequences of length 2^N.
|
||||
*
|
||||
* fft4g_h.c : FFT Package in C - Simple Version I (radix 4,2)
|
||||
*
|
||||
* rdft: Real Discrete Fourier Transform
|
||||
*
|
||||
* Method:
|
||||
* -------- rdft --------
|
||||
* A method with a following butterfly operation appended to "cdft".
|
||||
* In forward transform :
|
||||
* A[k] = sum_j=0^n-1 a[j]*W(n)^(j*k), 0<=k<=n/2,
|
||||
* W(n) = exp(2*pi*i/n),
|
||||
* this routine makes an array x[] :
|
||||
* x[j] = a[2*j] + i*a[2*j+1], 0<=j<n/2
|
||||
* and calls "cdft" of length n/2 :
|
||||
* X[k] = sum_j=0^n/2-1 x[j] * W(n/2)^(j*k), 0<=k<n.
|
||||
* The result A[k] are :
|
||||
* A[k] = X[k] - (1+i*W(n)^k)/2 * (X[k]-conjg(X[n/2-k])),
|
||||
* A[n/2-k] = X[n/2-k] +
|
||||
* conjg((1+i*W(n)^k)/2 * (X[k]-conjg(X[n/2-k]))),
|
||||
* 0<=k<=n/2
|
||||
* (notes: conjg() is a complex conjugate, X[n/2]=X[0]).
|
||||
* ----------------------
|
||||
*
|
||||
* Reference:
|
||||
* * Masatake MORI, Makoto NATORI, Tatuo TORII: Suchikeisan,
|
||||
* Iwanamikouzajyouhoukagaku18, Iwanami, 1982 (Japanese)
|
||||
* * Henri J. Nussbaumer: Fast Fourier Transform and Convolution
|
||||
* Algorithms, Springer Verlag, 1982
|
||||
* * C. S. Burrus, Notes on the FFT (with large FFT paper list)
|
||||
* http://www-dsp.rice.edu/research/fft/fftnote.asc
|
||||
*
|
||||
* Copyright:
|
||||
* Copyright(C) 1996-1999 Takuya OOURA
|
||||
* email: ooura@mmm.t.u-tokyo.ac.jp
|
||||
* download: http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
|
||||
* You may use, copy, modify this code for any purpose and
|
||||
* without fee. You may distribute this ORIGINAL package.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
functions
|
||||
rdft: Real Discrete Fourier Transform
|
||||
|
||||
function prototypes
|
||||
void rdft(int, int, double *);
|
||||
|
||||
-------- Real DFT / Inverse of Real DFT --------
|
||||
[definition]
|
||||
<case1> RDFT
|
||||
R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
|
||||
I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
|
||||
<case2> IRDFT (excluding scale)
|
||||
a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
|
||||
sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
|
||||
sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
|
||||
[usage]
|
||||
<case1>
|
||||
rdft(n, 1, a);
|
||||
<case2>
|
||||
rdft(n, -1, a);
|
||||
[parameters]
|
||||
n :data length (int)
|
||||
n >= 2, n = power of 2
|
||||
a[0...n-1] :input/output data (double *)
|
||||
<case1>
|
||||
output data
|
||||
a[2*k] = R[k], 0<=k<n/2
|
||||
a[2*k+1] = I[k], 0<k<n/2
|
||||
a[1] = R[n/2]
|
||||
<case2>
|
||||
input data
|
||||
a[2*j] = R[j], 0<=j<n/2
|
||||
a[2*j+1] = I[j], 0<j<n/2
|
||||
a[1] = R[n/2]
|
||||
[remark]
|
||||
Inverse of
|
||||
rdft(n, 1, a);
|
||||
is
|
||||
rdft(n, -1, a);
|
||||
for (j = 0; j <= n - 1; j++) {
|
||||
a[j] *= 2.0 / n;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void M_rdft(int n, int isgn, double *a)
|
||||
{
|
||||
double xi;
|
||||
|
||||
if (isgn >= 0)
|
||||
{
|
||||
if (n > 4)
|
||||
{
|
||||
M_bitrv2(n, a);
|
||||
M_cftfsub(n, a);
|
||||
M_rftfsub(n, a);
|
||||
}
|
||||
else if (n == 4)
|
||||
{
|
||||
M_cftfsub(n, a);
|
||||
}
|
||||
xi = a[0] - a[1];
|
||||
a[0] += a[1];
|
||||
a[1] = xi;
|
||||
}
|
||||
else
|
||||
{
|
||||
a[1] = 0.5 * (a[0] - a[1]);
|
||||
a[0] -= a[1];
|
||||
if (n > 4)
|
||||
{
|
||||
M_rftbsub(n, a);
|
||||
M_bitrv2(n, a);
|
||||
M_cftbsub(n, a);
|
||||
}
|
||||
else if (n == 4)
|
||||
{
|
||||
M_cftfsub(n, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_bitrv2(int n, double *a)
|
||||
{
|
||||
int j0, k0, j1, k1, l, m, i, j, k;
|
||||
double xr, xi, yr, yi;
|
||||
|
||||
l = n >> 2;
|
||||
m = 2;
|
||||
while (m < l)
|
||||
{
|
||||
l >>= 1;
|
||||
m <<= 1;
|
||||
}
|
||||
if (m == l)
|
||||
{
|
||||
j0 = 0;
|
||||
for (k0 = 0; k0 < m; k0 += 2)
|
||||
{
|
||||
k = k0;
|
||||
for (j = j0; j < j0 + k0; j += 2)
|
||||
{
|
||||
xr = a[j];
|
||||
xi = a[j + 1];
|
||||
yr = a[k];
|
||||
yi = a[k + 1];
|
||||
a[j] = yr;
|
||||
a[j + 1] = yi;
|
||||
a[k] = xr;
|
||||
a[k + 1] = xi;
|
||||
j1 = j + m;
|
||||
k1 = k + 2 * m;
|
||||
xr = a[j1];
|
||||
xi = a[j1 + 1];
|
||||
yr = a[k1];
|
||||
yi = a[k1 + 1];
|
||||
a[j1] = yr;
|
||||
a[j1 + 1] = yi;
|
||||
a[k1] = xr;
|
||||
a[k1 + 1] = xi;
|
||||
j1 += m;
|
||||
k1 -= m;
|
||||
xr = a[j1];
|
||||
xi = a[j1 + 1];
|
||||
yr = a[k1];
|
||||
yi = a[k1 + 1];
|
||||
a[j1] = yr;
|
||||
a[j1 + 1] = yi;
|
||||
a[k1] = xr;
|
||||
a[k1 + 1] = xi;
|
||||
j1 += m;
|
||||
k1 += 2 * m;
|
||||
xr = a[j1];
|
||||
xi = a[j1 + 1];
|
||||
yr = a[k1];
|
||||
yi = a[k1 + 1];
|
||||
a[j1] = yr;
|
||||
a[j1 + 1] = yi;
|
||||
a[k1] = xr;
|
||||
a[k1 + 1] = xi;
|
||||
for (i = n >> 1; i > (k ^= i); i >>= 1);
|
||||
}
|
||||
j1 = j0 + k0 + m;
|
||||
k1 = j1 + m;
|
||||
xr = a[j1];
|
||||
xi = a[j1 + 1];
|
||||
yr = a[k1];
|
||||
yi = a[k1 + 1];
|
||||
a[j1] = yr;
|
||||
a[j1 + 1] = yi;
|
||||
a[k1] = xr;
|
||||
a[k1 + 1] = xi;
|
||||
for (i = n >> 1; i > (j0 ^= i); i >>= 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j0 = 0;
|
||||
for (k0 = 2; k0 < m; k0 += 2)
|
||||
{
|
||||
for (i = n >> 1; i > (j0 ^= i); i >>= 1);
|
||||
k = k0;
|
||||
for (j = j0; j < j0 + k0; j += 2)
|
||||
{
|
||||
xr = a[j];
|
||||
xi = a[j + 1];
|
||||
yr = a[k];
|
||||
yi = a[k + 1];
|
||||
a[j] = yr;
|
||||
a[j + 1] = yi;
|
||||
a[k] = xr;
|
||||
a[k + 1] = xi;
|
||||
j1 = j + m;
|
||||
k1 = k + m;
|
||||
xr = a[j1];
|
||||
xi = a[j1 + 1];
|
||||
yr = a[k1];
|
||||
yi = a[k1 + 1];
|
||||
a[j1] = yr;
|
||||
a[j1 + 1] = yi;
|
||||
a[k1] = xr;
|
||||
a[k1 + 1] = xi;
|
||||
for (i = n >> 1; i > (k ^= i); i >>= 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_cftfsub(int n, double *a)
|
||||
{
|
||||
int j, j1, j2, j3, l;
|
||||
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
|
||||
|
||||
l = 2;
|
||||
if (n > 8)
|
||||
{
|
||||
M_cft1st(n, a);
|
||||
l = 8;
|
||||
while ((l << 2) < n)
|
||||
{
|
||||
M_cftmdl(n, l, a);
|
||||
l <<= 2;
|
||||
}
|
||||
}
|
||||
if ((l << 2) == n)
|
||||
{
|
||||
for (j = 0; j < l; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
j2 = j1 + l;
|
||||
j3 = j2 + l;
|
||||
x0r = a[j] + a[j1];
|
||||
x0i = a[j + 1] + a[j1 + 1];
|
||||
x1r = a[j] - a[j1];
|
||||
x1i = a[j + 1] - a[j1 + 1];
|
||||
x2r = a[j2] + a[j3];
|
||||
x2i = a[j2 + 1] + a[j3 + 1];
|
||||
x3r = a[j2] - a[j3];
|
||||
x3i = a[j2 + 1] - a[j3 + 1];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i + x2i;
|
||||
a[j2] = x0r - x2r;
|
||||
a[j2 + 1] = x0i - x2i;
|
||||
a[j1] = x1r - x3i;
|
||||
a[j1 + 1] = x1i + x3r;
|
||||
a[j3] = x1r + x3i;
|
||||
a[j3 + 1] = x1i - x3r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < l; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
x0r = a[j] - a[j1];
|
||||
x0i = a[j + 1] - a[j1 + 1];
|
||||
a[j] += a[j1];
|
||||
a[j + 1] += a[j1 + 1];
|
||||
a[j1] = x0r;
|
||||
a[j1 + 1] = x0i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_cftbsub(int n, double *a)
|
||||
{
|
||||
int j, j1, j2, j3, l;
|
||||
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
|
||||
|
||||
l = 2;
|
||||
if (n > 8)
|
||||
{
|
||||
M_cft1st(n, a);
|
||||
l = 8;
|
||||
while ((l << 2) < n)
|
||||
{
|
||||
M_cftmdl(n, l, a);
|
||||
l <<= 2;
|
||||
}
|
||||
}
|
||||
if ((l << 2) == n)
|
||||
{
|
||||
for (j = 0; j < l; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
j2 = j1 + l;
|
||||
j3 = j2 + l;
|
||||
x0r = a[j] + a[j1];
|
||||
x0i = -a[j + 1] - a[j1 + 1];
|
||||
x1r = a[j] - a[j1];
|
||||
x1i = -a[j + 1] + a[j1 + 1];
|
||||
x2r = a[j2] + a[j3];
|
||||
x2i = a[j2 + 1] + a[j3 + 1];
|
||||
x3r = a[j2] - a[j3];
|
||||
x3i = a[j2 + 1] - a[j3 + 1];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i - x2i;
|
||||
a[j2] = x0r - x2r;
|
||||
a[j2 + 1] = x0i + x2i;
|
||||
a[j1] = x1r - x3i;
|
||||
a[j1 + 1] = x1i - x3r;
|
||||
a[j3] = x1r + x3i;
|
||||
a[j3 + 1] = x1i + x3r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < l; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
x0r = a[j] - a[j1];
|
||||
x0i = -a[j + 1] + a[j1 + 1];
|
||||
a[j] += a[j1];
|
||||
a[j + 1] = -a[j + 1] - a[j1 + 1];
|
||||
a[j1] = x0r;
|
||||
a[j1 + 1] = x0i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_cft1st(int n, double *a)
|
||||
{
|
||||
int j, kj, kr;
|
||||
double ew, wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
|
||||
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
|
||||
|
||||
x0r = a[0] + a[2];
|
||||
x0i = a[1] + a[3];
|
||||
x1r = a[0] - a[2];
|
||||
x1i = a[1] - a[3];
|
||||
x2r = a[4] + a[6];
|
||||
x2i = a[5] + a[7];
|
||||
x3r = a[4] - a[6];
|
||||
x3i = a[5] - a[7];
|
||||
a[0] = x0r + x2r;
|
||||
a[1] = x0i + x2i;
|
||||
a[4] = x0r - x2r;
|
||||
a[5] = x0i - x2i;
|
||||
a[2] = x1r - x3i;
|
||||
a[3] = x1i + x3r;
|
||||
a[6] = x1r + x3i;
|
||||
a[7] = x1i - x3r;
|
||||
wn4r = WR5000;
|
||||
x0r = a[8] + a[10];
|
||||
x0i = a[9] + a[11];
|
||||
x1r = a[8] - a[10];
|
||||
x1i = a[9] - a[11];
|
||||
x2r = a[12] + a[14];
|
||||
x2i = a[13] + a[15];
|
||||
x3r = a[12] - a[14];
|
||||
x3i = a[13] - a[15];
|
||||
a[8] = x0r + x2r;
|
||||
a[9] = x0i + x2i;
|
||||
a[12] = x2i - x0i;
|
||||
a[13] = x0r - x2r;
|
||||
x0r = x1r - x3i;
|
||||
x0i = x1i + x3r;
|
||||
a[10] = wn4r * (x0r - x0i);
|
||||
a[11] = wn4r * (x0r + x0i);
|
||||
x0r = x3i + x1r;
|
||||
x0i = x3r - x1i;
|
||||
a[14] = wn4r * (x0i - x0r);
|
||||
a[15] = wn4r * (x0i + x0r);
|
||||
ew = MM_PI_2 / n;
|
||||
kr = 0;
|
||||
for (j = 16; j < n; j += 16)
|
||||
{
|
||||
for (kj = n >> 2; kj > (kr ^= kj); kj >>= 1);
|
||||
wk1r = cos(ew * kr);
|
||||
wk1i = sin(ew * kr);
|
||||
wk2r = 1 - 2 * wk1i * wk1i;
|
||||
wk2i = 2 * wk1i * wk1r;
|
||||
wk3r = wk1r - 2 * wk2i * wk1i;
|
||||
wk3i = 2 * wk2i * wk1r - wk1i;
|
||||
x0r = a[j] + a[j + 2];
|
||||
x0i = a[j + 1] + a[j + 3];
|
||||
x1r = a[j] - a[j + 2];
|
||||
x1i = a[j + 1] - a[j + 3];
|
||||
x2r = a[j + 4] + a[j + 6];
|
||||
x2i = a[j + 5] + a[j + 7];
|
||||
x3r = a[j + 4] - a[j + 6];
|
||||
x3i = a[j + 5] - a[j + 7];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i + x2i;
|
||||
x0r -= x2r;
|
||||
x0i -= x2i;
|
||||
a[j + 4] = wk2r * x0r - wk2i * x0i;
|
||||
a[j + 5] = wk2r * x0i + wk2i * x0r;
|
||||
x0r = x1r - x3i;
|
||||
x0i = x1i + x3r;
|
||||
a[j + 2] = wk1r * x0r - wk1i * x0i;
|
||||
a[j + 3] = wk1r * x0i + wk1i * x0r;
|
||||
x0r = x1r + x3i;
|
||||
x0i = x1i - x3r;
|
||||
a[j + 6] = wk3r * x0r - wk3i * x0i;
|
||||
a[j + 7] = wk3r * x0i + wk3i * x0r;
|
||||
x0r = wn4r * (wk1r - wk1i);
|
||||
wk1i = wn4r * (wk1r + wk1i);
|
||||
wk1r = x0r;
|
||||
wk3r = wk1r - 2 * wk2r * wk1i;
|
||||
wk3i = 2 * wk2r * wk1r - wk1i;
|
||||
x0r = a[j + 8] + a[j + 10];
|
||||
x0i = a[j + 9] + a[j + 11];
|
||||
x1r = a[j + 8] - a[j + 10];
|
||||
x1i = a[j + 9] - a[j + 11];
|
||||
x2r = a[j + 12] + a[j + 14];
|
||||
x2i = a[j + 13] + a[j + 15];
|
||||
x3r = a[j + 12] - a[j + 14];
|
||||
x3i = a[j + 13] - a[j + 15];
|
||||
a[j + 8] = x0r + x2r;
|
||||
a[j + 9] = x0i + x2i;
|
||||
x0r -= x2r;
|
||||
x0i -= x2i;
|
||||
a[j + 12] = -wk2i * x0r - wk2r * x0i;
|
||||
a[j + 13] = -wk2i * x0i + wk2r * x0r;
|
||||
x0r = x1r - x3i;
|
||||
x0i = x1i + x3r;
|
||||
a[j + 10] = wk1r * x0r - wk1i * x0i;
|
||||
a[j + 11] = wk1r * x0i + wk1i * x0r;
|
||||
x0r = x1r + x3i;
|
||||
x0i = x1i - x3r;
|
||||
a[j + 14] = wk3r * x0r - wk3i * x0i;
|
||||
a[j + 15] = wk3r * x0i + wk3i * x0r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_cftmdl(int n, int l, double *a)
|
||||
{
|
||||
int j, j1, j2, j3, k, kj, kr, m, m2;
|
||||
double ew, wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
|
||||
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
|
||||
|
||||
m = l << 2;
|
||||
for (j = 0; j < l; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
j2 = j1 + l;
|
||||
j3 = j2 + l;
|
||||
x0r = a[j] + a[j1];
|
||||
x0i = a[j + 1] + a[j1 + 1];
|
||||
x1r = a[j] - a[j1];
|
||||
x1i = a[j + 1] - a[j1 + 1];
|
||||
x2r = a[j2] + a[j3];
|
||||
x2i = a[j2 + 1] + a[j3 + 1];
|
||||
x3r = a[j2] - a[j3];
|
||||
x3i = a[j2 + 1] - a[j3 + 1];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i + x2i;
|
||||
a[j2] = x0r - x2r;
|
||||
a[j2 + 1] = x0i - x2i;
|
||||
a[j1] = x1r - x3i;
|
||||
a[j1 + 1] = x1i + x3r;
|
||||
a[j3] = x1r + x3i;
|
||||
a[j3 + 1] = x1i - x3r;
|
||||
}
|
||||
wn4r = WR5000;
|
||||
for (j = m; j < l + m; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
j2 = j1 + l;
|
||||
j3 = j2 + l;
|
||||
x0r = a[j] + a[j1];
|
||||
x0i = a[j + 1] + a[j1 + 1];
|
||||
x1r = a[j] - a[j1];
|
||||
x1i = a[j + 1] - a[j1 + 1];
|
||||
x2r = a[j2] + a[j3];
|
||||
x2i = a[j2 + 1] + a[j3 + 1];
|
||||
x3r = a[j2] - a[j3];
|
||||
x3i = a[j2 + 1] - a[j3 + 1];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i + x2i;
|
||||
a[j2] = x2i - x0i;
|
||||
a[j2 + 1] = x0r - x2r;
|
||||
x0r = x1r - x3i;
|
||||
x0i = x1i + x3r;
|
||||
a[j1] = wn4r * (x0r - x0i);
|
||||
a[j1 + 1] = wn4r * (x0r + x0i);
|
||||
x0r = x3i + x1r;
|
||||
x0i = x3r - x1i;
|
||||
a[j3] = wn4r * (x0i - x0r);
|
||||
a[j3 + 1] = wn4r * (x0i + x0r);
|
||||
}
|
||||
ew = MM_PI_2 / n;
|
||||
kr = 0;
|
||||
m2 = 2 * m;
|
||||
for (k = m2; k < n; k += m2)
|
||||
{
|
||||
for (kj = n >> 2; kj > (kr ^= kj); kj >>= 1);
|
||||
wk1r = cos(ew * kr);
|
||||
wk1i = sin(ew * kr);
|
||||
wk2r = 1 - 2 * wk1i * wk1i;
|
||||
wk2i = 2 * wk1i * wk1r;
|
||||
wk3r = wk1r - 2 * wk2i * wk1i;
|
||||
wk3i = 2 * wk2i * wk1r - wk1i;
|
||||
for (j = k; j < l + k; j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
j2 = j1 + l;
|
||||
j3 = j2 + l;
|
||||
x0r = a[j] + a[j1];
|
||||
x0i = a[j + 1] + a[j1 + 1];
|
||||
x1r = a[j] - a[j1];
|
||||
x1i = a[j + 1] - a[j1 + 1];
|
||||
x2r = a[j2] + a[j3];
|
||||
x2i = a[j2 + 1] + a[j3 + 1];
|
||||
x3r = a[j2] - a[j3];
|
||||
x3i = a[j2 + 1] - a[j3 + 1];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i + x2i;
|
||||
x0r -= x2r;
|
||||
x0i -= x2i;
|
||||
a[j2] = wk2r * x0r - wk2i * x0i;
|
||||
a[j2 + 1] = wk2r * x0i + wk2i * x0r;
|
||||
x0r = x1r - x3i;
|
||||
x0i = x1i + x3r;
|
||||
a[j1] = wk1r * x0r - wk1i * x0i;
|
||||
a[j1 + 1] = wk1r * x0i + wk1i * x0r;
|
||||
x0r = x1r + x3i;
|
||||
x0i = x1i - x3r;
|
||||
a[j3] = wk3r * x0r - wk3i * x0i;
|
||||
a[j3 + 1] = wk3r * x0i + wk3i * x0r;
|
||||
}
|
||||
x0r = wn4r * (wk1r - wk1i);
|
||||
wk1i = wn4r * (wk1r + wk1i);
|
||||
wk1r = x0r;
|
||||
wk3r = wk1r - 2 * wk2r * wk1i;
|
||||
wk3i = 2 * wk2r * wk1r - wk1i;
|
||||
for (j = k + m; j < l + (k + m); j += 2)
|
||||
{
|
||||
j1 = j + l;
|
||||
j2 = j1 + l;
|
||||
j3 = j2 + l;
|
||||
x0r = a[j] + a[j1];
|
||||
x0i = a[j + 1] + a[j1 + 1];
|
||||
x1r = a[j] - a[j1];
|
||||
x1i = a[j + 1] - a[j1 + 1];
|
||||
x2r = a[j2] + a[j3];
|
||||
x2i = a[j2 + 1] + a[j3 + 1];
|
||||
x3r = a[j2] - a[j3];
|
||||
x3i = a[j2 + 1] - a[j3 + 1];
|
||||
a[j] = x0r + x2r;
|
||||
a[j + 1] = x0i + x2i;
|
||||
x0r -= x2r;
|
||||
x0i -= x2i;
|
||||
a[j2] = -wk2i * x0r - wk2r * x0i;
|
||||
a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
|
||||
x0r = x1r - x3i;
|
||||
x0i = x1i + x3r;
|
||||
a[j1] = wk1r * x0r - wk1i * x0i;
|
||||
a[j1 + 1] = wk1r * x0i + wk1i * x0r;
|
||||
x0r = x1r + x3i;
|
||||
x0i = x1i - x3r;
|
||||
a[j3] = wk3r * x0r - wk3i * x0i;
|
||||
a[j3 + 1] = wk3r * x0i + wk3i * x0r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_rftfsub(int n, double *a)
|
||||
{
|
||||
int i, i0, j, k;
|
||||
double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi;
|
||||
|
||||
ec = 2 * MM_PI_2 / n;
|
||||
wkr = 0;
|
||||
wki = 0;
|
||||
wdi = cos(ec);
|
||||
wdr = sin(ec);
|
||||
wdi *= wdr;
|
||||
wdr *= wdr;
|
||||
w1r = 1 - 2 * wdr;
|
||||
w1i = 2 * wdi;
|
||||
ss = 2 * w1i;
|
||||
i = n >> 1;
|
||||
while (1)
|
||||
{
|
||||
i0 = i - 4 * RDFT_LOOP_DIV;
|
||||
if (i0 < 4)
|
||||
{
|
||||
i0 = 4;
|
||||
}
|
||||
for (j = i - 4; j >= i0; j -= 4)
|
||||
{
|
||||
k = n - j;
|
||||
xr = a[j + 2] - a[k - 2];
|
||||
xi = a[j + 3] + a[k - 1];
|
||||
yr = wdr * xr - wdi * xi;
|
||||
yi = wdr * xi + wdi * xr;
|
||||
a[j + 2] -= yr;
|
||||
a[j + 3] -= yi;
|
||||
a[k - 2] += yr;
|
||||
a[k - 1] -= yi;
|
||||
wkr += ss * wdi;
|
||||
wki += ss * (0.5 - wdr);
|
||||
xr = a[j] - a[k];
|
||||
xi = a[j + 1] + a[k + 1];
|
||||
yr = wkr * xr - wki * xi;
|
||||
yi = wkr * xi + wki * xr;
|
||||
a[j] -= yr;
|
||||
a[j + 1] -= yi;
|
||||
a[k] += yr;
|
||||
a[k + 1] -= yi;
|
||||
wdr += ss * wki;
|
||||
wdi += ss * (0.5 - wkr);
|
||||
}
|
||||
if (i0 == 4)
|
||||
{
|
||||
break;
|
||||
}
|
||||
wkr = 0.5 * sin(ec * i0);
|
||||
wki = 0.5 * cos(ec * i0);
|
||||
wdr = 0.5 - (wkr * w1r - wki * w1i);
|
||||
wdi = wkr * w1i + wki * w1r;
|
||||
wkr = 0.5 - wkr;
|
||||
i = i0;
|
||||
}
|
||||
xr = a[2] - a[n - 2];
|
||||
xi = a[3] + a[n - 1];
|
||||
yr = wdr * xr - wdi * xi;
|
||||
yi = wdr * xi + wdi * xr;
|
||||
a[2] -= yr;
|
||||
a[3] -= yi;
|
||||
a[n - 2] += yr;
|
||||
a[n - 1] -= yi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M_rftbsub(int n, double *a)
|
||||
{
|
||||
int i, i0, j, k;
|
||||
double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi;
|
||||
|
||||
ec = 2 * MM_PI_2 / n;
|
||||
wkr = 0;
|
||||
wki = 0;
|
||||
wdi = cos(ec);
|
||||
wdr = sin(ec);
|
||||
wdi *= wdr;
|
||||
wdr *= wdr;
|
||||
w1r = 1 - 2 * wdr;
|
||||
w1i = 2 * wdi;
|
||||
ss = 2 * w1i;
|
||||
i = n >> 1;
|
||||
a[i + 1] = -a[i + 1];
|
||||
while (1)
|
||||
{
|
||||
i0 = i - 4 * RDFT_LOOP_DIV;
|
||||
if (i0 < 4)
|
||||
{
|
||||
i0 = 4;
|
||||
}
|
||||
for (j = i - 4; j >= i0; j -= 4)
|
||||
{
|
||||
k = n - j;
|
||||
xr = a[j + 2] - a[k - 2];
|
||||
xi = a[j + 3] + a[k - 1];
|
||||
yr = wdr * xr + wdi * xi;
|
||||
yi = wdr * xi - wdi * xr;
|
||||
a[j + 2] -= yr;
|
||||
a[j + 3] = yi - a[j + 3];
|
||||
a[k - 2] += yr;
|
||||
a[k - 1] = yi - a[k - 1];
|
||||
wkr += ss * wdi;
|
||||
wki += ss * (0.5 - wdr);
|
||||
xr = a[j] - a[k];
|
||||
xi = a[j + 1] + a[k + 1];
|
||||
yr = wkr * xr + wki * xi;
|
||||
yi = wkr * xi - wki * xr;
|
||||
a[j] -= yr;
|
||||
a[j + 1] = yi - a[j + 1];
|
||||
a[k] += yr;
|
||||
a[k + 1] = yi - a[k + 1];
|
||||
wdr += ss * wki;
|
||||
wdi += ss * (0.5 - wkr);
|
||||
}
|
||||
if (i0 == 4)
|
||||
{
|
||||
break;
|
||||
}
|
||||
wkr = 0.5 * sin(ec * i0);
|
||||
wki = 0.5 * cos(ec * i0);
|
||||
wdr = 0.5 - (wkr * w1r - wki * w1i);
|
||||
wdi = wkr * w1i + wki * w1r;
|
||||
wkr = 0.5 - wkr;
|
||||
i = i0;
|
||||
}
|
||||
xr = a[2] - a[n - 2];
|
||||
xi = a[3] + a[n - 1];
|
||||
yr = wdr * xr + wdi * xi;
|
||||
yi = wdr * xi - wdi * xr;
|
||||
a[2] -= yr;
|
||||
a[3] = yi - a[3];
|
||||
a[n - 2] += yr;
|
||||
a[n - 1] = yi - a[n - 1];
|
||||
a[1] = -a[1];
|
||||
}
|
||||
|
||||
120
pgscript/utilities/m_apm/mapm_flr.cpp
Normal file
120
pgscript/utilities/m_apm/mapm_flr.cpp
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_flr.c
|
||||
*
|
||||
* Copyright (C) 2001 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the floor and ceil functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/*
|
||||
* input floor ceil
|
||||
* ----- ------ ------
|
||||
* 329.0 329.0 329.0
|
||||
* -837.0 -837.0 -837.0
|
||||
* 372.64 372.0 373.0
|
||||
* -237.52 -238.0 -237.0
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* return the nearest integer <= input
|
||||
*/
|
||||
void m_apm_floor(M_APM bb, M_APM aa)
|
||||
{
|
||||
M_APM mtmp;
|
||||
|
||||
m_apm_copy(bb, aa);
|
||||
|
||||
if (m_apm_is_integer(bb)) /* if integer, we're done */
|
||||
return;
|
||||
|
||||
if (bb->m_apm_exponent <= 0) /* if |bb| < 1, result is -1 or 0 */
|
||||
{
|
||||
if (bb->m_apm_sign < 0)
|
||||
m_apm_negate(bb, MM_One);
|
||||
else
|
||||
M_set_to_zero(bb);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (bb->m_apm_sign < 0)
|
||||
{
|
||||
mtmp = M_get_stack_var();
|
||||
m_apm_negate(mtmp, bb);
|
||||
|
||||
mtmp->m_apm_datalength = mtmp->m_apm_exponent;
|
||||
M_apm_normalize(mtmp);
|
||||
|
||||
m_apm_add(bb, mtmp, MM_One);
|
||||
bb->m_apm_sign = -1;
|
||||
M_restore_stack(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bb->m_apm_datalength = bb->m_apm_exponent;
|
||||
M_apm_normalize(bb);
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* return the nearest integer >= input
|
||||
*/
|
||||
void m_apm_ceil(M_APM bb, M_APM aa)
|
||||
{
|
||||
M_APM mtmp;
|
||||
|
||||
m_apm_copy(bb, aa);
|
||||
|
||||
if (m_apm_is_integer(bb)) /* if integer, we're done */
|
||||
return;
|
||||
|
||||
if (bb->m_apm_exponent <= 0) /* if |bb| < 1, result is 0 or 1 */
|
||||
{
|
||||
if (bb->m_apm_sign < 0)
|
||||
M_set_to_zero(bb);
|
||||
else
|
||||
m_apm_copy(bb, MM_One);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (bb->m_apm_sign < 0)
|
||||
{
|
||||
bb->m_apm_datalength = bb->m_apm_exponent;
|
||||
M_apm_normalize(bb);
|
||||
}
|
||||
else
|
||||
{
|
||||
mtmp = M_get_stack_var();
|
||||
m_apm_copy(mtmp, bb);
|
||||
|
||||
mtmp->m_apm_datalength = mtmp->m_apm_exponent;
|
||||
M_apm_normalize(mtmp);
|
||||
|
||||
m_apm_add(bb, mtmp, MM_One);
|
||||
M_restore_stack(1);
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
415
pgscript/utilities/m_apm/mapm_fpf.cpp
Normal file
415
pgscript/utilities/m_apm/mapm_fpf.cpp
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_fpf.c
|
||||
*
|
||||
* Copyright (C) 2001 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the Fixed Point Formatting functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/****************************************************************************/
|
||||
char *m_apm_to_fixpt_stringexp(int dplaces, M_APM atmp,
|
||||
char ch_radx, char ch_sep, int ct_sep)
|
||||
{
|
||||
int places, xp, dl, ii;
|
||||
char *cpr;
|
||||
|
||||
places = dplaces;
|
||||
|
||||
dl = atmp->m_apm_datalength;
|
||||
xp = atmp->m_apm_exponent;
|
||||
|
||||
if (places < 0) /* show ALL digits */
|
||||
{
|
||||
if (xp < 0)
|
||||
ii = dl - xp;
|
||||
else
|
||||
{
|
||||
if (dl > xp)
|
||||
ii = dl;
|
||||
else
|
||||
ii = xp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ii = places;
|
||||
|
||||
if (xp > 0)
|
||||
ii += xp;
|
||||
}
|
||||
|
||||
if (ct_sep != 0 && ch_sep != 0 && xp > 0)
|
||||
ii += xp / ct_sep;
|
||||
|
||||
if ((cpr = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL)
|
||||
return(NULL);
|
||||
|
||||
m_apm_to_fixpt_stringex(cpr, places, atmp, ch_radx, ch_sep, ct_sep);
|
||||
|
||||
return(cpr);
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_to_fixpt_stringex(char *s, int dplaces, M_APM atmp,
|
||||
char ch_radix, char ch_sep, int count_sep)
|
||||
{
|
||||
M_APM btmp;
|
||||
char ch, *cpd, *cps;
|
||||
int ii, jj, kk, ct, dl, xp, no_sep_flg, places;
|
||||
|
||||
btmp = M_get_stack_var();
|
||||
places = dplaces;
|
||||
cpd = s;
|
||||
no_sep_flg = FALSE;
|
||||
|
||||
m_apm_absolute_value(btmp, atmp); /* do conversion of positive number */
|
||||
|
||||
if (ch_sep == 0 || count_sep == 0) /* no separator char OR count */
|
||||
no_sep_flg = TRUE;
|
||||
|
||||
/* determine how much memory to get for the temp string */
|
||||
|
||||
dl = btmp->m_apm_datalength;
|
||||
xp = btmp->m_apm_exponent;
|
||||
|
||||
if (places < 0) /* show ALL digits */
|
||||
{
|
||||
if (xp < 0)
|
||||
ii = dl - xp;
|
||||
else
|
||||
{
|
||||
if (dl > xp)
|
||||
ii = dl;
|
||||
else
|
||||
ii = xp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ii = places;
|
||||
|
||||
if (xp > 0)
|
||||
ii += xp;
|
||||
}
|
||||
|
||||
if ((cps = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL)
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL,
|
||||
"\'m_apm_to_fixpt_stringex\', Out of memory");
|
||||
}
|
||||
|
||||
m_apm_to_fixpt_string(cps, places, btmp);
|
||||
|
||||
/*
|
||||
* the converted string may be all 'zero', 0.0000...
|
||||
* if so and the original number is negative,
|
||||
* do NOT set the '-' sign of our output string.
|
||||
*/
|
||||
|
||||
if (atmp->m_apm_sign == -1) /* if input number negative */
|
||||
{
|
||||
kk = 0;
|
||||
jj = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
ch = cps[kk++];
|
||||
if ((ch == '\0') || (jj != 0))
|
||||
break;
|
||||
|
||||
if (isdigit((int)ch))
|
||||
{
|
||||
if (ch != '0')
|
||||
jj = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (jj)
|
||||
*cpd++ = '-';
|
||||
}
|
||||
|
||||
ct = M_strposition(cps, (char *) "."); /* find the default (.) radix char */
|
||||
|
||||
if (ct == -1) /* if not found .. */
|
||||
{
|
||||
strcat(cps, "."); /* add one */
|
||||
ct = M_strposition(cps, (char *) "."); /* and then find it */
|
||||
}
|
||||
|
||||
if (places == 0) /* int format, terminate at radix char */
|
||||
cps[ct] = '\0';
|
||||
else
|
||||
cps[ct] = ch_radix; /* assign the radix char */
|
||||
|
||||
/*
|
||||
* if the number is small enough to not have any separator char's ...
|
||||
*/
|
||||
|
||||
if (ct <= count_sep)
|
||||
no_sep_flg = TRUE;
|
||||
|
||||
if (no_sep_flg)
|
||||
{
|
||||
strcpy(cpd, cps);
|
||||
}
|
||||
else
|
||||
{
|
||||
jj = 0;
|
||||
kk = count_sep;
|
||||
ii = ct / count_sep;
|
||||
|
||||
if ((ii = ct - ii * count_sep) == 0)
|
||||
ii = count_sep;
|
||||
|
||||
while (TRUE) /* write out the first 1,2 */
|
||||
{
|
||||
/* (up to count_sep) digits */
|
||||
*cpd++ = cps[jj++];
|
||||
|
||||
if (--ii == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
while (TRUE) /* write rest of the string */
|
||||
{
|
||||
if (kk == count_sep) /* write a new separator char */
|
||||
{
|
||||
if (jj != ct) /* unless we're at the radix */
|
||||
{
|
||||
*cpd++ = ch_sep; /* note that this also disables */
|
||||
kk = 0; /* the separator char AFTER */
|
||||
} /* the radix char */
|
||||
}
|
||||
|
||||
if ((*cpd++ = cps[jj++]) == '\0')
|
||||
break;
|
||||
|
||||
kk++;
|
||||
}
|
||||
}
|
||||
|
||||
MAPM_FREE(cps);
|
||||
M_restore_stack(1);
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_to_fixpt_string(char *ss, int dplaces, M_APM mtmp)
|
||||
{
|
||||
M_APM ctmp;
|
||||
void *vp;
|
||||
int places, i2, ii, jj, kk, xp, dl, numb;
|
||||
UCHAR *ucp, numdiv, numrem;
|
||||
char *cpw, *cpd, sbuf[128];
|
||||
|
||||
ctmp = M_get_stack_var();
|
||||
vp = NULL;
|
||||
cpd = ss;
|
||||
places = dplaces;
|
||||
|
||||
/* just want integer portion if places == 0 */
|
||||
|
||||
if (places == 0)
|
||||
{
|
||||
if (mtmp->m_apm_sign >= 0)
|
||||
m_apm_add(ctmp, mtmp, MM_0_5);
|
||||
else
|
||||
m_apm_subtract(ctmp, mtmp, MM_0_5);
|
||||
|
||||
m_apm_to_integer_string(cpd, ctmp);
|
||||
|
||||
M_restore_stack(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (places > 0)
|
||||
M_apm_round_fixpt(ctmp, places, mtmp);
|
||||
else
|
||||
m_apm_copy(ctmp, mtmp); /* show ALL digits */
|
||||
|
||||
if (ctmp->m_apm_sign == 0) /* result is 0 */
|
||||
{
|
||||
if (places < 0)
|
||||
{
|
||||
cpd[0] = '0'; /* "0.0" */
|
||||
cpd[1] = '.';
|
||||
cpd[2] = '0';
|
||||
cpd[3] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(cpd, '0', (places + 2)); /* pre-load string with all '0' */
|
||||
cpd[1] = '.';
|
||||
cpd[places + 2] = '\0';
|
||||
}
|
||||
|
||||
M_restore_stack(1);
|
||||
return;
|
||||
}
|
||||
|
||||
xp = ctmp->m_apm_exponent;
|
||||
dl = ctmp->m_apm_datalength;
|
||||
numb = (dl + 1) >> 1;
|
||||
|
||||
if (places < 0)
|
||||
{
|
||||
if (dl > xp)
|
||||
jj = dl + 16;
|
||||
else
|
||||
jj = xp + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
jj = places + 16;
|
||||
|
||||
if (xp > 0)
|
||||
jj += xp;
|
||||
}
|
||||
|
||||
if (jj > 112)
|
||||
{
|
||||
if ((vp = (void *)MAPM_MALLOC((jj + 16) * sizeof(char))) == NULL)
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL,
|
||||
"\'m_apm_to_fixpt_string\', Out of memory");
|
||||
}
|
||||
|
||||
cpw = (char *)vp;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpw = sbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* at this point, the number is non-zero and the output
|
||||
* string will contain at least 1 significant digit.
|
||||
*/
|
||||
|
||||
if (ctmp->m_apm_sign == -1) /* negative number */
|
||||
{
|
||||
*cpd++ = '-';
|
||||
}
|
||||
|
||||
ucp = ctmp->m_apm_data;
|
||||
ii = 0;
|
||||
|
||||
/* convert MAPM num to ASCII digits and store in working char array */
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
M_get_div_rem_10((int)(*ucp++), &numdiv, &numrem);
|
||||
|
||||
cpw[ii++] = numdiv + '0';
|
||||
cpw[ii++] = numrem + '0';
|
||||
|
||||
if (--numb == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
i2 = ii; /* save for later */
|
||||
|
||||
if (places < 0) /* show ALL digits */
|
||||
{
|
||||
places = dl - xp;
|
||||
|
||||
if (places < 1)
|
||||
places = 1;
|
||||
}
|
||||
|
||||
/* pad with trailing zeros if needed */
|
||||
|
||||
kk = xp + places + 2 - ii;
|
||||
|
||||
if (kk > 0)
|
||||
memset(&cpw[ii], '0', kk);
|
||||
|
||||
if (xp > 0) /* |num| >= 1, NO lead-in "0.nnn" */
|
||||
{
|
||||
ii = xp + places + 1;
|
||||
jj = 0;
|
||||
|
||||
for (kk = 0; kk < ii; kk++)
|
||||
{
|
||||
if (kk == xp)
|
||||
cpd[jj++] = '.';
|
||||
|
||||
cpd[jj++] = cpw[kk];
|
||||
}
|
||||
|
||||
cpd[ii] = '\0';
|
||||
}
|
||||
else /* |num| < 1, have lead-in "0.nnn" */
|
||||
{
|
||||
jj = 2 - xp;
|
||||
ii = 2 + places;
|
||||
memset(cpd, '0', (ii + 1)); /* pre-load string with all '0' */
|
||||
cpd[1] = '.'; /* assign decimal point */
|
||||
|
||||
for (kk = 0; kk < i2; kk++)
|
||||
{
|
||||
cpd[jj++] = cpw[kk];
|
||||
}
|
||||
|
||||
cpd[ii] = '\0';
|
||||
}
|
||||
|
||||
if (vp != NULL)
|
||||
MAPM_FREE(vp);
|
||||
|
||||
M_restore_stack(1);
|
||||
}
|
||||
/****************************************************************************/
|
||||
void M_apm_round_fixpt(M_APM btmp, int places, M_APM atmp)
|
||||
{
|
||||
int xp, ii;
|
||||
|
||||
xp = atmp->m_apm_exponent;
|
||||
ii = xp + places - 1;
|
||||
|
||||
M_set_to_zero(btmp); /* assume number is too small so the net result is 0 */
|
||||
|
||||
if (ii >= 0)
|
||||
{
|
||||
m_apm_round(btmp, ii, atmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ii == -1) /* next digit is significant which may round up */
|
||||
{
|
||||
if (atmp->m_apm_data[0] >= 50) /* digit >= 5, round up */
|
||||
{
|
||||
m_apm_copy(btmp, atmp);
|
||||
btmp->m_apm_data[0] = 10;
|
||||
btmp->m_apm_exponent += 1;
|
||||
btmp->m_apm_datalength = 1;
|
||||
M_apm_normalize(btmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
260
pgscript/utilities/m_apm/mapm_gcd.cpp
Normal file
260
pgscript/utilities/m_apm/mapm_gcd.cpp
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_gcd.c
|
||||
*
|
||||
* Copyright (C) 2001 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the GCD and LCM functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* From Knuth, The Art of Computer Programming:
|
||||
*
|
||||
* This is the binary GCD algorithm as described
|
||||
* in the book (Algorithm B)
|
||||
*/
|
||||
void m_apm_gcd(M_APM r, M_APM u, M_APM v)
|
||||
{
|
||||
M_APM tmpM, tmpN, tmpT, tmpU, tmpV;
|
||||
int kk, kr, mm;
|
||||
long pow_2;
|
||||
|
||||
/* 'is_integer' will return 0 || 1 */
|
||||
|
||||
if ((m_apm_is_integer(u) + m_apm_is_integer(v)) != 2)
|
||||
{
|
||||
M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_gcd\', Non-integer input");
|
||||
|
||||
M_set_to_zero(r);
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->m_apm_sign == 0)
|
||||
{
|
||||
m_apm_absolute_value(r, v);
|
||||
return;
|
||||
}
|
||||
|
||||
if (v->m_apm_sign == 0)
|
||||
{
|
||||
m_apm_absolute_value(r, u);
|
||||
return;
|
||||
}
|
||||
|
||||
tmpM = M_get_stack_var();
|
||||
tmpN = M_get_stack_var();
|
||||
tmpT = M_get_stack_var();
|
||||
tmpU = M_get_stack_var();
|
||||
tmpV = M_get_stack_var();
|
||||
|
||||
m_apm_absolute_value(tmpU, u);
|
||||
m_apm_absolute_value(tmpV, v);
|
||||
|
||||
/* Step B1 */
|
||||
|
||||
kk = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
mm = 1;
|
||||
if (m_apm_is_odd(tmpU))
|
||||
break;
|
||||
|
||||
mm = 0;
|
||||
if (m_apm_is_odd(tmpV))
|
||||
break;
|
||||
|
||||
m_apm_multiply(tmpN, MM_0_5, tmpU);
|
||||
m_apm_copy(tmpU, tmpN);
|
||||
|
||||
m_apm_multiply(tmpN, MM_0_5, tmpV);
|
||||
m_apm_copy(tmpV, tmpN);
|
||||
|
||||
kk++;
|
||||
}
|
||||
|
||||
/* Step B2 */
|
||||
|
||||
if (mm)
|
||||
{
|
||||
m_apm_negate(tmpT, tmpV);
|
||||
goto B4;
|
||||
}
|
||||
|
||||
m_apm_copy(tmpT, tmpU);
|
||||
|
||||
/* Step: */
|
||||
|
||||
B3:
|
||||
|
||||
m_apm_multiply(tmpN, MM_0_5, tmpT);
|
||||
m_apm_copy(tmpT, tmpN);
|
||||
|
||||
/* Step: */
|
||||
|
||||
B4:
|
||||
|
||||
if (m_apm_is_even(tmpT))
|
||||
goto B3;
|
||||
|
||||
/* Step B5 */
|
||||
|
||||
if (tmpT->m_apm_sign == 1)
|
||||
m_apm_copy(tmpU, tmpT);
|
||||
else
|
||||
m_apm_negate(tmpV, tmpT);
|
||||
|
||||
/* Step B6 */
|
||||
|
||||
m_apm_subtract(tmpT, tmpU, tmpV);
|
||||
|
||||
if (tmpT->m_apm_sign != 0)
|
||||
goto B3;
|
||||
|
||||
/*
|
||||
* result = U * 2 ^ kk
|
||||
*/
|
||||
|
||||
if (kk == 0)
|
||||
m_apm_copy(r, tmpU);
|
||||
else
|
||||
{
|
||||
if (kk == 1)
|
||||
m_apm_multiply(r, tmpU, MM_Two);
|
||||
|
||||
if (kk == 2)
|
||||
m_apm_multiply(r, tmpU, MM_Four);
|
||||
|
||||
if (kk >= 3)
|
||||
{
|
||||
mm = kk / 28;
|
||||
kr = kk % 28;
|
||||
pow_2 = 1L << kr;
|
||||
|
||||
if (mm == 0)
|
||||
{
|
||||
m_apm_set_long(tmpN, pow_2);
|
||||
m_apm_multiply(r, tmpU, tmpN);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_apm_copy(tmpN, MM_One);
|
||||
m_apm_set_long(tmpM, 0x10000000L); /* 2 ^ 28 */
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_multiply(tmpT, tmpN, tmpM);
|
||||
m_apm_copy(tmpN, tmpT);
|
||||
|
||||
if (--mm == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (kr == 0)
|
||||
{
|
||||
m_apm_multiply(r, tmpU, tmpN);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_apm_set_long(tmpM, pow_2);
|
||||
m_apm_multiply(tmpT, tmpN, tmpM);
|
||||
m_apm_multiply(r, tmpU, tmpT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
M_restore_stack(5);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* u * v
|
||||
* LCM(u,v) = ------------
|
||||
* GCD(u,v)
|
||||
*/
|
||||
|
||||
void m_apm_lcm(M_APM r, M_APM u, M_APM v)
|
||||
{
|
||||
M_APM tmpN, tmpG;
|
||||
|
||||
tmpN = M_get_stack_var();
|
||||
tmpG = M_get_stack_var();
|
||||
|
||||
m_apm_multiply(tmpN, u, v);
|
||||
m_apm_gcd(tmpG, u, v);
|
||||
m_apm_integer_divide(r, tmpN, tmpG);
|
||||
|
||||
M_restore_stack(2);
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef BIG_COMMENT_BLOCK
|
||||
|
||||
/*
|
||||
* traditional GCD included for reference
|
||||
* (also useful for testing ...)
|
||||
*/
|
||||
|
||||
/*
|
||||
* From Knuth, The Art of Computer Programming:
|
||||
*
|
||||
* To compute GCD(u,v)
|
||||
*
|
||||
* A1:
|
||||
* if (v == 0) return (u)
|
||||
* A2:
|
||||
* t = u mod v
|
||||
* u = v
|
||||
* v = t
|
||||
* goto A1
|
||||
*/
|
||||
void m_apm_gcd_traditional(M_APM r, M_APM u, M_APM v)
|
||||
{
|
||||
M_APM tmpD, tmpN, tmpU, tmpV;
|
||||
|
||||
tmpD = M_get_stack_var();
|
||||
tmpN = M_get_stack_var();
|
||||
tmpU = M_get_stack_var();
|
||||
tmpV = M_get_stack_var();
|
||||
|
||||
m_apm_absolute_value(tmpU, u);
|
||||
m_apm_absolute_value(tmpV, v);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (tmpV->m_apm_sign == 0)
|
||||
break;
|
||||
|
||||
m_apm_integer_div_rem(tmpD, tmpN, tmpU, tmpV);
|
||||
m_apm_copy(tmpU, tmpV);
|
||||
m_apm_copy(tmpV, tmpN);
|
||||
}
|
||||
|
||||
m_apm_copy(r, tmpU);
|
||||
M_restore_stack(4);
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
152
pgscript/utilities/m_apm/mapm_lg2.cpp
Normal file
152
pgscript/utilities/m_apm/mapm_lg2.cpp
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_lg2.c
|
||||
*
|
||||
* Copyright (C) 2003 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the iterative function to compute the LOG
|
||||
* This is an internal function to the library and is not intended
|
||||
* to be called directly by the user.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* compute rr = log(nn)
|
||||
*
|
||||
* input is assumed to not exceed the exponent range of a normal
|
||||
* 'C' double ( |exponent| must be < 308)
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
void M_log_solve_cubic(M_APM rr, int places, M_APM nn)
|
||||
{
|
||||
M_APM tmp0, tmp1, tmp2, tmp3, guess;
|
||||
int ii, maxp, tolerance, local_precision;
|
||||
|
||||
guess = M_get_stack_var();
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
tmp3 = M_get_stack_var();
|
||||
|
||||
M_get_log_guess(guess, nn);
|
||||
|
||||
tolerance = -(places + 4);
|
||||
maxp = places + 16;
|
||||
local_precision = 18;
|
||||
|
||||
/* Use the following iteration to solve for log :
|
||||
|
||||
exp(X) - N
|
||||
X = X - 2 * ------------
|
||||
n+1 exp(X) + N
|
||||
|
||||
|
||||
this is a cubically convergent algorithm
|
||||
(each iteration yields 3X more digits)
|
||||
*/
|
||||
|
||||
ii = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_exp(tmp1, local_precision, guess);
|
||||
|
||||
m_apm_subtract(tmp3, tmp1, nn);
|
||||
m_apm_add(tmp2, tmp1, nn);
|
||||
|
||||
m_apm_divide(tmp1, local_precision, tmp3, tmp2);
|
||||
m_apm_multiply(tmp0, MM_Two, tmp1);
|
||||
m_apm_subtract(tmp3, guess, tmp0);
|
||||
|
||||
if (ii != 0)
|
||||
{
|
||||
if (((3 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
m_apm_round(guess, local_precision, tmp3);
|
||||
|
||||
local_precision *= 3;
|
||||
|
||||
if (local_precision > maxp)
|
||||
local_precision = maxp;
|
||||
|
||||
ii = 1;
|
||||
}
|
||||
|
||||
m_apm_round(rr, places, tmp3);
|
||||
M_restore_stack(5);
|
||||
}
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* find log(N)
|
||||
*
|
||||
* if places < 360
|
||||
* solve with cubically convergent algorithm above
|
||||
*
|
||||
* else
|
||||
*
|
||||
* let 'X' be 'close' to the solution (we use ~110 decimal places)
|
||||
*
|
||||
* let Y = N * exp(-X) - 1
|
||||
*
|
||||
* then
|
||||
*
|
||||
* log(N) = X + log(1 + Y)
|
||||
*
|
||||
* since 'Y' will be small, we can use the efficient log_near_1 algorithm.
|
||||
*
|
||||
*/
|
||||
void M_log_basic_iteration(M_APM rr, int places, M_APM nn)
|
||||
{
|
||||
M_APM tmp0, tmp1, tmp2, tmpX;
|
||||
|
||||
if (places < 360)
|
||||
{
|
||||
M_log_solve_cubic(rr, places, nn);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
tmpX = M_get_stack_var();
|
||||
|
||||
M_log_solve_cubic(tmpX, 110, nn);
|
||||
|
||||
m_apm_negate(tmp0, tmpX);
|
||||
m_apm_exp(tmp1, (places + 8), tmp0);
|
||||
m_apm_multiply(tmp2, tmp1, nn);
|
||||
m_apm_subtract(tmp1, tmp2, MM_One);
|
||||
|
||||
M_log_near_1(tmp0, (places - 104), tmp1);
|
||||
|
||||
m_apm_add(tmp1, tmpX, tmp0);
|
||||
m_apm_round(rr, places, tmp1);
|
||||
|
||||
M_restore_stack(4);
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
204
pgscript/utilities/m_apm/mapm_lg3.cpp
Normal file
204
pgscript/utilities/m_apm/mapm_lg3.cpp
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_lg3.c
|
||||
*
|
||||
* Copyright (C) 2003 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the function to compute log(2), log(10),
|
||||
* and 1/log(10) to the desired precision using an AGM algorithm.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/*
|
||||
* using the 'R' function (defined below) for 'N' decimal places :
|
||||
*
|
||||
*
|
||||
* -N -N
|
||||
* log(2) = R(1, 0.5 * 10 ) - R(1, 10 )
|
||||
*
|
||||
*
|
||||
* -N -N
|
||||
* log(10) = R(1, 0.1 * 10 ) - R(1, 10 )
|
||||
*
|
||||
*
|
||||
* In general:
|
||||
*
|
||||
* -N -N
|
||||
* log(x) = R(1, 10 / x) - R(1, 10 )
|
||||
*
|
||||
*
|
||||
* I found this on a web site which went into considerable detail
|
||||
* on the history of log(2). This formula is algebraically identical
|
||||
* to the formula specified in J. Borwein and P. Borwein's book
|
||||
* "PI and the AGM". (reference algorithm 7.2)
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
* check if our local copy of log(2) & log(10) is precise
|
||||
* enough for our purpose. if not, calculate them so it's
|
||||
* as precise as desired, accurate to at least 'places'.
|
||||
*/
|
||||
void M_check_log_places(int places)
|
||||
{
|
||||
M_APM tmp6, tmp7, tmp8, tmp9;
|
||||
int dplaces;
|
||||
|
||||
dplaces = places + 4;
|
||||
|
||||
if (dplaces > MM_lc_log_digits)
|
||||
{
|
||||
MM_lc_log_digits = dplaces + 4;
|
||||
|
||||
tmp6 = M_get_stack_var();
|
||||
tmp7 = M_get_stack_var();
|
||||
tmp8 = M_get_stack_var();
|
||||
tmp9 = M_get_stack_var();
|
||||
|
||||
dplaces += 6 + (int)log10((double)places);
|
||||
|
||||
m_apm_copy(tmp7, MM_One);
|
||||
tmp7->m_apm_exponent = -places;
|
||||
|
||||
M_log_AGM_R_func(tmp8, dplaces, MM_One, tmp7);
|
||||
|
||||
m_apm_multiply(tmp6, tmp7, MM_0_5);
|
||||
|
||||
M_log_AGM_R_func(tmp9, dplaces, MM_One, tmp6);
|
||||
|
||||
m_apm_subtract(MM_lc_log2, tmp9, tmp8); /* log(2) */
|
||||
|
||||
tmp7->m_apm_exponent -= 1; /* divide by 10 */
|
||||
|
||||
M_log_AGM_R_func(tmp9, dplaces, MM_One, tmp7);
|
||||
|
||||
m_apm_subtract(MM_lc_log10, tmp9, tmp8); /* log(10) */
|
||||
m_apm_reciprocal(MM_lc_log10R, dplaces, MM_lc_log10); /* 1 / log(10) */
|
||||
|
||||
M_restore_stack(4);
|
||||
}
|
||||
}
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* define a notation for a function 'R' :
|
||||
*
|
||||
*
|
||||
*
|
||||
* 1
|
||||
* R (a0, b0) = ------------------------------
|
||||
*
|
||||
* ----
|
||||
* \
|
||||
* \ n-1 2 2
|
||||
* 1 - | 2 * (a - b )
|
||||
* / n n
|
||||
* /
|
||||
* ----
|
||||
* n >= 0
|
||||
*
|
||||
*
|
||||
* where a, b are the classic AGM iteration :
|
||||
*
|
||||
*
|
||||
* a = 0.5 * (a + b )
|
||||
* n+1 n n
|
||||
*
|
||||
*
|
||||
* b = sqrt(a * b )
|
||||
* n+1 n n
|
||||
*
|
||||
*
|
||||
*
|
||||
* define a variable 'c' for more efficient computation :
|
||||
*
|
||||
* 2 2 2
|
||||
* c = 0.5 * (a - b ) , c = a - b
|
||||
* n+1 n n n n n
|
||||
*
|
||||
*/
|
||||
|
||||
/****************************************************************************/
|
||||
void M_log_AGM_R_func(M_APM rr, int places, M_APM aa, M_APM bb)
|
||||
{
|
||||
M_APM tmp1, tmp2, tmp3, tmp4, tmpC2, sum, pow_2, tmpA0, tmpB0;
|
||||
int tolerance, dplaces;
|
||||
|
||||
tmpA0 = M_get_stack_var();
|
||||
tmpB0 = M_get_stack_var();
|
||||
tmpC2 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
tmp3 = M_get_stack_var();
|
||||
tmp4 = M_get_stack_var();
|
||||
sum = M_get_stack_var();
|
||||
pow_2 = M_get_stack_var();
|
||||
|
||||
tolerance = places + 8;
|
||||
dplaces = places + 16;
|
||||
|
||||
m_apm_copy(tmpA0, aa);
|
||||
m_apm_copy(tmpB0, bb);
|
||||
m_apm_copy(pow_2, MM_0_5);
|
||||
|
||||
m_apm_multiply(tmp1, aa, aa); /* 0.5 * [ a ^ 2 - b ^ 2 ] */
|
||||
m_apm_multiply(tmp2, bb, bb);
|
||||
m_apm_subtract(tmp3, tmp1, tmp2);
|
||||
m_apm_multiply(sum, MM_0_5, tmp3);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_subtract(tmp1, tmpA0, tmpB0); /* C n+1 = 0.5 * [ An - Bn ] */
|
||||
m_apm_multiply(tmp4, MM_0_5, tmp1); /* C n+1 */
|
||||
m_apm_multiply(tmpC2, tmp4, tmp4); /* C n+1 ^ 2 */
|
||||
|
||||
/* do the AGM */
|
||||
|
||||
m_apm_add(tmp1, tmpA0, tmpB0);
|
||||
m_apm_multiply(tmp3, MM_0_5, tmp1);
|
||||
|
||||
m_apm_multiply(tmp2, tmpA0, tmpB0);
|
||||
m_apm_sqrt(tmpB0, dplaces, tmp2);
|
||||
|
||||
m_apm_round(tmpA0, dplaces, tmp3);
|
||||
|
||||
/* end AGM */
|
||||
|
||||
m_apm_multiply(tmp2, MM_Two, pow_2);
|
||||
m_apm_copy(pow_2, tmp2);
|
||||
|
||||
m_apm_multiply(tmp1, tmpC2, pow_2);
|
||||
m_apm_add(tmp3, sum, tmp1);
|
||||
|
||||
if ((tmp1->m_apm_sign == 0) ||
|
||||
((-2 * tmp1->m_apm_exponent) > tolerance))
|
||||
break;
|
||||
|
||||
m_apm_round(sum, dplaces, tmp3);
|
||||
}
|
||||
|
||||
m_apm_subtract(tmp4, MM_One, tmp3);
|
||||
m_apm_reciprocal(rr, places, tmp4);
|
||||
|
||||
M_restore_stack(9);
|
||||
}
|
||||
/****************************************************************************/
|
||||
93
pgscript/utilities/m_apm/mapm_lg4.cpp
Normal file
93
pgscript/utilities/m_apm/mapm_lg4.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_lg4.c
|
||||
*
|
||||
* Copyright (C) 2003 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the LOG_NEAR_1 function.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
calculate log (1 + x) with the following series:
|
||||
|
||||
x
|
||||
y = ----- ( |y| < 1 )
|
||||
x + 2
|
||||
|
||||
|
||||
[ 1 + y ] y^3 y^5 y^7
|
||||
log [-------] = 2 * [ y + --- + --- + --- ... ]
|
||||
[ 1 - y ] 3 5 7
|
||||
|
||||
*/
|
||||
void M_log_near_1(M_APM rr, int places, M_APM xx)
|
||||
{
|
||||
M_APM tmp0, tmp1, tmp2, tmpS, term;
|
||||
int tolerance, dplaces, local_precision;
|
||||
long m1;
|
||||
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
tmpS = M_get_stack_var();
|
||||
term = M_get_stack_var();
|
||||
|
||||
tolerance = xx->m_apm_exponent - (places + 6);
|
||||
dplaces = (places + 12) - xx->m_apm_exponent;
|
||||
|
||||
m_apm_add(tmp0, xx, MM_Two);
|
||||
m_apm_divide(tmpS, (dplaces + 6), xx, tmp0);
|
||||
|
||||
m_apm_copy(term, tmpS);
|
||||
m_apm_multiply(tmp0, tmpS, tmpS);
|
||||
m_apm_round(tmp2, (dplaces + 6), tmp0);
|
||||
|
||||
m1 = 3L;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
m_apm_multiply(tmp0, term, tmp2);
|
||||
|
||||
if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0))
|
||||
break;
|
||||
|
||||
local_precision = dplaces + tmp0->m_apm_exponent;
|
||||
|
||||
if (local_precision < 20)
|
||||
local_precision = 20;
|
||||
|
||||
m_apm_set_long(tmp1, m1);
|
||||
m_apm_round(term, local_precision, tmp0);
|
||||
m_apm_divide(tmp0, local_precision, term, tmp1);
|
||||
m_apm_add(tmp1, tmpS, tmp0);
|
||||
m_apm_copy(tmpS, tmp1);
|
||||
m1 += 2;
|
||||
}
|
||||
|
||||
m_apm_multiply(tmp0, MM_Two, tmpS);
|
||||
m_apm_round(rr, places, tmp0);
|
||||
|
||||
M_restore_stack(5); /* restore the 5 locals we used here */
|
||||
}
|
||||
/****************************************************************************/
|
||||
138
pgscript/utilities/m_apm/mapm_log.cpp
Normal file
138
pgscript/utilities/m_apm/mapm_log.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_log.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains the LOG and LOG10 functions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/*
|
||||
Calls the LOG function. The formula used is :
|
||||
|
||||
log10(x) = A * log(x) where A = log (e) [0.43429448190325...]
|
||||
10
|
||||
*/
|
||||
void m_apm_log10(M_APM rr, int places, M_APM aa)
|
||||
{
|
||||
int dplaces;
|
||||
M_APM tmp8, tmp9;
|
||||
|
||||
tmp8 = M_get_stack_var();
|
||||
tmp9 = M_get_stack_var();
|
||||
|
||||
dplaces = places + 4;
|
||||
M_check_log_places(dplaces + 45);
|
||||
|
||||
m_apm_log(tmp9, dplaces, aa);
|
||||
m_apm_multiply(tmp8, tmp9, MM_lc_log10R);
|
||||
m_apm_round(rr, places, tmp8);
|
||||
M_restore_stack(2); /* restore the 2 locals we used here */
|
||||
}
|
||||
/****************************************************************************/
|
||||
void m_apm_log(M_APM r, int places, M_APM a)
|
||||
{
|
||||
M_APM tmp0, tmp1, tmp2;
|
||||
int mexp, dplaces;
|
||||
|
||||
if (a->m_apm_sign <= 0)
|
||||
{
|
||||
M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_log\', Negative argument");
|
||||
M_set_to_zero(r);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp0 = M_get_stack_var();
|
||||
tmp1 = M_get_stack_var();
|
||||
tmp2 = M_get_stack_var();
|
||||
|
||||
dplaces = places + 8;
|
||||
|
||||
/*
|
||||
* if the input is real close to 1, use the series expansion
|
||||
* to compute the log.
|
||||
*
|
||||
* 0.9999 < a < 1.0001
|
||||
*/
|
||||
|
||||
mexp = a->m_apm_exponent;
|
||||
|
||||
if (mexp == 0 || mexp == 1)
|
||||
{
|
||||
m_apm_subtract(tmp0, a, MM_One);
|
||||
|
||||
if (tmp0->m_apm_sign == 0) /* is input exactly 1 ?? */
|
||||
{
|
||||
/* if so, result is 0 */
|
||||
M_set_to_zero(r);
|
||||
M_restore_stack(3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tmp0->m_apm_exponent <= -4)
|
||||
{
|
||||
M_log_near_1(r, places, tmp0);
|
||||
M_restore_stack(3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure our log(10) is accurate enough for this calculation */
|
||||
/* (and log(2) which is called from M_log_basic_iteration) */
|
||||
|
||||
M_check_log_places(dplaces + 25);
|
||||
|
||||
if (abs(mexp) <= 3)
|
||||
{
|
||||
M_log_basic_iteration(r, places, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* use log (x * y) = log(x) + log(y)
|
||||
*
|
||||
* here we use y = exponent of our base 10 number.
|
||||
*
|
||||
* let 'C' = log(10) = 2.3025850929940....
|
||||
*
|
||||
* then log(x * y) = log(x) + ( C * base_10_exponent )
|
||||
*/
|
||||
|
||||
m_apm_copy(tmp2, a);
|
||||
|
||||
mexp = tmp2->m_apm_exponent - 2;
|
||||
tmp2->m_apm_exponent = 2; /* force number between 10 & 100 */
|
||||
|
||||
M_log_basic_iteration(tmp0, dplaces, tmp2);
|
||||
|
||||
m_apm_set_long(tmp1, (long)mexp);
|
||||
m_apm_multiply(tmp2, tmp1, MM_lc_log10);
|
||||
m_apm_add(tmp1, tmp2, tmp0);
|
||||
|
||||
m_apm_round(r, places, tmp1);
|
||||
}
|
||||
|
||||
M_restore_stack(3); /* restore the 3 locals we used here */
|
||||
}
|
||||
/****************************************************************************/
|
||||
131
pgscript/utilities/m_apm/mapm_mul.cpp
Normal file
131
pgscript/utilities/m_apm/mapm_mul.cpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
|
||||
/*
|
||||
* M_APM - mapm_mul.c
|
||||
*
|
||||
* Copyright (C) 1999 - 2007 Michael C. Ring
|
||||
*
|
||||
* Permission to use, copy, and distribute this software and its
|
||||
* documentation for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation.
|
||||
*
|
||||
* Permission to modify the software is granted. Permission to distribute
|
||||
* the modified code is granted. Modifications are to be distributed by
|
||||
* using the file 'license.txt' as a template to modify the file header.
|
||||
* 'license.txt' is available in the official MAPM distribution.
|
||||
*
|
||||
* This software is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* This file contains basic multiplication function.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pgAdmin3.h"
|
||||
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
|
||||
|
||||
extern void M_fast_multiply(M_APM, M_APM, M_APM);
|
||||
|
||||
/****************************************************************************/
|
||||
void m_apm_multiply(M_APM r, M_APM a, M_APM b)
|
||||
{
|
||||
int ai, itmp, sign, nexp, ii, jj, indexa, indexb, index0, numdigits;
|
||||
UCHAR *cp, *cpr, *cp_div, *cp_rem;
|
||||
void *vp;
|
||||
|
||||
sign = a->m_apm_sign * b->m_apm_sign;
|
||||
nexp = a->m_apm_exponent + b->m_apm_exponent;
|
||||
|
||||
if (sign == 0) /* one number is zero, result is zero */
|
||||
{
|
||||
M_set_to_zero(r);
|
||||
return;
|
||||
}
|
||||
|
||||
numdigits = a->m_apm_datalength + b->m_apm_datalength;
|
||||
indexa = (a->m_apm_datalength + 1) >> 1;
|
||||
indexb = (b->m_apm_datalength + 1) >> 1;
|
||||
|
||||
/*
|
||||
* If we are multiplying 2 'big' numbers, use the fast algorithm.
|
||||
*
|
||||
* This is a **very** approx break even point between this algorithm
|
||||
* and the FFT multiply. Note that different CPU's, operating systems,
|
||||
* and compiler's may yield a different break even point. This point
|
||||
* (~96 decimal digits) is how the test came out on the author's system.
|
||||
*/
|
||||
|
||||
if (indexa >= 48 && indexb >= 48)
|
||||
{
|
||||
M_fast_multiply(r, a, b);
|
||||
return;
|
||||
}
|
||||
|
||||
ii = (numdigits + 1) >> 1; /* required size of result, in bytes */
|
||||
|
||||
if (ii > r->m_apm_malloclength)
|
||||
{
|
||||
if ((vp = MAPM_REALLOC(r->m_apm_data, (ii + 32))) == NULL)
|
||||
{
|
||||
/* fatal, this does not return */
|
||||
|
||||
M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_multiply\', Out of memory");
|
||||
}
|
||||
|
||||
r->m_apm_malloclength = ii + 28;
|
||||
r->m_apm_data = (UCHAR *)vp;
|
||||
}
|
||||
|
||||
M_get_div_rem_addr(&cp_div, &cp_rem);
|
||||
|
||||
index0 = indexa + indexb;
|
||||
cp = r->m_apm_data;
|
||||
memset(cp, 0, index0);
|
||||
ii = indexa;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
index0--;
|
||||
cpr = cp + index0;
|
||||
jj = indexb;
|
||||
ai = (int)a->m_apm_data[--ii];
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
itmp = ai * b->m_apm_data[--jj];
|
||||
|
||||
*(cpr - 1) += cp_div[itmp];
|
||||
*cpr += cp_rem[itmp];
|
||||
|
||||
if (*cpr >= 100)
|
||||
{
|
||||
*cpr -= 100;
|
||||
*(cpr - 1) += 1;
|
||||
}
|
||||
|
||||
cpr--;
|
||||
|
||||
if (*cpr >= 100)
|
||||
{
|
||||
*cpr -= 100;
|
||||
*(cpr - 1) += 1;
|
||||
}
|
||||
|
||||
if (jj == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ii == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
r->m_apm_sign = sign;
|
||||
r->m_apm_exponent = nexp;
|
||||
r->m_apm_datalength = numdigits;
|
||||
|
||||
M_apm_normalize(r);
|
||||
}
|
||||
/****************************************************************************/
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue