Built in caching for primary key queries
Selects done against a primary key will automatically cache to Memcached (haven't tried it, but it should fail gracefully) indexed by the model name and the primary key ([NAMESPACE-]MODEL-PKEY). Any updates or deletes against the same primary key will purge the cache automatically. The major caveat here is the case of mass updates which would result in stale data. As it stands the data is being cached for a mere 5 minutes, so this multiple row update scenario would be short lived but ideally, I'll be pushing back the time to live on the cache and/or making it something that's configurable. If you have to do mass updates, you're probably doing them with a cronjob and should just be flushing all of the cache in that scenario (as it would be nearly impossible to detect the affected keys and purge them all).
This commit is contained in:
parent
dc0d98906f
commit
99aa78b6fa
3 changed files with 110 additions and 84 deletions
|
@ -24,7 +24,9 @@
|
|||
* don't entirely remember specifics, but the reason for not using Memcached()
|
||||
* was due to an unexplainable bug in the version in the repository for Ubuntu
|
||||
* 10.04 LTS. Memcached() does support more of the memcached protocol and will
|
||||
* eventually be what PICKLES uses.
|
||||
* eventually be what PICKLES uses. Keys are forced to be uppercase for
|
||||
* consistencies sake as I've been burned by the case sensitivity due to typos
|
||||
* in my code.
|
||||
*
|
||||
* Requires php5-memcache
|
||||
*
|
||||
|
@ -155,7 +157,7 @@ class Cache extends Object
|
|||
{
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->get($this->namespace . $key);
|
||||
return $this->connection->get(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -177,9 +179,11 @@ class Cache extends Object
|
|||
*/
|
||||
public function set($key, $value, $expire = 300)
|
||||
{
|
||||
$key = strtoupper($key);
|
||||
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->set($this->namespace . $key, $value, 0, $expire);
|
||||
return $this->connection->set(strtoupper($this->namespace . $key), $value, 0, $expire);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -197,7 +201,7 @@ class Cache extends Object
|
|||
{
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->delete($this->namespace . $key);
|
||||
return $this->connection->delete(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -216,7 +220,7 @@ class Cache extends Object
|
|||
{
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->increment($this->namespace . $key);
|
||||
return $this->connection->increment(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -26,6 +26,14 @@ class Model extends Object
|
|||
{
|
||||
// {{{ Properties
|
||||
|
||||
/**
|
||||
* Model Name
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $model = null;
|
||||
|
||||
/**
|
||||
* Database Object
|
||||
*
|
||||
|
@ -76,14 +84,6 @@ class Model extends Object
|
|||
*/
|
||||
private $input_parameters = array();
|
||||
|
||||
/**
|
||||
* Datasource
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $datasource;
|
||||
|
||||
/**
|
||||
* Insert Priority
|
||||
*
|
||||
|
@ -298,13 +298,16 @@ class Model extends Object
|
|||
// Runs the parent constructor so we have the config
|
||||
parent::__construct();
|
||||
|
||||
// Gets an instance of the cache and database
|
||||
// @todo Datasource has no way of being set
|
||||
$this->db = Database::getInstance($this->datasource != '' ? $this->datasource : null);
|
||||
$this->caching = $this->db->cache;
|
||||
// Gets an instance of the database and check which it is
|
||||
$this->db = Database::getInstance();
|
||||
$this->mysql = ($this->db->driver == 'pdo_mysql');
|
||||
$this->postgresql = ($this->db->driver == 'pdo_pgsql');
|
||||
|
||||
// Sets up the cache object and grabs the class name to use in our cache keys
|
||||
$this->cache = Cache::getInstance();
|
||||
$this->model = get_class($this);
|
||||
|
||||
// Default column mapping
|
||||
$columns = array(
|
||||
'id' => 'id',
|
||||
'created_at' => 'created_at',
|
||||
|
@ -342,12 +345,7 @@ class Model extends Object
|
|||
}
|
||||
}
|
||||
|
||||
$this->db->columns = $columns;
|
||||
|
||||
if ($this->caching)
|
||||
{
|
||||
$this->cache = Cache::getInstance();
|
||||
}
|
||||
$this->columns = $columns;
|
||||
|
||||
// Takes a snapshot of the [non-object] object properties
|
||||
foreach ($this as $variable => $value)
|
||||
|
@ -409,6 +407,7 @@ class Model extends Object
|
|||
}
|
||||
elseif (ctype_digit((string)$type_or_parameters))
|
||||
{
|
||||
$cache_key = $this->model . '-' . $type_or_parameters;
|
||||
$parameters = array($this->columns['id'] => $type_or_parameters);
|
||||
|
||||
if ($this->columns['is_deleted'])
|
||||
|
@ -417,10 +416,10 @@ class Model extends Object
|
|||
}
|
||||
|
||||
$this->loadParameters($parameters);
|
||||
$cache_key = 'PICKLES-' . $this->datasource . '-' . $this->table . '-' . $type_or_parameters;
|
||||
}
|
||||
elseif (ctype_digit((string)$parameters))
|
||||
{
|
||||
$cache_key = $this->model . '-' . $parameters;
|
||||
$parameters = array($this->columns['id'] => $parameters);
|
||||
|
||||
if ($this->columns['is_deleted'])
|
||||
|
@ -462,7 +461,7 @@ class Model extends Object
|
|||
|
||||
if (isset($cache_key))
|
||||
{
|
||||
//$cached = $this->cache->get($cache_key);
|
||||
$cached = $this->cache->get($cache_key);
|
||||
}
|
||||
|
||||
if (isset($cached) && $cached)
|
||||
|
@ -471,11 +470,14 @@ class Model extends Object
|
|||
}
|
||||
else
|
||||
{
|
||||
$this->records = $this->db->fetch(implode(' ', $this->sql), (count($this->input_parameters) == 0 ? null : $this->input_parameters));
|
||||
$this->records = $this->db->fetch(
|
||||
implode(' ', $this->sql),
|
||||
(count($this->input_parameters) == 0 ? null : $this->input_parameters)
|
||||
);
|
||||
|
||||
if (isset($cache_key))
|
||||
{
|
||||
//$this->cache->set($cache_key, $this->records);
|
||||
$this->cache->set($cache_key, $this->records);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,7 +602,7 @@ class Model extends Object
|
|||
{
|
||||
$format = (stripos($columns, 'USE ') === false);
|
||||
|
||||
$this->sql[] = ($format == true ? 'USE INDEX (' : '') . $columns . ($format == true ? ')' : '');
|
||||
$this->sql[] = ($format ? 'USE INDEX (' : '') . $columns . ($format ? ')' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -608,7 +610,7 @@ class Model extends Object
|
|||
{
|
||||
$format = (stripos($this->hints, 'USE ') === false);
|
||||
|
||||
$this->sql[] = ($format == true ? 'USE INDEX (' : '') . $this->hints . ($format == true ? ')' : '');
|
||||
$this->sql[] = ($format ? 'USE INDEX (' : '') . $this->hints . ($format ? ')' : '');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1063,7 +1065,7 @@ class Model extends Object
|
|||
}
|
||||
else
|
||||
{
|
||||
if ($update === true)
|
||||
if ($update == true)
|
||||
{
|
||||
$sql = 'UPDATE';
|
||||
}
|
||||
|
@ -1092,13 +1094,13 @@ class Model extends Object
|
|||
$sql .= ' INTO';
|
||||
}
|
||||
|
||||
$sql .= ' ' . $this->table . ($update === true ? ' SET ' : ' ');
|
||||
$sql .= ' ' . $this->table . ($update ? ' SET ' : ' ');
|
||||
}
|
||||
|
||||
$input_parameters = null;
|
||||
|
||||
// Limits the columns being updated
|
||||
$record = ($update === true ? array_diff_assoc($this->record, isset($this->original[$this->index]) ? $this->original[$this->index] : array()) : $this->record);
|
||||
$record = ($update ? array_diff_assoc($this->record, isset($this->original[$this->index]) ? $this->original[$this->index] : array()) : $this->record);
|
||||
|
||||
// Makes sure there's something to INSERT or UPDATE
|
||||
if (count($record) > 0)
|
||||
|
@ -1110,7 +1112,7 @@ class Model extends Object
|
|||
{
|
||||
if ($column != $this->columns['id'])
|
||||
{
|
||||
if ($update === true)
|
||||
if ($update == true)
|
||||
{
|
||||
if ($input_parameters != null)
|
||||
{
|
||||
|
@ -1129,7 +1131,7 @@ class Model extends Object
|
|||
}
|
||||
|
||||
// If it's an UPDATE tack on the ID
|
||||
if ($update === true)
|
||||
if ($update == true)
|
||||
{
|
||||
if ($this->columns['updated_at'] != false)
|
||||
{
|
||||
|
@ -1155,11 +1157,6 @@ class Model extends Object
|
|||
|
||||
$sql .= ' WHERE ' . $this->columns['id'] . ' = ?' . ($this->mysql ? ' LIMIT 1' : '') . ';';
|
||||
$input_parameters[] = $this->record[$this->columns['id']];
|
||||
|
||||
if ($this->caching)
|
||||
{
|
||||
//$this->cache->delete('PICKLES-' . $this->datasource . '-' . $this->table . '-' . $this->record[$this->columns['id']]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1187,7 +1184,7 @@ class Model extends Object
|
|||
}
|
||||
|
||||
// Executes the query
|
||||
if ($this->postgresql && $update === false)
|
||||
if ($this->postgresql && $update == false)
|
||||
{
|
||||
$results = $this->db->fetch($sql, $input_parameters);
|
||||
|
||||
|
@ -1195,7 +1192,15 @@ class Model extends Object
|
|||
}
|
||||
else
|
||||
{
|
||||
return $this->db->execute($sql, $input_parameters);
|
||||
$results = $this->db->execute($sql, $input_parameters);
|
||||
|
||||
// Clears the cache
|
||||
if ($update)
|
||||
{
|
||||
$this->cache->delete($this->model . '-' . $this->record[$this->columns['id']]);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1241,8 +1246,12 @@ class Model extends Object
|
|||
}
|
||||
|
||||
$input_parameters[] = $this->record[$this->columns['id']];
|
||||
$results = $this->db->execute($sql, $input_parameters);
|
||||
|
||||
return $this->db->execute($sql, $input_parameters);
|
||||
// Clears the cache
|
||||
$this->cache->delete($this->model . '-' . $this->record[$this->columns['id']]);
|
||||
|
||||
return $results;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
97
jar.php
97
jar.php
|
@ -457,7 +457,9 @@ class Browser
|
|||
* don't entirely remember specifics, but the reason for not using Memcached()
|
||||
* was due to an unexplainable bug in the version in the repository for Ubuntu
|
||||
* 10.04 LTS. Memcached() does support more of the memcached protocol and will
|
||||
* eventually be what PICKLES uses.
|
||||
* eventually be what PICKLES uses. Keys are forced to be uppercase for
|
||||
* consistencies sake as I've been burned by the case sensitivity due to typos
|
||||
* in my code.
|
||||
*
|
||||
* Requires php5-memcache
|
||||
*
|
||||
|
@ -588,7 +590,7 @@ class Cache extends Object
|
|||
{
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->get($this->namespace . $key);
|
||||
return $this->connection->get(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -610,9 +612,11 @@ class Cache extends Object
|
|||
*/
|
||||
public function set($key, $value, $expire = 300)
|
||||
{
|
||||
$key = strtoupper($key);
|
||||
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->set($this->namespace . $key, $value, 0, $expire);
|
||||
return $this->connection->set(strtoupper($this->namespace . $key), $value, 0, $expire);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -630,7 +634,7 @@ class Cache extends Object
|
|||
{
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->delete($this->namespace . $key);
|
||||
return $this->connection->delete(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -649,7 +653,7 @@ class Cache extends Object
|
|||
{
|
||||
if ($this->open())
|
||||
{
|
||||
return $this->connection->increment($this->namespace . $key);
|
||||
return $this->connection->increment(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -4036,6 +4040,14 @@ class Model extends Object
|
|||
{
|
||||
// {{{ Properties
|
||||
|
||||
/**
|
||||
* Model Name
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $model = null;
|
||||
|
||||
/**
|
||||
* Database Object
|
||||
*
|
||||
|
@ -4086,14 +4098,6 @@ class Model extends Object
|
|||
*/
|
||||
private $input_parameters = array();
|
||||
|
||||
/**
|
||||
* Datasource
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $datasource;
|
||||
|
||||
/**
|
||||
* Insert Priority
|
||||
*
|
||||
|
@ -4308,13 +4312,16 @@ class Model extends Object
|
|||
// Runs the parent constructor so we have the config
|
||||
parent::__construct();
|
||||
|
||||
// Gets an instance of the cache and database
|
||||
// @todo Datasource has no way of being set
|
||||
$this->db = Database::getInstance($this->datasource != '' ? $this->datasource : null);
|
||||
$this->caching = $this->db->cache;
|
||||
// Gets an instance of the database and check which it is
|
||||
$this->db = Database::getInstance();
|
||||
$this->mysql = ($this->db->driver == 'pdo_mysql');
|
||||
$this->postgresql = ($this->db->driver == 'pdo_pgsql');
|
||||
|
||||
// Sets up the cache object and grabs the class name to use in our cache keys
|
||||
$this->cache = Cache::getInstance();
|
||||
$this->model = get_class($this);
|
||||
|
||||
// Default column mapping
|
||||
$columns = array(
|
||||
'id' => 'id',
|
||||
'created_at' => 'created_at',
|
||||
|
@ -4352,12 +4359,7 @@ class Model extends Object
|
|||
}
|
||||
}
|
||||
|
||||
$this->db->columns = $columns;
|
||||
|
||||
if ($this->caching)
|
||||
{
|
||||
$this->cache = Cache::getInstance();
|
||||
}
|
||||
$this->columns = $columns;
|
||||
|
||||
// Takes a snapshot of the [non-object] object properties
|
||||
foreach ($this as $variable => $value)
|
||||
|
@ -4419,6 +4421,7 @@ class Model extends Object
|
|||
}
|
||||
elseif (ctype_digit((string)$type_or_parameters))
|
||||
{
|
||||
$cache_key = $this->model . '-' . $type_or_parameters;
|
||||
$parameters = array($this->columns['id'] => $type_or_parameters);
|
||||
|
||||
if ($this->columns['is_deleted'])
|
||||
|
@ -4427,10 +4430,10 @@ class Model extends Object
|
|||
}
|
||||
|
||||
$this->loadParameters($parameters);
|
||||
$cache_key = 'PICKLES-' . $this->datasource . '-' . $this->table . '-' . $type_or_parameters;
|
||||
}
|
||||
elseif (ctype_digit((string)$parameters))
|
||||
{
|
||||
$cache_key = $this->model . '-' . $parameters;
|
||||
$parameters = array($this->columns['id'] => $parameters);
|
||||
|
||||
if ($this->columns['is_deleted'])
|
||||
|
@ -4472,7 +4475,7 @@ class Model extends Object
|
|||
|
||||
if (isset($cache_key))
|
||||
{
|
||||
//$cached = $this->cache->get($cache_key);
|
||||
$cached = $this->cache->get($cache_key);
|
||||
}
|
||||
|
||||
if (isset($cached) && $cached)
|
||||
|
@ -4481,11 +4484,14 @@ class Model extends Object
|
|||
}
|
||||
else
|
||||
{
|
||||
$this->records = $this->db->fetch(implode(' ', $this->sql), (count($this->input_parameters) == 0 ? null : $this->input_parameters));
|
||||
$this->records = $this->db->fetch(
|
||||
implode(' ', $this->sql),
|
||||
(count($this->input_parameters) == 0 ? null : $this->input_parameters)
|
||||
);
|
||||
|
||||
if (isset($cache_key))
|
||||
{
|
||||
//$this->cache->set($cache_key, $this->records);
|
||||
$this->cache->set($cache_key, $this->records);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4610,7 +4616,7 @@ class Model extends Object
|
|||
{
|
||||
$format = (stripos($columns, 'USE ') === false);
|
||||
|
||||
$this->sql[] = ($format == true ? 'USE INDEX (' : '') . $columns . ($format == true ? ')' : '');
|
||||
$this->sql[] = ($format ? 'USE INDEX (' : '') . $columns . ($format ? ')' : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4618,7 +4624,7 @@ class Model extends Object
|
|||
{
|
||||
$format = (stripos($this->hints, 'USE ') === false);
|
||||
|
||||
$this->sql[] = ($format == true ? 'USE INDEX (' : '') . $this->hints . ($format == true ? ')' : '');
|
||||
$this->sql[] = ($format ? 'USE INDEX (' : '') . $this->hints . ($format ? ')' : '');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5073,7 +5079,7 @@ class Model extends Object
|
|||
}
|
||||
else
|
||||
{
|
||||
if ($update === true)
|
||||
if ($update == true)
|
||||
{
|
||||
$sql = 'UPDATE';
|
||||
}
|
||||
|
@ -5102,13 +5108,13 @@ class Model extends Object
|
|||
$sql .= ' INTO';
|
||||
}
|
||||
|
||||
$sql .= ' ' . $this->table . ($update === true ? ' SET ' : ' ');
|
||||
$sql .= ' ' . $this->table . ($update ? ' SET ' : ' ');
|
||||
}
|
||||
|
||||
$input_parameters = null;
|
||||
|
||||
// Limits the columns being updated
|
||||
$record = ($update === true ? array_diff_assoc($this->record, isset($this->original[$this->index]) ? $this->original[$this->index] : array()) : $this->record);
|
||||
$record = ($update ? array_diff_assoc($this->record, isset($this->original[$this->index]) ? $this->original[$this->index] : array()) : $this->record);
|
||||
|
||||
// Makes sure there's something to INSERT or UPDATE
|
||||
if (count($record) > 0)
|
||||
|
@ -5120,7 +5126,7 @@ class Model extends Object
|
|||
{
|
||||
if ($column != $this->columns['id'])
|
||||
{
|
||||
if ($update === true)
|
||||
if ($update == true)
|
||||
{
|
||||
if ($input_parameters != null)
|
||||
{
|
||||
|
@ -5139,7 +5145,7 @@ class Model extends Object
|
|||
}
|
||||
|
||||
// If it's an UPDATE tack on the ID
|
||||
if ($update === true)
|
||||
if ($update == true)
|
||||
{
|
||||
if ($this->columns['updated_at'] != false)
|
||||
{
|
||||
|
@ -5165,11 +5171,6 @@ class Model extends Object
|
|||
|
||||
$sql .= ' WHERE ' . $this->columns['id'] . ' = ?' . ($this->mysql ? ' LIMIT 1' : '') . ';';
|
||||
$input_parameters[] = $this->record[$this->columns['id']];
|
||||
|
||||
if ($this->caching)
|
||||
{
|
||||
//$this->cache->delete('PICKLES-' . $this->datasource . '-' . $this->table . '-' . $this->record[$this->columns['id']]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5197,7 +5198,7 @@ class Model extends Object
|
|||
}
|
||||
|
||||
// Executes the query
|
||||
if ($this->postgresql && $update === false)
|
||||
if ($this->postgresql && $update == false)
|
||||
{
|
||||
$results = $this->db->fetch($sql, $input_parameters);
|
||||
|
||||
|
@ -5205,7 +5206,15 @@ class Model extends Object
|
|||
}
|
||||
else
|
||||
{
|
||||
return $this->db->execute($sql, $input_parameters);
|
||||
$results = $this->db->execute($sql, $input_parameters);
|
||||
|
||||
// Clears the cache
|
||||
if ($update)
|
||||
{
|
||||
$this->cache->delete($this->model . '-' . $this->record[$this->columns['id']]);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5251,8 +5260,12 @@ class Model extends Object
|
|||
}
|
||||
|
||||
$input_parameters[] = $this->record[$this->columns['id']];
|
||||
$results = $this->db->execute($sql, $input_parameters);
|
||||
|
||||
return $this->db->execute($sql, $input_parameters);
|
||||
// Clears the cache
|
||||
$this->cache->delete($this->model . '-' . $this->record[$this->columns['id']]);
|
||||
|
||||
return $results;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue