<?php
|
/**
|
* PhalApi_Model_NotORM 基于NotORM的Model基类
|
*
|
* - 我们这里对ext_data使用json而不是序列化,是为了更容易阅读、理解、测试
|
* - 可重写formatExtData() & parseExtData()重新定制针对序列化LOB的转换
|
* - 具体子类需要实现getTableName($id)以提供对应的表名或者分表名
|
* - 对于如何寻找表主键,我们将配置中全部的表(包括分表)对应的主键进行了装配,如果觉得有性能问题,可重写getTableKey($table);这是一个手动和自动的问题
|
*
|
* @package PhalApi\Model
|
* @license http://www.phalapi.net/license
|
* @link http://www.phalapi.net/
|
* @author dogstar <chanzonghuang@gmail.com> 2015-02-22
|
*/
|
|
class PhalApi_Model_NotORM implements PhalApi_Model {
|
|
protected static $tableKeys = array();
|
|
public function get($id, $fields = '*') {
|
$needFields = is_array($fields) ? implode(',', $fields) : $fields;
|
$notorm = $this->getORM($id);
|
|
$table = $this->getTableName($id);
|
$rs = $notorm->select($needFields)
|
->where($this->getTableKey($table), $id)->fetch();
|
|
$this->parseExtData($rs);
|
|
return $rs;
|
}
|
|
public function insert($data, $id = NULL) {
|
$this->formatExtData($data);
|
|
$notorm = $this->getORM($id);
|
$notorm->insert($data);
|
|
return $notorm->insert_id();
|
}
|
|
public function update($id, $data) {
|
$this->formatExtData($data);
|
|
$notorm = $this->getORM($id);
|
|
$table = $this->getTableName($id);
|
return $notorm->where($this->getTableKey($table), $id)->update($data);
|
}
|
|
public function delete($id) {
|
$notorm = $this->getORM($id);
|
|
$table = $this->getTableName($id);
|
return $notorm->where($this->getTableKey($table), $id)->delete();
|
}
|
|
/**
|
* 对LOB的ext_data字段进行格式化(序列化)
|
*/
|
protected function formatExtData(&$data) {
|
if (isset($data['ext_data'])) {
|
$data['ext_data'] = json_encode($data['ext_data']);
|
}
|
}
|
|
/**
|
* 对LOB的ext_data字段进行解析(反序列化)
|
*/
|
protected function parseExtData(&$data) {
|
if (isset($data['ext_data'])) {
|
$data['ext_data'] = json_decode($data['ext_data'], true);
|
}
|
}
|
|
/**
|
* 根据主键值返回对应的表名,注意分表的情况
|
*
|
* 默认表名为:[表前缀] + 全部小写的匹配表名
|
*
|
* 在以下场景下,需要重写此方法以指定表名
|
* + 1. 自动匹配的表名与实际表名不符
|
* + 2. 存在分表
|
* + 3. Model类名不含有Model_
|
*/
|
protected function getTableName($id) {
|
$className = get_class($this);
|
$pos = strpos($className, 'Model');
|
|
$tableName = $pos !== FALSE ? substr($className, $pos + 6) : $className;
|
return strtolower($tableName);
|
}
|
|
/**
|
* 根据表名获取主键名
|
*
|
* - 考虑到配置中的表主键不一定是id,所以这里将默认自动装配数据库配置并匹配对应的主键名
|
* - 如果不希望因自动匹配所带来的性能问题,可以在每个实现子类手工返回对应的主键名
|
* - 注意分表的情况
|
*
|
* @param string $table 表名/分表名
|
* @return string 主键名
|
*/
|
protected function getTableKey($table) {
|
if (empty(static::$tableKeys)) {
|
$this->loadTableKeys();
|
}
|
|
return isset(static::$tableKeys[$table]) ? static::$tableKeys[$table] : static::$tableKeys['__default__'];
|
}
|
|
/**
|
* 快速获取ORM实例,注意每次获取都是新的实例
|
* @param string/int $id
|
* @return NotORM_Result
|
*/
|
protected function getORM($id = NULL) {
|
$table = $this->getTableName($id);
|
return DI()->notorm->$table;
|
}
|
|
protected function loadTableKeys() {
|
$tables = DI()->config->get('dbs.tables');
|
if (empty($tables)) {
|
throw new PhalApi_Exception_InternalServerError(T('dbs.tables should not be empty'));
|
}
|
|
foreach ($tables as $tableName => $tableConfig) {
|
if (isset($tableConfig['start']) && isset($tableConfig['end'])) {
|
for ($i = $tableConfig['start']; $i <= $tableConfig['end']; $i ++) {
|
static::$tableKeys[$tableName . '_' . $i] = $tableConfig['key'];
|
}
|
} else {
|
static::$tableKeys[$tableName] = $tableConfig['key'];
|
}
|
}
|
}
|
}
|