Hostname = $Hostname;
$this->Hostport = $Hostport;
$this->Database = $Database;
$this->Username = $Username;
$this->Password = $Password;
$this->Charset = $Charset;
$this->Persistent = $Persistent;
}
static public function NewParameter($Hostname = '', $Hostport = 0, $Database = '', $Username = '', $Password = '', $Persistent = false, $Charset = '')
{
return new ConnectParameter($Hostname, $Hostport, $Database, $Username, $Password, $Persistent, $Charset);
}
}
/// 2017-04-10: expand pdo request or execute parameter.
class CommandParameters
{
/**
* @var array of CommandParameter
*/
private $Parameters;
/**
* CommandParameters constructor.
*/
public function __construct()
{
$this->Parameters = array();
}
/**
*
*/
public function __destruct()
{
$this->Clear();
}
/**
* @param int $Index
* @return CommandParameter
*/
public function GetParameter($Index)
{
if (is_integer($Index) && is_array($this->Parameters) && !empty($this->Parameters) && ($Index >= 0) && ($Index < count($this->Parameters)))
return $this->Parameters[$Index];
else
return null;
}
/**
* @param CommandParameter $Parameter
* @return int
*/
public function Append($Parameter)
{
$Parameter->Owner = $this;
array_push($this->Parameters, $Parameter);
return count($this->Parameters);
}
/**
* @param int $Index
* @return int
*/
public function Delete($Index)
{
if (is_integer($Index) && is_array($this->Parameters) && !empty($this->Parameters) && ($Index >= 0) && ($Index < count($this->Parameters)))
array_splice($this->Parameters, $Index, 1);
return count($this->Parameters);
}
/**
* @return int
*/
public function Clear()
{
$this->Parameters = array();
return 0;
}
/**
* @return int
*/
public function GetCount()
{
return count($this->Parameters);
}
/**
* @param string $Name
* @param string $Type
* @param null $Value
* @param int $Size
* @param bool $Raw
* @param bool $Output
* @return CommandParameter
*/
public function CreateParameter($Name = '', $Type = TYPENAME_STRING, $Value = null, $Size = 0, $Raw = false, $Output = false)
{
$Return = new CommandParameter($this);
$this->Append($Return);
$Return->Name = $Name;
$Return->Type = $Type;
$Return->Value = empty($Value) ? '' : $Value;
$Return->Size = empty($Size) ? strlen($Value) : $Size;
$Return->Raw = $Raw;
$Return->Output = $Output;
return $Return;
}
}
class CommandParameter
{
/**
* @var CommandParameters
*/
public $Owner;
/**
* @var string
*/
public $Name;
/**
* @var string
*/
public $Type;
/**
* @var mixed
*/
public $Value;
/**
* @var int
*/
public $Size;
/**
* @var bool
*/
public $Raw;
/**
* @var bool
*/
public $Output;
/**
* CommandParameter constructor.
* @param $Parameter
*/
public function __construct($Parameter)
{
if ($Parameter instanceof CommandParameters)
{
$this->Owner = $Parameter;
$this->Name = '';
$this->Type = TYPENAME_STRING;
$this->Value = '';
$this->Size = 0;
$this->Raw = false;
$this->Output = false;
}
elseif (!empty($Parameter))
{
$this->ParseArray($Parameter);
}
else
{
$this->Owner = null;
$this->Name = '';
$this->Type = TYPENAME_STRING;
$this->Value = '';
$this->Size = 0;
$this->Raw = false;
$this->Output = false;
}
}
/**
* 从数组中获取值
* @param array $Parameter
* @return bool
* @link
* @auther 应俊
*/
public function ParseArray($Parameter)
{
if (empty($Parameter))
return false;
switch (gettype($Parameter))
{
case 'object':
{
if (method_exists($Parameter, 'GetObjectPropertyList'))
$Keys = $Parameter->GetObjectPropertyList();
else
$Keys = array_keys((array)$Parameter);
foreach ($Keys as $K)
{
$V = $Parameter->$K;
if (is_string($V) && null != ($o = JsonStringToJsonObject($V)) && is_object($o))
$this->$K = $o;
else
$this->$K = $V;
}
break;
}
case 'array':
{
foreach ($Parameter as $K => $V)
{
if (is_string($V) && null != ($o = JsonStringToJsonObject($V)) && is_object($o))
$this->$K = $o;
else
$this->$K = $V;
}
break;
}
default:
return false;
}
return true;
}
/**
* @param CommandParameters $Owner
* @param string $Name
* @param string $Type
* @param null $Value
* @param int $Size
* @param bool $Raw
* @param bool $Output
* @return CommandParameter
*/
static public function Parameter($Owner = null, $Name = '', $Type = TYPENAME_STRING, $Value = null, $Size = 0, $Raw = false, $Output = false)
{
$Return = new CommandParameter($Owner);
if ($Owner instanceof CommandParameters)
{
$Owner->Append($Return);
}
elseif (!is_array($Owner))
{
$Return->Name = $Name;
$Return->Type = $Type;
$Return->Value = empty($Value) ? '' : $Value;
$Return->Size = empty($Size) ? strlen($Value) : $Size;
$Return->Raw = $Raw;
$Return->Output = $Output;
}
return $Return;
}
}
/*******************************
* name: CommandInformation.
* note: sql command information class.
*******************************/
class CommandInformation
{
public $Command;
public $Paramer;
public function __construct($Command = '', $Paramer = array())
{
$this->Command = $Command;
$this->Paramer = $Paramer;
}
/**
* @param CommandInformation $CommandInformation
* @return bool.
*/
public function Merge($CommandInformation)
{
if (!($CommandInformation instanceof CommandInformation))
return false;
$this->Command .= $CommandInformation->Command;
foreach ((array)$CommandInformation->Paramer as $Key => $Value)
{
array_push($this->Paramer, $Value);
}
return true;
}
static public function NewCommandInformation($Command = '', $Paramer = array())
{
return new CommandInformation($Command, $Paramer);
}
}
/// ====================================================================================================================
interface IItem
{
/**
* @return IList
*/
public function GetOwner();
/**
* @param IList $Owner
*/
public function SetOwner($Owner);
}
interface IList
{
/**
* @param integer $Index
* @return IItem
*/
public function GetItem($Index);
/**
* @return integer
*/
public function GetCount();
/**
* @param IItem $Item
* @return integer
*/
public function Append($Item);
/**
* @param integer $Index
* @return integer
*/
public function Delete($Index);
/**
* @return integer
*/
public function Clear();
}
interface IField extends IItem
{
/**
* @note get field name.
* @return string
*/
public function GetName();
/**
* @note get field data type.
* @return string
*/
public function GetType();
/**
* @note get field data size.
* @return integer
*/
public function GetSize();
/**
* @note get field default value.
* @return mixed
*/
public function GetDefaultValue();
/**
* @return IFields
*/
public function GetOwner();
/**
* @param IFields $Owner
*/
public function SetOwner($Owner);
}
interface IFields extends IList
{
/**
* @return ITable
*/
public function GetOwner();
/**
* @param ITable $Owner
*/
public function SetOwner($Owner);
}
interface ITable extends IItem
{
/**
* @note get table field list.
* @return IFields
*/
public function GetFields();
/**
* @note get table name.
* @return string
*/
public function GetName();
public function Select();
public function Filter();
public function Limit();
public function WithPage();
public function Request();
/**
* @return ITables
*/
public function GetOwner();
/**
* @param ITables $Owner
*/
public function SetOwner($Owner);
}
interface ITables extends IList
{
/**
* @return IPDOHelper
*/
public function GetOwner();
/**
* @param IPDOHelper $Owner
*/
public function SetOwner($Owner);
}
/*******************************
* name: IPDOHelper.
* note: database helper base interface.
*******************************/
interface IPDOHelper
{
/*******************************
* name: Succeeded.
* note: test the success of the code.
* parameters: code.
* return: true if the code succeeded, false otherwise.
*******************************
* @param string|int $Code
* @return bool
*******************************/
public function Succeeded($Code);
/*******************************
* name: IsDone.
* note: test the success of the last code.
* parameters: none.
* return: true if the code succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function IsDone();
/*******************************
* name: Connect.
* note: connect to database.
* parameters: look at the derived class.
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Connect();
/*******************************
* name: Connect.
* note: close active connected.
* parameters: none.
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Close();
/*******************************
* name: GetTables.
* note: get the database all tables.
* parameters: none.
* return: table list if the method call succeeded, null otherwise.
*******************************
* @return ITables
*******************************/
public function GetTables();
/*******************************
* name: GetTableFields.
* note: get the table fields.
* parameters: table name.
* return: field list if the method call succeeded, null otherwise.
*******************************
* @param string $Tablename
* @return ITables
*******************************/
public function GetTableFields($Tablename);
/*******************************
* name: Request.
* note: request data from database(recordset was returned).
* parameters: sql command, parameter list.
* 2016-03-29: append the callback support(first parameter).
* return: recordset as array if the method call succeeded, null otherwise.
*******************************
* param callable $Callable
* param string $SqlCommand
* param mixed $Parameters...
* @return mixed|null
*******************************/
public function Request(/* $Callable, $SqlCommand, $Parameters, ... */);
/*******************************
* name: Execute.
* note: execute command from database(no recordset was returned).
* parameters: sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* param string $SqlCommand
* param mixed $Parameters...
* @return bool
*******************************/
public function Execute(/* $SqlCommand, $Parameters, ... */);
/*******************************
* name: LastInsertId.
* note: This method may not return a meaningful or consistent result across different PDO drivers, because the underlying database may not even support the notion of auto-increment fields or sequences.
* parameters: name
* return: PDO::lastInsertId method return value.
*******************************
* @param null|string $Name
* @return bool|string
******************************/
public function LastInsertId($Name = null);
/*******************************
* name: ColumnNames.
* note: get all field name of current recordset.
* parameters: none
* return: all field name of current recordset.
*******************************
* @return array|bool
*******************************/
public function ColumnNames();
/*******************************
* name: Records.
* note: return record list, deleted, or changed by the last statement.
* parameters: none
* return: the record list, deleted, or changed.
*******************************
* @return array
*******************************/
public function GetRecords();
/*******************************
* name: InTransaction.
* note: Checks if inside a transaction.
* parameters: none
* return: true if a transaction is currently active, false otherwise.
*******************************
* @return bool
*******************************/
public function InTransaction();
/*******************************
* name: BeginTransaction.
* note: turns off auto commit mode and begins a transaction.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function BeginTransaction();
/*******************************
* name: Commit.
* note: sends commands to the database that were issued after calling BeginTransaction and returns the connection to auto commit mode.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Commit();
/*******************************
* name: Rollback.
* note: discards database commands that were issued after calling BeginTransaction and returns the connection to auto commit mode.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Rollback();
/*******************************
* name: Quote.
* note: quotes a string for use in a query.
* param value The string to be quoted.
* param type Provides a data type hint for drivers that have alternate quoting styles.
* return string a quoted string that is theoretically safe to pass into an SQL statement. Returns FALSE if the driver does not support quoting in this way.
*******************************
* @param string $Value The string to be quoted.
* @param int $ValueType [optional] Provides a data type hint for drivers that have alternate quoting styles.
* @return string a quoted string that is theoretically safe to pass into an SQL statement. Returns FALSE if the driver does not support quoting in this way.
*******************************/
public function Quote($Value, $ValueType = PDO::PARAM_STR);
/*******************************
* name: NextRowset.
* note: moves the cursor to the next result set.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function NextRowset();
/*******************************
* name: RowCount.
* note: returns the number of rows added, deleted, or changed by the last statement.
* parameters: none
* return: the number of rows added, deleted, or changed.
*******************************
* @return int
*******************************/
public function GetRowCount();
/*******************************
* name: ColCount.
* note: returns the number of columns in a result set.
* parameters: none
* return: returns the number of columns in a result set. returns zero if the result set is empty.
*******************************
* @return int
*******************************/
public function GetColCount();
/*******************************
* name: ExportToFile.
* note: save request data to file.
* parameters: filename, sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* param string filename
* param string sqlcommand
* param mixed parameters...
* @return bool
*******************************/
public function ExportToFile(/* filename, sqlcommand, parameters */);
/*******************************
* name: ExportToBrowser.
* note: save request data to browser.
* parameters: sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* param string sqlcommand
* param mixed parameters...
* @return bool
*******************************/
public function ExportToBrowser(/* sqlcommand, parameters */);
/*******************************
* name: SaveArrayToFile.
* note: save data to file.
* parameters: filename, data
* return: true if the method call succeeded, false otherwise.
*******************************
* @param string $Filename
* @param array|mixed $Data
* @return bool
*******************************/
public function SaveArrayToFile($Filename, $Data);
/*******************************
* name: SaveArrayToBrowser.
* note: save data to browser.
* parameters: data
* return: true if the method call succeeded, false otherwise.
*******************************
* @param array|mixed $Data
* @return bool
*******************************/
public function SaveArrayToBrowser($Data);
/*******************************
* name: GetConnectParameter.
* note: get the parameter with connect method.
* parameters: nan
* return: connect parameter if the method call succeeded, null otherwise.
*******************************
* @return ConnectParameter
*******************************/
public function GetConnectParameter();
/*******************************
* name: GetCommandParameter.
* note: get the parameter with run sql command.
* parameters: nan
* return: command parameter if the method call succeeded, null otherwise.
*******************************
* @return CommandParameters
*******************************/
public function GetCommandParameter();
/*******************************
* name: GetConnected.
* note: get the connected status.
* parameters: nan
* return: current connected status succeeded, null otherwise.
*******************************
* @return ConnectParameter
*******************************/
public function GetConnected();
/*******************************
* name: GetConnectType.
* note: get the connect database type.
* parameters: nan
* return: connect database type if the method call succeeded, null otherwise.
*******************************
* @return null|string
*******************************/
public function GetConnectType();
/*******************************
* name: GetErrorCode.
* note: get the last method call return code.
* parameters: none.
* return: get the last method call return code.
*******************************
* @return int
*******************************/
public function GetErrorCode();
/*******************************
* name: GetErrorInfo.
* note: get the last method call return info.
* parameters: none.
* return: get the last method call return info.
*******************************
* @return mixed
*******************************/
public function GetErrorInfo();
/*******************************
* name: GetErrors.
* note: get the last method call return code and info.
* parameters: none.
* return: get the last method call return code and info.
*******************************
* @return array
*******************************/
public function GetErrors();
}
/**
* @note the sql command helper of database interface.
**************sample***************
* $this
* ->Select(...)
* ->From(...)
* ->InnerJoin|LeftJoin|RightJoin(...)
* ->On(...)
* ->Where(...)
* ->GroupBy(...)
* ->Having(...)
* ->OrderBy(...)
* ->WithPage(...)
* ->Request()
**********************************
* $this
* ->Insert(...)
* ->Fields(...)
* ->Values(...)
* ->Execute()
**********************************
* $this
* ->Update(...)
* ->Fields(...)
* ->Values(...)
* ->Where(...)
* ->Execute()
**********************************
* $this
* ->Delete(...)
* ->Where(...)
* ->Execute()
**********************************
* $this
* ->Truncate(...)
* ->Execute()
**********************************
* $this
* ->Merge(...)
* ->Fields(...)
* ->Values(...)
* ->MergeOn(...)
* ->Execute()
**********************************
* $this
* ->CallStoredProcedure(...)
* ->Values(...)
* ->Request()/Execute()
**********************************/
interface ISQLCommand
{
/*******************************
* name: GetIdentifiers.
* note: processing the identifier.
* parameters: field.
* return: always return locale instance.
*******************************
* @param string $Identifiers need processing identifier
* @param bool $Quoted need quoted?
* @param array|mixed $Specialchar need special treatment string.
* @return string
*******************************/
public function GetIdentifiers($Identifiers, $Quoted = false, $Specialchar = null);
/*******************************
* name: From.
* note: set the datasource or table information.
* parameters: datasource or table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function From();
/*******************************
* name: Where.
* note: set the where condition information.
* parameters: where condition.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Where();
/*******************************
* name: GroupBy.
* note: set the group expression information.
* parameters: group expression.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function GroupBy();
/*******************************
* name: Having.
* note: set the having condition information by group field.
* parameters: having condition.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Having();
/*******************************
* name: OrderBy.
* note: set the order information.
* parameters: order expression.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function OrderBy();
/*******************************
* name: WithPage.
* note: set paging select information.
* parameters: PageIndex, PageSize.
* return: always return locale instance.
*******************************
* @param int $PageIndex
* @param int $PageSize
* @return ISQLCommand
*******************************/
public function WithPage($PageIndex, $PageSize);
/*******************************
* name: Limit.
* note: set select max record count.
* parameters: maxcount.
* return: always return locale instance.
*******************************
* @param int $MaxCount
* @return ISQLCommand
*******************************/
public function Limit($MaxCount);
/*******************************
* name: Fields.
* note: set update column list.
* parameters: column list.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Fields();
/*******************************
* name: Values.
* note: set update value list.
* parameters: value list.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Values();
/*******************************
* name: Select.
* note: set the select field information.
* parameters: field.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Select();
/*******************************
* name: Insert.
* note: set the insert table or datasource information.
* parameters: table or datasource.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Insert();
/*******************************
* name: Update.
* note: set the update table or datasource information.
* parameters: table or datasource.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Update();
/*******************************
* name: delete.
* note: set the delete table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Delete();
/*******************************
* name: Truncate.
* note: set the truncate table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Truncate();
/*******************************
* name: Merge.
* note: set the merge table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Merge();
/*******************************
* name: Merge.
* note: set call stored procedure name.
* parameters: procedure name.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function CallStoredProcedure();
/*******************************
* name: InnerJoin.
* note: set the inner join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function InnerJoin();
/*******************************
* name: LeftJoin.
* note: set the left join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function LeftJoin();
/*******************************
* name: RightJoin.
* note: set the right join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function RightJoin();
/*******************************
* name: OuterJoin.
* note: set the outer join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function OuterJoin();
/*******************************
* name: On.
* note: set the join condition information.
* parameters: join condition.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function On();
/*******************************
* name: MergeOn.
* note: set the merge condition information.
* parameters: merge condition.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function MergeOn();
/*******************************
* name: Union.
* note: set the union object or sql command.
* parameters: union mixed.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function Union();
/*******************************
* name: BindParameters.
* note: bind other parameters of sql command needed.
* parameters: needed bind parameter list.
* return: always return locale instance.
*******************************
* @param array|string|CommandParameter
* @return ISQLCommand
*******************************/
public function BindParameters();
/**
* 2016-12-08增加
* @note 字符串转换为日期型的表达式
* @param string $StringTime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function String2DatetimeFormat($StringTime, $Quoted = true);
/**
* 2016-12-08增加
* @note 日期转换为字符串型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2StringFormat($Datetime, $Quoted = true);
/**
* 2016-12-08增加
* @note 时间戳转换为日期型的表达式
* @param string $Timestamp 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Timestamp2DatetimeFormat($Timestamp);
/**
* 2016-12-08增加
* @note 日期转换为时间戳型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2TimestampFormat($Datetime, $Quoted = true);
/**
* 2016-12-08增加
* @note 浮点转换为字符串型的表达式
* @param string $Float 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Float2StringFormat($Float);
/**
* 2016-01-16增加
* @note 获取当前服务器系统时间(或表达式)
* @param bool $IsRaw 是否返回数据库表达式
* @return string
* @note 应俊
*/
public function GetSystemTime($IsRaw = false);
/*******************************
* name: GetConnection.
* note: get database helper.
* parameters: nan.
* return: the database helper object.
*******************************
* @return IPDOHelper
*******************************/
public function GetConnection();
/*******************************
* name: GetCommandInformation.
* note: get sql command string.
* parameters: nan.
* return: sql command and parameter list as array if the method call succeeded, null otherwise.
*******************************
* @return CommandInformation
*******************************/
public function GetCommandInformation();
/*******************************
* name: Request.
* note: request data from database(recordset was returned).
* parameters: sql command, parameter list.
* return: recordset as array if the method call succeeded, null otherwise.
*******************************
* prarm clearmembers
*******************************
* param callable $Callable
* param string $SqlCommand
* param mixed $Parameters...
* @return mixed|null
*******************************/
public function Request(/* $Callable, $SqlCommand, $Parameters, ... */);
/*******************************
* name: Execute.
* note: execute command from database(no recordset was returned).
* parameters: sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* prarm clearmembers
*******************************
* param string $SqlCommand
* param mixed $Parameters...
* @return bool
*******************************/
public function Execute(/* $SqlCommand, $Parameters, ... */);
}
/// ====================================================================================================================
class CItem implements IItem
{
/**
* @var IList
*/
private $Owner;
/**
* @return IList
*/
public function GetOwner()
{
return $this->Owner;
}
/**
* @param IList $Owner
*/
public function SetOwner($Owner)
{
$this->Owner = $Owner;
}
}
class CList implements IList
{
protected $Items;
/**
* CList constructor.
*/
public function __construct()
{
$this->Items = array();
}
/**
*
*/
public function __destruct()
{
$this->Clear();
}
/**
* @param string $Name
* @return mixed
* @throws Exception
*/
public function __get($Name)
{
$Item = $this->GetItem($Name);
if (!empty($Item))
return $Item;
else
throw new Exception('undefined property: ' . get_class($this) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
/**
* @param integer $Index
* @return mixed
*/
public function GetItem($Index)
{
if (is_integer($Index) && is_array($this->Items) && !empty($this->Items) && ($Index >= 0) && ($Index < count($this->Items)))
return $this->Items[$Index];
else
return null;
}
/**
* @return integer
*/
public function GetCount()
{
return count($this->Items);
}
/**
* @param mixed $Item
* @return integer
*/
public function Append($Item)
{
if (is_object($Item))
{
if (method_exists($Item, 'SetOwner'))
$Item->SetOwner($this);
elseif (isset($Item->Owner))
$Item->Owner = $this;
}
array_push($this->Items, $Item);
return count($this->Items);
}
/**
* @param integer $Index
* @return integer
*/
public function Delete($Index)
{
if (is_integer($Index) && is_array($this->Items) && !empty($this->Items) && ($Index >= 0) && ($Index < count($this->Items)))
array_splice($this->Items, $Index, 1);
return count($this->Items);
}
/**
* @return integer
*/
public function Clear()
{
$this->Items = array();
return 0;
}
}
class Field extends CItem implements IField
{
/**
* @var string
*/
private $Name;
/**
* @var string
*/
private $Type;
/**
* @var int
*/
private $Size;
/**
* @var mixed
*/
private $DefaultValue;
public function __construct($Name, $Type, $Size, $DefaultValue)
{
$this->Name = $Name;
$this->Type = $Type;
$this->Size = $Size;
$this->DefaultValue = $DefaultValue;
}
/**
* @note get field name.
* @return string
*/
public function GetName()
{
return $this->Name;
}
/**
* @note get field data type.
* @return string
*/
public function GetType()
{
return $this->Type;
}
/**
* @note get field data size.
* @return integer
*/
public function GetSize()
{
return $this->Size;
}
/**
* @note get field default value.
* @return mixed
*/
public function GetDefaultValue()
{
return $this->DefaultValue;
}
}
class Fields extends CList implements IFields
{
/**
* @var ITable
*/
private $Owner;
public function __construct($Owner)
{
parent::__construct();
$this->SetOwner($Owner);
}
/**
* @param integer $Index
* @return IField
*/
public function GetItem($Index)
{
if (is_string($Index))
{
foreach ($this->Items as $Field)
{
if (!($Field instanceof IField))
continue;
if (strcasecmp($Field->GetName(), $Index) == 0)
return $Field;
}
}
return parent::GetItem($Index);
}
/**
* @param mixed $Item
* @return integer
*/
public function Append($Item)
{
if ($Item instanceof IField)
return parent::Append($Item);
else
return -1;
}
/**
* @return ITable
*/
public function GetOwner()
{
return $this->Owner;
}
/**
* @param ITable $Owner
*/
public function SetOwner($Owner)
{
$this->Owner = $Owner;
}
}
class Table extends CItem implements ITable
{
/**
* @var string
*/
private $Name;
/**
* @var ISQLCommand
*/
private $Command;
/**
* @var IFields
*/
private $Fields;
public function __construct($Name = '')
{
$this->Name = $Name;
$this->Fields = null;
}
/**
* @param string $Name
* @return mixed
* @throws Exception
*/
public function __get($Name)
{
if (is_null($this->Fields))
$this->RefreshFields();
if (!empty($this->Fields))
$Field = $this->Fields->GetItem($Name);
else
$Field = null;
if (!empty($Field))
return $Field;
throw new Exception('undefined property: ' . get_class($this) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
private function RefreshFields()
{
$this->Fields = null;
if (!method_exists($this->GetOwner(), 'GetOwner'))
return false;
$Helper = $this->GetOwner()->GetOwner();
if (empty($Helper) || !($Helper instanceof IPDOHelper))
return false;
$this->Fields = $Helper->GetTableFields($this->Name);
$this->Fields->SetOwner($this);
return !empty($this->Fields);
}
private function RefreshCommand()
{
$this->Command = null;
if (!method_exists($this->GetOwner(), 'GetOwner'))
return false;
$Helper = $this->GetOwner()->GetOwner();
if (empty($Helper) || !($Helper instanceof IPDOHelper))
return false;
$this->Command = new CommandDelegator($Helper);
return !empty($this->Command);
}
/**
* @note get table field list.
* @return IFields
*/
public function GetFields()
{
if (is_null($this->Fields))
$this->RefreshFields();
return $this->Fields;
}
/**
* @note get table name.
* @return string
*/
public function GetName()
{
return $this->Name;
}
public function Select()
{
if (is_null($this->Command))
$this->RefreshCommand();
if (is_null($this->Fields))
$this->RefreshFields();
if (0 == func_num_args())
{
$Fields = array();
for ($Index = 0; $Index < $this->Fields->GetCount(); $Index++)
{
if (method_exists($this->Fields, 'GetItem'))
$Item = call_user_func_array(array(&$this->Fields, 'GetItem'), array($Index));
else
$Item = null;
if (method_exists($Item, 'GetName'))
array_push($Fields, call_user_func(array(&$Item, 'GetName')));
}
}
else
$Fields = func_get_args();
call_user_func_array(array(&$this->Command, 'Select'), $Fields);
call_user_func_array(array(&$this->Command, 'From'), array($this->Name));
return $this;
}
public function Filter()
{
if (empty($this->Command))
$this->RefreshCommand();
call_user_func_array(array(&$this->Command, 'Where'), func_get_args());
return $this;
}
public function Limit()
{
if (empty($this->Command))
$this->RefreshCommand();
call_user_func_array(array(&$this->Command, 'Limit'), func_get_args());
return $this;
}
public function WithPage()
{
if (empty($this->Command))
$this->RefreshCommand();
call_user_func_array(array(&$this->Command, 'WithPage'), func_get_args());
return $this;
}
public function Request()
{
if (empty($this->Command))
$this->RefreshCommand();
return call_user_func_array(array(&$this->Command, 'Request'), func_get_args());
}
}
class Tables extends CList implements ITables
{
/**
* @var IPDOHelper
*/
private $Owner;
/**
* Tables constructor.
* @param IPDOHelper $Owner
*/
public function __construct($Owner)
{
parent::__construct();
$this->SetOwner($Owner);
}
/**
* @param integer $Index
* @return IField
*/
public function GetItem($Index)
{
if (is_string($Index))
{
foreach ($this->Items as $Table)
{
if (!($Table instanceof ITable))
continue;
if (strcasecmp($Table->GetName(), $Index) == 0)
return $Table;
}
}
return parent::GetItem($Index);
}
/**
* @param mixed $Item
* @return integer
*/
public function Append($Item)
{
if ($Item instanceof ITable)
return parent::Append($Item);
else
return -1;
}
/**
* @return IPDOHelper
*/
public function GetOwner()
{
return $this->Owner;
}
/**
* @param IPDOHelper $Owner
*/
public function SetOwner($Owner)
{
$this->Owner = $Owner;
}
}
/// ====================================================================================================================
/*******************************
* name: PDOHelper.
* note: database helper base class.
*******************************/
abstract class PDOHelper implements IPDOHelper
{
/**
* @note PDO object.
* @var PDO
*/
protected $Database;
/**
* @note PDOStatement object.
* @var PDOStatement
*/
private $Command;
/**
* @note request record row, properties map to columns.
* @var array
*/
private $Recordset;
/**
* @note request dataset fields.
* @var array
*/
private $Cols;
/**
* @note request recordsets, array of records.
* @var array
*/
private $Rows;
/**
* @note parameter list.
* @var CommandParameters
*/
protected $CommandParameters;
/**
* @note the connect database parameter
* @var ConnectParameter
*/
protected $ConnectParameter;
/**
* @note 2018-05-28: save data to $this->Rows
* @var bool
*/
public $CacheRecord;
/**
* @note fetch record style(default PDO::FETCH_OBJ)
* @var int
*/
public $FetchStyle;
/**
* @note load resource field by record, not used on 2017-04-10 later.
* @var bool
*/
private $LoadStream;
/**
* @note call bindParam, not used on 2017-04-10 later.
* @var bool
*/
private $BindParameter;
/**
* @note the last error code, 0 on success, otherwise other value.
* @var int
*/
private $ErrorCode;
/**
* @note the last error info, null on success, otherwise message.
* @var string|mixed
*/
private $ErrorInfo;
/// events
public $OnError;
public $OnConnected;
public $OnDisconnected;
public $OnBeforeOpen;
public $OnAfterOpen;
public $OnBeforeExecute;
public $OnAfterExecute;
/*******************************
* name: __construct.
* note: the construct function for class.
* parameters: nan.
* return: new object if the method call succeeded, null otherwise.
*******************************
* PDOHelper constructor.
*******************************/
public function __construct()
{
//parent::__construct();
$this->Database = null;
$this->CommandParameters = new CommandParameters();
$this->CacheRecord = true;
$this->FetchStyle = PDO::FETCH_OBJ;
$this->LoadStream = false;
$this->BindParameter = false;
$this->ClearMember();
}
/*******************************
* name: __destruct.
* note: the destruct function for class.
* parameters: nan.
* return: nan.
*******************************
* PDOHelper destructor.
*******************************/
public function __destruct()
{
$this->ClearMember();
$this->Database = null;
//parent::__destruct();
}
/**
* name GetParameterList
* @param Mixed $ParameterArrays
* @return array
*/
protected function GetParameterList($ParameterArrays)
{
$Result = array();
if ($ParameterArrays instanceof CommandParameter)
{
array_push($Result, $ParameterArrays);
}
else
{
switch (gettype($ParameterArrays))
{
case 'array':
{
foreach ($ParameterArrays as $Parameter)
{
foreach ($this->GetParameterList($Parameter) as $Item)
{
array_push($Result, $Item);
}
}
break;
}
case 'object':
{
if (class_exists('ReflectionClass'))
{
$Reflect = new ReflectionClass($ParameterArrays);
$Keys = array_keys($Reflect->getDefaultProperties());
}
else
{
$Keys = array();
}
$Keys += array_keys((array)$ParameterArrays);
foreach ($Keys as $Key)
{
if (isset($ParameterArrays->$Key))
{
$Parameter = $ParameterArrays->$Key;
foreach ($this->GetParameterList($Parameter) as $Item)
{
array_push($Result, $Item);
}
}
}
break;
}
default:
{
array_push($Result, $ParameterArrays);
break;
}
}
}
return $Result;
}
/*******************************
* name: InvokeEvent.
* note: call the event.
* parameters: event, parameters....
* return: bool
*******************************
* @return bool
*******************************/
protected function InvokeEvent()
{
if (0 == func_num_args())
return false;
$Parameters = func_get_args();
$Events = $Parameters[0];
if (is_callable($Events) || (is_object($Events) && strcasecmp('Closure', get_class($Events)) == 0))
{
try
{
$Parameters[0] = &$this;
return call_user_func_array($Events, $Parameters);
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
else
return false;
}
/*******************************
* name: ClearMember.
* note: clear all member for class.
* parameters: nan.
* return: nan.
*******************************
*
*******************************/
private function ClearMember()
{
//$this->Database = null;
$this->Command = null;
$this->Recordset = null;
$this->Cols = null;
$this->Rows = null;
$this->CommandParameters->Clear();
//$this->ConnectParameter = null;
$this->ErrorCode = null;
$this->ErrorInfo = null;
}
/*******************************
* name: GetRecord.
* note: convert record object.
* parameters: record.
* return: record.
*******************************
* @param mixed $Record
* @return mixed
*******************************/
protected function GetRecord($Record)
{
if (is_object($Record))
{
$Propertys = get_object_vars($Record);
foreach ($Propertys as $Name => $Value)
{
$Record->$Name = $this->GetRecord($Value);
}
}
elseif (is_array($Record))
{
foreach ($Record as $Name => $Value)
{
$Record[$Name] = $this->GetRecord($Value);
}
}
elseif (is_resource($Record))
{
$Record = stream_get_contents($Record);
}
return $Record;
}
/*******************************
* name: Characet.
* note: convert string code page.
* parameters: string, charset
* return: string if the function call succeeded, null otherwise.
*******************************
* @param string $String
* @param string $Charset
* @return string
*******************************/
protected function Characet($String, $Charset = USEDCHARSET)
{
if (!empty ($String))
{
$Encoding = mb_detect_encoding($String, array('ASCII', 'UTF-8', 'GBK', 'GB2312', 'LATIN1', 'BIG5',));
if (0 != strcasecmp($Encoding, $Charset))
$String = mb_convert_encoding($String, $Charset, $Encoding);
}
return $String;
}
/*******************************
* name: Succeeded.
* note: test the success of the code.
* parameters: code.
* return: true if the code succeeded, false otherwise.
*******************************
* @param string|int $Code
* @return bool
*******************************/
public function Succeeded($Code)
{
return (bool)(is_int($Code) && ERRORCODE_SUCCESS == intval($Code));
}
/*******************************
* name: IsDone.
* note: test the success of the last code.
* parameters: none.
* return: true if the code succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function IsDone()
{
return (bool)$this->Succeeded($this->ErrorCode);
}
/*******************************
* name: Connect.
* note: connect to database.
* parameters: look at the derived class.
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Connect()
{
$this->Close();
//$this->SetErrors(ERRORCODE_NOIMPLEMENT, ERRORINFO_NOIMPLEMENT);
//$this->ConnectParameter = null;
return false;
}
/*******************************
* name: Connect.
* note: close active connected.
* parameters: none.
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Close()
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$this->ClearMember();
$this->Database = null;
$this->ConnectParameter = null;
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
$this->InvokeEvent($this->OnDisconnected);
return true;
}
else
return false;
}
/*******************************
* name: GetTables.
* note: get the database all tables.
* parameters: none.
* return: table list if the method call succeeded, null otherwise.
*******************************
* @return ITables
*******************************/
abstract public function GetTables();
/*******************************
* name: GetTableFields.
* note: get the table fields.
* parameters: table name.
* return: field list if the method call succeeded, null otherwise.
*******************************
* @param string $Tablename
* @return ITables
*******************************/
abstract public function GetTableFields($Tablename);
/*******************************
* name: Request.
* note: request data from database(recordset was returned).
* parameters: sql command, parameter list.
* 2016-03-29: append the callback support(first parameter).
* return: recordset as array if the method call succeeded, null otherwise.
*******************************
* param callable $Callable
* param string $SqlCommand
* param mixed $Parameters...
* @return mixed|null
*******************************/
public function Request(/* $Callable, $SqlCommand, $Parameters, ... */)
{
$this->InvokeEvent($this->OnBeforeOpen);
if (!isset($this->Database) && !($this->Database instanceof PDO))
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return null;
}
$this->ClearMember();
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => callable
/// $Parameters[1] => sql command
/// $Parameters[...] => the parameters ...
/// call parent request field
//parent::Request($Parameters);
/// if no any parameter then exit
if (0 == count($Parameters))
{
$this->SetErrors(ERRORCODE_NOPARAMETER, ERRORINFO_NOPARAMETER);
return null;
}
/// lookup first parameter. save callback if it is function.
$Callable = null;
if (is_callable($Parameters[0]) || (is_object($Parameters[0]) && strcasecmp('Closure', get_class($Parameters[0])) == 0))
{
$Callable = $Parameters[0];
//unset($Parameters[0]); /// remove first.
//$Parameters = array_values($Parameters); /// reset parameters
array_shift($Parameters);
/// if no any parameter then exit
if (0 == count($Parameters))
{
$this->SetErrors(ERRORCODE_NOPARAMETER, ERRORINFO_NOPARAMETER);
return null;
}
}
/// the first parameter is the sql command string.
$this->Command = $this->Database->prepare($Parameters[0]);
if (null == $this->Command)
{
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return null;
}
/// reset parameters
//unset($Parameters[0]);
//$Parameters = array_values($Parameters);
array_shift($Parameters);
/// 2016-08-05: get all parameter
$Parameters = $this->GetParameterList($Parameters);
// /// 2017-01-05: now call bindParam method support to lob type(blob/clob/nclob)
// /// 2017-04-10: disabled this..
// if ($this->BindParameter)
// {
// /// bind parameter.
// for ($Index = 0; $Index < count($Parameters); $Index++)
// {
// $this->Command->bindParam($Index + 1, $Parameters[$Index], PDO::PARAM_STR, strlen($Parameters[$Index]));
// }
//
// /// run command.
// $Return = $this->Command->execute();
// }
// else
// {
// /// run command.
// $Return = $this->Command->execute($Parameters);
// }
/// 2017-04-10: expand parameter to class(CommandParameter)
/// bind parameter.
for ($Index = 0; $Index < count($Parameters); $Index++)
{
if ($Parameters[$Index] instanceof CommandParameter)
{
$Parameter = $Parameters[$Index];
$this->CommandParameters->Append($Parameter);
$this->Command->bindParam(
//$Index + 1,
$Parameter->Name,
$Parameter->Value,
(TYPENAME_LOB == $Parameter->Type ? PDO::PARAM_LOB : PDO::PARAM_STR) | ($Parameter->Output ? PDO::PARAM_INPUT_OUTPUT : 0),
$Parameter->Size);
}
else
{
if (is_numeric($Parameters[$Index]))
{
$Type = TYPENAME_NUMBER;
$Value = strval($Parameters[$Index]);
}
elseif (is_resource($Parameters[$Index]))
{
$Type = TYPENAME_LOB;
$Value = $Parameters[$Index];
}
else
{
$Type = TYPENAME_STRING;
$Value = $Parameters[$Index];
}
$this->CommandParameters->CreateParameter('', $Type, $Value, strlen($Value));
$this->Command->bindParam(
$Index + 1,
$Parameters[$Index],
PDO::PARAM_STR,
strlen($Parameters[$Index]));
}
}
$Return = $this->Command->execute();
/// 2017-04-10 end.
if (!$Return)
{
$this->SetErrors($this->Command->errorCode(), $this->Command->errorInfo());
return null;
}
/// if succeed fetch record to return object.
$this->Rows = array(); /// init return array
/// fetch record into array.
// /// 2017-04-10: disabled this..
// if ($this->LoadStream)
// {
if (null != $Callable)
{
//while ($this->Recordset = $this->GetRecord($this->Command->fetchObject()))
while ($this->Recordset = $this->GetRecord($this->Command->fetch($this->FetchStyle)))
{
/// callback function.
if (function_exists('call_user_func_array'))
$UserCallResult = call_user_func_array($Callable, array(&$this->Recordset)); /// must pass &$xxx in php4.x
// elseif (version_compare(PHP_VERSION, '5.4.0') < 0) /// less php 5.4
// $UserCallResult = $Callable(&$this->Recordset);
else
$UserCallResult = $Callable($this->Recordset);
if (!$UserCallResult)
{
$this->SetErrors(ERRORCODE_CANCELLED, ERRORINFO_CANCELLED);
break; /// break loop if return false;
}
/// 2018-05-28: if CacheRecord is set, save this record to Rows array.
if ($this->CacheRecord)
array_push($this->Rows, $this->Recordset);
$this->Recordset = null;
}
}
else
{
//while ($this->Recordset = $this->GetRecord($this->Command->fetchObject()))
while ($this->Recordset = $this->GetRecord($this->Command->fetch($this->FetchStyle)))
{
array_push($this->Rows, $this->Recordset);
$this->Recordset = null;
}
}
// /// 2017-04-10: disabled this..
// }
// else
// {
// if (null != $Callable)
// {
// while ($this->Recordset = $this->Command->fetch($this->FetchStyle))
// {
// /// callback function.
// if (function_exists('call_user_func'))
// $UserCallResult = call_user_func($Callable, $this->Recordset); /// must pass &$xxx in php4.x
// else
// $UserCallResult = $Callable($this->Recordset);
// if (!$UserCallResult)
// {
// $this->SetErrors(ERRORCODE_CANCELLED, ERRORINFO_CANCELLED);
// break; /// break loop if return false;
// }
//
// /// 2018-05-28: if CacheRecord is set, save this record to Rows array.
// if ($this->CacheRecord)
// array_push($this->Rows, $this->Recordset);
// $this->Recordset = null;
// }
// }
// else
// {
// while ($this->Recordset = $this->Command->fetch($this->FetchStyle))
// {
// array_push($this->Rows, $this->Recordset);
// $this->Recordset = null;
// }
// }
// }
/// if has record fetch all column names to array.
if (!empty($this->Rows) && !empty($this->Rows[0]))
{
/// get all column names
//$prop = get_object_vars($this->Rows[0]);
//$this->Cols = array_keys($prop); /// fetch into columns object.
$this->Cols = array_keys((array)$this->Rows[0]);
}
$this->InvokeEvent($this->OnAfterOpen);
return $this->Rows;
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return null;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return null;
}
}
/*******************************
* name: Execute.
* note: execute command from database(no recordset was returned).
* parameters: sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* param string $SqlCommand
* param mixed $Parameters...
* @return bool
*******************************/
public function Execute(/* sqlcommand, parameters, ... */)
{
$this->InvokeEvent($this->OnBeforeExecute);
if (!isset($this->Database) && !($this->Database instanceof PDO))
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
$this->ClearMember();
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => sql command
/// $Parameters[...] => the parameters ...
/// call parent execute field.
//parent::Execute($Parameters);
/// if no any parameter then exit
if (0 == count($Parameters))
{
$this->SetErrors(ERRORCODE_NOPARAMETER, ERRORINFO_NOPARAMETER);
return false;
}
/// the first parameter is the sql command string.
$this->Command = $this->Database->prepare($Parameters[0]);
if (null == $this->Command)
{
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return false;
}
/// reset parameters
//unset($Parameters[0]);
//$Parameters = array_values($Parameters);
array_shift($Parameters);
/// 2016-08-05: get all parameter
$Parameters = $this->GetParameterList($Parameters);
// /// 2017-01-05: now call bindParam method support to lob type(blob/clob/nclob)
// /// 2017-04-10: disabled this..
// if ($this->BindParameter)
// {
// /// bind parameter.
// for ($Index = 0; $Index < count($Parameters); $Index++)
// {
// $this->Command->bindParam($Index + 1, $Parameters[$Index], PDO::PARAM_STR, strlen($Parameters[$Index]));
// }
//
// /// run command.
// $Return = $this->Command->execute();
// }
// else
// {
// /// run command.
// $Return = $this->Command->execute($Parameters);
// }
/// 2017-04-10: expand parameter to class(CommandParameter)
/// bind parameter.
for ($Index = 0; $Index < count($Parameters); $Index++)
{
if ($Parameters[$Index] instanceof CommandParameter)
{
$Parameter = $Parameters[$Index];
$this->CommandParameters->Append($Parameter);
$this->Command->bindParam(
//$Index + 1,
$Parameter->Name,
$Parameter->Value,
(TYPENAME_LOB == $Parameter->Type ? PDO::PARAM_LOB : PDO::PARAM_STR) | ($Parameter->Output ? PDO::PARAM_INPUT_OUTPUT : 0),
$Parameter->Size);
}
else
{
if (is_numeric($Parameters[$Index]))
{
$Type = TYPENAME_NUMBER;
$Value = strval($Parameters[$Index]);
}
elseif (is_resource($Parameters[$Index]))
{
$Type = TYPENAME_LOB;
$Value = $Parameters[$Index];
}
else
{
$Type = TYPENAME_STRING;
$Value = $Parameters[$Index];
}
$this->CommandParameters->CreateParameter('', $Type, $Value, strlen($Value));
$this->Command->bindParam(
$Index + 1,
$Parameters[$Index],
PDO::PARAM_STR,
strlen($Parameters[$Index]));
}
}
$Return = $this->Command->execute();
/// 2017-04-10 end.
if (!$Return)
$this->SetErrors($this->Command->errorCode(), $this->Command->errorInfo());
else
$this->InvokeEvent($this->OnAfterExecute);
return $Return;
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: LastInsertId.
* note: This method may not return a meaningful or consistent result across different PDO drivers, because the underlying database may not even support the notion of auto-increment fields or sequences.
* parameters: name
* return: PDO::lastInsertId method return value.
*******************************
* @param null|string $Name
* @return bool|string
******************************/
public function LastInsertId($Name = null)
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$Return = $this->Database->lastInsertId($Name);
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
}
/*******************************
* name: ColumnNames.
* note: get all field name of current recordset.
* parameters: none
* return: all field name of current recordset.
*******************************
* @return array|bool
*******************************/
public function ColumnNames()
{
if (isset($this->Cols) && !empty($this->Cols))
return $this->Cols;
else
{
$this->SetErrors(ERRORCODE_UNKNOWN, ERRORINFO_UNKNOWN);
return false;
}
}
/*******************************
* name: Records.
* note: return record list, deleted, or changed by the last statement.
* parameters: none
* return: the record list, deleted, or changed.
*******************************
* @return array
*******************************/
public function GetRecords()
{
return $this->Rows;
}
/*******************************
* name: InTransaction.
* note: Checks if inside a transaction.
* parameters: none
* return: true if a transaction is currently active, false otherwise.
*******************************
* @return bool
*******************************/
public function InTransaction()
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$Return = $this->Database->inTransaction();
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
}
/*******************************
* name: BeginTransaction.
* note: turns off auto commit mode and begins a transaction.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function BeginTransaction()
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$Return = $this->Database->beginTransaction();
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
}
/*******************************
* name: Commit.
* note: sends commands to the database that were issued after calling BeginTransaction and returns the connection to auto commit mode.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Commit()
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$Return = $this->Database->commit();
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
}
/*******************************
* name: Rollback.
* note: discards database commands that were issued after calling BeginTransaction and returns the connection to auto commit mode.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function Rollback()
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$Return = $this->Database->rollBack();
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
}
/*******************************
* name: Quote.
* note: quotes a string for use in a query.
* param value The string to be quoted.
* param type Provides a data type hint for drivers that have alternate quoting styles.
* return string a quoted string that is theoretically safe to pass into an SQL statement. Returns FALSE if the driver does not support quoting in this way.
*******************************
* @param string $Value The string to be quoted.
* @param int $ValueType [optional] Provides a data type hint for drivers that have alternate quoting styles.
* @return string a quoted string that is theoretically safe to pass into an SQL statement. Returns FALSE if the driver does not support quoting in this way.
*******************************/
public function Quote($Value, $ValueType = PDO::PARAM_STR)
{
if (isset($this->Database) && ($this->Database instanceof PDO))
{
$Return = $this->Database->Quote($Value, $ValueType);
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
}
/*******************************
* name: NextRowset.
* note: moves the cursor to the next result set.
* parameters: none
* return: true if the method call succeeded, false otherwise.
*******************************
* @return bool
*******************************/
public function NextRowset()
{
if (isset($this->Command) && ($this->Command instanceof PDOStatement))
return $this->Command->nextRowset();
else
{
$this->SetErrors(ERRORCODE_NOCOMMANDED, ERRORINFO_NOCOMMANDED);
return -1;
}
}
/*******************************
* name: RowCount.
* note: returns the number of rows added, deleted, or changed by the last statement.
* parameters: none
* return: the number of rows added, deleted, or changed.
*******************************
* @return int
*******************************/
public function GetRowCount()
{
if (isset($this->Command) && ($this->Command instanceof PDOStatement))
{
$Return = $this->Command->rowCount();
$this->SetErrors($this->Command->errorCode(), $this->Command->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCOMMANDED, ERRORINFO_NOCOMMANDED);
return -1;
}
}
/*******************************
* name: ColCount.
* note: returns the number of columns in a result set.
* parameters: none
* return: returns the number of columns in a result set. returns zero if the result set is empty.
*******************************
* @return int
*******************************/
public function GetColCount()
{
if (isset($this->Command) && ($this->Command instanceof PDOStatement))
{
$Return = $this->Command->columnCount();
$this->SetErrors($this->Command->errorCode(), $this->Command->errorInfo());
return $Return;
}
else
{
$this->SetErrors(ERRORCODE_NOCOMMANDED, ERRORINFO_NOCOMMANDED);
return -1;
}
}
/*******************************
* name: ExportToFile.
* note: save request data to file.
* parameters: filename, sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* param string filename
* param string sqlcommand
* param mixed parameters...
* @return bool
*******************************/
public function ExportToFile(/* filename, sqlcommand, parameters */)
{
if (!isset($this->Database) && !($this->Database instanceof PDO))
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => export file name
/// $Parameters[1] => sql command
/// $Parameters[...] => the parameters ...
$ParameterCount = func_num_args();
if (0 == $ParameterCount)
{
$this->SetErrors(ERRORCODE_NOPARAMETER, ERRORINFO_NOPARAMETER);
return false;
}
$Filename = $Parameters[0];
// if (file_exists($Filename))
// unlink($Filename);
//unset($Parameters[0]);
//$Parameters = array_values($Parameters);
array_shift($Parameters);
/// call request method.
if (function_exists('call_user_func_array') && $ParameterCount > 1)
call_user_func_array(array(&$this, 'Request'), $Parameters); /// must pass &$xxx in php4.x
$Headers = '';
foreach ($this->Cols as $Key => $Value) /// all field names.
{
$Headers .= $Value . ",";
}
$Headers .= PHP_EOL;
$Lines = '';
foreach ($this->GetRecords() as $RowKey => $RowValue) /// all data.
{
$array = (array)$RowValue;
foreach ($array as $ColKey => $ColValue)
{
$Lines .= $ColValue . ',';
}
$Lines .= PHP_EOL;
}
$Text = $this->Characet($Headers . $Lines, 'GBK');
//$Encoding = mb_detect_encoding($Text, array('ASCII', 'UTF-8', 'GBK', 'GB2312', 'LATIN1', 'BIG5'));
//if (0 != strcasecmp('gbk', $Encoding))
// $Text = mb_convert_encoding($Text, 'gbk', $Encoding);
//$Lines = mb_convert_encoding($Lines, 'gbk', 'utf-8');
//$Lines = iconv('utf-8', 'gbk', $Lines);
if ($File = fopen($Filename, 'a+')) /// write to file
{
fwrite($File, $Text);
fclose($File);
}
return true;
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: ExportToBrowser.
* note: save request data to browser.
* parameters: sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* param string sqlcommand
* param mixed parameters...
* @return bool
*******************************/
public function ExportToBrowser(/* sqlcommand, parameters */)
{
if (!isset($this->Database) && !($this->Database instanceof PDO))
{
$this->SetErrors(ERRORCODE_NOCONNECTED, ERRORINFO_NOCONNECTED);
return false;
}
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => export file name
/// $Parameters[1] => sql command
/// $Parameters[...] => the parameters ...
$ParameterCount = func_num_args();
if (0 == $ParameterCount)
{
$this->SetErrors(ERRORCODE_NOPARAMETER, ERRORINFO_NOPARAMETER);
return false;
}
global $Handles;
global $First;
$Handles = fopen('php://output', 'a'); /// open the output stream.
$First = true;
$Callable = function (&$Record)
{
global $Handles;
global $First;
/// if the first record, must to get column names.
if ($First)
{
$First = false;
$Headers = array();
/// get key names
foreach (array_keys((array)$Record) as $Key => $Value)
{
/// write the header.
array_push($Headers, Characet($Value, 'GBK'));
}
fputcsv($Handles, $Headers);
}
/// write the record data.
$Lines = array();
foreach ((array)$Record as $Key => $Value)
{
array_push($Lines, Characet($Value, 'GBK'));
}
fputcsv($Handles, $Lines);
ob_flush();
flush();
unset($Lines);
unset($Record);
return true;
};
// $Callable = '
//global $Handles;
//global $First;
//
///// if the first record, must to get column names.
//if ($First)
//{
// $First = false;
//
// $Headers = array();
// /// get key names
// foreach (array_keys((array)$Record) as $Key => $Value)
// {
// /// write the header.
// array_push($Headers, Characet($Value, \'GBK\'));
// }
// fputcsv($Handles, $Headers);
//}
//
///// write the record data.
//$Lines = array();
//foreach ((array)$Record as $Key => $Value)
//{
// array_push($Lines, Characet($Value, \'GBK\'));
//}
//fputcsv($Handles, $Lines);
//
//ob_flush();
//flush();
//
//unset($Record);
//
//return true;
//';
// $Callable = create_function('$Record', $Callable);
array_splice($Parameters, 0, 0, $Callable);
/// echo http header.
$Filename = date('YmdHis');
header("Content-type:application/vnd.ms-excel");
header("Content-Disposition:filename={$Filename}.csv");
/// saved max execute time count.
$MaxExecuteTime = ini_get('max_execution_time');
/// disable timeout limit.
set_time_limit(0);
/// 2018-05-28: saved CacheRecord settings
$SavedCacheRecord = $this->CacheRecord;
$this->CacheRecord = false;
/// call request method.
if (function_exists('call_user_func_array'))
call_user_func_array(array(&$this, 'Request'), $Parameters); /// must pass &$xxx in php4.x
/// 2018-05-28: restore CacheRecord settings
$this->CacheRecord = $SavedCacheRecord;
/// close the handle of file.
fclose($Handles);
/// restore max execute time count.
set_time_limit($MaxExecuteTime);
/// destroy the global variable.
unset($First);
unset($Handles);
return true;
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: SaveArrayToFile.
* note: save data to file.
* parameters: filename, data
* return: true if the method call succeeded, false otherwise.
*******************************
* @param string $Filename
* @param array|mixed $Data
* @return bool
*******************************/
public function SaveArrayToFile($Filename, $Data)
{
if (empty($Data))
{
$this->SetErrors(ERRORCODE_INVALIDPARAMETER, ERRORINFO_INVALIDPARAMETER);
return false;
}
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
if (is_object($Data))
$Data = (array)$Data;
if (!is_array($Data))
{
$this->SetErrors(ERRORCODE_INVALIDPARAMETER, ERRORINFO_INVALIDPARAMETER);
return false;
}
$Text = '';
foreach ($Data as $Line)
{
if (is_object($Line))
$Line = (array)$Line;
if (is_array($Line))
{
foreach ($Line as $Value)
{
$Text .= $Value . ",";
}
}
else
$Text .= $Line;
$Text .= PHP_EOL;
}
$Text = $this->Characet($Text, 'GBK');
//$Encoding = mb_detect_encoding($Text, array('ASCII', 'UTF-8', 'GBK', 'GB2312', 'LATIN1', 'BIG5'));
//if (0 != strcasecmp('gbk', $Encoding))
// $Text = mb_convert_encoding($Text, 'gbk', $Encoding);
if ($File = fopen($Filename, 'w+')) /// write to file
{
fwrite($File, $Text);
fclose($File);
}
return true;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: SaveArrayToBrowser.
* note: save data to browser.
* parameters: data
* return: true if the method call succeeded, false otherwise.
*******************************
* @param array|mixed $Data
* @return bool
*******************************/
public function SaveArrayToBrowser($Data)
{
if (empty($Data))
{
$this->SetErrors(ERRORCODE_INVALIDPARAMETER, ERRORINFO_INVALIDPARAMETER);
return false;
}
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
if (is_object($Data))
$Data = (array)$Data;
if (!is_array($Data))
{
$this->SetErrors(ERRORCODE_INVALIDPARAMETER, ERRORINFO_INVALIDPARAMETER);
return false;
}
$Text = '';
foreach ($Data as $Line)
{
if (is_object($Line))
$Line = (array)$Line;
if (is_array($Line))
{
foreach ($Line as $Value)
{
$Text .= $Value . ",";
}
}
else
$Text .= $Line;
$Text .= PHP_EOL;
}
$Text = $this->Characet($Text, 'GBK');
//$Encoding = mb_detect_encoding($Text, array('ASCII', 'UTF-8', 'GBK', 'GB2312', 'LATIN1', 'BIG5'));
//if (0 != strcasecmp('gbk', $Encoding))
// $Text = mb_convert_encoding($Text, 'gbk', $Encoding);
if ($File = fopen('php://output', 'a')) /// write to file
{
/// echo http header.
$Filename = date('YmdHis');
header("Content-type:application/vnd.ms-excel");
header("Content-Disposition:filename={$Filename}.csv");
/// saved max execute time count.
$MaxExecuteTime = ini_get('max_execution_time');
/// disable timeout limit.
set_time_limit(0);
fwrite($File, $Text);
fclose($File);
/// restore max execute time count.
set_time_limit($MaxExecuteTime);
}
return true;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: GetConnectParameter.
* note: get the parameter with connect method.
* parameters: nan
* return: connect parameter if the method call succeeded, null otherwise.
*******************************
* @return ConnectParameter
*******************************/
public function GetConnectParameter()
{
return $this->ConnectParameter;
}
/*******************************
* name: GetCommandParameter.
* note: get the parameter with run sql command.
* parameters: nan
* return: command parameter if the method call succeeded, null otherwise.
*******************************
* @return CommandParameters
*******************************/
public function GetCommandParameter()
{
return $this->CommandParameters;
}
/*******************************
* name: GetConnected.
* note: get the connected status.
* parameters: nan
* return: current connected status succeeded, null otherwise.
*******************************
* @return ConnectParameter
*******************************/
public function GetConnected()
{
return null != $this->ConnectParameter;
}
/*******************************
* name: GetConnectType.
* note: get the connect database type.
* parameters: nan
* return: connect database type if the method call succeeded, null otherwise.
*******************************
* @return null|string
*******************************/
public function GetConnectType()
{
return null;
}
/*******************************
* name: GetErrorCode.
* note: get the last method call return code.
* parameters: none.
* return: get the last method call return code.
*******************************
* @return int
*******************************/
public function GetErrorCode()
{
return $this->ErrorCode;
}
/*******************************
* name: GetErrorInfo.
* note: get the last method call return info.
* parameters: none.
* return: get the last method call return info.
*******************************
* @return mixed
*******************************/
public function GetErrorInfo()
{
return $this->ErrorInfo;
}
/*******************************
* name: GetErrors.
* note: get the last method call return code and info.
* parameters: none.
* return: get the last method call return code and info.
*******************************
* @return array
*******************************/
public function GetErrors()
{
return array('ErrorCode' => $this->ErrorCode,'ErrorInfo' => $this->ErrorInfo,);
}
/*******************************
* name: SetErrors.
* note: set the last method call return code and info.
* parameters: code, info.
* return: always return true.
*******************************
* @param int $ErrorCode
* @param mixed $ErrorInfo
* @return bool
*******************************/
protected function SetErrors($ErrorCode, $ErrorInfo)
{
if (is_object($ErrorInfo))
$ErrorInfo = (array)$ErrorInfo;
if (is_array($ErrorInfo))
{
//array_keys
$Keys = array_keys($ErrorInfo);
$ErrorInfo = $ErrorInfo[$Keys[count($Keys) - 1]];
}
//if (is_object($ErrorInfo) || is_array($ErrorInfo))
//{
// $ErrorInfo = serialize($ErrorInfo);
//}
$this->ErrorCode = $ErrorCode;
$this->ErrorInfo = $ErrorInfo;
if (!$this->IsDone())
$this->InvokeEvent($this->OnError);
return true;
// switch (gettype($ErrorInfo))
// {
// case 'object':
// case 'array':
// $ErrorInfo = JsonObjectToJsonString($ErrorInfo);
// break;
// }
//
// $this->ErrorCode = $ErrorCode;
// $this->ErrorInfo = Characet($ErrorInfo);
//
// return true;
}
}
/*******************************
* name: ORACLEHelper.
* note: oracle helper.
*******************************/
class ORACLEHelper extends PDOHelper
{
/*******************************
* name: Succeeded.
* note: test the success of the code.
* parameters: code.
* return: true if the code succeeded, false otherwise.
*******************************
* @param string|int $Code
* @return bool
*******************************/
public function Succeeded($Code)
{
return (bool) (/*strcasecmp('HY000', $Code) == 0 ||*/ strcasecmp('00000', $Code) == 0 || strcasecmp('01000', $Code) == 0 || parent::Succeeded($Code));
}
/*******************************
* name: Connect.
* note: connect to database.
* parameters: hostname, hostport, servicename, username, password.
* return: true if the method call succeeded, false otherwise.
*******************************
* param string hostname
* param int|string hostport
* param string servicename
* param string username
* param string password
* @return bool
*******************************/
public function Connect(/* hostname, hostport, servicename, username, password */)
{
/// call parent connect field.
parent::Connect();
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => hostname
/// $Parameters[1] => hostport
/// $Parameters[2] => database
/// $Parameters[3] => username
/// $Parameters[4] => password
$ParameterCount = func_num_args();
if (0 == $ParameterCount)
{
$Hostname = null;
$Hostport = null;
$Database = null;
$Username = null;
$Password = null;
$Persistent = null;
}
elseif (is_array($Parameters[0]))
{
$Hostname = isset($Parameters[0][PARAMETERNAME_HOSTNAME]) ? $Parameters[0][PARAMETERNAME_HOSTNAME] : null;
$Hostport = isset($Parameters[0][PARAMETERNAME_HOSTPORT]) ? $Parameters[0][PARAMETERNAME_HOSTPORT] : null;
$Database = isset($Parameters[0][PARAMETERNAME_DATABASE]) ? $Parameters[0][PARAMETERNAME_DATABASE] : null;
$Username = isset($Parameters[0][PARAMETERNAME_USERNAME]) ? $Parameters[0][PARAMETERNAME_USERNAME] : null;
$Password = isset($Parameters[0][PARAMETERNAME_PASSWORD]) ? $Parameters[0][PARAMETERNAME_PASSWORD] : null;
$Persistent = isset($Parameters[0][PARAMETERNAME_PERSISTENT]) ? $Parameters[0][PARAMETERNAME_PERSISTENT] : null;
}
elseif ($Parameters[0] instanceof ConnectParameter)
{
$Hostname = isset($Parameters[0]->Hostname) ? $Parameters[0]->Hostname : null;
$Hostport = isset($Parameters[0]->Hostport) ? $Parameters[0]->Hostport : null;
$Database = isset($Parameters[0]->Database) ? $Parameters[0]->Database : null;
$Username = isset($Parameters[0]->Username) ? $Parameters[0]->Username : null;
$Password = isset($Parameters[0]->Password) ? $Parameters[0]->Password : null;
$Persistent = isset($Parameters[0]->Persistent) ? $Parameters[0]->Persistent : null;
}
else
{
$Hostname = isset($Parameters[0]) ? $Parameters[0] : null;
$Hostport = isset($Parameters[1]) ? $Parameters[1] : null;
$Database = isset($Parameters[2]) ? $Parameters[2] : null;
$Username = isset($Parameters[3]) ? $Parameters[3] : null;
$Password = isset($Parameters[4]) ? $Parameters[4] : null;
$Persistent = isset($Parameters[5]) ? $Parameters[5] : null;
}
if (empty($Hostname))
$Hostname = DEFAULTHOSTNAME_ORACLE;
if (empty($Hostport))
$Hostport = DEFAULTHOSTPORT_ORACLE;
if (empty($Database))
$Database = DEFAULTDATABASE_ORACLE;
if (empty($Username))
$Username = DEFAULTUSERNAME_ORACLE;
if (empty($Password))
$Password = DEFAULTPASSWORD_ORACLE;
if (empty($Persistent))
$Persistent = DEFAULTPERSISTENT_ORACLE;
$this->ConnectParameter = new ConnectParameter($Hostname, $Hostport, $Database, $Username, $Password, $Persistent);
/// connect to database by oracle.
$driver = sprintf('oci:dbname=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = %s)(PORT = %s))
)
(CONNECT_DATA =
(SERVICE_NAME = %s)
)
);', $Hostname, $Hostport, $Database);
$this->Database = new PDO($driver, $Username, $Password, array(PDO::ATTR_PERSISTENT => (bool)$Persistent));
$this->InvokeEvent($this->OnConnected);
return true;
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: GetTables.
* note: get the database all tables.
* parameters: none.
* return: table list if the method call succeeded, null otherwise.
*******************************
* @return ITables
*******************************/
public function GetTables()
{
$CommandString = /** @lang text */
'select' . PHP_EOL .
' table_name,' . PHP_EOL .
' tablespace_name,' . PHP_EOL .
' temporary' . PHP_EOL .
'from' . PHP_EOL .
' user_tables' . PHP_EOL .
'/*' . PHP_EOL .
'union all' . PHP_EOL .
'select' . PHP_EOL .
' view_name,' . PHP_EOL .
' null,' . PHP_EOL .
' null' . PHP_EOL .
'from' . PHP_EOL .
' user_views' . PHP_EOL .
'*/' . PHP_EOL;
$Return = new Tables($this);
$Tables = $this->Request($CommandString);
foreach ($Tables as $Table)
{
$Table = (array)$Table;
$Return->Append(new Table($Table['table_name']));
}
return $Return;
}
/*******************************
* name: GetTableFields.
* note: get the table fields.
* parameters: table name.
* return: field list if the method call succeeded, null otherwise.
*******************************
* @param string $Tablename
* @return ITables
*******************************/
public function GetTableFields($Tablename)
{
$CommandString = /** @lang text */
'select' . PHP_EOL .
' column_id,' . PHP_EOL .
' table_name,' . PHP_EOL .
' column_name,' . PHP_EOL .
' data_type,' . PHP_EOL .
' data_length,' . PHP_EOL .
' data_precision,' . PHP_EOL .
' data_scale,' . PHP_EOL .
' data_default' . PHP_EOL .
'from' . PHP_EOL .
' user_tab_columns' . PHP_EOL .
'where' . PHP_EOL .
' upper(table_name) = upper(?)' . PHP_EOL .
'order by' . PHP_EOL .
' column_id' . PHP_EOL;
$Return = new Fields(null);
$Fields = $this->Request($CommandString, $Tablename);
foreach ($Fields as $Field)
{
$Field = (array)$Field;
$Return->Append(new Field($Field['column_name'], $Field['data_type'], $Field['data_length'], $Field['data_default']));
}
return $Return;
}
/*******************************
* name: GetConnectType.
* note: get the connect database type.
* parameters: nan
* return: connect database type if the method call succeeded, null otherwise.
*******************************
* @return null|string
*******************************/
public function GetConnectType()
{
return DATABASE_TYPE_ORACLE;
}
}
/*******************************
* name: SQLSRVHelper.
* note: sql server helper.
*******************************/
class SQLSRVHelper extends PDOHelper
{
/*******************************
* name: Connect.
* note: connect to database.
* parameters: hostname, hostport, database, username, password
* return: true if the method call succeeded, false otherwise.
*******************************
* param string hostname
* param int|string hostport
* param string database
* param string username
* param string password
* @return bool
*******************************/
public function Connect(/* hostname, hostport, database, username, password */)
{
/// call parent connect field.
parent::Connect();
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => hostname
/// $Parameters[1] => hostport
/// $Parameters[2] => database
/// $Parameters[3] => username
/// $Parameters[4] => password
$ParameterCount = func_num_args();
if (0 == $ParameterCount)
{
$Hostname = null;
$Hostport = null;
$Database = null;
$Username = null;
$Password = null;
$Persistent = null;
}
elseif (is_array($Parameters[0]))
{
$Hostname = isset($Parameters[0][PARAMETERNAME_HOSTNAME]) ? $Parameters[0][PARAMETERNAME_HOSTNAME] : null;
$Hostport = isset($Parameters[0][PARAMETERNAME_HOSTPORT]) ? $Parameters[0][PARAMETERNAME_HOSTPORT] : null;
$Database = isset($Parameters[0][PARAMETERNAME_DATABASE]) ? $Parameters[0][PARAMETERNAME_DATABASE] : null;
$Username = isset($Parameters[0][PARAMETERNAME_USERNAME]) ? $Parameters[0][PARAMETERNAME_USERNAME] : null;
$Password = isset($Parameters[0][PARAMETERNAME_PASSWORD]) ? $Parameters[0][PARAMETERNAME_PASSWORD] : null;
$Persistent = isset($Parameters[0][PARAMETERNAME_PERSISTENT]) ? $Parameters[0][PARAMETERNAME_PERSISTENT] : null;
}
elseif ($Parameters[0] instanceof ConnectParameter)
{
$Hostname = isset($Parameters[0]->Hostname) ? $Parameters[0]->Hostname : null;
$Hostport = isset($Parameters[0]->Hostport) ? $Parameters[0]->Hostport : null;
$Database = isset($Parameters[0]->Database) ? $Parameters[0]->Database : null;
$Username = isset($Parameters[0]->Username) ? $Parameters[0]->Username : null;
$Password = isset($Parameters[0]->Password) ? $Parameters[0]->Password : null;
$Persistent = isset($Parameters[0]->Persistent) ? $Parameters[0]->Persistent : null;
}
else
{
$Hostname = isset($Parameters[0]) ? $Parameters[0] : null;
$Hostport = isset($Parameters[1]) ? $Parameters[1] : null;
$Database = isset($Parameters[2]) ? $Parameters[2] : null;
$Username = isset($Parameters[3]) ? $Parameters[3] : null;
$Password = isset($Parameters[4]) ? $Parameters[4] : null;
$Persistent = isset($Parameters[5]) ? $Parameters[5] : null;
}
if (empty($Hostname))
$Hostname = DEFAULTHOSTNAME_SQLSRV;
if (empty($Hostport))
$Hostport = DEFAULTHOSTPORT_SQLSRV;
if (empty($Database))
$Database = DEFAULTDATABASE_SQLSRV;
if (empty($Username))
$Username = DEFAULTUSERNAME_SQLSRV;
if (empty($Password))
$Password = DEFAULTPASSWORD_SQLSRV;
if (empty($Persistent))
$Persistent = DEFAULTPERSISTENT_SQLSRV;
$this->ConnectParameter = new ConnectParameter($Hostname, $Hostport, $Database, $Username, $Password, $Persistent);
/// connect to database by sql server.
$driver = sprintf('sqlsrv:server=%s,%s;Database=%s;', $Hostname, $Hostport, $Database);
$this->Database = new PDO($driver, $Username, $Password, array(PDO::ATTR_PERSISTENT => (bool)$Persistent));
$this->InvokeEvent($this->OnConnected);
return true;
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: GetTables.
* note: get the database all tables.
* parameters: none.
* return: table list if the method call succeeded, null otherwise.
*******************************
* @return ITables
*******************************/
public function GetTables()
{
$CommandString = /** @lang text */
'select' . PHP_EOL .
' name table_name,' . PHP_EOL .
' crdate createdate,' . PHP_EOL .
' uid userid' . PHP_EOL .
'from' . PHP_EOL .
' sysobjects' . PHP_EOL .
'where' . PHP_EOL .
' --xtype in (N\'u\', N\'v\')' . PHP_EOL .
' xtype = N\'u\'' . PHP_EOL;
$Return = new Tables($this);
$Tables = $this->Request($CommandString);
foreach ($Tables as $Table)
{
$Table = (array)$Table;
$Return->Append(new Table($Table['table_name']));
}
return $Return;
}
/*******************************
* name: GetTableFields.
* note: get the table fields.
* parameters: table name.
* return: field list if the method call succeeded, null otherwise.
*******************************
* @param string $Tablename
* @return ITables
*******************************/
public function GetTableFields($Tablename)
{
$CommandString = /** @lang text */
'select' . PHP_EOL .
' a.colid column_id,' . PHP_EOL .
' c.name table_name,' . PHP_EOL .
' a.name column_name,' . PHP_EOL .
' b.name data_type,' . PHP_EOL .
' a.length data_length,' . PHP_EOL .
' a.xprec,' . PHP_EOL .
' a.xscale,' . PHP_EOL .
' a.isnullable' . PHP_EOL .
'from' . PHP_EOL .
' syscolumns a, systypes b, sysobjects c' . PHP_EOL .
'where' . PHP_EOL .
' a.xtype = b.xusertype and a.id = c.id and c.name = N?' . PHP_EOL .
'order by' . PHP_EOL .
' a.colid' . PHP_EOL;
$Return = new Fields(null);
$Fields = $this->Request($CommandString, $Tablename);
foreach ($Fields as $Field)
{
$Field = (array)$Field;
$Return->Append(new Field($Field['column_name'], $Field['data_type'], $Field['data_length'], null));
}
return $Return;
}
/*******************************
* name: GetConnectType.
* note: get the connect database type.
* parameters: nan
* return: connect database type if the method call succeeded, null otherwise.
*******************************
* @return null|string
*******************************/
public function GetConnectType()
{
return DATABASE_TYPE_SQLSRV;
}
}
/*******************************
* name: MYSQLHelper.
* note: mysql helper.
*******************************/
class MYSQLHelper extends PDOHelper
{
/*******************************
* name: Succeeded.
* note: test the success of the code.
* parameters: code.
* return: true if the code succeeded, false otherwise.
*******************************
* @param string|int $Code
* @return bool
*******************************/
public function Succeeded($Code)
{
return (bool) ( strcasecmp('00000', $Code) == 0 || strcasecmp('01000', $Code) == 0 || parent::Succeeded($Code) );
}
/*******************************
* name: Connect.
* note: connect to database.
* parameters: hostname, hostport, database, username, password, charset.
* return: true if the method call succeeded, false otherwise.
*******************************
* param string hostname
* param int|string hostport
* param string database
* param string username
* param string password
* param string charset
* @return bool
*******************************/
public function Connect(/* hostname, hostport, databasename, username, password, charset */)
{
/// call parent connect field.
parent::Connect();
$this->SetErrors(ERRORCODE_SUCCESS, ERRORINFO_SUCCESS);
try
{
/// get parameters
$Parameters = func_get_args();
/// $Parameters[0] => hostname
/// $Parameters[1] => hostport
/// $Parameters[2] => database
/// $Parameters[3] => username
/// $Parameters[4] => password
/// $Parameters[5] => charset
$ParameterCount = func_num_args();
if (0 == $ParameterCount)
{
$Hostname = null;
$Hostport = null;
$Database = null;
$Username = null;
$Password = null;
$Persistent = null;
$Charset = null;
}
elseif (is_array($Parameters[0]))
{
$Hostname = isset($Parameters[0][PARAMETERNAME_HOSTNAME]) ? $Parameters[0][PARAMETERNAME_HOSTNAME] : null;
$Hostport = isset($Parameters[0][PARAMETERNAME_HOSTPORT]) ? $Parameters[0][PARAMETERNAME_HOSTPORT] : null;
$Database = isset($Parameters[0][PARAMETERNAME_DATABASE]) ? $Parameters[0][PARAMETERNAME_DATABASE] : null;
$Username = isset($Parameters[0][PARAMETERNAME_USERNAME]) ? $Parameters[0][PARAMETERNAME_USERNAME] : null;
$Password = isset($Parameters[0][PARAMETERNAME_PASSWORD]) ? $Parameters[0][PARAMETERNAME_PASSWORD] : null;
$Persistent = isset($Parameters[0][PARAMETERNAME_PERSISTENT]) ? $Parameters[0][PARAMETERNAME_PERSISTENT] : null;
$Charset = isset($Parameters[0][PARAMETERNAME_CHARSET]) ? $Parameters[0][PARAMETERNAME_CHARSET] : null;
}
elseif ($Parameters[0] instanceof ConnectParameter)
{
$Hostname = isset($Parameters[0]->Hostname) ? $Parameters[0]->Hostname : null;
$Hostport = isset($Parameters[0]->Hostport) ? $Parameters[0]->Hostport : null;
$Database = isset($Parameters[0]->Database) ? $Parameters[0]->Database : null;
$Username = isset($Parameters[0]->Username) ? $Parameters[0]->Username : null;
$Password = isset($Parameters[0]->Password) ? $Parameters[0]->Password : null;
$Persistent = isset($Parameters[0]->Persistent) ? $Parameters[0]->Persistent : null;
$Charset = isset($Parameters[0]->Charset) ? $Parameters[0]->Charset : null;
}
else
{
$Hostname = isset($Parameters[0]) ? $Parameters[0] : null;
$Hostport = isset($Parameters[1]) ? $Parameters[1] : null;
$Database = isset($Parameters[2]) ? $Parameters[2] : null;
$Username = isset($Parameters[3]) ? $Parameters[3] : null;
$Password = isset($Parameters[4]) ? $Parameters[4] : null;
$Persistent = isset($Parameters[6]) ? $Parameters[6] : null;
$Charset = isset($Parameters[5]) ? $Parameters[5] : null;
}
if (empty($Hostname))
$Hostname = DEFAULTHOSTNAME_MYSQL;
if (empty($Hostport))
$Hostport = DEFAULTHOSTPORT_MYSQL;
if (empty($Database))
$Database = DEFAULTDATABASE_MYSQL;
if (empty($Username))
$Username = DEFAULTUSERNAME_MYSQL;
if (empty($Password))
$Password = DEFAULTPASSWORD_MYSQL;
if (empty($Persistent))
$Persistent = DEFAULTPERSISTENT_MYSQL;
if (empty($Charset))
$Charset = DEFAULTCHARSET_MYSQL;
$this->ConnectParameter = new ConnectParameter($Hostname, $Hostport, $Database, $Username, $Password, $Persistent, $Charset);
/// connect to database by mysql.
$driver = sprintf('mysql:host=%s;port=%s;dbname=%s;charset=%s;', $Hostname, $Hostport, $Database, $Charset);
$this->Database = new PDO($driver, $Username, $Password, array(PDO::ATTR_PERSISTENT => (bool)$Persistent));
/// select database
if (!($this->Database->exec('use ' . $Database . ';') || $this->Succeeded($this->Database->errorCode())))
{
$this->SetErrors($this->Database->errorCode(), $this->Database->errorInfo());
return false;
}
else
{
$this->InvokeEvent($this->OnConnected);
return true;
}
}
catch (PDOException $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
catch (Exception $Exception)
{
$this->SetErrors($Exception->GetCode(), $Exception->GetMessage());
return false;
}
}
/*******************************
* name: GetTables.
* note: get the database all tables.
* parameters: none.
* return: table list if the method call succeeded, null otherwise.
*******************************
* @return ITables
*******************************/
public function GetTables()
{
$CommandString = /** @lang text */
'select' . PHP_EOL .
' table_name' . PHP_EOL .
'from' . PHP_EOL .
' information_schema.tables' . PHP_EOL .
'where' . PHP_EOL .
' table_schema = ? and table_type = \'base table\'' . PHP_EOL;
$Return = new Tables($this);
$Tables = $this->Request($CommandString, $this->ConnectParameter->Database);
foreach ($Tables as $Table)
{
$Table = (array)$Table;
$Return->Append(new Table($Table['table_name']));
}
return $Return;
}
/*******************************
* name: GetTableFields.
* note: get the table fields.
* parameters: table name.
* return: field list if the method call succeeded, null otherwise.
*******************************
* @param string $Tablename
* @return ITables
*******************************/
public function GetTableFields($Tablename)
{
$CommandString = /** @lang text */
'select' . PHP_EOL .
' column_name,' . PHP_EOL .
' data_type,' . PHP_EOL .
' column_default' . PHP_EOL .
'from' . PHP_EOL .
' information_schema.columns' . PHP_EOL .
'where' . PHP_EOL .
' table_schema = ? and table_name = ?' . PHP_EOL .
'order by' . PHP_EOL .
' ordinal_position' . PHP_EOL;
$Return = new Fields(null);
$Fields = $this->Request($CommandString, $this->ConnectParameter->Database, $Tablename);
foreach ($Fields as $Field)
{
$Field = (array)$Field;
$Return->Append(new Field($Field['column_name'], $Field['data_type'], 0, $Field['column_default']));
}
return $Return;
}
/*******************************
* name: GetConnectType.
* note: get the connect database type.
* parameters: nan
* return: connect database type if the method call succeeded, null otherwise.
*******************************
* @return null|string
*******************************/
public function GetConnectType()
{
return DATABASE_TYPE_MYSQL;
}
}
/// ====================================================================================================================
/**
* @note the sql command helper of database interface.
**************sample***************
* $this
* ->Select(...)
* ->From(...)
* ->InnerJoin|LeftJoin|RightJoin(...)
* ->On(...)
* ->Where(...)
* ->GroupBy(...)
* ->Having(...)
* ->OrderBy(...)
* ->WithPage(...)
* ->Request()
**********************************
* $this
* ->Insert(...)
* ->Fields(...)
* ->Values(...)
* ->Execute()
**********************************
* $this
* ->Update(...)
* ->Fields(...)
* ->Values(...)
* ->Where(...)
* ->Execute()
**********************************
* $this
* ->Delete(...)
* ->Where(...)
* ->Execute()
**********************************
* $this
* ->Truncate(...)
* ->Execute()
**********************************
* $this
* ->Merge(...)
* ->Fields(...)
* ->Values(...)
* ->MergeOn(...)
* ->Execute()
**********************************
* $this
* ->CallStoredProcedure(...)
* ->Values(...)
* ->Request()/Execute()
**********************************/
abstract class SQLCommand implements ISQLCommand
{
/**
* @var IPDOHelper
*/
protected $Connection;
//private $ReferenceCharacter;
/**
* @var string
*/
protected $RefCharLeft;
/**
* @var string
*/
protected $RefCharRight;
/**
* @var string
*/
protected $CommandType; /// 语句类型
/**
* @var array of mixed
*/
protected $DataFieldNames; /// 字段名
/**
* @var array of string
*/
protected $DataFieldAlias; /// 别名
/**
* @var array of mixed
*/
protected $InternalSourceNames; /// 数据源
/**
* @var array of string
*/
protected $InternalSourceAlias; /// 数据源别名
/**
* @var string
*/
protected $StoredProcedureName; /// 存储过程、函数名
/**
* @var array of mixed
*/
//protected $ExternalSourceNames; /// 要插入|修改|合并的数据源
/**
* @var array of string
*/
//protected $ExternalSourceAlias; /// 要插入|修改|合并的数据源别名
/**
* @var array of string
*/
protected $WhereConditionColumn; /// 过滤字段
/**
* @var array of mixed
*/
protected $WhereConditionValues; /// 过滤字段值描述
/**
* @var array of mixed
*/
protected $WhereConditionParams; /// 过滤字段值参数
/**
* @var array of string
*/
protected $GroupFieldList; /// 分组字段
/**
* @var array of string
*/
protected $HavingConditionColumn; /// 过滤分组信息的条件
/**
* @var array of mixed
*/
protected $HavingConditionValues; /// 过滤分组信息条件带的参数列表
/**
* @var array of mixed
*/
protected $HavingConditionParams; /// 过滤分组信息条件带的参数列表
/**
* @var array of string
*/
protected $OrderFieldNames; /// 排序信息
protected $OrderFieldTypes; /// 排序类型
protected $PageIndex; /// 分组时的页序号
protected $PageSize; /// 分组时的页大小
protected $MaxRequestCount; /// 限制查询的记录数
/**
* @var array of mixed
*/
protected $ChangeFields; /// 要插入|修改|合并的字段名
/**
* @var array of mixed
*/
protected $ChangeValues; /// 要插入|修改|合并的值描述
/**
* @var array of mixed
*/
protected $ChangeParams; /// 要插入|修改|合并的值参数
/**
* @var int
*/
protected $JoinCount; /// 连接个数
/**
* @var string
*/
protected $JoinType; /// 连接方式
/**
* @var string
*/
protected $JoinSourceNames; /// 连接源
/**
* @var array
*/
protected $JoinSourceAlias; /// 连接源别名
/**
* @var array of string
*/
protected $JoinConditionColumn; /// 连接的字段(列)
/**
* @var array of mixed
*/
protected $JoinConditionValues; /// 连接的字段(列)的值描述
/**
* @var array of mixed
*/
protected $JoinConditionParams; /// 连接的字段(列)的值的参数列表
/**
* @var string
*/
protected $MergeJoinSourceNames; /// 连接源
/**
* @var array
*/
protected $MergeJoinSourceAlias; /// 连接源别名
/**
* @var array of string
*/
protected $MergeJoinConditionColumn; /// 连接的字段(列)
/**
* @var array of mixed
*/
protected $MergeJoinConditionValues; /// 连接的字段(列)的值描述
/**
* @var array of mixed
*/
protected $MergeJoinConditionParams; /// 连接的字段(列)的值的参数列表
/**
* @var array of ISQLCommand|string
*/
protected $UnionSourceNames; /// 需要链接的对象或语句。
/**
* @var array of mixed
*/
protected $OtherParameterList; /// 需要绑定的其他参数
/*******************************
* name: __construct.
* note: the construct function for class.
* parameters: Connection for PDOHelper.
* return: new object if the method call succeeded, null otherwise.
*******************************
* SQLCommand constructor.
* @param IPDOHelper $Connection
* @throws Exception
*******************************/
public function __construct($Connection)
{
if (null == $Connection || !($Connection instanceof IPDOHelper))
throw new Exception('the $Connection is invalid IPDOHelper instance! in ' . __FILE__ . ' on line ' . __LINE__);
$this->ClearMethod();
$this->Connection = $Connection;
}
/*******************************
* name: __destruct.
* note: the destruct function for class.
* parameters: nan.
* return: nan.
*******************************
* SQLCommand destructor.
*******************************/
public function __destruct()
{
$this->ClearMethod();
}
// function __call($Name, $Args)
// {
// $Reflect = new ReflectionClass($this->Connection);
// if ($Method = $Reflect->getMethod($Name))
// {
// if ($Method->isPublic() && !$Method->isAbstract())
// {
// return $Method->invokeArgs($this->Connection, $Args);
// }
// }
// }
// function __get($Name)
// {
// $Reflect = new ReflectionClass($this->Connection);
// if ($Property = $Reflect->getProperty($Name))
// {
// if ($Property->isPublic())
// {
// return $Property->getValue($this->Connection);
// }
// }
// }
// function __set($Name, $Value)
// {
// $Reflect = new ReflectionClass($this->Connection);
// if ($Property = $Reflect->GetProperty($Name))
// {
// if ($Property->IsPublic())
// {
// return $Property->SetValue($this->Connection, $Value);
// }
// }
// }
/*******************************
* name: ClearMember.
* note: clear all member for class.
* parameters: nan.
* return: nan.
*******************************
*
*******************************/
protected function ClearMethod()
{
$this->CommandType = ''; /// 语句类型
$this->DataFieldNames = array(); /// 字段名
$this->DataFieldAlias = array(); /// 字段别名
$this->InternalSourceNames = array(); /// 数据源
$this->InternalSourceAlias = array(); /// 数据源别名
$this->StoredProcedureName = ''; /// 要调用的存储过程或函数名
//$this->ExternalSourceNames = array(); /// 要插入|修改|合并的数据源
//$this->ExternalSourceAlias = array(); /// 要插入|修改|合并的数据源别名
$this->WhereConditionColumn = array(); /// 过滤列
$this->WhereConditionValues = array(); /// 过滤值的描述
$this->WhereConditionParams = array(); /// 过滤值的参数
$this->GroupFieldList = array(); /// 分组字段
$this->HavingConditionColumn = array(); /// 过滤分组信息的列
$this->HavingConditionValues = array(); /// 过滤分组信息的值的描述
$this->HavingConditionParams = array(); /// 过滤分组信息的值的参数
$this->OrderFieldNames = array(); /// 排序字段
$this->OrderFieldTypes = array(); /// 排序类型
$this->PageIndex = 0; /// 分组时的页序号
$this->PageSize = 0; /// 分组时的页大小
$this->MaxRequestCount = 0; /// 限制要查询的记录数
$this->ChangeFields = array(); /// 要插入|修改|合并的字段名
$this->ChangeValues = array(); /// 要插入|修改|合并的值描述
$this->ChangeParams = array(); /// 要插入|修改|合并的值参数
/// 用于多表联查
$this->JoinCount = 0; /// 连接个数
$this->JoinType = array(); /// 连接方式
$this->JoinSourceNames = array(); /// 连接源
$this->JoinSourceAlias = array(); /// 连接源的别名
$this->JoinConditionColumn = array(); /// 连接条件
$this->JoinConditionValues = array(); /// 连接条件的参数列表
$this->JoinConditionParams = array(); /// 链接条件的参数值
/// 用于多表合并
$this->MergeJoinSourceNames = array(); /// 连接源
$this->MergeJoinSourceAlias = array(); /// 连接源的别名
$this->MergeJoinConditionColumn = array(); /// 连接条件
$this->MergeJoinConditionValues = array(); /// 连接条件的参数列表
$this->MergeJoinConditionParams = array(); /// 链接条件的参数值
/// 用于多表链接
$this->UnionSourceNames = array(); /// 需要链接的对象或语句。
///
$this->OtherParameterList = array(); /// 需要绑定的其他参数
}
/*******************************
* name: ProcessSelectColumn.
* note: get the select field information.
* parameters: expressions, return field list, return alias list.
* return: field list and alias list as array if the method call succeeded, null otherwise.
*******************************
* @param ISQLCommand|string|array|mixed $Expressions
* @param array $FieldList
* @param array $AliasList
* @return bool
*******************************/
private function ProcessSelectColumn($Expressions, &$FieldList, &$AliasList)
{
$FieldList = array();
$AliasList = array();
if (empty($Expressions))
return false;
if ($Expressions instanceof ISQLCommand)
{
array_push($FieldList, $Expressions);
array_push($AliasList, $this->CreateRandString('nsfa_'));
return true;
}
if (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
foreach ($Expressions as $Alias => $Field)
{
if (is_null($Field))
continue;
elseif ($Field instanceof ISQLCommand)
{
array_push($FieldList, $Field);
array_push($AliasList, $this->GetIdentifiers($Alias));
continue;
}
elseif (is_object($Field) || is_array($Field))
{
$TempFieldList = $TempAliasList = array();
if ($this->ProcessSelectColumn($Field, $TempFieldList, $TempAliasList))
{
$this->MergeArray($FieldList, $TempFieldList);
$this->MergeArray($AliasList, $TempAliasList);
}
continue;
}
$Value = mb_strstr($Field, '.', false, USEDCHARSET);
if (!empty($Value)) /// 包含.则两边增加限定符。
{
$Field = $this->GetObjectName($Field);
$SubLen = mb_strlen('.', USEDCHARSET);
$Value = $this->GetIdentifiers(mb_substr($Value, $SubLen, mb_strlen($Value, USEDCHARSET) - $SubLen, USEDCHARSET));
}
else
{
$Field = $this->GetObjectName($Field);
$Value = $Field;
}
/// 别名
if (!empty($Alias) && !is_numeric($Alias))
$Value = $this->GetObjectName($Alias);
array_push($FieldList, $Field);
array_push($AliasList, $Value);
}
}
else
{
array_push($FieldList, $Expressions);
array_push($AliasList, $Expressions);
}
return true;
}
/*******************************
* name: ProcessDataSource.
* note: get the datasource or table information.
* parameters: datasource or table.
* return: table list and alias list as array if the method call succeeded, null otherwise.
*******************************
* @param ISQLCommand|string|array|mixed $Expressions
* @param array $TableList
* @param array $AliasList
* @return bool
*******************************/
private function ProcessDataSource($Expressions, &$TableList, &$AliasList)
{
$TableList = array();
$AliasList = array();
if (empty($Expressions))
return false;
if ($Expressions instanceof ISQLCommand)
{
array_push($TableList, $Expressions);
array_push($AliasList, $this->CreateRandString('nds_'));
return true;
}
if (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
foreach ($Expressions as $Alias => $Table)
{
if (is_null($Table))
continue;
elseif ($Table instanceof ISQLCommand)
{
array_push($TableList, $Table);
array_push($AliasList, $this->GetObjectName($Alias));
continue;
}
elseif (is_array($Table) || is_object($Table))
{
$TempTableList = $TempAliasList = array();
if ($this->ProcessDataSource($Table, $TempTableList, $TempAliasList))
{
$this->MergeArray($TableList, $TempTableList);
$this->MergeArray($AliasList, $TempAliasList);
}
continue;
}
array_push($TableList, $this->GetObjectName($Table));
array_push($AliasList, (!empty($Alias) && !is_numeric($Alias)) ? $this->GetObjectName($Alias) : '');
}
}
else
{
array_push($TableList, $Expressions);
array_push($AliasList, $Expressions);
}
return true;
}
/*******************************
* name: ProcessCondition.
* note: get the condition information.
* parameters: condition.
* return: condition list and value list as array if the method call succeeded, null otherwise.
*******************************
* @param ISQLCommand|string|array|mixed $Expressions
* @param array $ConditionsColumn
* @param array $ConditionsValues
* @param array $ConditionsParams
* @return array
*******************************/
private function ProcessCondition($Expressions, &$ConditionsColumn, &$ConditionsValues, &$ConditionsParams)
{
$ConditionsColumn = array(); /// colunm name
$ConditionsValues = array(); /// column mask or value
$ConditionsParams = array(); /// column parameter value
if (empty($Expressions))
return false;
elseif ($Expressions instanceof CommandParameter)
$Expressions = array($Expressions);
elseif (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
foreach ($Expressions as $Key => $Value)
{
array_push($ConditionsColumn, $this->GetObjectName($Key));
if (is_null($Value))
{
array_push($ConditionsValues, '?');
array_push($ConditionsParams, null);
continue;
}
elseif ($Value instanceof ISQLCommand)
{
array_push($ConditionsValues, $Value);
array_push($ConditionsParams, null);
continue;
}
elseif ($Value instanceof CommandParameter)
{
$IsRaw = $Value->Raw;
$Type = $Value->Type;
$Value = $Value->Value;
}
else
{
$IsRaw = false;
$Type = TYPENAME_RAW;
if (is_array($Value) || is_object($Value))
$Value = JsonObjectToJsonString((array)$Value);
}
if ($IsRaw)
{
switch ($Type)
{
case TYPENAME_DATE:
{
if (is_numeric($Value))
array_push($ConditionsValues, $this->Timestamp2DatetimeFormat($Value));
else
array_push($ConditionsValues, $this->String2DatetimeFormat($Value));
break;
}
case TYPENAME_TIMESTAMP:
{
if (is_numeric($Value))
array_push($ConditionsValues, $Value);
else
array_push($ConditionsValues, $this->Datetime2TimestampFormat($Value));
break;
}
case TYPENAME_STRING:
{
array_push($ConditionsValues, $this->GetIdentifiers($Value, true));
break;
}
default:
{
array_push($ConditionsValues, $Value);
break;
}
}
array_push($ConditionsParams, null);
}
else
{
switch ($Type)
{
case TYPENAME_DATE:
{
if (is_numeric($Value))
array_push($ConditionsValues, $this->Timestamp2DatetimeFormat('?'));
else
array_push($ConditionsValues, $this->String2DatetimeFormat('?', false));
break;
}
case TYPENAME_TIMESTAMP:
{
if (is_numeric($Value))
array_push($ConditionsValues, '?');
else
array_push($ConditionsValues, $this->Datetime2TimestampFormat('?', false));
break;
}
default:
{
array_push($ConditionsValues, '?');
break;
}
}
array_push($ConditionsParams, $Value);
}
}
}
else
{
array_push($ConditionsColumn, $Expressions);
array_push($ConditionsValues, null);
array_push($ConditionsParams, null);
}
return true;
}
/*******************************
* name: ProcessGroupColumn.
* note: get the group expression information.
* parameters: group expression.
* return: group field list as string if the method call succeeded, null otherwise.
*******************************
* @param string|array $Expressions
* @param array $FieldList
* @return bool
*******************************/
private function ProcessGroupColumn($Expressions, &$FieldList)
{
$FieldList = array();
if (empty($Expressions))
return false;
if (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
foreach ($Expressions as $Alias => $Field)
{
array_push($FieldList, $this->GetObjectName($Field));
}
}
else
$FieldList = (array)$Expressions;
return true;
}
/*******************************
* name: ProcessOrderColumn.
* note: get the order expression.
* parameters: order expression.
* return: field and type list as string if the method call succeeded, null otherwise.
*******************************
* @param ISQLCommand|string|array|mixed $Expressions
* @param array $FieldList
* @param array $OrderList
* @return array
*******************************/
private function ProcessOrderColumn($Expressions, &$FieldList, &$OrderList)
{
$FieldList = array();
$OrderList = array();
if (empty($Expressions))
{
return false;
}
if (is_object($Expressions))
{
$Expressions = (array)$Expressions;
}
if (is_array($Expressions))
{
foreach ($Expressions as $Order => $Field)
{
if (strcasecmp('asc', $Order) != 0 && strcasecmp('desc', $Order) != 0)
$Order = 'asc';
array_push($FieldList, $this->GetObjectName($Field));
array_push($OrderList, $Order);
}
}
else
{
array_push($FieldList, $Expressions);
array_push($OrderList, 'asc');
}
return true;
}
/*******************************
* name: ProcessSourceColumn.
* note: get the insert or update column list.
* parameters: insert or update column list.
* return: insert or update column list as array if the method call succeeded, null otherwise.
*******************************
* @param string|array $Expressions
* @param array $Columns
* @return array
*******************************/
private function ProcessSourceColumn($Expressions, &$Columns)
{
$Columns = array();
if (empty($Expressions))
return false;
if (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
foreach ($Expressions as $Value)
{
if (is_object($Value) || is_array($Value))
{
$List = array();
if ($this->ProcessSourceColumn($Value, $List))
$this->MergeArray($Columns, $List);
continue;
}
elseif (is_null($Value))
continue;
array_push($Columns, $this->GetObjectName($Value));
}
}
else
array_push($Columns, $Expressions);
return true;
}
/*******************************
* name: ProcessTargetColumn.
* note: get the insert or update column list.
* parameters: insert or update column list.
* return: true if the method call succeeded, false otherwise.
*******************************
* @param string|array $Expressions
* @param array $Values
* @param array $Params
* @return boolean
*******************************/
private function ProcessTargetColumn($Expressions, &$Values, &$Params)
{
$Values = array();
$Params = array();
if (empty($Expressions))
return false;
if ($Expressions instanceof ISQLCommand)
{
array_push($Values, $Expressions);
array_push($Params, null);
return true;
}
elseif ($Expressions instanceof CommandParameter)
$Expressions = array($Expressions);
elseif (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
/// 分解字段,并拼接成需要的格式
foreach ($Expressions as $Value)
{
if (is_null($Value))
continue;
elseif ($Value instanceof CommandParameter)
{
$IsRaw = $Value->Raw;
$Type = $Value->Type;
$Value = $Value->Value;
}
else
{
$IsRaw = false;
$Type = TYPENAME_RAW;
if (is_array($Value) || is_object($Value))
$Value = JsonObjectToJsonString((array)$Value);
}
/// 处理参数值
if ($IsRaw)
{
switch ($Type)
{
case TYPENAME_DATE:
{
if (is_numeric($Value))
array_push($Values, $this->Timestamp2DatetimeFormat($Value));
else
array_push($Values, $this->String2DatetimeFormat($Value));
break;
}
case TYPENAME_TIMESTAMP:
{
if (is_numeric($Value))
array_push($Values, $Value);
else
array_push($Values, $this->Datetime2TimestampFormat($Value));
break;
}
case TYPENAME_RAW:
{
array_push($Values, $Value);
break;
}
default:
{
array_push($Values, $this->GetIdentifiers($Value, true));
break;
}
}
/// 为null表示不传参
array_push($Params, null);
}
else
{
switch ($Type)
{
case TYPENAME_DATE:
{
if (is_numeric($Value))
array_push($Values, $this->Timestamp2DatetimeFormat('?'));
else
array_push($Values, $this->String2DatetimeFormat('?', false));
break;
}
case TYPENAME_TIMESTAMP:
{
if (is_numeric($Value))
array_push($Values, '?');
else
array_push($Values, $this->Datetime2TimestampFormat('?', false));
break;
}
default:
{
array_push($Values, '?');
break;
}
}
/// 把字段值加入参数列表中
array_push($Params, $Value);
}
}
}
else
{
array_push($Values, $Expressions);
array_push($Params, null);
}
return true;
}
/*******************************
* name: ProcessBindParameter.
* note: get the bind others parameter list.
* parameters: others parameter list.
* return: true if the method call succeeded, false otherwise.
*******************************
* @param string|array $Expressions
* @param array $Params
* @return boolean
*******************************/
private function ProcessBindParameter($Expressions, &$Params)
{
$Params = array();
if (empty($Expressions))
return false;
if ($Expressions instanceof CommandParameter)
{
array_push($Params, $Expressions);
return true;
}
elseif (is_object($Expressions))
$Expressions = (array)$Expressions;
if (is_array($Expressions))
{
foreach ($Expressions as $Value)
{
if (is_object($Value) || is_array($Value))
{
$List = array();
if ($this->ProcessBindParameter($Value, $List))
$this->MergeArray($Params, $List);
continue;
}
elseif (is_null($Value))
continue;
array_push($Params, $Value);
}
}
else
array_push($Params, $Expressions);
return true;
}
/// =====================================================================================================================
/*******************************
* name: ReceiveSelectColumn.
* note: receive the select field information.
* parameters: expressions.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveSelectColumn() /// select ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->DataFieldNames = array();
$this->DataFieldAlias = array();
for ($Index = 0; $Index < $Count; $Index++)
{
$Field = array();
$Alias = array();
if ($this->ProcessSelectColumn((array)$Args[$Index], $Field, $Alias))
{
$this->MergeArray($this->DataFieldNames, $Field);
$this->MergeArray($this->DataFieldAlias, $Alias);
}
}
}
/*******************************
* name: ReceiveInternalSource.
* note: receive the datasource or table information by source.
* parameters: datasource or table.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveInternalSource() /// [select from|insert into|update|merge into] ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->InternalSourceNames = array();
$this->InternalSourceAlias = array();
for ($Index = 0; $Index < $Count; $Index++)
{
if ($Args[$Index] instanceof ISQLCommand)
{
$Table = array($Args[$Index]);
$Alias = array($this->CreateRandString('nds_'));
}
else
{
$Table = array();
$Alias = array();
if (!$this->ProcessDataSource((array)$Args[$Index], $Table, $Alias))
{
$Table = array();
$Alias = array();
}
}
$this->MergeArray($this->InternalSourceNames, $Table);
$this->MergeArray($this->InternalSourceAlias, $Alias);
}
}
/*******************************
* name: ReceiveStoredProcedureName.
* note: receive the name of stored procedure.
* parameters: stored procedure name.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveStoredProcedureName($StoredProcedureName)
{
/// $Args = func_get_args();
/// $Count = func_num_args();
$this->StoredProcedureName = $StoredProcedureName;
}
/*******************************
* name: ReceiveExternalSource.
* note: receive the datasource or table information by target.
* parameters: datatarget or table.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
// private function ReceiveExternalSource() /// [] ...
// {
// $Args = func_get_args();
// $Count = func_num_args();
//
// $this->ExternalSourceNames = array();
// $this->ExternalSourceAlias = array();
//
// for ($Index = 0; $Index < $Count; $Index++)
// {
// if ($Args[$Index] instanceof ISQLCommand)
// {
// $Table = array($Args[$Index]);
// $Alias = array($this->CreateRandString('ndt_'));
// }
// else
// {
// $Table = array();
// $Alias = array();
// if (!$this->ProcessDataSource((array)$Args[$Index], $Table, $Alias))
// {
// $Table = array();
// $Alias = array();
// }
// }
//
// $this->MergeArray($this->ExternalSourceNames, $Table);
// $this->MergeArray($this->ExternalSourceAlias, $Alias);
// }
// }
/*******************************
* name: ReceiveExternalSource.
* note: receive the datasource or table information by join source.
* parameters: datatarget or table.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveJoinSource() /// [inner|left|right|outer] join ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->JoinSourceNames[$this->JoinCount - 1] = array();
$this->JoinSourceAlias[$this->JoinCount - 1] = array();
for ($Index = 0; $Index < $Count; $Index++)
{
if ($Args[$Index] instanceof ISQLCommand)
{
$Table = array($Args[$Index]);
$Alias = array($this->CreateRandString('ndt_'));
}
else
{
$Table = array();
$Alias = array();
if (!$this->ProcessDataSource((array)$Args[$Index], $Table, $Alias))
{
$Table = array();
$Alias = array();
}
}
$this->MergeArray($this->JoinSourceNames[$this->JoinCount - 1], $Table);
$this->MergeArray($this->JoinSourceAlias[$this->JoinCount - 1], $Alias);
}
}
/*******************************
* name: ReceiveJoinCondition.
* note: receive the datasource or table condition information by join source.
* parameters: join condition.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveJoinCondition() /// join on ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->JoinConditionColumn[$this->JoinCount - 1] = array();
$this->JoinConditionValues[$this->JoinCount - 1] = array();
$this->JoinConditionParams[$this->JoinCount - 1] = array();
for ($Index = 0; $Index < $Count; $Index++)
{
$ConditionColumn = array();
$ConditionValues = array();
$ConditionParams = array();
if ($this->ProcessCondition($Args[$Index], $ConditionColumn, $ConditionValues, $ConditionParams))
{
$this->MergeArray($this->JoinConditionColumn[$this->JoinCount - 1], $ConditionColumn);
$this->MergeArray($this->JoinConditionValues[$this->JoinCount - 1], $ConditionValues);
$this->MergeArray($this->JoinConditionParams[$this->JoinCount - 1], $ConditionParams);
}
}
}
/*******************************
* name: ReceiveMergeJoinCondition.
* note: receive the datasource or table condition information by join source.
* parameters: join condition.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveMergeJoinCondition()
{
$Args = func_get_args();
$Count = func_num_args();
$this->MergeJoinConditionColumn = array();
$this->MergeJoinConditionValues = array();
$this->MergeJoinConditionParams = array();
for ($Index = 0; $Index < $Count; $Index++)
{
$ConditionColumn = array();
$ConditionValues = array();
$ConditionParams = array();
if ($this->ProcessCondition($Args[$Index], $ConditionColumn, $ConditionValues, $ConditionParams))
{
$this->MergeArray($this->MergeJoinConditionColumn, $ConditionColumn);
$this->MergeArray($this->MergeJoinConditionValues, $ConditionValues);
$this->MergeArray($this->MergeJoinConditionParams, $ConditionParams);
}
}
}
/*******************************
* name: ReceiveWhereCondition.
* note: receive the where condition information.
* parameters: condition.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveWhereCondition() /// where ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->WhereConditionColumn = array();
$this->WhereConditionValues = array();
$this->WhereConditionParams = array();
for ($Index = 0; $Index < $Count; $Index++)
{
$ConditionColumn = array();
$ConditionValues = array();
$ConditionParams = array();
if ($this->ProcessCondition($Args[$Index], $ConditionColumn, $ConditionValues, $ConditionParams))
{
$this->MergeArray($this->WhereConditionColumn, $ConditionColumn);
$this->MergeArray($this->WhereConditionValues, $ConditionValues);
$this->MergeArray($this->WhereConditionParams, $ConditionParams);
}
}
}
/*******************************
* name: ReceiveGroupExpression.
* note: receive the group express information.
* parameters: group express.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveGroupExpression() /// group by ...
{
$this->GroupFieldList = array();
$this->ProcessGroupColumn(func_get_args(), $this->GroupFieldList);
}
/*******************************
* name: ReceiveHavingCondition.
* note: receive the having condition information by group express.
* parameters: having condition.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveHavingCondition() /// having ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->HavingConditionColumn = array();
$this->HavingConditionValues = array();
$this->HavingConditionParams = array();
for ($Index = 0; $Index < $Count; $Index++)
{
$ConditionColumn = array();
$ConditionValues = array();
$ConditionParams = array();
if ($this->ProcessCondition($Args[$Index], $ConditionColumn, $ConditionValues, $ConditionParams))
{
$this->MergeArray($this->HavingConditionColumn, $ConditionColumn);
$this->MergeArray($this->HavingConditionValues, $ConditionValues);
$this->MergeArray($this->HavingConditionParams, $ConditionParams);
}
}
}
/*******************************
* name: ReceiveOrderExpression.
* note: receive the order express information.
* parameters: order express.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveOrderExpression() /// order by ...
{
$Args = func_get_args();
$Count = func_num_args();
$this->OrderFieldNames = array();
$this->OrderFieldTypes = array();
for ($Index = 0; $Index < $Count; $Index++)
{
$FieldList = array();
$OrderList = array();
if ($this->ProcessOrderColumn((array)$Args[$Index], $FieldList, $OrderList))
{
$this->MergeArray($this->OrderFieldNames, $FieldList);
$this->MergeArray($this->OrderFieldTypes, $OrderList);
}
}
}
/*******************************
* name: ReceiveInternalColumn.
* note: receive the source column information.
* parameters: source column.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveInternalColumn()
{
$this->ProcessSourceColumn(func_get_args(), $this->ChangeFields);
}
/*******************************
* name: ReceiveExternalColumn.
* note: receive the target column information.
* parameters: target column.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveExternalColumn()
{
$this->ChangeValues = array();
$this->ChangeParams = array();
$Args = func_get_args();
$Count = func_num_args();
for ($Index = 0; $Index < $Count; $Index++)
{
if ($Args[$Index] instanceof ISQLCommand)
{
array_push($this->ChangeValues, $Args[$Index]);
array_push($this->ChangeParams, null);
}
else
{
$Values = array();
$Params = array();
if ($this->ProcessTargetColumn(is_object($Args[$Index]) ? $Args[$Index] : (array)$Args[$Index], $Values, $Params))
{
$this->MergeArray($this->ChangeValues, $Values);
$this->MergeArray($this->ChangeParams, $Params);
}
}
}
}
/*******************************
* name: ReceiveUnionSource.
* note: receive the union source information.
* parameters: union source.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveUnionSource()
{
$this->UnionSourceNames = array();
$Args = func_get_args();
$Count = func_num_args();
for ($Index = 0; $Index < $Count; $Index++)
{
array_push($this->UnionSourceNames, $Args[$Index]);
}
}
/*******************************
* name: ReceiveBindParameters.
* note: receive the bind others parameter list.
* parameters: needed bind parameter list.
* return: nan.
*******************************
* @param ISQLCommand|string|array|mixed
*******************************/
private function ReceiveBindParameters()
{
$this->OtherParameterList = array();
$Args = func_get_args();
$Count = func_num_args();
for ($Index = 0; $Index < $Count; $Index++)
{
$Parameters = array();
if ($this->ProcessBindParameter($Args[$Index], $Parameters))
$this->MergeArray($this->OtherParameterList, $Parameters);
}
}
/// =====================================================================================================================
/*******************************
* name: CreateRandString.
* note: create a rand string.
* parameters: string prefix.
* return: string.
*******************************
* @param string $Prefix
* @return string
*******************************/
protected function CreateRandString($Prefix = '')
{
return (empty($Prefix) ? '' : $Prefix) . rand(100000, 999999);
}
/*******************************
* name: SetReferenceCharacter.
* note: set left and right reference character.
* parameters: reference character.
* return: nan.
*******************************
* @param string $Left left reference character
* @param string $Right right reference character
* @return ISQLCommand
*******************************/
protected function SetReferenceCharacter($Left, $Right)
{
$this->RefCharLeft = $Left;
$this->RefCharRight = $Right;
}
/*******************************
* name: SelectFieldListToCommandInformation.
* note: connect select field array to string.
* parameters: name array, alia array.
* return: CommandInformation.
*******************************
* @param array $Columns need to connect to the array.
* @param array $Alias need to connect to the alia for array.
* @return CommandInformation
*******************************/
protected function SelectFieldListToCommandInformation($Columns, $Alias)
{
$Return = new CommandInformation();
if (!(is_array($Columns) && is_array($Alias)))
return $Return;
for ($Index = 0; $Index < count($Columns); $Index++)
{
if ($Columns[$Index] instanceof ISQLCommand)
{
$Command = call_user_func(array(&$Columns[$Index], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return->Command .= ", ({$Command->Command}) {$Alias[$Index]}";
$this->MergeArray($Return->Paramer, $Command->Paramer);
}
elseif (!empty($Alias[$Index]) && ($Alias[$Index] != $Columns[$Index]))
$Return->Command .= ", {$Columns[$Index]} {$Alias[$Index]}";
else
$Return->Command .= ", {$Columns[$Index]}";
}
$SubLen = mb_strlen(', ', USEDCHARSET);
$Return->Command = mb_substr($Return->Command, $SubLen, mb_strlen($Return->Command, USEDCHARSET), USEDCHARSET);
return $Return;
}
/*******************************
* name: ConditionsListToCommandInformation.
* note: connect conditions list to string.
* parameters: name array, value array, param array.
* return: CommandInformation.
*******************************
* @param array $Columns need to connect to the array.
* @param array $Values need to connect to the value description for array.
* @param array $Params need to connect to the param for value of array.
* @return CommandInformation
*******************************/
protected function ConditionsListToCommandInformation($Columns, $Values, $Params)
{
$Return = new CommandInformation();
if (!(is_array($Columns) && is_array($Values) && is_array($Params)))
return $Return;
for ($Index = 0; $Index < count($Columns); $Index++)
{
if ($Values[$Index] instanceof ISQLCommand)
{
$Command = call_user_func(array(&$Values[$Index], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return->Command .= " and ({$Columns[$Index]} = ({$Command->Command}))";
$this->MergeArray($Return->Paramer, $Command->Paramer);
}
else
{
if (is_null($Values[$Index]))
$Return->Command .= " and ({$Columns[$Index]})";
elseif (is_null($Params[$Index]))
$Return->Command .= " and ({$Columns[$Index]} is null)"; /// 2017-12-14: if value is null use this command.
else
$Return->Command .= " and ({$Columns[$Index]} = {$Values[$Index]})";
if (!is_null($Params[$Index]))
$this->MergeArray($Return->Paramer, $Params[$Index]);
}
}
$SubLen = mb_strlen(' and ', USEDCHARSET);
$Return->Command = mb_substr($Return->Command, $SubLen, mb_strlen($Return->Command, USEDCHARSET), USEDCHARSET);
return $Return;
}
/*******************************
* name: ValueFieldListToCommandInformation.
* note: connect source field array to string.
* parameters: name array, alia array.
* return: CommandInformation.
*******************************
* @param array $Columns need to connect to the array.
* @param array $Values need to connect to the value for field.
* @param array $Params need to connect to the param for field
* @return CommandInformation
*******************************/
protected function ValueFieldListToCommandInformation($Columns, $Values, $Params)
{
if ($Columns instanceof ISQLCommand)
return call_user_func(array(&$Columns, 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return = new CommandInformation();
if (!is_array($Columns))
return $Return;
for ($Index = 0; $Index < count($Columns); $Index++)
{
if ($Columns[$Index] instanceof ISQLCommand)
{
$Command = call_user_func(array(&$Columns[$Index], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return->Command .= ", {$Command->Command}";
$this->MergeArray($Return->Paramer, $Command->Paramer);
}
elseif (!is_null($Columns[$Index]))
$Return->Command .= ", {$Columns[$Index]}";
elseif (is_null($Params))
$Return->Command .= ', null';
if (!is_null($Values))
{
/// 2017-12-14: if value is null use this command.
if (!isset($Values[$Index]))
{
$Return->Command .= ' = null';
continue;
}
if ($Values[$Index] instanceof ISQLCommand)
{
$Command = call_user_func(array(&$Values[$Index], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return->Command .= " = ({$Command->Command})";
$this->MergeArray($Return->Paramer, $Command->Paramer);
}
elseif (!is_null($Values[$Index]))
$Return->Command .= " = {$Values[$Index]}";
}
if (!is_null($Params[$Index]))
$this->MergeArray($Return->Paramer, $Params[$Index]);
}
$SubLen = mb_strlen(', ', USEDCHARSET);
$Return->Command = mb_substr($Return->Command, $SubLen, mb_strlen($Return->Command, USEDCHARSET), USEDCHARSET);
return $Return;
}
/*******************************
* name: SourceListToCommandInformation.
* note: connect the union source list to CommandInformation array.
* parameters: array of union source.
* return: CommandInformation.
*******************************
* @param array $Sources need to union of the source.
* @return CommandInformation
*******************************/
protected function SourceListToCommandInformation($Sources)
{
$Return = new CommandInformation();
if ($Sources instanceof ISQLCommand)
{
$Return = call_user_func(array(&$Sources, 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return->Command = PHP_EOL . 'union all' . PHP_EOL . "({$Return->Command})";
}
elseif (is_string($Sources))
{
$Return->Command = PHP_EOL . 'union all' . PHP_EOL . "({$Sources})";
}
elseif (is_array($Sources))
{
for ($Index = 0; $Index < count($Sources); $Index++)
{
if ($Sources[$Index] instanceof ISQLCommand)
{
$Command = call_user_func(array(&$Sources[$Index], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Return->Command .= PHP_EOL . 'union all' . PHP_EOL . "({$Command->Command})";
$this->MergeArray($Return->Paramer, $Command->Paramer);
}
elseif (!is_null($Sources[$Index]))
$Return->Command .= PHP_EOL . 'union all' . PHP_EOL . "({$Sources[$Index]})";
}
}
return $Return;
}
/// =====================================================================================================================
protected function GetSelectColumns()
{
return $this->SelectFieldListToCommandInformation($this->DataFieldNames, $this->DataFieldAlias);
}
protected function GetSelectAliaColumns()
{
return $this->SelectFieldListToCommandInformation($this->DataFieldAlias, $this->DataFieldAlias);
}
protected function GetInternalSource()
{
return $this->SelectFieldListToCommandInformation($this->InternalSourceNames, $this->InternalSourceAlias);
}
// protected function GetExternalSource()
// {
// return $this->SelectFieldListToCommandInformation($this->ExternalSourceNames, $this->ExternalSourceAlias);
// }
protected function GetJoinSources($Index)
{
return $this->SelectFieldListToCommandInformation($this->JoinSourceNames[$Index], $this->JoinSourceAlias[$Index]);
}
protected function GetJoinConditions($Index)
{
return $this->ConditionsListToCommandInformation($this->JoinConditionColumn[$Index], $this->JoinConditionValues[$Index], $this->JoinConditionParams[$Index]);
}
protected function GetMergeJoinConditions()
{
return $this->ConditionsListToCommandInformation($this->MergeJoinConditionColumn, $this->MergeJoinConditionValues, $this->MergeJoinConditionParams);
}
protected function GetWhereConditions()
{
return $this->ConditionsListToCommandInformation($this->WhereConditionColumn, $this->WhereConditionValues, $this->WhereConditionParams);
}
protected function GetGroupColumns()
{
return $this->ValueFieldListToCommandInformation($this->GroupFieldList, null, null);
}
protected function GetHavingConditions()
{
return $this->ConditionsListToCommandInformation($this->HavingConditionColumn, $this->HavingConditionValues, $this->HavingConditionParams);
}
protected function GetOrderColumns()
{
return $this->SelectFieldListToCommandInformation($this->OrderFieldNames, $this->OrderFieldTypes);
}
protected function GetChangeFields()
{
if ($this->ChangeFields[0] instanceof ISQLCommand)
return $this->ValueFieldListToCommandInformation($this->ChangeFields[0], null, null);
else
return $this->ValueFieldListToCommandInformation($this->ChangeFields, null, null);
}
protected function GetChangeValues()
{
if ($this->ChangeValues[0] instanceof ISQLCommand)
return $this->ValueFieldListToCommandInformation($this->ChangeValues[0], null, $this->ChangeParams);
else
return $this->ValueFieldListToCommandInformation($this->ChangeValues, null, $this->ChangeParams);
}
protected function GetChangeAllColumns()
{
return $this->ValueFieldListToCommandInformation($this->ChangeFields, $this->ChangeValues, $this->ChangeParams);
}
protected function GetUnionSources()
{
return $this->SourceListToCommandInformation($this->UnionSourceNames);
}
/// =====================================================================================================================
public function GetDataFieldNames()
{
return $this->DataFieldNames;
}
public function GetDataFieldAlias()
{
return $this->DataFieldAlias;
}
/// =====================================================================================================================
/*******************************
* name: GetIdentifiers.
* note: processing the identifier.
* parameters: identifier, quoted, Special char.
* return: processed identifier.
*******************************
* @param string $Identifiers need processing identifier
* @param bool $Quoted need quoted?
* @param array|mixed $Specialchar need special treatment string.
* @return string
*******************************/
public function GetIdentifiers($Identifiers, $Quoted = false, $Specialchar = null)
{
if (is_null($Identifiers) || '' == $Identifiers)
{
return '';
}
elseif ($Quoted)
{
if (method_exists($this->Connection, 'Quote'))
return $this->Connection->Quote($Identifiers);
else
{
$Length = mb_strlen($Identifiers, USEDCHARSET);
if ("'" == mb_substr($Identifiers, 0, 1, USEDCHARSET))
{
$Length--;
$Identifiers = mb_substr($Identifiers, 1, $Length, USEDCHARSET);
}
if ("'" == mb_substr($Identifiers, $Length - 1, 1, USEDCHARSET))
{
$Length--;
$Identifiers = mb_substr($Identifiers, 0, $Length, USEDCHARSET);
}
return "'" . str_replace("'", "''", $Identifiers) . "'";
}
}
else
{
if (!empty($Specialchar))
{
$Specialchar = (array)$Specialchar;
foreach ($Specialchar as $Key => $Value)
{
$Identifiers = str_replace($Value, $this->RefCharRight . $Value . $this->RefCharLeft, $Identifiers);
}
}
return $this->RefCharLeft . $Identifiers . $this->RefCharRight;
}
}
/*******************************
* name: GetObjectName.
* note: processing the objectname identifier.
* parameters: objectname.
* return: processed object name.
*******************************
* @param string $ObjectName need processing identifier
* @return string
*******************************/
protected function GetObjectName($ObjectName)
{
return $this->GetIdentifiers($ObjectName, false, array('.', ',', ' '));
}
/*******************************
* name: RemoveReferenceCharacter.
* note: remove the identifier reference character.
* parameters: identifier.
* return: identifier.
*******************************
* @param string $Identifiers need processing identifier
* @return string
*******************************/
protected function RemoveReferenceCharacter($Identifiers)
{
if (is_object($Identifiers))
{
$Reflect = new ReflectionClass($Identifiers);
$Properties = $Reflect->GetProperties(ReflectionProperty::IS_PUBLIC);
foreach ($Properties as $Property)
{
//$Name = $Property->GetName();
$Value = $Property->GetValue($Identifiers);
$Value = $this->RemoveReferenceCharacter($Value);
$Property->SetValue($Identifiers, $Value);
}
}
elseif (is_array($Identifiers))
{
foreach($Identifiers as $Key => $Value)
{
$Identifiers->$Key = $this->RemoveReferenceCharacter($Value);
}
}
else
{
$Identifiers = str_replace($this->RefCharLeft, '', $Identifiers);
$Identifiers = str_replace($this->RefCharRight, '', $Identifiers);
}
return $Identifiers;
}
/*******************************
* name: GetSelectCommandInformation.
* note: get the select command information(not support page).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetSelectCommandInformation()
{
$Return = new CommandInformation();
$Fields = $this->GetSelectColumns();
/// select 部分
$Return->Command = "select {$Fields->Command}";
$Return->Paramer = $Fields->Paramer;
/// from 部分
if (!empty($this->InternalSourceNames))
{
$Tables = $this->GetInternalSource();
$Return->Command .= " from {$Tables->Command}";
$this->MergeArray($Return->Paramer, $Tables->Paramer);
}
/// join 部分
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
/// where 部分
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
/// group by 和 having 部分
if (!empty($this->GroupFieldList))
{
$GroupFields = $this->GetGroupColumns();
$Return->Command .= " group by {$GroupFields->Command}";
if (!empty($this->HavingConditionColumn))
{
$HavingCondition = $this->GetHavingConditions();
$Return->Command .= " having {$HavingCondition->Command}";
$this->MergeArray($Return->Paramer, $HavingCondition->Paramer);
}
}
/// order by 部分
if (!empty($this->OrderFieldNames))
{
$OrderFields = $this->GetOrderColumns();
$Return->Command .= " order by {$OrderFields->Command}";
}
return $Return;
}
/*******************************
* name: GetUnionCommandInformation.
* note: get the select union command information.
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetUnionCommandInformation()
{
return $this->GetUnionSources();
}
/*******************************
* name: GetInsertCommandInformation.
* note: get the insert command information.
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetInsertCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = /** @lang text */ "insert into {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
$Fields = $this->GetChangeFields();
$Values = $this->GetChangeValues();
/// 如果包含select表示则表示是一个子查询, 那么就不用values包裹了.
if (mb_stristr($Values->Command, 'select', false, USEDCHARSET))
$Return->Command .= " ({$Fields->Command}) {$Values->Command}";
else
$Return->Command .= " ({$Fields->Command}) values ({$Values->Command})";
$this->MergeArray($Return->Paramer, $Fields->Paramer);
$this->MergeArray($Return->Paramer, $Values->Paramer);
return $Return;
}
/*******************************
* name: GetUpdateCommandInformation.
* note: get the update command information(not support join method).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetUpdateCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = "update {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
$Fields = $this->GetChangeAllColumns();
$Return->Command .= " set {$Fields->Command}";
$this->MergeArray($Return->Paramer, $Fields->Paramer);
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
return $Return;
}
/*******************************
* name: GetDeleteCommandInformation.
* note: get the delete command information(not support join method).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetDeleteCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = /** @lang text */ "delete from {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
return $Return;
}
/*******************************
* name: GetTruncCommandInformation.
* note: get the truncate table command information.
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetTruncCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = "truncate table {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
return $Return;
}
/*******************************
* name: GetMergeCommandInformation.
* note: get the merge into command information(not implement).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
abstract protected function GetMergeCommandInformation();
/*******************************
* name: GetCallStoredProcedureCommandInformation.
* note: get the call stored procedure command information(not implement).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetCallStoredProcedureCommandInformation()
{
$Return = new CommandInformation();
$Return->Command = "call {$this->StoredProcedureName}";
$Values = $this->GetChangeValues();
if (!empty($Values))
{
$Return->Command .= "($Values->Command)";
$this->MergeArray($Return->Paramer, $Values->Paramer);
}
return $Return;
}
/*******************************
* name: MergeArray.
* note: merge array.
* parameters: array, sub.
* return: true if the method call succeeded, false otherwise.
*******************************
* @param array $Array
* @param array $SubArray
* @return bool
*******************************/
public function MergeArray(&$Array, $SubArray = array())
{
if (!is_array($Array))
return false;
foreach ((array)$SubArray as $Key => $Value)
{
array_push($Array, $Value);
}
return true;
}
/*******************************
* name: From.
* note: set the datasource or table information.
* parameters: datasource or table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function From()
{
call_user_func_array(array(&$this, 'ReceiveInternalSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: InnerJoin.
* note: set the inner join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function InnerJoin()
{
$Index = $this->JoinCount++;
$this->JoinType[$Index] = JOINTYPE_INNER;
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
call_user_func_array(array(&$this, 'ReceiveJoinSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: LeftJoin.
* note: set the left join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function LeftJoin()
{
$Index = $this->JoinCount++;
$this->JoinType[$Index] = JOINTYPE_LEFT;
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
call_user_func_array(array(&$this, 'ReceiveJoinSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: RightJoin.
* note: set the right join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function RightJoin()
{
$Index = $this->JoinCount++;
$this->JoinType[$Index] = JOINTYPE_RIGHT;
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
call_user_func_array(array(&$this, 'ReceiveJoinSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: OuterJoin.
* note: set the outer join table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function OuterJoin()
{
$Index = $this->JoinCount++;
$this->JoinType[$Index] = JOINTYPE_OUTER;
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
call_user_func_array(array(&$this, 'ReceiveJoinSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: On.
* note: set the join condition information.
* parameters: join condition.
* return: always return locale instance.
*******************************
* @param array|string
* @return ISQLCommand
*******************************/
public function On()
{
call_user_func_array(array(&$this, 'ReceiveJoinCondition'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: MergeOn.
* note: set the merge condition information.
* parameters: merge condition.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function MergeOn()
{
call_user_func_array(array(&$this, 'ReceiveMergeJoinCondition'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Union.
* note: set the union object or sql command.
* parameters: union mixed.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function Union()
{
call_user_func_array(array(&$this, 'ReceiveUnionSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: BindParameters.
* note: bind other parameters of sql command needed.
* parameters: needed bind parameter list.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string
* @return ISQLCommand
*******************************/
public function BindParameters()
{
call_user_func_array(array(&$this, 'ReceiveBindParameters'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Where.
* note: set the where condition information.
* parameters: where condition.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Where()
{
//array_walk($Args, create_function('&$Value, $Key, $Sender', '$Value = $Sender->ProcessCondition($Value);'), $this);
call_user_func_array(array(&$this, 'ReceiveWhereCondition'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: GroupBy.
* note: set the group expression information.
* parameters: group expression.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function GroupBy()
{
call_user_func_array(array(&$this, 'ReceiveGroupExpression'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Having.
* note: set the having condition information by group field.
* parameters: having condition.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Having()
{
call_user_func_array(array(&$this, 'ReceiveHavingCondition'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: OrderBy.
* note: set the order information.
* parameters: order expression.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function OrderBy()
{
call_user_func_array(array(&$this, 'ReceiveOrderExpression'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: WithPage.
* note: set paging select information.
* parameters: PageIndex, PageSize.
* return: always return locale instance.
*******************************
* @param int $PageIndex
* @param int $PageSize
* @return ISQLCommand
*******************************/
public function WithPage($PageIndex, $PageSize)
{
$this->PageIndex = $PageIndex;
$this->PageSize = $PageSize;
return $this;
}
/*******************************
* name: Limit.
* note: set select max record count.
* parameters: maxcount.
* return: always return locale instance.
*******************************
* @param int $MaxCount
* @return ISQLCommand
*******************************/
public function Limit($MaxCount)
{
$this->MaxRequestCount = $MaxCount;
return $this;
}
/*******************************
* name: Fields.
* note: set update column list.
* parameters: column list.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Fields()
{
call_user_func_array(array(&$this, 'ReceiveInternalColumn'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Values.
* note: set update value list.
* parameters: value list.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return array
*******************************/
public function Values()
{
call_user_func_array(array(&$this, 'ReceiveExternalColumn'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Select.
* note: set the select field information.
* parameters: field.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Select()
{
$this->CommandType = COMMANDTYPE_SELECT;
call_user_func_array(array(&$this, 'ReceiveSelectColumn'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Insert.
* note: set the insert table or datasource information.
* parameters: table or datasource.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Insert()
{
$this->CommandType = COMMANDTYPE_INSERT;
call_user_func_array(array(&$this, 'ReceiveInternalSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Update.
* note: set the update table or datasource information.
* parameters: table or datasource.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Update()
{
$this->CommandType = COMMANDTYPE_UPDATE;
call_user_func_array(array(&$this, 'ReceiveInternalSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: delete.
* note: set the delete table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Delete()
{
$this->CommandType = COMMANDTYPE_DELETE;
call_user_func_array(array(&$this, 'ReceiveInternalSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Truncate.
* note: set the truncate table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Truncate()
{
$this->CommandType = COMMANDTYPE_TRUNC;
call_user_func_array(array(&$this, 'ReceiveInternalSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Merge.
* note: set the merge table information.
* parameters: table.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function Merge()
{
$this->CommandType = COMMANDTYPE_MERGE;
call_user_func_array(array(&$this, 'ReceiveInternalSource'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/*******************************
* name: Merge.
* note: set call stored procedure name.
* parameters: procedure name.
* return: always return locale instance.
*******************************
* @param ISQLCommand|string|array|mixed
* @return ISQLCommand
*******************************/
public function CallStoredProcedure()
{
$this->CommandType = COMMANDTYPE_CALLSTOREDPROCEDURE;
call_user_func_array(array(&$this, 'ReceiveStoredProcedureName'), func_get_args()); /// must pass &$xxx in php4.x
return $this;
}
/**
* 2016-12-08增加
* @note 字符串转换为日期型的表达式
* @param string $StringTime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function String2DatetimeFormat($StringTime, $Quoted = true)
{
if ($Quoted)
$StringTime = $this->GetIdentifiers($StringTime, true);
return $StringTime;
}
/**
* 2016-12-08增加
* @note 日期转换为字符串型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2StringFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return $Datetime;
}
/**
* 2016-12-08增加
* @note 时间戳转换为日期型的表达式
* @param string $Timestamp 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Timestamp2DatetimeFormat($Timestamp)
{
return $Timestamp;
}
/**
* 2016-12-08增加
* @note 日期转换为时间戳型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2TimestampFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return $Datetime;
}
/**
* 2016-12-08增加
* @note 浮点转换为字符串型的表达式
* @param string $Float 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Float2StringFormat($Float)
{
return $Float;
}
/**
* 2016-01-16增加
* @note 获取当前服务器系统时间(或表达式)
* @param bool $IsRaw 是否返回数据库表达式
* @return string
* @note 应俊
*/
public function GetSystemTime($IsRaw = false)
{
return date('Y-m-d H:i:s');
}
/*******************************
* name: GetConnection.
* note: get database helper.
* parameters: nan.
* return: the database helper object.
*******************************
* @return IPDOHelper
*******************************/
public function GetConnection()
{
return $this->Connection;
}
/*******************************
* name: GetCommandInformation.
* note: get sql command string.
* parameters: nan.
* return: sql command and parameter list as array if the method call succeeded, null otherwise.
*******************************
* @return CommandInformation
*******************************/
public function GetCommandInformation()
{
$Return = null;
switch ($this->CommandType)
{
/// select 语句(未实现分页查询)
case COMMANDTYPE_SELECT:
/// 获取基础的查询
$Return = $this->GetSelectCommandInformation();
/// 获取union链接的查询
$Union = $this->GetUnionCommandInformation();
if (($Union instanceof CommandInformation) && !empty($Union->Command))
{
$Return->Command = "({$Return->Command})";
$Return->Merge($Union);
}
break;
/// insert 语句(已支持from子句)
case COMMANDTYPE_INSERT:
$Return = $this->GetInsertCommandInformation();
break;
/// update 语句(不支持into关联语句)
case COMMANDTYPE_UPDATE:
$Return = $this->GetUpdateCommandInformation();
break;
/// delete 语句(不支持into关联语句)
case COMMANDTYPE_DELETE:
$Return = $this->GetDeleteCommandInformation();
break;
/// truncate 语句
case COMMANDTYPE_TRUNC:
$Return = $this->GetTruncCommandInformation();
break;
/// merge into 语句(由子类实现)
case COMMANDTYPE_MERGE:
$Return = $this->GetMergeCommandInformation();
break;
/// call 语句(调用存储过程、函数)
case COMMANDTYPE_CALLSTOREDPROCEDURE:
$Return = $this->GetCallStoredProcedureCommandInformation();
break;
/// 其他语句
default:
$Return = null;
break;
}
if ($Return)
$this->MergeArray($Return->Paramer, $this->OtherParameterList);
return $Return;
}
/*******************************
* name: Request.
* note: request data from database(recordset was returned).
* parameters: sql command, parameter list.
* return: recordset as array if the method call succeeded, null otherwise.
*******************************
* prarm clearmembers
*******************************
* param callable $Callable
* param string $SqlCommand
* param mixed $Parameters...
* @return mixed|null
*******************************/
public function Request(/* $Callable, $SqlCommand, $Parameters, ... */)
{
$Return = null;
$Param = func_get_args();
$Count = func_num_args();
if (0 == $Count)
$Param = array(true);
if (is_bool($Param[0]))
{
if ($Command = $this->GetCommandInformation())
{
/** @noinspection PhpIncludeInspection */
//$Return = $this->Connection->Request($Command->Command, $Command->Paramer);
$Return = call_user_func_array(array(&$this->Connection, 'Request'), array($Command->Command, $Command->Paramer)); /// must pass &$xxx in php4.x
if ($Param[0])
$this->ClearMethod();
}
}
else
$Return = call_user_func_array(array(&$this->Connection, 'Request'), $Param); /// must pass &$xxx in php4.x
return $Return;
}
/*******************************
* name: Execute.
* note: execute command from database(no recordset was returned).
* parameters: sql command, parameter list
* return: true if the method call succeeded, false otherwise.
*******************************
* prarm clearmembers
*******************************
* param string $SqlCommand
* param mixed $Parameters...
* @return bool
*******************************/
public function Execute(/* sqlcommand, parameters, ... */)
{
$Return = null;
$Param = func_get_args();
$Count = func_num_args();
if (0 == $Count)
$Param = array(true);
if (is_bool($Param[0]))
{
if ($Command = $this->GetCommandInformation())
{
/** @noinspection PhpIncludeInspection */
//$Return = $this->Connection->Execute($Command->Command, $Command->Paramer);
$Return = call_user_func_array(array(&$this->Connection, 'Execute'), array($Command->Command, $Command->Paramer)); /// must pass &$xxx in php4.x
if ($Param[0])
$this->ClearMethod();
}
}
else
$Return = call_user_func_array(array(&$this->Connection, 'Execute'), $Param); /// must pass &$xxx in php4.x
return $Return;
}
}
class ORACLECommand extends SQLCommand
{
/*******************************
* name: __construct.
* note: the construct function for class.
* parameters: Connection for PDOHelper.
* return: new object if the method call succeeded, null otherwise.
*******************************
* SQLCommand constructor.
* @param IPDOHelper $Connection
* @throws Exception
*******************************/
public function __construct($Connection)
{
parent::__construct($Connection);
//$this->Connection = new ORACLEHelper();
$this->SetReferenceCharacter('', '');
}
/*******************************
* name: ClearMember.
* note: clear all member for class.
* parameters: nan.
* return: nan.
*******************************
*
*******************************/
public function ClearMethod()
{
parent::ClearMethod();
$this->From('dual');
}
/*******************************
* name: GetSelectCommandInformation.
* note: get the select command string(the page method was support).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetSelectCommandInformation()
{
$Return = new CommandInformation();
/// 限制记录条数
$MaxRequestCount = intval($this->MaxRequestCount);
$Limit = $MaxRequestCount > 0 ? "(rownum <= {$MaxRequestCount})" : null;
if (0 == $this->PageIndex || 0 == $this->PageSize)
{
$Fields = $this->GetSelectColumns();
/// select 部分
$Return->Command = "select {$Fields->Command}";
$Return->Paramer = $Fields->Paramer;
/// from 部分
if (!empty($this->InternalSourceNames))
{
$Tables = $this->GetInternalSource();
$Return->Command .= " from {$Tables->Command}";
$this->MergeArray($Return->Paramer, $Tables->Paramer);
}
/// join 部分
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
/// where 部分
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}" . (!empty($Limit) ? " and {$Limit}" : '');
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
elseif (!empty($Limit))
{
$Return->Command .= " where {$Limit}";
}
/// group by 部分
if (!empty($this->GroupFieldList))
{
$GroupFields = $this->GetGroupColumns();
$Return->Command .= " group by {$GroupFields->Command}";
if (!empty($this->HavingConditionColumn))
{
$HavingCondition = $this->GetHavingConditions();
$Return->Command .= " having {$HavingCondition->Command}";
$this->MergeArray($Return->Paramer, $HavingCondition->Paramer);
}
}
/// order by 部分
if (!empty($this->OrderFieldNames))
{
$OrderFields = $this->GetOrderColumns();
$Return->Command .= " order by {$OrderFields->Command}";
}
}
else
{
/// 处理分页处
$Start = (intval(@$this->PageIndex) - 1) * intval(@$this->PageSize) + 1; /// 起始序号
$Stop = intval(@$this->PageIndex) * intval(@$this->PageSize); /// 终止序号
if (0 == $MaxRequestCount || $Stop < $MaxRequestCount)
$Limit = "(rownum <= {$Stop})";
$SelectColumns = $this->GetSelectColumns();
$OrderColumns = $this->GetOrderColumns();
$SortField = $this->GetIdentifiers($this->CreateRandString('nfs_'));
/// select 部分(order by放在这里用于开窗函数row_number()使用)
$Return->Command = "select {$SelectColumns->Command}, row_number() over(order by {$OrderColumns->Command}) {$SortField}";
$Return->Paramer = $SelectColumns->Paramer;
/// from 部分
if (!empty($this->InternalSourceNames))
{
$Tables = $this->GetInternalSource();
$Return->Command .= " from {$Tables->Command}";
$this->MergeArray($Return->Paramer, $Tables->Paramer);
}
else
{
$Return->Command .= " from dual";
}
/// join 部分
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
/// where 部分
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}" . (!empty($Limit) ? " and {$Limit}" : '');
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
elseif (!empty($Limit))
{
$Return->Command .= " where {$Limit}";
}
/// group by 部分
if (!empty($this->GroupFieldList))
{
$GroupFields = $this->GetGroupColumns();
$Return->Command .= " group by {$GroupFields->Command}";
if (!empty($this->HavingConditionColumn))
{
$HavingCondition = $this->GetHavingConditions();
$Return->Command .= " having {$HavingCondition->Command}";
$this->MergeArray($Return->Paramer, $HavingCondition->Paramer);
}
}
$SortTable = $this->GetIdentifiers($this->CreateRandString('nst_'));
$Alias = $this->GetSelectAliaColumns();
$Return->Command = /** @lang text */ "select {$Alias->Command} from ({$Return->Command}) {$SortTable} where ({$SortField} between {$Start} and {$Stop})";
}
return $Return;
}
/*******************************
* name: GetMergeCommandInformation.
* note: get the merge into command string(implemented. but delete not support.).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetMergeCommandInformation()
{
$Return = new CommandInformation();
/// merge into 表名 别名
/// using 源记录集 别名
/// on (关联关系)
/// when matched then
/// 修改
/// when not matched then
/// 新增
/// 目标表别名
$Target = $this->GetIdentifiers($this->CreateRandString('ndt_'));
/// 源数据别名
$Source = $this->GetIdentifiers($this->CreateRandString('nds_'));
/// 要插入的目标表
$Table = $this->GetInternalSource();
/// 要查询的字段(源数据集的字段)
$SelectColumn = '';
/// 源数据集
$SourceFields = '';
/// 目标数据集
$TargetFields = '';
/// 合并关系
$UpdateFields = '';
/// 关联关系
$JoinCondition = $this->GetMergeJoinConditions();
/// 从关联关系中提取出需要忽略的字段
$Ignore = explode(' ', str_replace('=', ' ', $this->RemoveReferenceCharacter($JoinCondition->Command)));
if ($this->ChangeValues[0] instanceof ISQLCommand)
{
$SelectColumn = call_user_func(array(&$this->ChangeValues[0], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Fields = call_user_func(array(&$this->ChangeValues[0], 'GetDataFieldAlias')); /// must pass &$xxx in php4.x
for ($Index = 0; $Index < count($this->ChangeFields); $Index++)
{
$SourceField = $Fields[$Index];
$TargetField = $this->ChangeFields[$Index];
$SourceFields .= ", {$Source}.{$SourceField}";
$TargetFields .= ", {$Target}.{$TargetField}";
$UpdateFields .= ", {$Target}.{$TargetField} = {$Source}.{$SourceField}";
}
$SubLen = mb_strlen(', ', USEDCHARSET);
if (!empty($SourceFields))
$SourceFields = mb_substr($SourceFields, $SubLen, mb_strlen($SourceFields, USEDCHARSET), USEDCHARSET);
if (!empty($TargetFields))
$TargetFields = mb_substr($TargetFields, $SubLen, mb_strlen($TargetFields, USEDCHARSET), USEDCHARSET);
if (!empty($UpdateFields))
$UpdateFields = mb_substr($UpdateFields, $SubLen, mb_strlen($UpdateFields, USEDCHARSET), USEDCHARSET);
$SelectParams = $SelectColumn->Paramer;
$SelectColumn = "({$SelectColumn->Command}) {$Source}";
}
else
{
$Fields = $this->ChangeFields;
$Values = $this->ChangeValues;
for ($Index = 0; $Index < count($this->ChangeFields); $Index++)
{
$Field = $Fields[$Index];
$Value = $Values[$Index];
$SelectColumn .= ", {$Value} {$Field}";
$SourceFields .= ", {$Source}.{$Field}";
$TargetFields .= ", {$Target}.{$Field}";
/// 这里要忽略掉关联关系中参照的字段。
//if (!mb_strstr($JoinCondition->Command, $Field, false, USEDCHARSET))
if (!in_array($this->RemoveReferenceCharacter($Field), $Ignore))
$UpdateFields .= ", {$Target}.{$Field} = {$Source}.{$Field}";
}
$SubLen = mb_strlen(', ', USEDCHARSET);
if (!empty($SelectColumn))
$SelectColumn = mb_substr($SelectColumn, $SubLen, mb_strlen($SelectColumn, USEDCHARSET), USEDCHARSET);
if (!empty($SourceFields))
$SourceFields = mb_substr($SourceFields, $SubLen, mb_strlen($SourceFields, USEDCHARSET), USEDCHARSET);
if (!empty($TargetFields))
$TargetFields = mb_substr($TargetFields, $SubLen, mb_strlen($TargetFields, USEDCHARSET), USEDCHARSET);
if (!empty($UpdateFields))
$UpdateFields = mb_substr($UpdateFields, $SubLen, mb_strlen($UpdateFields, USEDCHARSET), USEDCHARSET);
$SelectParams = $this->ChangeParams;
$SelectColumn = "(select {$SelectColumn} from dual) {$Source}";
}
$Return->Command =
"merge into {$Table->Command} {$Target}" . PHP_EOL .
"using {$SelectColumn}" . PHP_EOL .
"on ({$JoinCondition->Command})" . PHP_EOL .
"when matched then" . PHP_EOL .
" update set {$UpdateFields}" . PHP_EOL .
"when not matched then" . PHP_EOL .
" insert" . PHP_EOL .
" ({$TargetFields})" . PHP_EOL .
" values" . PHP_EOL .
" ({$SourceFields})";
$this->MergeArray($Return->Paramer, $Table->Paramer);
$this->MergeArray($Return->Paramer, $SelectParams);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
return $Return;
}
/**
* 2016-12-08增加
* @note 字符串转换为日期型的表达式
* @param string $StringTime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function String2DatetimeFormat($StringTime, $Quoted = true)
{
if ($Quoted)
$StringTime = $this->GetIdentifiers($StringTime, true);
return "(to_date({$StringTime}, 'yyyy-mm-dd hh24:mi:ss'))";
}
/**
* 2016-12-08增加
* @note 日期转换为字符串型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2StringFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return "(to_char({$Datetime}, 'yyyy-mm-dd hh24:mi:ss'))";
}
/**
* 2016-12-08增加
* @note 时间戳转换为日期型的表达式
* @param string $Timestamp 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Timestamp2DatetimeFormat($Timestamp)
{
return "(to_date('19700101', 'yyyymmdd') + {$Timestamp} / 86400 + to_number(substr(tz_offset(sessiontimezone), 1, 3)) / 24)";
}
/**
* 2016-12-08增加
* @note 日期转换为时间戳型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2TimestampFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return "((to_date({$Datetime}, 'yyyy-mm-dd hh24:mi:ss') - to_date('19700101', 'yyyymmdd')) * 86400 - to_number(substr(tz_offset(sessiontimezone), 1, 3)) * 3600)";
}
/**
* 2016-12-08增加
* @note 浮点转换为字符串型的表达式
* @param string $Float 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Float2StringFormat($Float)
{
return "(to_char({$Float}, 'fm99999990.00'))";
}
/**
* 2016-01-16增加
* @note 获取当前服务器系统时间(或表达式)
* @param bool $IsRaw 是否返回数据库表达式
* @return string
* @note 应俊
*/
public function GetSystemTime($IsRaw = false)
{
if ($IsRaw)
return 'sysdate';
else
return parent::GetSystemTime($IsRaw);
}
}
class SQLSRVCommand extends SQLCommand
{
/*******************************
* name: __construct.
* note: the construct function for class.
* parameters: Connection for PDOHelper.
* return: new object if the method call succeeded, null otherwise.
*******************************
* SQLCommand constructor.
* @param IPDOHelper $Connection
* @throws Exception
*******************************/
public function __construct($Connection)
{
parent::__construct($Connection);
$this->SetReferenceCharacter('[', ']');
}
/*******************************
* name: GetSelectCommandInformation.
* note: get the select command string(the page method was support).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetSelectCommandInformation()
{
$Return = new CommandInformation();
/// 限定记录条数
$MaxRequestCount = intval($this->MaxRequestCount);
$Limit = $MaxRequestCount > 0 ? " top {$MaxRequestCount} " : ' ';
if (0 == $this->PageIndex || 0 == $this->PageSize)
{
$Fields = $this->GetSelectColumns();
/// select 部分
$Return->Command = "select{$Limit}{$Fields->Command}";
$Return->Paramer = $Fields->Paramer;
/// from 部分
if (!empty($this->InternalSourceNames))
{
$Tables = $this->GetInternalSource();
$Return->Command .= " from {$Tables->Command}";
$this->MergeArray($Return->Paramer, $Tables->Paramer);
}
/// join 部分
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
/// where 部分
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
/// group by 和 having 部分
if (!empty($this->GroupFieldList))
{
$GroupFields = $this->GetGroupColumns();
$Return->Command .= " group by {$GroupFields->Command}";
if (!empty($this->HavingConditionColumn))
{
$HavingCondition = $this->GetHavingConditions();
$Return->Command .= " having {$HavingCondition->Command}";
$this->MergeArray($Return->Paramer, $HavingCondition->Paramer);
}
}
/// order 部分
if (!empty($this->OrderFieldNames))
{
$OrderFields = $this->GetOrderColumns();
$Return->Command .= " order by {$OrderFields->Command}";
}
}
else
{
/// 处理分页处
$Start = (intval(@$this->PageIndex) - 1) * intval(@$this->PageSize) + 1; /// 起始序号
$Stop = intval(@$this->PageIndex) * intval(@$this->PageSize); /// 终止序号
if (0 == $MaxRequestCount || $Stop < $MaxRequestCount)
$Limit = " top {$Stop} ";
$SelectColumns = $this->GetSelectColumns();
$OrderColumns = $this->GetOrderColumns();
$SortField = $this->GetIdentifiers($this->CreateRandString('nfs_'));
/// select 部分(order排序放在这里用于row_number函数使用)
$Return->Command = "select{$Limit}{$SelectColumns->Command}, row_number() over(order by {$OrderColumns->Command}) {$SortField}";
$Return->Paramer = $SelectColumns->Paramer;
/// from 部分
if (!empty($this->InternalSourceNames))
{
$Tables = $this->GetInternalSource();
$Return->Command .= " from {$Tables->Command}";
$this->MergeArray($Return->Paramer, $Tables->Paramer);
}
/// join 部分
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
/// where 部分
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
/// group by 和 having 部分
if (!empty($this->GroupFieldList))
{
$GroupFields = $this->GetGroupColumns();
$Return->Command .= " group by {$GroupFields->Command}";
if (!empty($this->HavingConditionColumn))
{
$HavingCondition = $this->GetHavingConditions();
$Return->Command .= " having {$HavingCondition->Command}";
$this->MergeArray($Return->Paramer, $HavingCondition->Paramer);
}
}
$SortTable = $this->GetIdentifiers($this->CreateRandString('nst_'));
$Alias = $this->GetSelectAliaColumns();
$Return->Command = /** @lang text */ "select {$Alias->Command} from ({$Return->Command}) {$SortTable} where ({$SortField} between {$Start} and {$Stop})";
}
return $Return;
}
/*******************************
* name: GetUpdateCommandInformation.
* note: get the update command string(the join method was support).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetUpdateCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = "update {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
$Fields = $this->GetChangeAllColumns();
$Return->Command .= " set {$Fields->Command}";
$this->MergeArray($Return->Paramer, $Fields->Paramer);
if (!empty($this->InternalSourceNames))
{
$Tables = $this->GetInternalSource();
$Return->Command .= " from {$Tables->Command}";
$this->MergeArray($Return->Paramer, $Tables->Paramer);
}
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
return $Return;
}
/*******************************
* name: GetDeleteCommandInformation.
* note: get the delete command string(the join method was support).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetDeleteCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = /** @lang text */ "delete from {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
for ($Index = 0; $Index < $this->JoinCount; $Index++)
{
if (!empty($this->JoinType[$Index]))
{
$Joins = $this->GetJoinSources($Index);
$JoinCondition = $this->GetJoinConditions($Index);
switch ($this->JoinType[$Index])
{
case JOINTYPE_INNER:
{
$Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_LEFT:
{
$Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_RIGHT:
{
$Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
case JOINTYPE_OUTER:
{
$Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
break;
}
default:
{
$this->JoinSourceNames[$Index] = array();
$this->JoinSourceAlias[$Index] = array();
$this->JoinConditionColumn[$Index] = array();
$this->JoinConditionValues[$Index] = array();
$this->JoinConditionParams[$Index] = array();
break;
}
}
$this->MergeArray($Return->Paramer, $Joins->Paramer);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
}
}
if (!empty($this->WhereConditionColumn))
{
$WhereCondition = $this->GetWhereConditions();
$Return->Command .= " where {$WhereCondition->Command}";
$this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
}
return $Return;
}
/*******************************
* name: GetMergeCommandInformation(implemented. but delete not support.).
* note: get the merge into command string.
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetMergeCommandInformation()
{
$Return = new CommandInformation();
/// merge into 表名 别名
/// using 源记录集 别名
/// on (关联关系)
/// when matched then
/// 修改
/// when not matched then
/// 新增
/// 目标表别名
$Target = $this->GetIdentifiers($this->CreateRandString('ndt_'));
/// 源数据别名
$Source = $this->GetIdentifiers($this->CreateRandString('nds_'));
/// 要插入的目标表
$Table = $this->GetInternalSource();
/// 要查询的字段(源数据集的字段)
$SelectColumn = '';
/// 源数据集
$SourceFields = '';
/// 目标数据集
$TargetFields = '';
/// 合并关系
$UpdateFields = '';
/// 关联关系
$JoinCondition = $this->GetMergeJoinConditions();
/// 从关联关系中提取出需要忽略的字段
$Ignore = explode(' ', str_replace('=', ' ', $this->RemoveReferenceCharacter($JoinCondition->Command)));
if ($this->ChangeValues[0] instanceof ISQLCommand)
{
$SelectColumn = call_user_func(array(&$this->ChangeValues[0], 'GetCommandInformation')); /// must pass &$xxx in php4.x
$Fields = call_user_func(array(&$this->ChangeValues[0], 'GetDataFieldAlias')); /// must pass &$xxx in php4.x
for ($Index = 0; $Index < count($this->ChangeFields); $Index++)
{
$SourceField = $Fields[$Index];
$TargetField = $this->ChangeFields[$Index];
$SourceFields .= ", {$Source}.{$SourceField}";
$TargetFields .= ", {$Target}.{$TargetField}";
$UpdateFields .= ", {$Target}.{$TargetField} = {$Source}.{$SourceField}";
}
$SubLen = mb_strlen(', ', USEDCHARSET);
if (!empty($SourceFields))
$SourceFields = mb_substr($SourceFields, $SubLen, mb_strlen($SourceFields, USEDCHARSET), USEDCHARSET);
if (!empty($TargetFields))
$TargetFields = mb_substr($TargetFields, $SubLen, mb_strlen($TargetFields, USEDCHARSET), USEDCHARSET);
if (!empty($UpdateFields))
$UpdateFields = mb_substr($UpdateFields, $SubLen, mb_strlen($UpdateFields, USEDCHARSET), USEDCHARSET);
$SelectParams = $SelectColumn->Paramer;
$SelectColumn = "({$SelectColumn->Command}) {$Source}";
}
else
{
$Fields = $this->ChangeFields;
$Values = $this->ChangeValues;
for ($Index = 0; $Index < count($this->ChangeFields); $Index++)
{
$Field = $Fields[$Index];
$Value = $Values[$Index];
$SelectColumn .= ", {$Value} {$Field}";
$SourceFields .= ", {$Source}.{$Field}";
$TargetFields .= ", {$Target}.{$Field}";
/// 这里要忽略掉关联关系中参照的字段。
//if (!mb_strstr($JoinCondition->Command, $Field, false, USEDCHARSET))
if (!in_array($this->RemoveReferenceCharacter($Field), $Ignore))
$UpdateFields .= ", {$Target}.{$Field} = {$Source}.{$Field}";
}
$SubLen = mb_strlen(', ', USEDCHARSET);
if (!empty($SelectColumn))
$SelectColumn = mb_substr($SelectColumn, $SubLen, mb_strlen($SelectColumn, USEDCHARSET), USEDCHARSET);
if (!empty($SourceFields))
$SourceFields = mb_substr($SourceFields, $SubLen, mb_strlen($SourceFields, USEDCHARSET), USEDCHARSET);
if (!empty($TargetFields))
$TargetFields = mb_substr($TargetFields, $SubLen, mb_strlen($TargetFields, USEDCHARSET), USEDCHARSET);
if (!empty($UpdateFields))
$UpdateFields = mb_substr($UpdateFields, $SubLen, mb_strlen($UpdateFields, USEDCHARSET), USEDCHARSET);
$SelectParams = $this->ChangeParams;
$SelectColumn = "(select {$SelectColumn}) {$Source}";
}
$Return->Command =
"merge into {$Table->Command} {$Target}" . PHP_EOL .
"using {$SelectColumn}" . PHP_EOL .
"on ({$JoinCondition->Command})" . PHP_EOL .
"when matched then" . PHP_EOL .
" update set {$UpdateFields}" . PHP_EOL .
"when not matched then" . PHP_EOL .
" insert" . PHP_EOL .
" ({$TargetFields})" . PHP_EOL .
" values" . PHP_EOL .
" ({$SourceFields})";
$this->MergeArray($Return->Paramer, $Table->Paramer);
$this->MergeArray($Return->Paramer, $SelectParams);
$this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
return $Return;
}
/**
* 2016-12-08增加
* @note 字符串转换为日期型的表达式
* @param string $StringTime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function String2DatetimeFormat($StringTime, $Quoted = true)
{
if ($Quoted)
$StringTime = $this->GetIdentifiers($StringTime, true);
return "(convert(datetime, {$StringTime}, 120))";
}
/**
* 2016-12-08增加
* @note 日期转换为字符串型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2StringFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return "(convert(varchar, {$Datetime}, 120))";
}
/**
* 2016-12-08增加
* @note 时间戳转换为日期型的表达式
* @param string $Timestamp 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Timestamp2DatetimeFormat($Timestamp)
{
return "(dateadd(S, {$Timestamp} + 8 * 3600, '1970-01-01 00:00:00'))";
}
/**
* 2016-12-08增加
* @note 日期转换为时间戳型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2TimestampFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return "(datediff(S, '1970-01-01 00:00:00', {$Datetime}) - 8 * 3600)";
}
/**
* 2016-12-08增加
* @note 浮点转换为字符串型的表达式
* @param string $Float 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Float2StringFormat($Float)
{
return "(cast(convert(decimal(18, 2), {$Float}) as char))";
}
/**
* 2016-01-16增加
* @note 获取当前服务器系统时间(或表达式)
* @param bool $IsRaw 是否返回数据库表达式
* @return string
* @note 应俊
*/
public function GetSystemTime($IsRaw = false)
{
if ($IsRaw)
return 'getdate()';
else
return parent::GetSystemTime($IsRaw);
}
}
class MYSQLCommand extends SQLCommand
{
/*******************************
* name: __construct.
* note: the construct function for class.
* parameters: Connection for PDOHelper.
* return: new object if the method call succeeded, null otherwise.
*******************************
* SQLCommand constructor.
* @param IPDOHelper $Connection
* @throws Exception
*******************************/
public function __construct($Connection)
{
parent::__construct($Connection);
//$this->Connection = new ORACLEHelper();
$this->SetReferenceCharacter('`', '`');
}
/*******************************
* name: GetSelectCommandInformation.
* note: get the select command string(the page method was support).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetSelectCommandInformation()
{
$Return = parent::GetSelectCommandInformation();
if (0 != $this->PageIndex && 0 != $this->PageSize)
{
/// 处理分页处
$Offset = (intval(@$this->PageIndex) - 1) * intval(@$this->PageSize); /// 起始偏移
$PageSize = intval(@$this->PageSize); /// 记录条目
$MaxRequestCount = intval($this->MaxRequestCount);
if ($MaxRequestCount > 0 && $PageSize > intval($this->MaxRequestCount))
$PageSize = $this->MaxRequestCount;
$Return->Command .= " limit {$Offset}, {$PageSize}";
}
// $Return = new CommandInformation();
// /// 不分页
// if (0 == $this->PageIndex || 0 == $this->PageSize)
// {
// $Return = parent::GetSelectCommandInformation();
// }
// else
// {
// /// 处理分页处
// $Start = (intval(@$this->PageIndex) - 1) * intval(@$this->PageSize) + 1; /// 起始序号
// $Stop = intval(@$this->PageIndex) * intval(@$this->PageSize); /// 终止序号
// if ($Stop < intval($this->MaxRequestCount))
// $Limit = $Stop;
// else
// $Limit = $this->MaxRequestCount;
//
// $SelectColumns = $this->GetSelectColumns();
// $SortField = $this->GetIdentifiers($this->CreateRandString('nfs_'));
// $SortTable = $this->GetIdentifiers($this->CreateRandString('nst_'));
//
// /// select 部分(用全局变量@Index模拟row_number() over()函数来实现分页)
// $Return->Command = "select {$SelectColumns->Command}, @Index := @Index + 1 {$SortField}";
// $Return->Paramer = $SelectColumns->Paramer;
//
// /// from 部分
// if (!empty($this->InternalSourceNames))
// {
// $Tables = $this->GetInternalSource();
// $Return->Command .= " from {$Tables->Command}, (select @Index := 0) {$SortTable}";
// $this->MergeArray($Return->Paramer, $Tables->Paramer);
// }
//
// /// join 部分
// for ($Index = 0; $Index < $this->JoinCount; $Index++)
// {
// if (!empty($this->JoinType[$Index]))
// {
// $Joins = $this->GetJoinSources($Index);
// $JoinCondition = $this->GetJoinConditions($Index);
//
// switch ($this->JoinType[$Index])
// {
// case JOINTYPE_INNER:
// {
// $Return->Command .= " inner join {$Joins->Command} on {$JoinCondition->Command}";
// break;
// }
// case JOINTYPE_LEFT:
// {
// $Return->Command .= " left outer join {$Joins->Command} on {$JoinCondition->Command}";
// break;
// }
// case JOINTYPE_RIGHT:
// {
// $Return->Command .= " right outer join {$Joins->Command} on {$JoinCondition->Command}";
// break;
// }
// case JOINTYPE_OUTER:
// {
// $Return->Command .= " full outer join {$Joins->Command} on {$JoinCondition->Command}";
// break;
// }
// default:
// {
// $this->JoinSourceNames[$Index] = array();
// $this->JoinSourceAlias[$Index] = array();
// $this->JoinConditionColumn[$Index] = array();
// $this->JoinConditionValues[$Index] = array();
// $this->JoinConditionParams[$Index] = array();
// break;
// }
//
// }
//
// $this->MergeArray($Return->Paramer, $Joins->Paramer);
// $this->MergeArray($Return->Paramer, $JoinCondition->Paramer);
// }
// }
//
// /// where 部分
// if (!empty($this->WhereConditionColumn))
// {
// $WhereCondition = $this->GetWhereConditions();
//
// $Return->Command .= " where {$WhereCondition->Command}";
// $this->MergeArray($Return->Paramer, $WhereCondition->Paramer);
// }
//
// /// group by 和 having 部分
// if (!empty($this->GroupFieldList))
// {
// $GroupFields = $this->GetGroupColumns();
// $Return->Command .= " group by {$GroupFields->Command}";
// if (!empty($this->HavingConditionColumn))
// {
// $HavingCondition = $this->GetHavingConditions();
// $Return->Command .= " having {$HavingCondition->Command}";
// $this->MergeArray($Return->Paramer, $HavingCondition->Paramer);
// }
// }
//
// /// order 部分
// if (!empty($this->OrderFieldNames))
// {
// $OrderFields = $this->GetOrderColumns();
// $Return->Command .= " order by {$OrderFields->Command}";
// }
//
// $Alias = $this->GetSelectAliaColumns();
// $Return->Command = /** @lang text */ "select {$Alias->Command} from ({$Return->Command} limit {$Limit}) {$SortTable} where ({$SortField} between {$Start} and {$Stop})";
// }
return $Return;
}
/*******************************
* name: GetMergeCommandInformation.
* note: get the merge into command string(implemented. but delete not support.).
* parameters: none.
* return: object of CommandInformation.
*******************************
* @return CommandInformation
*******************************/
protected function GetMergeCommandInformation()
{
$Return = new CommandInformation();
$Tables = $this->GetInternalSource();
$Return->Command = /** @lang text */ "replace into {$Tables->Command}";
$Return->Paramer = $Tables->Paramer;
$Fields = $this->GetChangeFields();
$Values = $this->GetChangeValues();
/// 如果包含select表示则表示是一个子查询, 那么就不用values包裹了.
if (mb_stristr($Values->Command, 'select', false, USEDCHARSET))
$Return->Command .= " ({$Fields->Command}) {$Values->Command}";
else
$Return->Command .= " ({$Fields->Command}) values ({$Values->Command})";
$this->MergeArray($Return->Paramer, $Fields->Paramer);
$this->MergeArray($Return->Paramer, $Values->Paramer);
return $Return;
}
/**
* 2016-12-08增加
* @note 字符串转换为日期型的表达式
* @param string $StringTime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function String2DatetimeFormat($StringTime, $Quoted = true)
{
if ($Quoted)
$StringTime = $this->GetIdentifiers($StringTime, true);
return "(STR_TO_DATE({$StringTime}, '%Y-%m-%d %H:%i:%s'))";
}
/**
* 2016-12-08增加
* @note 日期转换为字符串型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2StringFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return "(date_format({$Datetime}, '%Y-%m-%d %H:%i:%s'))";
}
/**
* 2016-12-08增加
* @note 时间戳转换为日期型的表达式
* @param string $Timestamp 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Timestamp2DatetimeFormat($Timestamp)
{
return "(from_unixtime({$Timestamp}))";
}
/**
* 2016-12-08增加
* @note 日期转换为时间戳型的表达式
* @param string $Datetime 要转换的字段或表达式
* @param bool $Quoted 是否需要处理(增加)引号
* @return string
* @note 应俊
*/
public function Datetime2TimestampFormat($Datetime, $Quoted = true)
{
if ($Quoted)
$Datetime = $this->GetIdentifiers($Datetime, true);
return "(unix_timestamp({$Datetime}))";
}
/**
* 2016-12-08增加
* @note 浮点转换为字符串型的表达式
* @param string $Float 要转换的字段或表达式
* @return string
* @note 应俊
*/
public function Float2StringFormat($Float)
{
return "(cast(convert({$Float}, decimal(18, 2)) as char))";
}
/**
* 2016-01-16增加
* @note 获取当前服务器系统时间(或表达式)
* @param bool $IsRaw 是否返回数据库表达式
* @return string
* @note 应俊
*/
public function GetSystemTime($IsRaw = false)
{
if ($IsRaw)
return 'now()';
else
return parent::GetSystemTime($IsRaw);
}
}
class Delegator
{
/**
* @var mixed
*/
protected $Helper;
/**
* @return mixed
*/
public function GetHelper()
{
return $this->Helper;
}
/**
* @param mixed $Helper
*/
public function SetHelper($Helper)
{
$this->Helper = $Helper;
}
/**
* @param string $Name
* @param mixed $Args
* @return mixed
* @throws Exception
*/
public function __call($Name, $Args)
{
$Reflect = new ReflectionClass($this->Helper);
if ($Method = $Reflect->getMethod($Name))
{
if ($Method->isPublic() && !$Method->isAbstract())
return $Method->invokeArgs($this->Helper, $Args);
elseif ($Method->isPrivate())
throw new Exception('can not call private method: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
elseif ($Method->isProtected())
throw new Exception('can not call protected method: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
elseif ($Method->isAbstract())
throw new Exception('can not call abstract method: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
else
throw new Exception('can not call unknown method: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
else
throw new Exception('undefined method: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
/**
* @param string $Name
* @return mixed
* @throws Exception
*/
public function __get($Name)
{
$Reflect = new ReflectionClass($this->Helper);
if ($Property = $Reflect->getProperty($Name))
{
if ($Property->isPublic())
return $Property->getValue($this->Helper);
elseif ($Property->isPrivate())
throw new Exception('can not access private property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
elseif ($Property->isProtected())
throw new Exception('can not access protected property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
else
throw new Exception('can not access unknown property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
else
throw new Exception('undefined property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
/**
* @param string $Name
* @param mixed $Value
* @throws Exception
*/
public function __set($Name, $Value)
{
$Reflect = new ReflectionClass($this->Helper);
if ($Property = $Reflect->GetProperty($Name))
{
if ($Property->IsPublic())
//return $Property->SetValue($this->Helper, $Value);
$Property->SetValue($this->Helper, $Value);
elseif ($Property->IsPrivate())
throw new Exception('can not access private property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
elseif ($Property->IsProtected())
throw new Exception('can not access protected property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
else
throw new Exception('can not access unknown property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
else
throw new Exception('undefined property: ' . get_class($this->Helper) . '::' . $Name . ' in ' . __FILE__ . ' on line ' . __LINE__);
}
}
/*******************************
* name: PDODelegator.
* note: delegator of database helper.
******************************/
class PDODelegator extends Delegator
{
/**
* PDODelegator constructor.
* @param string $Type
* @throws Exception
*/
public function __construct($Type)
{
switch ($Type)
{
case DATABASE_TYPE_ORACLE:
$this->Helper = new ORACLEHelper();
break;
case DATABASE_TYPE_SQLSRV:
$this->Helper = new SQLSRVHelper();
break;
case DATABASE_TYPE_MYSQL:
$this->Helper = new MYSQLHelper();
break;
default:
$this->Helper = null;
throw new Exception('unknown database type: ' . $Type . ' in ' . __FILE__ . ' on line ' . __LINE__);
break;
}
}
/**
* @return IPDOHelper
*/
public function GetHelper()
{
return parent::GetHelper(); // TODO: Change the autogenerated stub
}
}
class CommandDelegator extends Delegator
{
/**
* CommandDelegator constructor.
* @param IPDOHelper|PDODelegator $Connection
* @throws Exception
*/
public function __construct($Connection)
{
if ($Connection instanceof PDODelegator)
$Connection = $Connection->GetHelper();
elseif (!($Connection instanceof IPDOHelper))
{
switch ($Type = gettype($Connection))
{
case 'object':
case 'interface':
$Message = 'Incompatible types: IPDOHelper or PDODelegator and ' . get_class($Connection) . ' with parameter $Connection!';
break;
default:
$Message = 'Incompatible types: IPDOHelper or PDODelegator and ' . $Type . ' with parameter $Connection!';
break;
}
throw new Exception($Message);
}
switch ($Connection->GetConnectType())
{
case DATABASE_TYPE_ORACLE:
$this->Helper = new ORACLECommand($Connection);
break;
case DATABASE_TYPE_SQLSRV:
$this->Helper = new SQLSRVCommand($Connection);
break;
case DATABASE_TYPE_MYSQL:
$this->Helper = new MYSQLCommand($Connection);
break;
default:
$this->Helper = null;
throw new Exception('unkonwn database type: ' . $Connection->GetConnectType() . '!');
break;
}
}
/**
* @return ISQLCommand
*/
public function GetHelper()
{
return parent::GetHelper(); // TODO: Change the autogenerated stub
}
}
function ReplaceValue($str)
{
$ret = str_ireplace("'", ''', $str);
$ret = str_ireplace('"', '"', $ret);
$ret = str_ireplace(',', ',', $ret);
$ret = str_ireplace('.', '。', $ret);
$ret = str_ireplace(':', ':', $ret);
$ret = str_ireplace(';', ';', $ret);
$ret = str_ireplace('(', '(', $ret);
$ret = str_ireplace(')', ')', $ret);
$ret = str_ireplace('[', '【', $ret);
$ret = str_ireplace(']', '】', $ret);
$ret = str_ireplace('{', '〖', $ret);
$ret = str_ireplace('}', '〗', $ret);
$ret = str_ireplace("\r", ' ', $ret);
$ret = str_ireplace("\n", ' ', $ret);
$ret = str_ireplace("\t", ' ', $ret);
$ret = str_ireplace(' ', ' ', $ret);
$ret = str_ireplace('\\', '\\\\', $ret);
return $ret;
}
/*******************************
* name: UnicodeCodeToUnicodeString.
* note: convert unicodecode to string(\uxxxx-->xx).
* parameters: string
* return: unicodestring if the function call succeeded, null otherwise.
*******************************
* @param string $String
* @return string
*******************************/
function UnicodeCodeToUnicodeString($String)
{
try
{
if (function_exists('preg_replace_callback'))
return preg_replace_callback('#\\\u([0-9a-f]{4})#i', function ($r) { return iconv('UCS-2BE', 'UTF-8', pack('H4', $r[1])); }, $String);
elseif (function_exists('preg_replace'))
return preg_replace('#\\\u([0-9a-f]{4})#ie', 'iconv(\'UCS-2BE\', \'UTF-8\', pack(\'H4\', \'\\1\'))', $String);
else
return $String;
}
catch (Exception $Exception)
{
return null;
}
}
/*******************************
* name: JsonObjectToJsonString.
* note: convert object to string on json_encode function.
* parameters: mixed object
* return: return value for json_encode.
*******************************
* @param mixed $Object
* @return string
*******************************/
function JsonObjectToJsonString($Object)
{
/// http://php.net/manual/zh/function.json-encode.php
if (defined('JSON_UNESCAPED_UNICODE'))
return json_encode($Object, JSON_UNESCAPED_UNICODE);
else
return UnicodeCodeToUnicodeString(json_encode($Object));
}
/*******************************
* name: JsonStringToJsonObject.
* note: convert string to object on json_decode function.
* parameters: string
* return: object if the function call succeeded, null otherwise.
*******************************
* @param string $String
* @return mixed
*******************************/
function JsonStringToJsonObject($String)
{
/// http://php.net/manual/zh/function.json-decode.php
if (!$Object = json_decode($String))
{
//$Object = json_decode(addslashes($String));
//stripslashes
/** @noinspection PhpIncludeInspection */
///$String = preg_replace_callback('/' . preg_quote('\\') . '/', function ($char){return '\\\\';}, $String);
$String = str_replace('\\', '\\\\', $String);
$Object = json_decode($String);
if (!$Object)
$Object = $String;
}
return $Object;
}
function XmlObjectToXmlString($Object)
{
if (is_object($Object))
$Xml = (array)$Object;
else
$Xml = $Object;
if (!is_array($Xml))
return strval($Xml);
elseif (Count($Xml) <= 0)
return '';
$Result = '';
foreach ($Xml as $Key => $Value)
{
if (is_numeric($Value))
{
$Result .= "<{$Key}>{$Value}{$Key}>";
}
elseif (is_object($Value) || is_array($Value))
{
$Value = XmlObjectToXmlString($Value);
$Result .= "<{$Key}>{$Key}>";
}
else
{
$Result .= "<{$Key}>{$Key}>";
}
}
$Result .= '';
return $Result;
}
function XmlStringToXmlObject($String)
{
// 将XML转为array
// 禁止引用外部xml实体
libxml_disable_entity_loader(true);
$Result = @simplexml_load_string($String, 'SimpleXMLElement', LIBXML_NOCDATA);
return $Result ? $Result : $String;
}
function ObjectToLinkString($Object)
{
if (is_object($Object))
$Object = (array)$Object;
if (!is_array($Object))
return strval($Object);
$Result = array();
foreach($Object as $Name => $Value)
{
if (is_object($Value) || is_array($Value))
$Value = JsonObjectToJsonString($Value);
array_push($Result, "{$Name}={$Value}");
}
return implode('&', $Result);
}
function LinkStringToObject($String)
{
$Params = explode('&', $String);
$Result = array();
foreach ($Params as $Param)
{
$Param = explode('=', $Param);
$Result[$Param[0]] = $Param[1];
}
return $Result;
}
/*******************************
* name: Characet.
* note: convert string code page.
* parameters: string, charset
* return: string if the function call succeeded, null otherwise.
*******************************
* @param string $String
* @param string $Charset
* @return string
*******************************/
function Characet($String, $Charset = USEDCHARSET)
{
if (!empty ($String))
{
$Encoding = mb_detect_encoding($String, array('ASCII', 'UTF-8', 'GBK', 'GB2312', 'LATIN1', 'BIG5',));
if (0 != strcasecmp($Encoding, $Charset))
$String = mb_convert_encoding($String, $Charset, $Encoding);
}
return $String;
}
/*
spl_autoload_register(
function ($class)
{
if (strcasecmp('PDOHelper', $class) == 0 ||
strcasecmp('ORACLEHelper', $class) == 0 ||
strcasecmp('SQLSRVHelper', $class) == 0 ||
strcasecmp('MYSQLHelper', $class) == 0)
require_once($_SERVER['PHP_SELF']);
}
);
/// html header.
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With");
header("Access-Control-Allow-Credentials: true");
header("Content-Type: text/html; charset=utf-8");
*/
if (!(function_exists('call_user_func') && function_exists('call_user_func_array')))
throw new Exception('Don\'t support the current version. The code requires PHP 5.0 or later.');
/*
if (!function_exists('call_user_func_array'))
{
function call_user_func_array($Callable, array $Parameters)
{
/// 第一个参数如果不是合法的回调对象则直接返回false;
if (!is_callable($Callable))
return null;
/// 回调对象,定义成全局对象是为了在字符串代码中可以截获这个对象。
global $__global__method__callable__owner__;
/// 回调时需要的参数
global $__global__method__parameter__;
$__global__method__parameter__ = $Parameters;
$Parameter = '';
foreach ($Parameters as $Key => $Value)
$Parameter .= '$__global__method__parameter__[' . $Key . '], ';
$len = mb_strlen($Parameter);
$sublen = mb_strlen(', ');
if ($len > 0)
$Parameter = mb_substr($Parameter, 0, $len - $sublen);
/// 要执行的代码
$Code = '';
/// 如果回调对象是一个数组,并且数组元素不少于2个元素则表示是调用类中的方法
/// 其中:
/// 第一个元素是宿主,宿主可以是类或实例。
/// 第二个元素是需要调用的方法名。
if (is_array($Callable) && count($Callable) >= 2)
{
$__global__method__callable__owner__ = $Callable[0];
if (is_object($Callable[0])) /// 对象表示是一个实例。
$Code =
'global $__global__method__callable__owner__;' . PHP_EOL .
'global $__global__method__parameter__;' . PHP_EOL .
'return $__global__method__callable__owner__->' . "{$Callable[1]}({$Parameter});";
else /// 其他类型表示是一个类。
$Code =
'global $__global__method__parameter__;' . PHP_EOL .
"return {$Callable[0]}::{$Callable[1]}({$Parameter});";
}
else /// 非数组表示调用静态方法
$Code =
'global $__global__method__parameter__;' . PHP_EOL .
"return {$Callable}({$Parameter})";
///echo $Code;
return eval($Code);
}
}
if (!function_exists('call_user_func'))
{
function call_user_func($function, $Parameter = null, $_ = null)
{
$Parameters = func_get_args();
array_shift($Parameters);
return call_user_func_array($function, $Parameters);
}
}
*/
///** @var IPDOHelper $db */
//$db = new PDODelegator(DATABASE_TYPE_MYSQL);
//$db->Connect('120.76.97.225', 3309, 'game_db', 'root', 'root_root');
//$callable = function($Record)
//{
// echo $Record->NickName, '
';
// return true;
//};
//$db->Request($callable, 'select play_playerid id, play_nickname NickName from player where 1 = ?', 2);