204 lines
6.7 KiB
PHP
204 lines
6.7 KiB
PHP
<?php defined('SYSPATH') or die('No direct access allowed.');
|
|
|
|
/**
|
|
* This class extends Kohana's [ORM] class to create defaults for TSM.
|
|
*
|
|
* @package TSM Database Module
|
|
* @category Helpers
|
|
* @author Deon George
|
|
* @copyright (c) 2010-2014 Deon George
|
|
* @license http://dev.leenooks.net/license.html
|
|
*/
|
|
abstract class ORM_TSM extends ORM {
|
|
protected $_created_column = NULL;
|
|
protected $_updated_column = NULL;
|
|
|
|
// Suppress ORMs inclusion of <table_name>.*
|
|
protected $_disable_wild_select = TRUE;
|
|
// Suppress ORMs inclusion of <table_name>. to column joins
|
|
protected $_disable_join_table_name = TRUE;
|
|
// Suppress ORMs use of limit
|
|
protected $_disable_limit = TRUE;
|
|
// To enable effective caching, this must disabled.
|
|
protected $_reload_on_wakeup = FALSE;
|
|
|
|
// Enable the formating of columns
|
|
protected $_object_formated = array();
|
|
protected $_formated = FALSE;
|
|
protected $_formats = array();
|
|
|
|
protected $_custom_cols = array();
|
|
protected $_tsm = array();
|
|
|
|
/**
|
|
*
|
|
* Configuration to enable PLA to work with DSMADMC & DB2 connections
|
|
* This is required, because the schema is different between each
|
|
* connection?
|
|
*/
|
|
protected function _initialize() {
|
|
// Set out DB connection configuration.
|
|
$this->_db_group = Kohana::$config->load('tsm')->client_type;
|
|
|
|
// Adjustments for DSMADMC or DB2 connections
|
|
if (array_key_exists($this->_db_group,$this->_tsm))
|
|
foreach ($this->_tsm[$this->_db_group] as $k => $v)
|
|
if (preg_match('/^_/',$k))
|
|
$this->{$k} = $v;
|
|
|
|
if ($this->_db_group == 'db2')
|
|
$this->_disable_join_table_name = FALSE;
|
|
|
|
parent::_initialize();
|
|
}
|
|
|
|
public function __get($column) {
|
|
// Get a substited column name - need for DB2/DSMADMC schema differences
|
|
if (isset($this->_tsm[$this->_db_group]['translate']) AND array_key_exists($column,$this->_tsm[$this->_db_group]['translate']))
|
|
return is_null($c=$this->_tsm[$this->_db_group]['translate'][$column]) ? NULL : parent::__get($c);
|
|
|
|
else
|
|
return parent::__get($column);
|
|
}
|
|
|
|
public function __set($column,$value) {
|
|
if (in_array($column,$this->_custom_cols)) {
|
|
|
|
// See if the data really changed
|
|
if (! isset($this->_object[$column]) OR $value !== $this->_object[$column]) {
|
|
$this->_table_columns[$column]['data_type'] = 'custom';
|
|
|
|
$this->_object[$column] = $value;
|
|
|
|
// Data has changed
|
|
$this->_changed[$column] = $column;
|
|
|
|
// Object is no longer saved or valid
|
|
$this->_saved = $this->_valid = FALSE;
|
|
}
|
|
|
|
} else
|
|
parent::__set($column,$value);
|
|
}
|
|
|
|
public function find() {
|
|
Log::instance()->add(LOG::DEBUG,'ENTER :method',array(':method'=>__METHOD__));
|
|
|
|
Log::instance()->add(LOG::DEBUG,'METHOD :method: isCacheable: :cable, table: :table',array(':method'=>__METHOD__,':cable'=>($x=$this->isCacheable()) ? $x : 'N',':table'=>$this->_table_name));
|
|
// Check if we can preload our data and havent already done it
|
|
// Kohana uses Kohana::cache here, instead of Cache()
|
|
if ($time = $this->isCacheable() AND is_null(Kohana::cache($cache_key = 'PRELOAD:'.$this->_table_name))) {
|
|
Log::instance()->add(LOG::DEBUG,'PRELOADING :method: table: :table',array(':method'=>__METHOD__,':table'=>$this->_table_name));
|
|
|
|
// Firstly set our cache, so that we dont get in a loop
|
|
Kohana::cache($cache_key,TRUE,$time-1);
|
|
|
|
// Find all records of this type
|
|
$c = get_class($this);
|
|
$x = new $c;
|
|
|
|
foreach ($x->find_all() as $record) {
|
|
// Simulate loading the record so that we can get the SQL to use as our cache key
|
|
$y = new $c;
|
|
$y->where($y->_primary_key,'=',(string)$record);
|
|
|
|
// Code, as extracted from ORM to complete building the SQL
|
|
$y->_build(Database::SELECT);
|
|
$y->_db_builder->from(array($y->_table_name,$y->_object_name));
|
|
if (! isset($y->_db_applied['order_by']) AND ! empty($y->_sorting))
|
|
foreach ($y->_sorting as $column => $direction) {
|
|
if (strpos($column, '.') === FALSE)
|
|
// Sorting column for use in JOINs
|
|
$column = ($y->_disable_join_table_name ? '' : $y->_table_name.'.').$column;
|
|
|
|
$y->_db_builder->order_by($column, $direction);
|
|
}
|
|
|
|
// Set the cache key based on the database instance name and SQL
|
|
$cache_key = 'Database::query("'.$y->_db.'", "'.(string)$y->_db_builder.'")';
|
|
unset($y);
|
|
|
|
// Cache the record, our subsequent find should get a cache hit now.
|
|
Kohana::cache($cache_key, array($record->as_array()), $time);
|
|
Log::instance()->add(LOG::DEBUG,'Cache SET for TIME: :time, KEY: :cache_key',array(':cache_key'=>$cache_key,':time'=>$time));
|
|
}
|
|
|
|
unset($x);
|
|
}
|
|
|
|
Log::instance()->add(LOG::DEBUG,'LEAVE :method',array(':method'=>__METHOD__));
|
|
|
|
// Contiue as normal
|
|
return parent::find();
|
|
}
|
|
|
|
private function isCacheable() {
|
|
$config = Kohana::$config->load('database')->{Kohana::$config->load('tsm')->client_type};
|
|
|
|
if ($config['caching'] AND isset($config['cachepreload'][$this->_table_name]) AND count($this->_db_pending) == 1 AND $this->_db_pending[0]['name'] == 'where' AND $this->_db_pending[0]['args'][0] == $this->_primary_key AND $this->_db_pending[0]['args'][1] == '=')
|
|
return $config['cachepreload'][$this->_table_name];
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
protected function _load_result($multiple = FALSE) {
|
|
// We'll cache our query results
|
|
if ($c = $this->_db->caching($this->_table_name))
|
|
$this->_db_builder->cached($c);
|
|
|
|
return parent::_load_result($multiple);
|
|
}
|
|
|
|
/**
|
|
* Proxy method to Database list_columns.
|
|
* This enables caching of the list_columns queries. Since this doesnt
|
|
* we hard code the cache to 7 days.
|
|
*
|
|
* @return array
|
|
* @todo This cache time needs to be better integrated with other caching times.
|
|
*/
|
|
public function list_columns() {
|
|
// We'll cache our query results
|
|
if ($this->_db->caching('SCHEMA')) {
|
|
// Set the cache key based on the database instance name and SQL
|
|
$cache_key = 'Database::query(LC:'.$this->_table_name.')';
|
|
|
|
if (! is_null($result = Cache::instance()->get($cache_key)))
|
|
// Return a cached result
|
|
return $result;
|
|
}
|
|
|
|
// Proxy to database
|
|
$result = $this->_db->list_columns($this->_table_name);
|
|
|
|
// Cache the result array
|
|
if (isset($cache_key))
|
|
Cache::instance()->set($cache_key, $result, 604800);
|
|
|
|
return $result;
|
|
}
|
|
|
|
// Load our values into the ORM object
|
|
public function load_object(array $values) {
|
|
return parent::_load_values($values);
|
|
}
|
|
|
|
public static function date($date,$format) {
|
|
return $date ? date($format,strtotime($date)) : '';
|
|
}
|
|
|
|
protected function datatypemap($type) {
|
|
$x = Kohana::$config->load('tsm')->datatypes;
|
|
|
|
return array_key_exists($type,$x) ? $x[$type] : $x;
|
|
}
|
|
|
|
public function values(array $values,array $expected=NULL) {
|
|
foreach (array_intersect(array_keys($values),$this->_custom_cols) as $col)
|
|
$this->_table_columns[$col]['data_type'] = 'custom';
|
|
|
|
return parent::values($values,$expected);
|
|
}
|
|
}
|
|
?>
|