8823 lines
233 KiB
PHP
8823 lines
233 KiB
PHP
<?php
|
||
/**************************************************************************
|
||
* 文件名: DatabaseHelper.php
|
||
* 版本号: v1.0
|
||
* 创建日期: 2016-03-21
|
||
* 最后修改日期: 2018-04-27
|
||
* 功能: 对PDO类的简单封装,暂仅支持MSSQL、MYSQL、ORACLE
|
||
* by: bahamut
|
||
**************************************************************************
|
||
* 2016-03-21:
|
||
* 创建文件。
|
||
* 2016-03-22:
|
||
* 增加ORACLE支持。
|
||
* 2016-03-25:
|
||
* 增加EXCEL文件导出。
|
||
* 2016-03-29:
|
||
* Request方法新增回调函数的支持,ExportToFile方法支持指定新的查询语句和参数。
|
||
* 2016-04-14:
|
||
* 增加Succeeded方法来判断pdo类的errorcode值是否成功。
|
||
* 增加对MYSQL的支持(MYSQLHelper类),在Connect方法中,创建PDO对象后,立即执行"use database;"语句(如果不执行,mysql会报'no selected database'的错误。)。
|
||
* 2016-04-20:
|
||
* 修改Connect方法,参数提供默认参数,并可支持数组方式传递。
|
||
* 2016-05-01:
|
||
* 新增LastInsertId方法,用来获取最后一次新增数据时产生的自动编号。
|
||
* 2016-05-10:
|
||
* 新增错误返回值(ERRORCODE_CUSTOMFIRST、ERRORCODE_CUSTOMLAST),用于提供后期扩展。
|
||
* 2016-05-11:
|
||
* 新增ReplaceValue函数用来处理特殊字符。
|
||
* 2016-05-12:
|
||
* 修改SetErrors方法,errorinfo总是获取最后一个元素(如果是对象或者数组)。
|
||
* 2016-05-20:
|
||
* 增加FetchStyle成员, 用来设置提取记录时的提取方式(默认PDO::FETCH_OBJ)。
|
||
* 2016-07-08:
|
||
* MYSQLHelper增加可用参数charset,用来指定数据库的编码,默认为utf8
|
||
* 2016-08-05:
|
||
* 新增GetParameterList方法,用来处理传入类型为array与object的参数。
|
||
* 2017-01-05:
|
||
* 新增BindParameter和LoadStream属性, 用来支持大数据类型。
|
||
* BindParameter为true表示强制按传入的参数大小绑定参数到pdo对象中,
|
||
* LoadStream为true表示将判断查询语句中的返回值类型,如果为resorce则会用stream_get_contents去读取这个资源的实际值
|
||
* 2017-04-01:
|
||
* 新增接口IDatabaseHelper用于描述DatabaseHelper类的方法。
|
||
* 2017-04-06:
|
||
* 新增SQLCommand类来实现sql语句的封装。
|
||
* 2017-04-10:
|
||
* 新增CommandParameters类和CommandParameter类,用于扩展DatabaseHelper的Request和Execute方法。
|
||
* 扩展DatabaseHelper的Request和Execute方法,让传入的参数支持CommandParameter类型。
|
||
* 作废BindParameter和LoadStream属性, 总是支持大数据类型.
|
||
* 2017-07-03:
|
||
* ISQLCommand新增CallStoredProcedure方法用来调用存储过程或函数.
|
||
* 2017-07-16:
|
||
* ISQLCommand新增Union方法用来连接其他结果集(union all语句).
|
||
* 2017-07-24:
|
||
* IDatabaseHelper接口增加方法NextRowset用来移动当前记录集指针(用于多记录集时切换记录集操作),
|
||
* IDatabaseHelper接口增加方法Records用来获取当前已打开的记录集,
|
||
* DatabaseHelper类增加属性OnConnected(连接), OnDisconnected(断开连接), OnBeforeOpen(打开记录前), OnAfterOpen(打开记录后), OnBeforeExecute(执行命令前), OnAfterExecute(执行命令后), OnError(错误)用来捕捉事件。
|
||
* 2017-12-14:
|
||
* 解決了在設置條件時(where, join on, having等)當設置值為null時,出現的bug.
|
||
* 2018-01-21:
|
||
* 增加ExportToBrowser方法(无需服务器端缓存临时文件。)用于导出excel文件。
|
||
* ExportToBrowser方法导出并没有做分页处理,如果后期出现out of memory的情况则需要做分页导出。
|
||
* 2018-04-27:
|
||
* IDatabaseHelper改名为IPDOHelper, DatabaseHelper改名为PDOHelper.
|
||
* 2018-05-28:
|
||
* PDOHelper增加CacheRecord属性用来控制在执行有回调函数的查询语句时,是否把查询到的记录缓存到本地。
|
||
**************************************************************************/
|
||
|
||
require_once __DIR__ . '/CommonConstant.php';
|
||
|
||
class ConnectParameter
|
||
{
|
||
public $Hostname;
|
||
public $Hostport;
|
||
public $Database;
|
||
public $Username;
|
||
public $Password;
|
||
public $Persistent;
|
||
public $Charset;
|
||
|
||
|
||
public function __construct($Hostname = '', $Hostport = 0, $Database = '', $Username = '', $Password = '', $Persistent = false, $Charset = '')
|
||
{
|
||
$this->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 <b>FALSE</b> 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 <b>FALSE</b> 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 = '<xml>';
|
||
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}><![CDATA[{$Value}]]></{$Key}>";
|
||
}
|
||
else
|
||
{
|
||
$Result .= "<{$Key}><![CDATA[{$Value}]]></{$Key}>";
|
||
}
|
||
}
|
||
$Result .= '</xml>';
|
||
|
||
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, '<br>';
|
||
// return true;
|
||
//};
|
||
//$db->Request($callable, 'select play_playerid id, play_nickname NickName from player where 1 = ?', 2);
|