Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • develop
  • issue-424
  • issue-525
  • master
  • master-no-logins
  • svn-staging
  • svn-testing
  • svn-trunk
  • topics/add-contribution-info
  • 2010-11-11
  • 2010-12-15
  • 2011-01-11
  • 2011-01-18
  • 2011-01-26
  • 2011-02-10
  • 2011-02-23
  • 2011-03-09
  • 2011-03-15
  • 2011-03-30
  • 2011-04-05
  • 2011-05-03
  • 2011-05-12
  • 2011-06-16
  • 2011-06-21
  • 2011-06-23
  • 2011-06-29
  • 2011-06-30
  • 2011-07-11
  • 2011-07-18
  • 2011-07-20
  • 2011-07-21
  • 2011-07-28
  • 2011-08-03
  • 2011-08-05
  • 2011-08-15
  • 2011-08-17
  • 2011-08-29
  • 2011-08-30
  • 2011-09-19
  • 2011-10-03
  • 2011-10-06
  • 2011-10-27
  • 2011-11-01
  • 2011-11-08
  • 2011-11-08.2
  • 2011-11-14
  • 2011-11-17
  • 2011-12-05
  • 2011-12-16
  • 2012-01-12
  • 2012-01-13
  • 2012-02-07
  • 2012-03-01
  • 2012-04-02
  • 2012-04-03
  • 2012-04-18
  • 20120207
  • 7.1
  • 7.2
  • 7.3
  • 7.3.1
  • 7.4
  • 7.5
  • 7.5.1
  • 7.6
  • 7.6.1
66 results

Target

Select target project
  • rklusman2/UNL-CMS
  • yzha1/UNL-CMS
  • pear/UNL-CMS
  • bbieber2/UNL-CMS
  • tsteiner2/UNL-CMS
  • erasmussen2/UNL-CMS
  • UNL-Information-Services/UNL-CMS
7 results
Select Git revision
  • develop
  • issue-424
  • master
  • master-no-logins
  • svn-staging
  • svn-testing
  • svn-trunk
  • topics/add-contribution-info
  • 2010-11-11
  • 2010-12-15
  • 2011-01-11
  • 2011-01-18
  • 2011-01-26
  • 2011-02-10
  • 2011-02-23
  • 2011-03-09
  • 2011-03-15
  • 2011-03-30
  • 2011-04-05
  • 2011-05-03
  • 2011-05-12
  • 2011-06-16
  • 2011-06-21
  • 2011-06-23
  • 2011-06-29
  • 2011-06-30
  • 2011-07-11
  • 2011-07-18
  • 2011-07-20
  • 2011-07-21
  • 2011-07-28
  • 2011-08-03
  • 2011-08-05
  • 2011-08-15
  • 2011-08-17
  • 2011-08-29
  • 2011-08-30
  • 2011-09-19
  • 2011-10-03
  • 2011-10-06
  • 2011-10-27
  • 2011-11-01
  • 2011-11-08
  • 2011-11-08.2
  • 2011-11-14
  • 2011-11-17
  • 2011-12-05
  • 2011-12-16
  • 2012-01-12
  • 2012-01-13
  • 2012-02-07
  • 2012-03-01
  • 2012-04-02
  • 2012-04-03
  • 2012-04-18
  • 20120207
  • 7.1
  • 7.10
  • 7.11
  • 7.12
  • 7.13
  • 7.14
  • 7.15
  • 7.16
  • 7.16.1
  • 7.17
  • 7.18
  • 7.19
  • 7.2
  • 7.3
  • 7.3.1
  • 7.4
  • 7.5
  • 7.5.1
  • 7.6
  • 7.6.1
  • 7.7
  • 7.7.1
  • 7.7.2
  • 7.7.3
  • 7.8
  • 7.9
82 results
Show changes
Showing
with 3367 additions and 1547 deletions
<?php <?php
// $Id: batch.queue.inc,v 1.1 2010/01/08 06:36:34 webchick Exp $
/** /**
* @file * @file
* Queue handlers used by the Batch API. * Queue handlers used by the Batch API.
* *
* Those implementations: * These implementations:
* - ensure FIFO ordering, * - Ensure FIFO ordering.
* - let an item be repeatedly claimed until it is actually deleted (no notion * - Allow an item to be repeatedly claimed until it is actually deleted (no
* of lease time or 'expire' date), to allow multipass operations. * notion of lease time or 'expire' date), to allow multipass operations.
*/ */
/** /**
* Batch queue implementation. * Defines a batch queue.
* *
* Stale items from failed batches are cleaned from the {queue} table on cron * Stale items from failed batches are cleaned from the {queue} table on cron
* using the 'created' date. * using the 'created' date.
*/ */
class BatchQueue extends SystemQueue { class BatchQueue extends SystemQueue {
/**
* Overrides SystemQueue::claimItem().
*
* Unlike SystemQueue::claimItem(), this method provides a default lease
* time of 0 (no expiration) instead of 30. This allows the item to be
* claimed repeatedly until it is deleted.
*/
public function claimItem($lease_time = 0) { public function claimItem($lease_time = 0) {
$item = db_query('SELECT data, item_id FROM {queue} q WHERE name = :name ORDER BY item_id ASC', array(':name' => $this->name))->fetchObject(); $item = db_query_range('SELECT data, item_id FROM {queue} q WHERE name = :name ORDER BY item_id ASC', 0, 1, array(':name' => $this->name))->fetchObject();
if ($item) { if ($item) {
$item->data = unserialize($item->data); $item->data = unserialize($item->data);
return $item; return $item;
...@@ -30,9 +35,9 @@ class BatchQueue extends SystemQueue { ...@@ -30,9 +35,9 @@ class BatchQueue extends SystemQueue {
} }
/** /**
* Retrieve all remaining items in the queue. * Retrieves all remaining items in the queue.
* *
* This is specific to Batch API and is not part of the DrupalQueueInterface, * This is specific to Batch API and is not part of the DrupalQueueInterface.
*/ */
public function getAllItems() { public function getAllItems() {
$result = array(); $result = array();
...@@ -45,10 +50,17 @@ class BatchQueue extends SystemQueue { ...@@ -45,10 +50,17 @@ class BatchQueue extends SystemQueue {
} }
/** /**
* Batch queue implementation used for non-progressive batches. * Defines a batch queue for non-progressive batches.
*/ */
class BatchMemoryQueue extends MemoryQueue { class BatchMemoryQueue extends MemoryQueue {
/**
* Overrides MemoryQueue::claimItem().
*
* Unlike MemoryQueue::claimItem(), this method provides a default lease
* time of 0 (no expiration) instead of 30. This allows the item to be
* claimed repeatedly until it is deleted.
*/
public function claimItem($lease_time = 0) { public function claimItem($lease_time = 0) {
if (!empty($this->queue)) { if (!empty($this->queue)) {
reset($this->queue); reset($this->queue);
...@@ -58,9 +70,9 @@ class BatchMemoryQueue extends MemoryQueue { ...@@ -58,9 +70,9 @@ class BatchMemoryQueue extends MemoryQueue {
} }
/** /**
* Retrieve all remaining items in the queue. * Retrieves all remaining items in the queue.
* *
* This is specific to Batch API and is not part of the DrupalQueueInterface, * This is specific to Batch API and is not part of the DrupalQueueInterface.
*/ */
public function getAllItems() { public function getAllItems() {
$result = array(); $result = array();
......
This diff is collapsed.
<?php <?php
// $Id: cache-install.inc,v 1.9 2010/05/18 18:26:30 dries Exp $
/** /**
* @file * @file
...@@ -7,7 +6,7 @@ ...@@ -7,7 +6,7 @@
*/ */
/** /**
* A stub cache implementation to be used during the installation process. * Defines a stub cache implementation to be used during installation.
* *
* The stub implementation is needed when database access is not yet available. * The stub implementation is needed when database access is not yet available.
* Because Drupal's caching system never requires that cached data be present, * Because Drupal's caching system never requires that cached data be present,
...@@ -16,22 +15,35 @@ ...@@ -16,22 +15,35 @@
* normal operations would have a negative impact on performance. * normal operations would have a negative impact on performance.
*/ */
class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterface { class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterface {
/**
* Overrides DrupalDatabaseCache::get().
*/
function get($cid) { function get($cid) {
return FALSE; return FALSE;
} }
/**
* Overrides DrupalDatabaseCache::getMultiple().
*/
function getMultiple(&$cids) { function getMultiple(&$cids) {
return array(); return array();
} }
/**
* Overrides DrupalDatabaseCache::set().
*/
function set($cid, $data, $expire = CACHE_PERMANENT) { function set($cid, $data, $expire = CACHE_PERMANENT) {
} }
/**
* Overrides DrupalDatabaseCache::clear().
*/
function clear($cid = NULL, $wildcard = FALSE) { function clear($cid = NULL, $wildcard = FALSE) {
// If there is a database cache, attempt to clear it whenever possible. The // If there is a database cache, attempt to clear it whenever possible. The
// reason for doing this is that the database cache can accumulate data // reason for doing this is that the database cache can accumulate data
// during installation due to any full bootstraps that may occur at the // during installation due to any full bootstraps that may occur at the
// same time (for example, AJAX requests triggered by the installer). If we // same time (for example, Ajax requests triggered by the installer). If we
// didn't try to clear it whenever this function is called, the data in the // didn't try to clear it whenever this function is called, the data in the
// cache would become stale; for example, the installer sometimes calls // cache would become stale; for example, the installer sometimes calls
// variable_set(), which updates the {variable} table and then clears the // variable_set(), which updates the {variable} table and then clears the
...@@ -53,6 +65,9 @@ class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterfac ...@@ -53,6 +65,9 @@ class DrupalFakeCache extends DrupalDatabaseCache implements DrupalCacheInterfac
} }
} }
/**
* Overrides DrupalDatabaseCache::isEmpty().
*/
function isEmpty() { function isEmpty() {
return TRUE; return TRUE;
} }
......
<?php <?php
// $Id: cache.inc,v 1.49 2010/10/07 17:44:53 dries Exp $
/** /**
* Get the cache object for a cache bin. * @file
* Functions and interfaces for cache handling.
*/
/**
* Gets the cache object for a cache bin.
* *
* By default, this returns an instance of the DrupalDatabaseCache class. * By default, this returns an instance of the DrupalDatabaseCache class.
* Classes implementing DrupalCacheInterface can register themselves both as a * Classes implementing DrupalCacheInterface can register themselves both as a
* default implementation and for specific bins. * default implementation and for specific bins.
* *
* @see DrupalCacheInterface
*
* @param $bin * @param $bin
* The cache bin for which the cache object should be returned. * The cache bin for which the cache object should be returned.
* @return DrupalCacheInterface * @return DrupalCacheInterface
* The cache object associated with the specified bin. * The cache object associated with the specified bin.
*
* @see DrupalCacheInterface
*/ */
function _cache_get_object($bin) { function _cache_get_object($bin) {
// We do not use drupal_static() here because we do not want to change the // We do not use drupal_static() here because we do not want to change the
...@@ -30,7 +34,7 @@ function _cache_get_object($bin) { ...@@ -30,7 +34,7 @@ function _cache_get_object($bin) {
} }
/** /**
* Return data from the persistent cache * Returns data from the persistent cache.
* *
* Data may be stored as either plain text or as serialized data. cache_get * Data may be stored as either plain text or as serialized data. cache_get
* will automatically return unserialized objects and arrays. * will automatically return unserialized objects and arrays.
...@@ -45,19 +49,22 @@ function _cache_get_object($bin) { ...@@ -45,19 +49,22 @@ function _cache_get_object($bin) {
* *
* @return * @return
* The cache or FALSE on failure. * The cache or FALSE on failure.
*
* @see cache_set()
*/ */
function cache_get($cid, $bin = 'cache') { function cache_get($cid, $bin = 'cache') {
return _cache_get_object($bin)->get($cid); return _cache_get_object($bin)->get($cid);
} }
/** /**
* Return data from the persistent cache when given an array of cache IDs. * Returns data from the persistent cache when given an array of cache IDs.
* *
* @param $cids * @param $cids
* An array of cache IDs for the data to retrieve. This is passed by * An array of cache IDs for the data to retrieve. This is passed by
* reference, and will have the IDs successfully returned from cache removed. * reference, and will have the IDs successfully returned from cache removed.
* @param $bin * @param $bin
* The cache bin where the data is stored. * The cache bin where the data is stored.
*
* @return * @return
* An array of the items successfully returned from cache indexed by cid. * An array of the items successfully returned from cache indexed by cid.
*/ */
...@@ -66,7 +73,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') { ...@@ -66,7 +73,7 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
} }
/** /**
* Store data in the persistent cache. * Stores data in the persistent cache.
* *
* The persistent cache is split up into several cache bins. In the default * The persistent cache is split up into several cache bins. In the default
* cache implementation, each cache bin corresponds to a database table by the * cache implementation, each cache bin corresponds to a database table by the
...@@ -133,13 +140,15 @@ function cache_get_multiple(array &$cids, $bin = 'cache') { ...@@ -133,13 +140,15 @@ function cache_get_multiple(array &$cids, $bin = 'cache') {
* general cache wipe. * general cache wipe.
* - A Unix timestamp: Indicates that the item should be kept at least until * - A Unix timestamp: Indicates that the item should be kept at least until
* the given time, after which it behaves like CACHE_TEMPORARY. * the given time, after which it behaves like CACHE_TEMPORARY.
*
* @see cache_get()
*/ */
function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) { function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
return _cache_get_object($bin)->set($cid, $data, $expire); return _cache_get_object($bin)->set($cid, $data, $expire);
} }
/** /**
* Expire data from the cache. * Expires data from the cache.
* *
* If called without arguments, expirable entries will be cleared from the * If called without arguments, expirable entries will be cleared from the
* cache_page and cache_block bins. * cache_page and cache_block bins.
...@@ -147,15 +156,12 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) { ...@@ -147,15 +156,12 @@ function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
* @param $cid * @param $cid
* If set, the cache ID to delete. Otherwise, all cache entries that can * If set, the cache ID to delete. Otherwise, all cache entries that can
* expire are deleted. * expire are deleted.
*
* @param $bin * @param $bin
* If set, the bin $bin to delete from. Mandatory * If set, the cache bin to delete from. Mandatory argument if $cid is set.
* argument if $cid is set.
*
* @param $wildcard * @param $wildcard
* If $wildcard is TRUE, cache IDs starting with $cid are deleted in * If TRUE, cache IDs starting with $cid are deleted in addition to the
* addition to the exact cache ID specified by $cid. If $wildcard is * exact cache ID specified by $cid. If $wildcard is TRUE and $cid is '*',
* TRUE and $cid is '*' then the entire bin $bin is emptied. * the entire cache bin is emptied.
*/ */
function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) { function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
if (!isset($cid) && !isset($bin)) { if (!isset($cid) && !isset($bin)) {
...@@ -171,13 +177,14 @@ function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) { ...@@ -171,13 +177,14 @@ function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
} }
/** /**
* Check if a cache bin is empty. * Checks if a cache bin is empty.
* *
* A cache bin is considered empty if it does not contain any valid data for any * A cache bin is considered empty if it does not contain any valid data for any
* cache ID. * cache ID.
* *
* @param $bin * @param $bin
* The cache bin to check. * The cache bin to check.
*
* @return * @return
* TRUE if the cache bin specified is empty. * TRUE if the cache bin specified is empty.
*/ */
...@@ -186,7 +193,7 @@ function cache_is_empty($bin) { ...@@ -186,7 +193,7 @@ function cache_is_empty($bin) {
} }
/** /**
* Interface for cache implementations. * Defines an interface for cache implementations.
* *
* All cache implementations have to implement this interface. * All cache implementations have to implement this interface.
* DrupalDatabaseCache provides the default implementation, which can be * DrupalDatabaseCache provides the default implementation, which can be
...@@ -198,7 +205,7 @@ function cache_is_empty($bin) { ...@@ -198,7 +205,7 @@ function cache_is_empty($bin) {
* DrupalCacheInterface was called MyCustomCache, the following line would make * DrupalCacheInterface was called MyCustomCache, the following line would make
* Drupal use it for the 'cache_page' bin: * Drupal use it for the 'cache_page' bin:
* @code * @code
* variable_set('cache_page', 'MyCustomCache'); * variable_set('cache_class_cache_page', 'MyCustomCache');
* @endcode * @endcode
* *
* Additionally, you can register your cache implementation to be used by * Additionally, you can register your cache implementation to be used by
...@@ -208,12 +215,23 @@ function cache_is_empty($bin) { ...@@ -208,12 +215,23 @@ function cache_is_empty($bin) {
* variable_set('cache_default_class', 'MyCustomCache'); * variable_set('cache_default_class', 'MyCustomCache');
* @endcode * @endcode
* *
* To implement a completely custom cache bin, use the same variable format:
* @code
* variable_set('cache_class_custom_bin', 'MyCustomCache');
* @endcode
* To access your custom cache bin, specify the name of the bin when storing
* or retrieving cached data:
* @code
* cache_set($cid, $data, 'custom_bin', $expire);
* cache_get($cid, 'custom_bin');
* @endcode
*
* @see _cache_get_object() * @see _cache_get_object()
* @see DrupalDatabaseCache * @see DrupalDatabaseCache
*/ */
interface DrupalCacheInterface { interface DrupalCacheInterface {
/** /**
* Constructor. * Constructs a new cache interface.
* *
* @param $bin * @param $bin
* The cache bin for which the object is created. * The cache bin for which the object is created.
...@@ -221,31 +239,34 @@ interface DrupalCacheInterface { ...@@ -221,31 +239,34 @@ interface DrupalCacheInterface {
function __construct($bin); function __construct($bin);
/** /**
* Return data from the persistent cache. Data may be stored as either plain * Returns data from the persistent cache.
* text or as serialized data. cache_get will automatically return *
* unserialized objects and arrays. * Data may be stored as either plain text or as serialized data. cache_get()
* will automatically return unserialized objects and arrays.
* *
* @param $cid * @param $cid
* The cache ID of the data to retrieve. * The cache ID of the data to retrieve.
*
* @return * @return
* The cache or FALSE on failure. * The cache or FALSE on failure.
*/ */
function get($cid); function get($cid);
/** /**
* Return data from the persistent cache when given an array of cache IDs. * Returns data from the persistent cache when given an array of cache IDs.
* *
* @param $cids * @param $cids
* An array of cache IDs for the data to retrieve. This is passed by * An array of cache IDs for the data to retrieve. This is passed by
* reference, and will have the IDs successfully returned from cache * reference, and will have the IDs successfully returned from cache
* removed. * removed.
*
* @return * @return
* An array of the items successfully returned from cache indexed by cid. * An array of the items successfully returned from cache indexed by cid.
*/ */
function getMultiple(&$cids); function getMultiple(&$cids);
/** /**
* Store data in the persistent cache. * Stores data in the persistent cache.
* *
* @param $cid * @param $cid
* The cache ID of the data to store. * The cache ID of the data to store.
...@@ -266,8 +287,10 @@ interface DrupalCacheInterface { ...@@ -266,8 +287,10 @@ interface DrupalCacheInterface {
/** /**
* Expire data from the cache. If called without arguments, expirable * Expires data from the cache.
* entries will be cleared from the cache_page and cache_block bins. *
* If called without arguments, expirable entries will be cleared from the
* cache_page and cache_block bins.
* *
* @param $cid * @param $cid
* If set, the cache ID to delete. Otherwise, all cache entries that can * If set, the cache ID to delete. Otherwise, all cache entries that can
...@@ -280,7 +303,7 @@ interface DrupalCacheInterface { ...@@ -280,7 +303,7 @@ interface DrupalCacheInterface {
function clear($cid = NULL, $wildcard = FALSE); function clear($cid = NULL, $wildcard = FALSE);
/** /**
* Check if a cache bin is empty. * Checks if a cache bin is empty.
* *
* A cache bin is considered empty if it does not contain any valid data for * A cache bin is considered empty if it does not contain any valid data for
* any cache ID. * any cache ID.
...@@ -292,7 +315,7 @@ interface DrupalCacheInterface { ...@@ -292,7 +315,7 @@ interface DrupalCacheInterface {
} }
/** /**
* Default cache implementation. * Defines a default cache implementation.
* *
* This is Drupal's default cache implementation. It uses the database to store * This is Drupal's default cache implementation. It uses the database to store
* cached data. Each cache bin corresponds to a database table by the same name. * cached data. Each cache bin corresponds to a database table by the same name.
...@@ -300,32 +323,38 @@ interface DrupalCacheInterface { ...@@ -300,32 +323,38 @@ interface DrupalCacheInterface {
class DrupalDatabaseCache implements DrupalCacheInterface { class DrupalDatabaseCache implements DrupalCacheInterface {
protected $bin; protected $bin;
/**
* Constructs a new DrupalDatabaseCache object.
*/
function __construct($bin) { function __construct($bin) {
$this->bin = $bin; $this->bin = $bin;
} }
/**
* Implements DrupalCacheInterface::get().
*/
function get($cid) { function get($cid) {
try { $cids = array($cid);
// Garbage collection necessary when enforcing a minimum cache lifetime. $cache = $this->getMultiple($cids);
$this->garbageCollection($this->bin); return reset($cache);
$cache = db_query("SELECT data, created, expire, serialized FROM {" . $this->bin . "} WHERE cid = :cid", array(':cid' => $cid))->fetchObject();
return $this->prepareItem($cache);
}
catch (Exception $e) {
// If the database is never going to be available, cache requests should
// return FALSE in order to allow exception handling to occur.
return FALSE;
}
} }
/**
* Implements DrupalCacheInterface::getMultiple().
*/
function getMultiple(&$cids) { function getMultiple(&$cids) {
try { try {
// Garbage collection necessary when enforcing a minimum cache lifetime. // Garbage collection necessary when enforcing a minimum cache lifetime.
$this->garbageCollection($this->bin); $this->garbageCollection($this->bin);
$query = db_select($this->bin);
$query->fields($this->bin, array('cid', 'data', 'created', 'expire', 'serialized')); // When serving cached pages, the overhead of using db_select() was found
$query->condition($this->bin . '.cid', $cids, 'IN'); // to add around 30% overhead to the request. Since $this->bin is a
$result = $query->execute(); // variable, this means the call to db_query() here uses a concatenated
// string. This is highly discouraged under any other circumstances, and
// is used here only due to the performance overhead we would incur
// otherwise. When serving an uncached page, the overhead of using
// db_select() is a much smaller proportion of the request.
$result = db_query('SELECT cid, data, created, expire, serialized FROM {' . db_escape_table($this->bin) . '} WHERE cid IN (:cids)', array(':cids' => $cids));
$cache = array(); $cache = array();
foreach ($result as $item) { foreach ($result as $item) {
$item = $this->prepareItem($item); $item = $this->prepareItem($item);
...@@ -366,13 +395,14 @@ class DrupalDatabaseCache implements DrupalCacheInterface { ...@@ -366,13 +395,14 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
} }
/** /**
* Prepare a cached item. * Prepares a cached item.
* *
* Checks that items are either permanent or did not expire, and unserializes * Checks that items are either permanent or did not expire, and unserializes
* data as appropriate. * data as appropriate.
* *
* @param $cache * @param $cache
* An item loaded from cache_get() or cache_get_multiple(). * An item loaded from cache_get() or cache_get_multiple().
*
* @return * @return
* The item with data unserialized as appropriate or FALSE if there is no * The item with data unserialized as appropriate or FALSE if there is no
* valid item to load. * valid item to load.
...@@ -401,6 +431,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface { ...@@ -401,6 +431,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
return $cache; return $cache;
} }
/**
* Implements DrupalCacheInterface::set().
*/
function set($cid, $data, $expire = CACHE_PERMANENT) { function set($cid, $data, $expire = CACHE_PERMANENT) {
$fields = array( $fields = array(
'serialized' => 0, 'serialized' => 0,
...@@ -427,6 +460,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface { ...@@ -427,6 +460,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
} }
} }
/**
* Implements DrupalCacheInterface::clear().
*/
function clear($cid = NULL, $wildcard = FALSE) { function clear($cid = NULL, $wildcard = FALSE) {
global $user; global $user;
...@@ -489,6 +525,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface { ...@@ -489,6 +525,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
} }
} }
/**
* Implements DrupalCacheInterface::isEmpty().
*/
function isEmpty() { function isEmpty() {
$this->garbageCollection(); $this->garbageCollection();
$query = db_select($this->bin); $query = db_select($this->bin);
......
This diff is collapsed.
This diff is collapsed.
<?php <?php
// $Id: log.inc,v 1.8 2010/03/31 15:09:21 dries Exp $
/** /**
* @file * @file
......
<?php <?php
// $Id: database.inc,v 1.34 2010/10/03 01:29:41 dries Exp $
/** /**
* @file * @file
...@@ -38,14 +37,20 @@ class DatabaseConnection_mysql extends DatabaseConnection { ...@@ -38,14 +37,20 @@ class DatabaseConnection_mysql extends DatabaseConnection {
$dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']); $dsn = 'mysql:host=' . $connection_options['host'] . ';port=' . (empty($connection_options['port']) ? 3306 : $connection_options['port']);
} }
$dsn .= ';dbname=' . $connection_options['database']; $dsn .= ';dbname=' . $connection_options['database'];
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array( // Allow PDO options to be overridden.
$connection_options += array(
'pdo' => array(),
);
$connection_options['pdo'] += array(
// So we don't have to mess around with cursors and unbuffered queries by default. // So we don't have to mess around with cursors and unbuffered queries by default.
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => TRUE,
// Because MySQL's prepared statements skip the query cache, because it's dumb. // Because MySQL's prepared statements skip the query cache, because it's dumb.
PDO::ATTR_EMULATE_PREPARES => TRUE, PDO::ATTR_EMULATE_PREPARES => TRUE,
// Force column names to lower case. // Force column names to lower case.
PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_CASE => PDO::CASE_LOWER,
)); );
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
// Force MySQL to use the UTF-8 character set. Also set the collation, if a // Force MySQL to use the UTF-8 character set. Also set the collation, if a
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci' // certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
...@@ -57,12 +62,22 @@ class DatabaseConnection_mysql extends DatabaseConnection { ...@@ -57,12 +62,22 @@ class DatabaseConnection_mysql extends DatabaseConnection {
$this->exec('SET NAMES utf8'); $this->exec('SET NAMES utf8');
} }
// Force MySQL's behavior to conform more closely to SQL standards. // Set MySQL init_commands if not already defined. Default Drupal's MySQL
// This allows Drupal to run almost seamlessly on many different // behavior to conform more closely to SQL standards. This allows Drupal
// kinds of database systems. These settings force MySQL to behave // to run almost seamlessly on many different kinds of database systems.
// the same as postgresql, or sqlite in regards to syntax interpretation // These settings force MySQL to behave the same as postgresql, or sqlite
// and invalid data handling. See http://drupal.org/node/344575 for further discussion. // in regards to syntax interpretation and invalid data handling. See
$this->exec("SET sql_mode='ANSI,TRADITIONAL'"); // http://drupal.org/node/344575 for further discussion. Also, as MySQL 5.5
// changed the meaning of TRADITIONAL we need to spell out the modes one by
// one.
$connection_options += array(
'init_commands' => array(),
);
$connection_options['init_commands'] += array(
'sql_mode' => "SET sql_mode = 'ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER'",
);
// Set connection options.
$this->exec(implode('; ', $connection_options['init_commands']));
} }
public function queryRange($query, $from, $count, array $args = array(), array $options = array()) { public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
...@@ -134,6 +149,53 @@ class DatabaseConnection_mysql extends DatabaseConnection { ...@@ -134,6 +149,53 @@ class DatabaseConnection_mysql extends DatabaseConnection {
catch (PDOException $e) { catch (PDOException $e) {
} }
} }
/**
* Overridden to work around issues to MySQL not supporting transactional DDL.
*/
protected function popCommittableTransactions() {
// Commit all the committable layers.
foreach (array_reverse($this->transactionLayers) as $name => $active) {
// Stop once we found an active transaction.
if ($active) {
break;
}
// If there are no more layers left then we should commit.
unset($this->transactionLayers[$name]);
if (empty($this->transactionLayers)) {
if (!PDO::commit()) {
throw new DatabaseTransactionCommitFailedException();
}
}
else {
// Attempt to release this savepoint in the standard way.
try {
$this->query('RELEASE SAVEPOINT ' . $name);
}
catch (PDOException $e) {
// However, in MySQL (InnoDB), savepoints are automatically committed
// when tables are altered or created (DDL transactions are not
// supported). This can cause exceptions due to trying to release
// savepoints which no longer exist.
//
// To avoid exceptions when no actual error has occurred, we silently
// succeed for MySQL error code 1305 ("SAVEPOINT does not exist").
if ($e->errorInfo[1] == '1305') {
// If one SAVEPOINT was released automatically, then all were.
// Therefore, clean the transaction stack.
$this->transactionLayers = array();
// We also have to explain to PDO that the transaction stack has
// been cleaned-up.
PDO::commit();
}
else {
throw $e;
}
}
}
}
}
} }
......
<?php <?php
// $Id: install.inc,v 1.4 2010/07/30 01:59:14 dries Exp $
/** /**
* @file * @file
...@@ -10,7 +9,6 @@ ...@@ -10,7 +9,6 @@
* Specifies installation tasks for MySQL and equivalent databases. * Specifies installation tasks for MySQL and equivalent databases.
*/ */
class DatabaseTasks_mysql extends DatabaseTasks { class DatabaseTasks_mysql extends DatabaseTasks {
/** /**
* The PDO driver name for MySQL and equivalent databases. * The PDO driver name for MySQL and equivalent databases.
* *
...@@ -22,7 +20,14 @@ class DatabaseTasks_mysql extends DatabaseTasks { ...@@ -22,7 +20,14 @@ class DatabaseTasks_mysql extends DatabaseTasks {
* Returns a human-readable name string for MySQL and equivalent databases. * Returns a human-readable name string for MySQL and equivalent databases.
*/ */
public function name() { public function name() {
return 'MySQL, MariaDB, or equivalent'; return st('MySQL, MariaDB, or equivalent');
}
/**
* Returns the minimum version for MySQL.
*/
public function minimumVersion() {
return '5.0.15';
} }
} }
<?php <?php
// $Id: query.inc,v 1.18 2010/06/26 01:40:05 dries Exp $
/** /**
* @ingroup database * @ingroup database
...@@ -43,8 +42,8 @@ class InsertQuery_mysql extends InsertQuery { ...@@ -43,8 +42,8 @@ class InsertQuery_mysql extends InsertQuery {
} }
public function __toString() { public function __toString() {
// Create a comments string to prepend to the query. // Create a sanitized comment string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; $comments = $this->connection->makeComment($this->comments);
// Default fields are always placed first for consistency. // Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields); $insert_fields = array_merge($this->defaultFields, $this->insertFields);
...@@ -93,8 +92,8 @@ class TruncateQuery_mysql extends TruncateQuery { ...@@ -93,8 +92,8 @@ class TruncateQuery_mysql extends TruncateQuery {
// not transactional, and result in an implicit COMMIT. When we are in a // not transactional, and result in an implicit COMMIT. When we are in a
// transaction, fallback to the slower, but transactional, DELETE. // transaction, fallback to the slower, but transactional, DELETE.
if ($this->connection->inTransaction()) { if ($this->connection->inTransaction()) {
// Create a comments string to prepend to the query. // Create a comment string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; $comments = $this->connection->makeComment($this->comments);
return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}'; return $comments . 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '}';
} }
else { else {
......
<?php <?php
// $Id: schema.inc,v 1.43 2010/10/22 15:18:56 webchick Exp $
/** /**
* @file * @file
...@@ -337,7 +336,7 @@ class DatabaseSchema_mysql extends DatabaseSchema { ...@@ -337,7 +336,7 @@ class DatabaseSchema_mysql extends DatabaseSchema {
$this->connection->query($query); $this->connection->query($query);
if (isset($spec['initial'])) { if (isset($spec['initial'])) {
$this->connection->update($table) $this->connection->update($table)
->fields(array($field, $spec['initial'])) ->fields(array($field => $spec['initial']))
->execute(); ->execute();
} }
if ($fixnull) { if ($fixnull) {
......
<?php <?php
// $Id: database.inc,v 1.43 2010/10/03 01:29:41 dries Exp $
/** /**
* @file * @file
...@@ -35,11 +34,25 @@ class DatabaseConnection_pgsql extends DatabaseConnection { ...@@ -35,11 +34,25 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
if (empty($connection_options['password'])) { if (empty($connection_options['password'])) {
$connection_options['password'] = NULL; $connection_options['password'] = NULL;
} }
// If the password contains a backslash it is treated as an escape character
// http://bugs.php.net/bug.php?id=53217
// so backslashes in the password need to be doubled up.
// The bug was reported against pdo_pgsql 1.0.2, backslashes in passwords
// will break on this doubling up when the bug is fixed, so check the version
//elseif (phpversion('pdo_pgsql') < 'version_this_was_fixed_in') {
else {
$connection_options['password'] = str_replace('\\', '\\\\', $connection_options['password']);
}
$this->connectionOptions = $connection_options; $this->connectionOptions = $connection_options;
$dsn = 'pgsql:host=' . $connection_options['host'] . ' dbname=' . $connection_options['database'] . ' port=' . $connection_options['port']; $dsn = 'pgsql:host=' . $connection_options['host'] . ' dbname=' . $connection_options['database'] . ' port=' . $connection_options['port'];
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], array(
// Allow PDO options to be overridden.
$connection_options += array(
'pdo' => array(),
);
$connection_options['pdo'] += array(
// Prepared statements are most effective for performance when queries // Prepared statements are most effective for performance when queries
// are recycled (used several times). However, if they are not re-used, // are recycled (used several times). However, if they are not re-used,
// prepared statements become ineffecient. Since most of Drupal's // prepared statements become ineffecient. Since most of Drupal's
...@@ -51,10 +64,16 @@ class DatabaseConnection_pgsql extends DatabaseConnection { ...@@ -51,10 +64,16 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
PDO::ATTR_STRINGIFY_FETCHES => TRUE, PDO::ATTR_STRINGIFY_FETCHES => TRUE,
// Force column names to lower case. // Force column names to lower case.
PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_CASE => PDO::CASE_LOWER,
)); );
parent::__construct($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
// Force PostgreSQL to use the UTF-8 character set by default. // Force PostgreSQL to use the UTF-8 character set by default.
$this->exec("SET NAMES 'UTF8'"); $this->exec("SET NAMES 'UTF8'");
// Execute PostgreSQL init_commands.
if (isset($connection_options['init_commands'])) {
$this->exec(implode('; ', $connection_options['init_commands']));
}
} }
public function query($query, array $args = array(), $options = array()) { public function query($query, array $args = array(), $options = array()) {
...@@ -137,10 +156,9 @@ class DatabaseConnection_pgsql extends DatabaseConnection { ...@@ -137,10 +156,9 @@ class DatabaseConnection_pgsql extends DatabaseConnection {
if (!isset($specials)) { if (!isset($specials)) {
$specials = array( $specials = array(
// In PostgreSQL, 'LIKE' is case-sensitive. For case-insensitive LIKE // In PostgreSQL, 'LIKE' is case-sensitive. For case-insensitive LIKE
// statements, we need to use ILIKE instead. Use backslash for escaping // statements, we need to use ILIKE instead.
// wildcard characters. 'LIKE' => array('operator' => 'ILIKE'),
'LIKE' => array('operator' => 'ILIKE', 'postfix' => ' ESCAPE ' . $this->quote("\\")), 'NOT LIKE' => array('operator' => 'NOT ILIKE'),
'NOT LIKE' => array('operator' => 'NOT ILIKE', 'postfix' => ' ESCAPE ' . $this->quote("\\")),
); );
} }
......
<?php <?php
// $Id: install.inc,v 1.10 2010/08/16 21:01:23 dries Exp $
/** /**
* @file * @file
...@@ -21,6 +20,10 @@ class DatabaseTasks_pgsql extends DatabaseTasks { ...@@ -21,6 +20,10 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
'function' => 'checkPHPVersion', 'function' => 'checkPHPVersion',
'arguments' => array(), 'arguments' => array(),
); );
$this->tasks[] = array(
'function' => 'checkBinaryOutput',
'arguments' => array(),
);
$this->tasks[] = array( $this->tasks[] = array(
'function' => 'initializeDatabase', 'function' => 'initializeDatabase',
'arguments' => array(), 'arguments' => array(),
...@@ -28,7 +31,11 @@ class DatabaseTasks_pgsql extends DatabaseTasks { ...@@ -28,7 +31,11 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
} }
public function name() { public function name() {
return 'PostgreSQL'; return st('PostgreSQL');
}
public function minimumVersion() {
return '8.3';
} }
/** /**
...@@ -49,7 +56,8 @@ class DatabaseTasks_pgsql extends DatabaseTasks { ...@@ -49,7 +56,8 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
$text .= 'Recreate the database with %encoding encoding. See !link for more details.'; $text .= 'Recreate the database with %encoding encoding. See !link for more details.';
$this->fail(st($text, $replacements)); $this->fail(st($text, $replacements));
} }
} catch (Exception $e) { }
catch (Exception $e) {
$this->fail(st('Drupal could not determine the encoding of the database was set to UTF-8')); $this->fail(st('Drupal could not determine the encoding of the database was set to UTF-8'));
} }
} }
...@@ -71,6 +79,60 @@ class DatabaseTasks_pgsql extends DatabaseTasks { ...@@ -71,6 +79,60 @@ class DatabaseTasks_pgsql extends DatabaseTasks {
}; };
} }
/**
* Check Binary Output.
*
* Unserializing does not work on Postgresql 9 when bytea_output is 'hex'.
*/
function checkBinaryOutput() {
// PostgreSQL < 9 doesn't support bytea_output, so verify we are running
// at least PostgreSQL 9.
$database_connection = Database::getConnection();
if (version_compare($database_connection->version(), '9') >= 0) {
if (!$this->checkBinaryOutputSuccess()) {
// First try to alter the database. If it fails, raise an error telling
// the user to do it themselves.
$connection_options = $database_connection->getConnectionOptions();
// It is safe to include the database name directly here, because this
// code is only called when a connection to the database is already
// established, thus the database name is guaranteed to be a correct
// value.
$query = "ALTER DATABASE \"" . $connection_options['database'] . "\" SET bytea_output = 'escape';";
try {
db_query($query);
}
catch (Exception $e) {
// Ignore possible errors when the user doesn't have the necessary
// privileges to ALTER the database.
}
// Close the database connection so that the configuration parameter
// is applied to the current connection.
db_close();
// Recheck, if it fails, finally just rely on the end user to do the
// right thing.
if (!$this->checkBinaryOutputSuccess()) {
$replacements = array(
'%setting' => 'bytea_output',
'%current_value' => 'hex',
'%needed_value' => 'escape',
'!query' => "<code>" . $query . "</code>",
);
$this->fail(st("The %setting setting is currently set to '%current_value', but needs to be '%needed_value'. Change this by running the following query: !query", $replacements));
}
}
}
}
/**
* Verify that a binary data roundtrip returns the original string.
*/
protected function checkBinaryOutputSuccess() {
$bytea_output = db_query("SELECT 'encoding'::bytea AS output")->fetchField();
return ($bytea_output == 'encoding');
}
/** /**
* Make PostgreSQL Drupal friendly. * Make PostgreSQL Drupal friendly.
*/ */
......
<?php <?php
// $Id: query.inc,v 1.23 2010/09/24 21:24:13 webchick Exp $
/** /**
* @ingroup database * @ingroup database
...@@ -104,8 +103,8 @@ class InsertQuery_pgsql extends InsertQuery { ...@@ -104,8 +103,8 @@ class InsertQuery_pgsql extends InsertQuery {
} }
public function __toString() { public function __toString() {
// Create a comments string to prepend to the query. // Create a sanitized comment string to prepend to the query.
$comments = (!empty($this->comments)) ? '/* ' . implode('; ', $this->comments) . ' */ ' : ''; $comments = $this->connection->makeComment($this->comments);
// Default fields are always placed first for consistency. // Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields); $insert_fields = array_merge($this->defaultFields, $this->insertFields);
...@@ -208,95 +207,3 @@ class UpdateQuery_pgsql extends UpdateQuery { ...@@ -208,95 +207,3 @@ class UpdateQuery_pgsql extends UpdateQuery {
return $stmt->rowCount(); return $stmt->rowCount();
} }
} }
class SelectQuery_pgsql extends SelectQuery {
public function orderRandom() {
$alias = $this->addExpression('RANDOM()', 'random_field');
$this->orderBy($alias);
return $this;
}
/**
* Overrides SelectQuery::orderBy().
*
* PostgreSQL adheres strictly to the SQL-92 standard and requires that when
* using DISTINCT or GROUP BY conditions, fields and expressions that are
* ordered on also need to be selected. This is a best effort implementation
* to handle the cases that can be automated by adding the field if it is not
* yet selected.
*
* @code
* $query = db_select('node', 'n');
* $query->join('node_revision', 'nr', 'n.vid = nr.vid');
* $query
* ->distinct()
* ->fields('n')
* ->orderBy('timestamp');
* @endcode
*
* In this query, it is not possible (without relying on the schema) to know
* whether timestamp belongs to node_revisions and needs to be added or
* belongs to node and is already selected. Queries like this will need to be
* corrected in the original query by adding an explicit call to
* SelectQuery::addField() or SelectQuery::fields().
*
* Since this has a small performance impact, both by the additional
* processing in this function and in the database that needs to return the
* additional fields, this is done as an override instead of implementing it
* directly in SelectQuery::orderBy().
*/
public function orderBy($field, $direction = 'ASC') {
// Call parent function to order on this.
$return = parent::orderBy($field, $direction);
// If there is a table alias specified, split it up.
if (strpos($field, '.') !== FALSE) {
list($table, $table_field) = explode('.', $field);
}
// Figure out if the field has already been added.
foreach ($this->fields as $existing_field) {
if (!empty($table)) {
// If table alias is given, check if field and table exists.
if ($existing_field['table'] == $table && $existing_field['field'] == $table_field) {
return $return;
}
}
else {
// If there is no table, simply check if the field exists as a field or
// an aliased field.
if ($existing_field['alias'] == $field) {
return $return;
}
}
}
// Also check expression aliases.
foreach ($this->expressions as $expression) {
if ($expression['alias'] == $field) {
return $return;
}
}
// If a table loads all fields, it can not be added again. It would
// result in an ambigious alias error because that field would be loaded
// twice: Once through table_alias.* and once directly. If the field
// actually belongs to a different table, it must be added manually.
foreach ($this->tables as $table) {
if (!empty($table['all_fields'])) {
return $return;
}
}
// If $field contains an characters which are not allowed in a field name
// it is considered an expression, these can't be handeld automatically
// either.
if ($this->connection->escapeField($field) != $field) {
return $return;
}
// This is a case that can be handled automatically, add the field.
$this->addField(NULL, $field);
return $return;
}
}
<?php <?php
// $Id: schema.inc,v 1.39 2010/10/22 15:18:56 webchick Exp $
/** /**
* @file * @file
...@@ -74,6 +73,39 @@ class DatabaseSchema_pgsql extends DatabaseSchema { ...@@ -74,6 +73,39 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
return $this->tableInformation[$key]; return $this->tableInformation[$key];
} }
/**
* Fetch the list of CHECK constraints used on a field.
*
* We introspect the database to collect the information required by field
* alteration.
*
* @param $table
* The non-prefixed name of the table.
* @param $field
* The name of the field.
* @return
* An array of all the checks for the field.
*/
public function queryFieldInformation($table, $field) {
$prefixInfo = $this->getPrefixInfo($table, TRUE);
// Split the key into schema and table for querying.
$schema = $prefixInfo['schema'];
$table_name = $prefixInfo['table'];
$field_information = (object) array(
'checks' => array(),
);
$checks = $this->connection->query("SELECT conname FROM pg_class cl INNER JOIN pg_constraint co ON co.conrelid = cl.oid INNER JOIN pg_attribute attr ON attr.attrelid = cl.oid AND attr.attnum = ANY (co.conkey) INNER JOIN pg_namespace ns ON cl.relnamespace = ns.oid WHERE co.contype = 'c' AND ns.nspname = :schema AND cl.relname = :table AND attr.attname = :column", array(
':schema' => $schema,
':table' => $table_name,
':column' => $field,
));
$field_information = $checks->fetchCol();
return $field_information;
}
/** /**
* Generate SQL to create a new table from a Drupal schema definition. * Generate SQL to create a new table from a Drupal schema definition.
* *
...@@ -335,7 +367,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema { ...@@ -335,7 +367,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
$this->connection->query($query); $this->connection->query($query);
if (isset($spec['initial'])) { if (isset($spec['initial'])) {
$this->connection->update($table) $this->connection->update($table)
->fields(array($field, $spec['initial'])) ->fields(array($field => $spec['initial']))
->execute(); ->execute();
} }
if ($fixnull) { if ($fixnull) {
...@@ -469,15 +501,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema { ...@@ -469,15 +501,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new))); throw new DatabaseSchemaObjectExistsException(t("Cannot rename field %table.%name to %name_new: target field already exists.", array('%table' => $table, '%name' => $field, '%name_new' => $field_new)));
} }
if (!array_key_exists('size', $spec)) { $spec = $this->processField($spec);
$spec['size'] = 'normal';
}
// Map type definition to the PostgreSQL type.
if (!isset($spec['pgsql_type'])) {
$map = $this->getFieldTypeMap();
$spec['pgsql_type'] = $map[$spec['type'] . ':' . $spec['size']];
}
// We need to typecast the new column to best be able to transfer the data // We need to typecast the new column to best be able to transfer the data
// Schema_pgsql::getFieldTypeMap() will return possibilities that are not // Schema_pgsql::getFieldTypeMap() will return possibilities that are not
...@@ -489,8 +513,35 @@ class DatabaseSchema_pgsql extends DatabaseSchema { ...@@ -489,8 +513,35 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
$typecast = $spec['pgsql_type']; $typecast = $spec['pgsql_type'];
} }
if (in_array($spec['pgsql_type'], array('varchar', 'character', 'text')) && isset($spec['length'])) {
$typecast .= '(' . $spec['length'] . ')';
}
elseif (isset($spec['precision']) && isset($spec['scale'])) {
$typecast .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')';
}
// Remove old check constraints.
$field_info = $this->queryFieldInformation($table, $field);
foreach ($field_info as $check) {
$this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $check . '"');
}
// Remove old default.
$this->fieldSetNoDefault($table, $field);
$this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" TYPE ' . $typecast . ' USING "' . $field . '"::' . $typecast); $this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" TYPE ' . $typecast . ' USING "' . $field . '"::' . $typecast);
if (isset($spec['not null'])) {
if ($spec['not null']) {
$nullaction = 'SET NOT NULL';
}
else {
$nullaction = 'DROP NOT NULL';
}
$this->connection->query('ALTER TABLE {' . $table . '} ALTER "' . $field . '" ' . $nullaction);
}
if (in_array($spec['pgsql_type'], array('serial', 'bigserial'))) { if (in_array($spec['pgsql_type'], array('serial', 'bigserial'))) {
// Type "serial" is known to PostgreSQL, but *only* during table creation, // Type "serial" is known to PostgreSQL, but *only* during table creation,
// not when altering. Because of that, the sequence needs to be created // not when altering. Because of that, the sequence needs to be created
...@@ -508,6 +559,16 @@ class DatabaseSchema_pgsql extends DatabaseSchema { ...@@ -508,6 +559,16 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
$this->connection->query('ALTER TABLE {' . $table . '} RENAME "' . $field . '" TO "' . $field_new . '"'); $this->connection->query('ALTER TABLE {' . $table . '} RENAME "' . $field . '" TO "' . $field_new . '"');
} }
// Add unsigned check if necessary.
if (!empty($spec['unsigned'])) {
$this->connection->query('ALTER TABLE {' . $table . '} ADD CHECK ("' . $field_new . '" >= 0)');
}
// Add default if necessary.
if (isset($spec['default'])) {
$this->fieldSetDefault($table, $field_new, $spec['default']);
}
// Change description if necessary. // Change description if necessary.
if (!empty($spec['description'])) { if (!empty($spec['description'])) {
$this->connection->query('COMMENT ON COLUMN {' . $table . '}."' . $field_new . '" IS ' . $this->prepareComment($spec['description'])); $this->connection->query('COMMENT ON COLUMN {' . $table . '}."' . $field_new . '" IS ' . $this->prepareComment($spec['description']));
......
This diff is collapsed.
<?php <?php
// $Id: prefetch.inc,v 1.10 2010/04/30 13:47:46 dries Exp $
/** /**
* @file * @file
...@@ -371,7 +370,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface ...@@ -371,7 +370,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
} }
} }
public function fetchField($index = 0) { public function fetchColumn($index = 0) {
if (isset($this->currentRow) && isset($this->columnNames[$index])) { if (isset($this->currentRow) && isset($this->columnNames[$index])) {
// We grab the value directly from $this->data, and format it. // We grab the value directly from $this->data, and format it.
$return = $this->currentRow[$this->columnNames[$index]]; $return = $this->currentRow[$this->columnNames[$index]];
...@@ -383,6 +382,10 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface ...@@ -383,6 +382,10 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
} }
} }
public function fetchField($index = 0) {
return $this->fetchColumn($index);
}
public function fetchObject($class_name = NULL, $constructor_args = array()) { public function fetchObject($class_name = NULL, $constructor_args = array()) {
if (isset($this->currentRow)) { if (isset($this->currentRow)) {
if (!isset($class_name)) { if (!isset($class_name)) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.