You've already forked qlg.tsgz.moe
Init Repo
This commit is contained in:
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
interface LtDbConnectionAdapter
|
||||
{
|
||||
/**
|
||||
* @todo 兼容使用Unix Domain Socket方式连接数据库(即:可以不指定port)
|
||||
*/
|
||||
public function connect($connConf);
|
||||
public function exec($sql, $connResource);
|
||||
public function query($sql, $connResource);
|
||||
public function lastInsertId($connResource);
|
||||
public function escape($sql, $connResource);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterMysql implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
return mysql_connect($connConf["host"] . ":" . $connConf["port"], $connConf["username"], $connConf["password"]);
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
return mysql_query($sql, $connResource) ? mysql_affected_rows($connResource) : false;
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$result = mysql_query($sql, $connResource);
|
||||
$rows = array();
|
||||
while($row = mysql_fetch_assoc($result))
|
||||
{
|
||||
$rows[] = $row;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return mysql_insert_id($connResource);
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return mysql_real_escape_string($sql, $connResource);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterMysqli implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
return new mysqli($connConf["host"], $connConf["username"], $connConf["password"], $connConf["dbname"], $connConf["port"]);
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
$connResource->query($sql);
|
||||
return $connResource->affected_rows;
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$rows = array();
|
||||
$result = $connResource->query($sql);
|
||||
while($row = $result->fetch_assoc())
|
||||
{
|
||||
$rows[] = $row;
|
||||
}
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return $connResource->insert_id;
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return mysqli_real_escape_string($connResource, $sql);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterPdo implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
// $option = array(PDO::ATTR_PERSISTENT => true);
|
||||
if (isset($connConf['pconnect']) && true == $connConf['pconnect'])
|
||||
{
|
||||
$option[PDO::ATTR_PERSISTENT] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$option[PDO::ATTR_PERSISTENT] = false;
|
||||
}
|
||||
switch ($connConf['adapter'])
|
||||
{
|
||||
case "pdo_mysql":
|
||||
$dsn = "mysql:host={$connConf['host']};dbname={$connConf['dbname']}";
|
||||
break;
|
||||
case "pdo_sqlite":
|
||||
$connConf["host"] = rtrim($connConf["host"], '\\/') . DIRECTORY_SEPARATOR;
|
||||
if (!is_dir($connConf["host"]))
|
||||
{
|
||||
if (!@mkdir($connConf["host"], 0777, true))
|
||||
{
|
||||
trigger_error("Can not create {$connConf['host']}");
|
||||
}
|
||||
}
|
||||
$dsn = "{$connConf['sqlite_version']}:{$connConf['host']}{$connConf['dbname']}";
|
||||
break;
|
||||
case "pdo_pgsql":
|
||||
$dsn = "pgsql:host={$connConf['host']} port={$connConf['port']} dbname={$connConf['dbname']} user={$connConf['username']} password={$connConf['password']}";
|
||||
break;
|
||||
case "odbc":
|
||||
$dsn = "odbc:" . $connConf["host"];
|
||||
break;
|
||||
}
|
||||
return new PDO($dsn, $connConf['username'], $connConf['password'], $option);
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
return $connResource->exec($sql);
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
return $connResource->query($sql)->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @todo pgsql support
|
||||
*/
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return $connResource->lastInsertId();
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
// quote返回值带最前面和最后面的单引号, 这里去掉, DbHandler中加
|
||||
return trim($connResource->quote($sql), "'");
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
class LtDbConnectionAdapterPgsql implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
if (isset($connConf['pconnect']) && true == $connConf['pconnect'])
|
||||
{
|
||||
$func = 'pg_pconnect';
|
||||
}
|
||||
else
|
||||
{
|
||||
$func = 'pg_connect';
|
||||
}
|
||||
return $func("host={$connConf['host']} port={$connConf['port']} user={$connConf['username']} password={$connConf['password']}");
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
$result = pg_query($connResource, $sql);
|
||||
return pg_affected_rows($result);
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$result = pg_query($connResource, $sql);
|
||||
return pg_fetch_all($result);
|
||||
}
|
||||
|
||||
// SELECT CURRVAL(
|
||||
// pg_get_serial_sequence('my_tbl_name','id_col_name'));"
|
||||
// ------------------------------------------------------
|
||||
// CREATE FUNCTION last_insert_id() RETURNS bigint AS $$
|
||||
// SELECT lastval();
|
||||
// $$ LANGUAGE SQL VOLATILE;
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
$result = pg_query($connResource, "SELECT lastval()");
|
||||
$row = pg_fetch_array($result, 0, PGSQL_NUM);
|
||||
return $row[0];
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return pg_escape_string($sql);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Sqlite 预定义了类 SQLiteDatabase 本实现没有使用。
|
||||
* 这里使用的全部是过程函数。
|
||||
* 无论是函数还是类,本实现只支持sqlite的2.x系列版本。
|
||||
* php5.3新增扩展sqlite3用来支持3.x版本。
|
||||
* PDO则同时支持2.x和3.x版本。
|
||||
*/
|
||||
class LtDbConnectionAdapterSqlite implements LtDbConnectionAdapter
|
||||
{
|
||||
public function connect($connConf)
|
||||
{
|
||||
if (isset($connConf['pconnect']) && true == $connConf['pconnect'])
|
||||
{
|
||||
$func = 'sqlite_popen';
|
||||
}
|
||||
else
|
||||
{
|
||||
$func = 'sqlite_open';
|
||||
}
|
||||
$connConf["host"] = rtrim($connConf["host"], '\\/') . DIRECTORY_SEPARATOR;
|
||||
if(!is_dir($connConf["host"]))
|
||||
{
|
||||
if(!@mkdir($connConf["host"], 0777, true))
|
||||
{
|
||||
trigger_error("Can not create {$connConf['host']}");
|
||||
}
|
||||
}
|
||||
$error = '';
|
||||
$connResource = $func($connConf["host"] . $connConf["dbname"], 0666, $error);
|
||||
if (!$connResource)
|
||||
{
|
||||
trigger_error($error, E_USER_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $connResource;
|
||||
}
|
||||
}
|
||||
|
||||
public function exec($sql, $connResource)
|
||||
{
|
||||
if(empty($sql))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
sqlite_exec($connResource, $sql);
|
||||
// echo '<pre>';
|
||||
// print_r(debug_backtrace());
|
||||
// debug_print_backtrace();
|
||||
// echo '</pre>';
|
||||
// delete from table 结果为0,原因未知。
|
||||
// 使用 delete from table where 1 能返回正确结果
|
||||
return sqlite_changes($connResource);
|
||||
}
|
||||
|
||||
public function query($sql, $connResource)
|
||||
{
|
||||
$result = sqlite_query($connResource, $sql, SQLITE_ASSOC);
|
||||
return sqlite_fetch_all($result, SQLITE_ASSOC);
|
||||
}
|
||||
|
||||
public function lastInsertId($connResource)
|
||||
{
|
||||
return sqlite_last_insert_rowid($connResource);
|
||||
}
|
||||
|
||||
public function escape($sql, $connResource)
|
||||
{
|
||||
return sqlite_escape_string($sql);
|
||||
}
|
||||
}
|
31
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php
Executable file
31
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php
Executable file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
interface LtDbSqlAdapter
|
||||
{
|
||||
/**
|
||||
* Return SQL statements
|
||||
*/
|
||||
public function setCharset($charset);
|
||||
public function setSchema($schema);
|
||||
|
||||
public function showSchemas($database);
|
||||
public function showTables($schema);
|
||||
public function showFields($table);
|
||||
|
||||
public function beginTransaction();
|
||||
public function commit();
|
||||
public function rollBack();
|
||||
|
||||
public function limit($limit, $offset);
|
||||
|
||||
/**
|
||||
* Retrive recordset
|
||||
*/
|
||||
public function getSchemas($queryResult);
|
||||
public function getTables($queryResult);
|
||||
public function getFields($queryResult);
|
||||
|
||||
/**
|
||||
* Parse SQL
|
||||
*/
|
||||
public function detectQueryType($sql);
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
class LtDbSqlAdapterMysql implements LtDbSqlAdapter
|
||||
{
|
||||
public function setCharset($charset)
|
||||
{
|
||||
return "SET NAMES " . str_replace('-', '', $charset);
|
||||
}
|
||||
public function setSchema($schema)
|
||||
{
|
||||
return "USE $schema";
|
||||
}
|
||||
|
||||
public function showSchemas($database)
|
||||
{
|
||||
return "SHOW DATABASES";
|
||||
}
|
||||
public function showTables($schema)
|
||||
{
|
||||
return "SHOW TABLES";
|
||||
}
|
||||
public function showFields($table)
|
||||
{
|
||||
return "DESCRIBE $table";
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return "START TRANSACTION";
|
||||
}
|
||||
public function commit()
|
||||
{
|
||||
return "COMMIT";
|
||||
}
|
||||
public function rollBack()
|
||||
{
|
||||
return "ROLLBACK";
|
||||
}
|
||||
|
||||
public function limit($limit, $offset)
|
||||
{
|
||||
return " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
public function getSchemas($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getTables($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getFields($queryResult)
|
||||
{
|
||||
foreach ($queryResult as $key => $value)
|
||||
{
|
||||
$fields[$value['Field']]['name'] = $value['Field'];
|
||||
$fields[$value['Field']]['type'] = $value['Type'];
|
||||
/*
|
||||
* not null is NO or empty, null is YES
|
||||
*/
|
||||
$fields[$value['Field']]['notnull'] = (bool) ($value['Null'] != 'YES');
|
||||
$fields[$value['Field']]['default'] = $value['Default'];
|
||||
$fields[$value['Field']]['primary'] = (strtolower($value['Key']) == 'pri');
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
public function detectQueryType($sql)
|
||||
{
|
||||
if (preg_match("/^\s*SELECT|^\s*EXPLAIN|^\s*SHOW|^\s*DESCRIBE/i", $sql))
|
||||
{
|
||||
$ret = 'SELECT';
|
||||
}
|
||||
else if (preg_match("/^\s*INSERT/i", $sql))
|
||||
{
|
||||
$ret = 'INSERT';
|
||||
}
|
||||
else if (preg_match("/^\s*UPDATE|^\s*DELETE|^\s*REPLACE/i", $sql))
|
||||
{
|
||||
$ret = 'CHANGE_ROWS';
|
||||
}
|
||||
else if (preg_match("/^\s*USE|^\s*SET/i", $sql))
|
||||
{
|
||||
$ret = 'SET_SESSION_VAR';
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = 'OTHER';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
class LtDbSqlAdapterPgsql implements LtDbSqlAdapter
|
||||
{
|
||||
public function setCharset($charset)
|
||||
{
|
||||
return "SET client_encoding TO '$charset'";
|
||||
}
|
||||
public function setSchema($schema)
|
||||
{
|
||||
return "SET search_path TO $schema";
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public function commit()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
public function rollBack()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public function showSchemas($database)
|
||||
{
|
||||
|
||||
}
|
||||
public function showTables($schema)
|
||||
{
|
||||
return "SELECT case when n.nspname='public' then c.relname else n.nspname||'.'||c.relname end as relname
|
||||
FROM pg_class c join pg_namespace n on (c.relnamespace=n.oid)
|
||||
WHERE c.relkind = 'r'
|
||||
AND n.nspname NOT IN ('information_schema','pg_catalog')
|
||||
AND n.nspname NOT LIKE 'pg_temp%'
|
||||
AND n.nspname NOT LIKE 'pg_toast%'
|
||||
ORDER BY relname";
|
||||
}
|
||||
public function showFields($table)
|
||||
{
|
||||
return "SELECT a.attnum, a.attname AS field, t.typname AS type,
|
||||
format_type(a.atttypid, a.atttypmod) AS complete_type,
|
||||
a.attnotnull AS isnotnull,
|
||||
( SELECT 't' FROM pg_index
|
||||
WHERE c.oid = pg_index.indrelid
|
||||
AND pg_index.indkey[0] = a.attnum
|
||||
AND pg_index.indisprimary = 't') AS pri,
|
||||
(SELECT pg_attrdef.adsrc FROM pg_attrdef
|
||||
WHERE c.oid = pg_attrdef.adrelid
|
||||
AND pg_attrdef.adnum=a.attnum) AS default
|
||||
FROM pg_attribute a, pg_class c, pg_type t
|
||||
WHERE c.relname = '$table'
|
||||
AND a.attnum > 0
|
||||
AND a.attrelid = c.oid
|
||||
AND a.atttypid = t.oid
|
||||
ORDER BY a.attnum";
|
||||
}
|
||||
|
||||
public function limit($limit, $offset)
|
||||
{
|
||||
return " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
|
||||
public function getSchemas($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getTables($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getFields($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function detectQueryType($sql)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
120
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php
Executable file
120
extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php
Executable file
@ -0,0 +1,120 @@
|
||||
<?php
|
||||
class LtDbSqlAdapterSqlite implements LtDbSqlAdapter
|
||||
{
|
||||
public function setCharset($charset)
|
||||
{
|
||||
// return 'PRAGMA encoding = "' . $charset . '"';
|
||||
return '';
|
||||
}
|
||||
public function setSchema($schema)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
{
|
||||
return 'BEGIN TRANSACTION';
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
return 'COMMIT TRANSACTION';
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
return 'ROLLBACK TRANSACTION';
|
||||
}
|
||||
|
||||
public function showSchemas($database)
|
||||
{
|
||||
//return "SHOW DATABASES";
|
||||
return '';
|
||||
}
|
||||
public function showTables($schema)
|
||||
{
|
||||
// 临时表及其索引不在 SQLITE_MASTER 表中而在 SQLITE_TEMP_MASTER 中出现
|
||||
return "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name";
|
||||
}
|
||||
public function showFields($table)
|
||||
{
|
||||
return "PRAGMA table_info('" . $table . "')";
|
||||
|
||||
}
|
||||
public function limit($limit, $offset)
|
||||
{
|
||||
return " LIMIT $limit OFFSET $offset";
|
||||
}
|
||||
|
||||
public function getSchemas($queryResult)
|
||||
{
|
||||
|
||||
}
|
||||
public function getTables($queryResult)
|
||||
{
|
||||
return $queryResult;
|
||||
}
|
||||
public function getFields($queryResult)
|
||||
{
|
||||
$fields = array();
|
||||
foreach ($queryResult as $key => $value)
|
||||
{
|
||||
// 字段名
|
||||
$fields[$value['name']]['name'] = $value['name'];
|
||||
// 字段类型
|
||||
$fulltype = $value['type'];
|
||||
$size = null;
|
||||
$precision = null;
|
||||
$scale = null;
|
||||
|
||||
if (preg_match('/^([^\(]+)\(\s*(\d+)\s*,\s*(\d+)\s*\)$/',$fulltype, $matches))
|
||||
{
|
||||
$type = $matches[1];
|
||||
$precision = $matches[2];
|
||||
$scale = $matches[3]; // aka precision
|
||||
}
|
||||
elseif (preg_match('/^([^\(]+)\(\s*(\d+)\s*\)$/',$fulltype, $matches))
|
||||
{
|
||||
$type = $matches[1];
|
||||
$size = $matches[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = $fulltype;
|
||||
}
|
||||
|
||||
$fields[$value['name']]['type'] = $type;
|
||||
/**
|
||||
* not null is 99, null is 0
|
||||
*/
|
||||
$fields[$value['name']]['notnull'] = (bool) ($value['notnull'] != 0);
|
||||
$fields[$value['name']]['default'] = $value['dflt_value'];
|
||||
$fields[$value['name']]['primary'] = (bool) ($value['pk'] == 1 && strtoupper($fulltype) == 'INTEGER');
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
public function detectQueryType($sql)
|
||||
{
|
||||
if (preg_match("/^\s*SELECT|^\s*PRAGMA/i", $sql))
|
||||
{
|
||||
$ret = 'SELECT';
|
||||
}
|
||||
else if (preg_match("/^\s*INSERT/i", $sql))
|
||||
{
|
||||
$ret = 'INSERT';
|
||||
}
|
||||
else if (preg_match("/^\s*UPDATE|^\s*DELETE|^\s*REPLACE/i", $sql))
|
||||
{
|
||||
$ret = 'CHANGE_ROWS';
|
||||
}
|
||||
else if (preg_match("/^\s*USE|^\s*SET/i", $sql))
|
||||
{
|
||||
$ret = 'SET_SESSION_VAR';
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret = 'OTHER';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
91
extend/app_alipay/lotusphp_runtime/DB/Db.php
Executable file
91
extend/app_alipay/lotusphp_runtime/DB/Db.php
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
class LtDb
|
||||
{
|
||||
public $configHandle;
|
||||
|
||||
public $group;
|
||||
public $node;
|
||||
protected $dbh;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (! $this->configHandle instanceof LtConfig)
|
||||
{
|
||||
if (class_exists("LtObjectUtil", false))
|
||||
{
|
||||
$this->configHandle = LtObjectUtil::singleton("LtConfig");
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->configHandle = new LtConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->dbh = new LtDbHandle;
|
||||
$this->dbh->configHandle = $this->configHandle;
|
||||
$this->dbh->group = $this->getGroup();
|
||||
$this->dbh->node = $this->getNode();
|
||||
$this->dbh->init();
|
||||
}
|
||||
|
||||
public function getDbHandle()
|
||||
{
|
||||
return $this->dbh;
|
||||
}
|
||||
|
||||
public function getTDG($tableName)
|
||||
{
|
||||
$tg = new LtDbTableDataGateway;
|
||||
$tg->configHandle = $this->configHandle;
|
||||
$tg->tableName = $tableName;
|
||||
$tg->createdColumn = 'created';
|
||||
$tg->modifiedColumn = 'modified';
|
||||
$tg->dbh = $this->dbh;
|
||||
return $tg;
|
||||
}
|
||||
|
||||
public function getSqlMapClient()
|
||||
{
|
||||
$smc = new LtDbSqlMapClient;
|
||||
$smc->configHandle = $this->configHandle;
|
||||
$smc->dbh = $this->dbh;
|
||||
return $smc;
|
||||
}
|
||||
|
||||
public function changeNode($node)
|
||||
{
|
||||
$this->node = $node;
|
||||
$this->dbh->node = $node;
|
||||
}
|
||||
|
||||
protected function getGroup()
|
||||
{
|
||||
if ($this->group)
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
$servers = $this->configHandle->get("db.servers");
|
||||
if (1 == count($servers))
|
||||
{
|
||||
return key($servers);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getNode()
|
||||
{
|
||||
if ($this->node)
|
||||
{
|
||||
return $this->node;
|
||||
}
|
||||
$servers = $this->configHandle->get("db.servers");
|
||||
if (1 == count($servers[$this->getGroup()]))
|
||||
{
|
||||
return key($servers[$this->getGroup()]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
15
extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php
Executable file
15
extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php
Executable file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
class LtDbAdapterFactory
|
||||
{
|
||||
public function getConnectionAdapter($connectionAdapterType)
|
||||
{
|
||||
$LtDbConnectionAdapter = "LtDbConnectionAdapter" . ucfirst($connectionAdapterType);
|
||||
return new $LtDbConnectionAdapter;
|
||||
}
|
||||
|
||||
public function getSqlAdapter($sqlAdapterType)
|
||||
{
|
||||
$LtDbSqlAdapter = "LtDbSqlAdapter" . ucfirst($sqlAdapterType);
|
||||
return new $LtDbSqlAdapter;
|
||||
}
|
||||
}
|
122
extend/app_alipay/lotusphp_runtime/DB/DbConfigBuilder.php
Executable file
122
extend/app_alipay/lotusphp_runtime/DB/DbConfigBuilder.php
Executable file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
class LtDbConfigBuilder
|
||||
{
|
||||
protected $servers = array();
|
||||
|
||||
protected $tables = array();
|
||||
|
||||
protected $adapters = array(
|
||||
//"php_ext" => array("connection_adapter" => "", "sql_adapter" => "")
|
||||
"pgsql" => array("connection_adapter" => "pgsql", "sql_adapter" => "pgsql"),
|
||||
"pdo_pgsql" => array("connection_adapter" => "pdo", "sql_adapter" => "pgsql"),
|
||||
"oci" => array("connection_adapter" => "oci", "sql_adapter" => "oracle"),
|
||||
"pdo_oci" => array("connection_adapter" => "pdo", "sql_adapter" => "oracle"),
|
||||
"mssql" => array("connection_adapter" => "mssql", "sql_adapter" => "mssql"),
|
||||
"pdo_dblib" => array("connection_adapter" => "pdo", "sql_adapter" => "mssql"),
|
||||
"mysql" => array("connection_adapter" => "mysql", "sql_adapter" => "mysql"),
|
||||
"mysqli" => array("connection_adapter" => "mysqli", "sql_adapter" => "mysql"),
|
||||
"pdo_mysql" => array("connection_adapter" => "pdo", "sql_adapter" => "mysql"),
|
||||
"sqlite" => array("connection_adapter" => "sqlite", "sql_adapter" => "sqlite"),
|
||||
"sqlite3" => array("connection_adapter" => "sqlite3", "sql_adapter" => "sqlite"),
|
||||
"pdo_sqlite" => array("connection_adapter" => "pdo", "sql_adapter" => "sqlite"),
|
||||
);
|
||||
|
||||
protected $defaultConfig = array(
|
||||
"host" => "localhost", //some ip, hostname
|
||||
//"port" => 3306,
|
||||
"username" => "root",
|
||||
"password" => null,
|
||||
//"adapter" => "mysql", //mysql,mysqli,pdo_mysql,sqlite,pdo_sqlite
|
||||
"charset" => "UTF-8",
|
||||
"pconnect" => true, //true,false
|
||||
"connection_ttl" => 3600, //any seconds
|
||||
"dbname" => null, //default dbname
|
||||
"schema" => null, //default schema
|
||||
"connection_adapter" => null,
|
||||
"sql_adapter" => null,
|
||||
);
|
||||
|
||||
protected $defaultAdapterConfigs = array(
|
||||
"pgsql" => array(
|
||||
"port" => 5432,
|
||||
),
|
||||
"oracle" => array(
|
||||
"port" => 1521,
|
||||
),
|
||||
"mssql" => array(
|
||||
"port" => 1433,
|
||||
),
|
||||
"mysql" => array(
|
||||
"port" => 3306,
|
||||
"pconnect" => false,
|
||||
"connection_ttl" => 30,
|
||||
),
|
||||
);
|
||||
|
||||
public function addSingleHost($hostConfig)
|
||||
{
|
||||
$this->addHost("group_0", "node_0", "master", $hostConfig);
|
||||
}
|
||||
|
||||
public function addHost($groupId, $nodeId = "node_0", $role = "master", $hostConfig)
|
||||
{
|
||||
if (isset($this->servers[$groupId][$nodeId][$role]))
|
||||
{//以相同role的第一个host为默认配置
|
||||
$ref = $this->servers[$groupId][$nodeId][$role][0];
|
||||
}
|
||||
else if ("slave" == $role && isset($this->servers[$groupId][$nodeId]["master"]))
|
||||
{//slave host以master的第一个host为默认配置
|
||||
$ref = $this->servers[$groupId][$nodeId]["master"][0];
|
||||
}
|
||||
else if (isset($this->servers[$groupId]) && count($this->servers[$groupId]))
|
||||
{//以本group第一个node的master第一个host为默认配置
|
||||
$refNode = key($this->servers[$groupId]);
|
||||
$ref = $this->servers[$groupId][$refNode]["master"][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isset($hostConfig["adapter"]))
|
||||
{
|
||||
trigger_error("No db adapter specified");
|
||||
}
|
||||
$ref = $this->defaultConfig;
|
||||
if (isset($this->defaultAdapterConfigs[$this->adapters[$hostConfig["adapter"]]["sql_adapter"]]))
|
||||
{
|
||||
$ref = array_merge($ref, $this->defaultAdapterConfigs[$this->adapters[$hostConfig["adapter"]]["sql_adapter"]]);
|
||||
}
|
||||
}
|
||||
$conf = array_merge($ref, $hostConfig);
|
||||
$conf = array_merge($conf, $this->adapters[$conf["adapter"]]);
|
||||
$conf = $this->convertDbnameToSchema($conf);
|
||||
$this->servers[$groupId][$nodeId][$role][] = $conf;
|
||||
}
|
||||
|
||||
public function getServers()
|
||||
{
|
||||
return $this->servers;
|
||||
}
|
||||
|
||||
public function getTables()
|
||||
{
|
||||
return $this->tables;
|
||||
}
|
||||
|
||||
public function buildTablesConfig()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert dbname to schema for: FrontBase, MySQL, mSQL, MS SQL Server, MaxDB, Sybase
|
||||
* See: http://www.php.net/manual-lookup.php?pattern=_select_db
|
||||
*/
|
||||
protected function convertDbnameToSchema($conf)
|
||||
{
|
||||
if (preg_match("/fbsql|mysql|msql|mssql|maxdb|sybase/i", $conf["sql_adapter"]) && isset($conf["dbname"]))
|
||||
{
|
||||
$conf["schema"] = $conf["dbname"];
|
||||
$conf["dbname"] = null;
|
||||
}
|
||||
return $conf;
|
||||
}
|
||||
}
|
117
extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php
Executable file
117
extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php
Executable file
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
class LtDbConnectionManager
|
||||
{
|
||||
/**
|
||||
* Connection management
|
||||
* array(
|
||||
* "connection" => connection resource id,
|
||||
* "expire_time" => expire time,
|
||||
* "schema" => default schema name,
|
||||
* "charset" => char set / encoding
|
||||
* )
|
||||
*/
|
||||
static public $connectionPool;
|
||||
public $configHandle;
|
||||
protected $connectionAdapter;
|
||||
protected $sqlAdapter;
|
||||
private $servers;
|
||||
|
||||
public function getConnection($group, $node, $role = "master")
|
||||
{
|
||||
if(empty($this->servers))
|
||||
{
|
||||
$this->servers = $this->configHandle->get("db.servers");
|
||||
}
|
||||
if (($connection = $this->getNewConnection($group, $node, $role)) ||($connection = $this->getCachedConnection($group, $node, $role)))
|
||||
{
|
||||
return array(
|
||||
"connectionAdapter" => $this->connectionAdapter,
|
||||
"connectionResource" => $connection
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("db server can not be connected: group=$group, node=$node, role=$role", E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getConnectionKey($connConf)
|
||||
{
|
||||
return $connConf['adapter'] . $connConf['host'] . $connConf['port'] . $connConf['username'] . $connConf['dbname'];
|
||||
}
|
||||
|
||||
protected function saveConnection($connConf, $connection, $ttl)
|
||||
{
|
||||
$connectionInfo = array(
|
||||
"connection" => $connection,
|
||||
"expire_time" => time() + $ttl,
|
||||
"schema" => $connConf["schema"],
|
||||
"charset" => $connConf["charset"],
|
||||
);
|
||||
self::$connectionPool[$this->getConnectionKey($connConf)] = $connectionInfo;
|
||||
}
|
||||
|
||||
protected function getCachedConnection($group, $node, $role)
|
||||
{
|
||||
foreach($this->servers[$group][$node][$role] as $hostConfig)
|
||||
{
|
||||
$key = $this->getConnectionKey($hostConfig);
|
||||
if(isset(self::$connectionPool[$key]) && time() < self::$connectionPool[$key]['expire_time'])
|
||||
{//cached connection resource FOUND
|
||||
$connectionInfo = self::$connectionPool[$key];
|
||||
if ($connectionInfo["schema"] != $hostConfig["schema"] || $connectionInfo["charset"] != $hostConfig["charset"])
|
||||
{//检查当前schema和charset与用户要操作的目标不一致
|
||||
$hostConfig = $this->servers[$group][$node][$role][$hostIndexArray[$hashNumber]];
|
||||
$dbFactory = new LtDbAdapterFactory;
|
||||
$this->connectionAdapter = $dbFactory->getConnectionAdapter($hostConfig["connection_adapter"]);
|
||||
$this->sqlAdapter = $dbFactory->getSqlAdapter($hostConfig["sql_adapter"]);
|
||||
if ($connectionInfo["schema"] != $hostConfig["schema"])
|
||||
{
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setSchema($hostConfig["schema"]), $connectionInfo["connection"]);
|
||||
}
|
||||
if ($connectionInfo["charset"] != $hostConfig["charset"])
|
||||
{
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setCharset($hostConfig["charset"]), $connectionInfo["connection"]);
|
||||
}
|
||||
$this->saveConnection($hostConfig, $connectionInfo["connection"], $hostConfig["connection_ttl"]);
|
||||
}
|
||||
return $connectionInfo["connection"];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getNewConnection($group, $node, $role)
|
||||
{
|
||||
$hostTotal = count($this->servers[$group][$node][$role]);
|
||||
$hostIndexArray = array_keys($this->servers[$group][$node][$role]);
|
||||
while ($hostTotal)
|
||||
{
|
||||
$hashNumber = substr(microtime(),7,1) % $hostTotal;
|
||||
$hostConfig = $this->servers[$group][$node][$role][$hostIndexArray[$hashNumber]];
|
||||
$dbFactory = new LtDbAdapterFactory;
|
||||
$this->connectionAdapter = $dbFactory->getConnectionAdapter($hostConfig["connection_adapter"]);
|
||||
$this->sqlAdapter = $dbFactory->getSqlAdapter($hostConfig["sql_adapter"]);
|
||||
if ($connection = $this->connectionAdapter->connect($hostConfig))
|
||||
{
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setSchema($hostConfig["schema"]), $connection);
|
||||
$this->connectionAdapter->exec($this->sqlAdapter->setCharset($hostConfig["charset"]), $connection);
|
||||
$this->saveConnection($hostConfig, $connection, $hostConfig["connection_ttl"]);
|
||||
return $connection;
|
||||
}
|
||||
else
|
||||
{
|
||||
//trigger_error('connection fail', E_USER_WARNING);
|
||||
//delete the unavailable server
|
||||
for ($i = $hashNumber; $i < $hostTotal - 1; $i ++)
|
||||
{
|
||||
$hostIndexArray[$i] = $hostIndexArray[$i+1];
|
||||
}
|
||||
unset($hostIndexArray[$hostTotal-1]);
|
||||
$hostTotal --;
|
||||
}//end else
|
||||
}//end while
|
||||
return false;
|
||||
}
|
||||
}
|
200
extend/app_alipay/lotusphp_runtime/DB/DbHandle.php
Executable file
200
extend/app_alipay/lotusphp_runtime/DB/DbHandle.php
Executable file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
class LtDbHandle
|
||||
{
|
||||
public $configHandle;
|
||||
public $group;
|
||||
public $node;
|
||||
public $role = "master";
|
||||
public $connectionAdapter;
|
||||
public $connectionResource;
|
||||
public $sqlAdapter;
|
||||
protected $connectionManager;
|
||||
private $servers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if(empty($this->servers))
|
||||
{
|
||||
$this->servers = $this->configHandle->get("db.servers");
|
||||
}
|
||||
$this->connectionManager = new LtDbConnectionManager;
|
||||
$this->connectionManager->configHandle = $this->configHandle;
|
||||
$this->sqlAdapter = $this->getCurrentSqlAdapter();
|
||||
$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
|
||||
$this->connectionAdapter = $connectionInfo["connectionAdapter"];
|
||||
$this->connectionResource = $connectionInfo["connectionResource"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Trancaction methods
|
||||
*/
|
||||
public function beginTransaction()
|
||||
{
|
||||
return $this->connectionAdapter->exec($this->sqlAdapter->beginTransaction(), $this->connectionResource);
|
||||
}
|
||||
|
||||
public function commit()
|
||||
{
|
||||
return $this->connectionAdapter->exec($this->sqlAdapter->commit(), $this->connectionResource);
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
return $this->connectionAdapter->exec($this->sqlAdapter->rollBack(), $this->connectionResource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an sql query
|
||||
*
|
||||
* @param $sql
|
||||
* @param $bind
|
||||
* @param $forceUseMaster
|
||||
* @return false on query failed
|
||||
* --sql type-- --return value--
|
||||
* SELECT, SHOW, DESECRIBE, EXPLAIN rowset or NULL when no record found
|
||||
* INSERT the ID generated for an AUTO_INCREMENT column
|
||||
* UPDATE, DELETE, REPLACE affected count
|
||||
* USE, DROP, ALTER, CREATE, SET etc true
|
||||
* @notice 每次只能执行一条SQL
|
||||
* 不要通过此接口执行USE DATABASE, SET NAMES这样的语句
|
||||
*/
|
||||
public function query($sql, $bind = null, $forceUseMaster = false)
|
||||
{
|
||||
$sql = trim($sql);
|
||||
if (empty($sql))
|
||||
{
|
||||
trigger_error('Empty the SQL statement');
|
||||
}
|
||||
$queryType = $this->sqlAdapter->detectQueryType($sql);
|
||||
switch ($queryType)
|
||||
{
|
||||
case "SELECT":
|
||||
if (!$forceUseMaster && isset($this->servers[$this->group][$this->node]["slave"]))
|
||||
{
|
||||
$this->role = "slave";
|
||||
}
|
||||
$queryMethod = "select";
|
||||
break;
|
||||
case "INSERT":
|
||||
$this->role = "master";
|
||||
$queryMethod = "insert";
|
||||
break;
|
||||
case "CHANGE_ROWS":
|
||||
$this->role = "master";
|
||||
$queryMethod = "changeRows";
|
||||
break;
|
||||
case "SET_SESSION_VAR":
|
||||
$queryMethod = "setSessionVar";
|
||||
break;
|
||||
case "OTHER":
|
||||
default:
|
||||
$this->role = "master";
|
||||
$queryMethod = "other";
|
||||
break;
|
||||
}
|
||||
$connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role);
|
||||
$this->connectionAdapter = $connectionInfo["connectionAdapter"];
|
||||
$this->connectionResource = $connectionInfo["connectionResource"];
|
||||
if (is_array($bind) && 0 < count($bind))
|
||||
{
|
||||
$sql = $this->bindParameter($sql, $bind);
|
||||
}
|
||||
return $this->$queryMethod($sql, $this->connectionResource);
|
||||
}
|
||||
/**
|
||||
* function posted by renlu
|
||||
*/
|
||||
public function escape($str)
|
||||
{
|
||||
return $this->connectionAdapter->escape($str, $this->connectionResource);
|
||||
}
|
||||
/**
|
||||
* function posted by renlu
|
||||
*/
|
||||
public function insertid()
|
||||
{
|
||||
return $this->connectionAdapter->lastInsertId($this->connectionResource);
|
||||
}
|
||||
/**
|
||||
* Generate complete sql from sql template (with placeholder) and parameter
|
||||
*
|
||||
* @param $sql
|
||||
* @param $parameter
|
||||
* @return string
|
||||
* @todo 兼容pgsql等其它数据库,pgsql的某些数据类型不接受单引号引起来的值
|
||||
*/
|
||||
public function bindParameter($sql, $parameter)
|
||||
{
|
||||
// 注意替换结果尾部加一个空格
|
||||
$sql = preg_replace("/:([a-zA-Z0-9_\-\x7f-\xff][a-zA-Z0-9_\-\x7f-\xff]*)\s*([,\)]?)/", "\x01\x02\x03\\1\x01\x02\x03\\2 ", $sql);
|
||||
foreach($parameter as $key => $value)
|
||||
{
|
||||
$find[] = "\x01\x02\x03$key\x01\x02\x03";
|
||||
if ($value instanceof LtDbSqlExpression)
|
||||
{
|
||||
$replacement[] = $value->__toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
$replacement[] = "'" . $this->connectionAdapter->escape($value, $this->connectionResource) . "'";
|
||||
}
|
||||
}
|
||||
$sql = str_replace($find, $replacement, $sql);
|
||||
return $sql;
|
||||
}
|
||||
|
||||
protected function getCurrentSqlAdapter()
|
||||
{
|
||||
$factory = new LtDbAdapterFactory;
|
||||
$host = key($this->servers[$this->group][$this->node][$this->role]);
|
||||
return $factory->getSqlAdapter($this->servers[$this->group][$this->node][$this->role][$host]["sql_adapter"]);
|
||||
}
|
||||
|
||||
protected function select($sql, $connResource)
|
||||
{
|
||||
$result = $this->connectionAdapter->query($sql, $connResource);
|
||||
if (empty($result))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
protected function insert($sql, $connResource)
|
||||
{
|
||||
if ($result = $this->connectionAdapter->exec($sql, $connResource))
|
||||
{
|
||||
return $this->connectionAdapter->lastInsertId($connResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
protected function changeRows($sql, $connResource)
|
||||
{
|
||||
return $this->connectionAdapter->exec($sql, $connResource);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @todo 更新连接缓存
|
||||
*/
|
||||
protected function setSessionVar($sql, $connResource)
|
||||
{
|
||||
return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;
|
||||
}
|
||||
|
||||
protected function other($sql, $connResource)
|
||||
{
|
||||
return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true;
|
||||
}
|
||||
}
|
15
extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php
Executable file
15
extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php
Executable file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
class LtDbSqlExpression
|
||||
{
|
||||
private $_expression;
|
||||
|
||||
public function __construct($string)
|
||||
{
|
||||
$this->_expression = (string) $string;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->_expression;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* 加工工厂类由开发者自行开发,继承自这个类
|
||||
*/
|
||||
abstract class LtAbstractDbSqlMapFilterObject {
|
||||
|
||||
// query()方法返回的结果集,用于加工的原料
|
||||
public $result;
|
||||
|
||||
/**
|
||||
* 需要被继承,实现逻辑的操作类,输入query()方法返回的结果集
|
||||
* 经过处理后返回开发者定义的对象或结构
|
||||
*/
|
||||
abstract protected function process();
|
||||
}
|
||||
|
14
extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapClient.php
Executable file
14
extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapClient.php
Executable file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
class LtDbSqlMapClient
|
||||
{
|
||||
public $configHandle;
|
||||
public $dbh;
|
||||
|
||||
public function execute($mapId, $bind = null)
|
||||
{
|
||||
$sqlMap = $this->configHandle->get($this->dbh->group . "." . $mapId);
|
||||
$forceUseMaster = isset($sqlMap["force_use_master"]) ? $sqlMap["force_use_master"] : false;
|
||||
return $this->dbh->query($sqlMap["sql"], $bind, $forceUseMaster);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* 用于加工DB句柄query方法返回的数组
|
||||
* 开发者在一次会话中可配置多个Filter
|
||||
*/
|
||||
class LtDbSqlMapResultFactory {
|
||||
// Filter列表
|
||||
public $filters;
|
||||
public $configHandle;
|
||||
|
||||
public function init() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 工厂入口,sql map client调用的方法
|
||||
* 在这个方法中调用开发者自定义的
|
||||
* LtAbstractSqlMapFilterObject.process()方法
|
||||
* 可配置多个process方法
|
||||
*/
|
||||
public function run() {
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,300 @@
|
||||
<?php
|
||||
/**
|
||||
* Database Table abstract
|
||||
*
|
||||
* @todo pretty join support
|
||||
*/
|
||||
class LtDbTableDataGateway
|
||||
{
|
||||
public $configHandle;
|
||||
public $dbh;
|
||||
/**
|
||||
* The created field name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $createdColumn;
|
||||
|
||||
/**
|
||||
* The modified field name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $modifiedColumn;
|
||||
|
||||
/**
|
||||
* The table name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $tableName;
|
||||
|
||||
/**
|
||||
* The fields array
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fields;
|
||||
|
||||
/**
|
||||
* The primary key
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey;
|
||||
protected $servers;
|
||||
|
||||
/**
|
||||
* Build table's field list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildFieldList()
|
||||
{
|
||||
if (!empty($this->fields))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
$servers = $this->configHandle->get('db.servers');
|
||||
$group = $this->dbh->group;
|
||||
$node = $this->dbh->node;
|
||||
$role = $this->dbh->role;
|
||||
$table = $this->tableName;
|
||||
$host = key($servers[$group][$node][$role]);
|
||||
$key = md5($group . $node . $role . $table . $host . $table);
|
||||
if (!$value = $this->configHandle->get($key))
|
||||
{
|
||||
$sql = $this->dbh->sqlAdapter->showFields($this->tableName);
|
||||
$rs = $this->dbh->query($sql);
|
||||
$this->fields = $this->dbh->sqlAdapter->getFields($rs);
|
||||
foreach($this->fields as $field)
|
||||
{
|
||||
if ($field['primary'] == 1)
|
||||
{
|
||||
$this->primaryKey = $field['name'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$value['fields'] = $this->fields;
|
||||
$value['primaryKey'] = $this->primaryKey;
|
||||
$this->configHandle->addConfig(array($key => $value));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->fields = $value['fields'];
|
||||
$this->primaryKey = $value['primaryKey'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A shortcut to SELECT COUNT(*) FROM table WHERE condition
|
||||
*
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example count(array('expression' => 'id < :id', 'value' => array('id' => 10)));
|
||||
*/
|
||||
public function count($args = null)
|
||||
{
|
||||
$selectTemplate = 'SELECT COUNT(*) AS total FROM %s%s';
|
||||
$where = isset($args['where']['expression']) ? ' WHERE ' . $args['where']['expression'] : '';
|
||||
$bind = isset($args['where']['value']) ? $args['where']['value'] : array();
|
||||
$join = isset($args['join']) ? ' ' . $args['join'] : '';
|
||||
$sql = sprintf($selectTemplate, $this->tableName, $join . $where);
|
||||
$queryResult = $this->dbh->query($sql, $bind);
|
||||
return $queryResult[0]['total'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a row by primary key
|
||||
*
|
||||
* @param string $primaryKeyId
|
||||
* @return string
|
||||
* @example delete(10);
|
||||
*/
|
||||
public function delete($primaryKeyId)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$where['expression'] = $this->primaryKey . '=:' . $this->primaryKey;
|
||||
$where['value'][$this->primaryKey] = $primaryKeyId;
|
||||
return $this->deleteRows($where);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete many rows from table
|
||||
* Please use this method carefully!
|
||||
*
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example deleteRows(array('expression' => "id > :id", 'value' => array('id' => 2)));
|
||||
*/
|
||||
public function deleteRows($args = null)
|
||||
{
|
||||
$deleteTemplate = 'DELETE FROM %s%s';
|
||||
$where = isset($args['expression']) ? ' WHERE ' . $args['expression'] : '';
|
||||
$bind = isset($args['value']) ? $args['value'] : array();
|
||||
$sql = sprintf($deleteTemplate, $this->tableName, $where);
|
||||
return $this->dbh->query($sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch one row from table by primary key
|
||||
*
|
||||
* @param string $primaryKeyId
|
||||
* @param array $args
|
||||
* @param boolean $useSlave
|
||||
* @return array
|
||||
* @example fetch(10)
|
||||
*/
|
||||
public function fetch($primaryKeyId, $args = null, $useSlave = true)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$fetchRowsArgs['where']['expression'] = $this->tableName . '.' . $this->primaryKey . '=:' . $this->primaryKey;
|
||||
$fetchRowsArgs['where']['value'][$this->primaryKey] = $primaryKeyId;
|
||||
$fetchRowsArgs['fields'] = isset($args['fields']) ? $args['fields'] : null;
|
||||
$fetchRowsArgs['join'] = isset($args['join']) ? $args['join'] : null;
|
||||
$fetchResult = $this->fetchRows($fetchRowsArgs, $useSlave);
|
||||
return $fetchResult ? $fetchResult[0] : $fetchResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch many rows from table
|
||||
*
|
||||
* @param array $args
|
||||
* @param boolean $useSlave
|
||||
* @return array
|
||||
* @example fetchRows(array('where' => array('expression' => "id > :id", 'value' => array('id' => 2))));
|
||||
*/
|
||||
public function fetchRows($args = null, $useSlave = true)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$selectTemplate = 'SELECT %s FROM %s%s';
|
||||
$fields = isset($args['fields']) ? $args['fields'] : '*';
|
||||
$where = isset($args['where']['expression']) ? ' WHERE ' . $args['where']['expression'] : '';
|
||||
$bind = isset($args['where']['value']) ? $args['where']['value'] : array();
|
||||
$join = isset($args['join']) ? ' ' . $args['join'] : '';
|
||||
$orderby = isset($args['orderby']) ? ' ORDER BY ' . $args['orderby'] : '';
|
||||
$groupby = isset($args['groupby']) ? ' GROUP BY ' . $args['groupby'] : '';
|
||||
$sql = sprintf($selectTemplate, $fields, $this->tableName, $join . $where . $groupby . $orderby);
|
||||
if (isset($args['limit']))
|
||||
{
|
||||
$offset = isset($args['offset']) ? $args['offset'] : 0;
|
||||
$sql = $sql . ' ' . $this->dbh->sqlAdapter->limit($args['limit'], $offset);
|
||||
}
|
||||
return $this->dbh->query($sql, $bind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert one row into table, then return the inserted row's pk
|
||||
*
|
||||
* @param array $args
|
||||
* @return string
|
||||
* @example insert(array('name' => 'lily', 'age' => '12'));
|
||||
*/
|
||||
public function insert($args = null)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$insertTemplate = 'INSERT INTO %s (%s) VALUES (%s)';
|
||||
$fields = array();
|
||||
$placeHolders = array();
|
||||
foreach($args as $field => $value)
|
||||
{
|
||||
if (isset($this->fields[$field]))
|
||||
{
|
||||
$fields[] = $field;
|
||||
$placeholders[] = ":$field";
|
||||
$values[$field] = $value;
|
||||
}
|
||||
}
|
||||
if (isset($this->fields[$this->createdColumn]) && !isset($args[$this->createdColumn]))
|
||||
{
|
||||
$fields[] = $this->createdColumn;
|
||||
$placeholders[] = ':' . $this->createdColumn;
|
||||
$values[$this->createdColumn] = time();
|
||||
}
|
||||
if (isset($this->fields[$this->modifiedColumn]) && !isset($args[$this->modifiedColumn]))
|
||||
{
|
||||
$fields[] = $this->modifiedColumn;
|
||||
$placeholders[] = ':' . $this->modifiedColumn;
|
||||
$values[$this->modifiedColumn] = time();
|
||||
}
|
||||
$sql = sprintf($insertTemplate, $this->tableName, implode(",", $fields), implode(",", $placeholders));
|
||||
$bind = $values;
|
||||
$queryResult = $this->dbh->query($sql, $bind);
|
||||
return isset($args[$this->primaryKey]) ? $args[$this->primaryKey] : $queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one row by primary key
|
||||
*
|
||||
* @param string $primaryKeyId
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example update(1, array('name' => 'lily', 'age' => '18'));
|
||||
*/
|
||||
public function update($primaryKeyId, $args = null)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$where['expression'] = $this->primaryKey . '=:' . $this->primaryKey;
|
||||
$where['value'][$this->primaryKey] = $primaryKeyId;
|
||||
return $this->updateRows($where, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update manay rows
|
||||
* Please use this method carefully!
|
||||
*
|
||||
* @param array $where
|
||||
* @param array $args
|
||||
* @return integer
|
||||
* @example updateRows(array('expression' => "id > :id", 'value' => array('id' => 2)), array('name' => 'kiwi', 'age' => '1'));
|
||||
*/
|
||||
public function updateRows($where, $args = null)
|
||||
{
|
||||
$this->buildFieldList();
|
||||
$updateTemplate = 'UPDATE %s SET %s%s';
|
||||
$fields = array();
|
||||
$bindParameters = array();
|
||||
$placeholderStyle = isset($where['value']) && array_key_exists(0, $where['value']) ? 'questionMark' : 'named';
|
||||
foreach($args as $field => $value)
|
||||
{
|
||||
if (isset($this->fields[$field]))
|
||||
{
|
||||
if ($args[$field] instanceof DbExpression)
|
||||
{
|
||||
$fields[] = "$field=" . $args[$field]->__toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ('named' == $placeholderStyle)
|
||||
{
|
||||
$fields[] = "$field=:$field";
|
||||
$bindParameters[$field] = $args[$field];
|
||||
}
|
||||
else
|
||||
{
|
||||
$fields[] = "$field=?";
|
||||
$bindParameters[] = $args[$field];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->fields[$this->modifiedColumn]) && !isset($args[$this->modifiedColumn]))
|
||||
{
|
||||
if ('named' == $placeholderStyle)
|
||||
{
|
||||
$fields[] = $this->modifiedColumn . '=:' . $this->modifiedColumn;
|
||||
$bindParameters[$this->modifiedColumn] = time();
|
||||
}
|
||||
else
|
||||
{
|
||||
$fields[] = $this->modifiedColumn . '=?';
|
||||
$bindParameters[] = time();
|
||||
}
|
||||
}
|
||||
$whereCause = isset($where['expression']) ? ' WHERE ' . $where['expression'] : '';
|
||||
$bind = isset($where['value']) ? array_merge($bindParameters, $where['value']) : $bindParameters;
|
||||
$sql = sprintf($updateTemplate, $this->tableName, implode(",", $fields), $whereCause);
|
||||
return $this->dbh->query($sql, $bind);
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
<?php
|
@ -0,0 +1 @@
|
||||
<?php
|
Reference in New Issue
Block a user