Kohana v3.3.5
This commit is contained in:
37
modules/database/.travis.yml
Normal file
37
modules/database/.travis.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
sudo: false
|
||||
|
||||
language: php
|
||||
|
||||
# Only build the main develop/master branches - feature branches will be covered by PRs
|
||||
branches:
|
||||
only:
|
||||
- /^[0-9\.]+\/(develop|master)$/
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
env: 'COMPOSER_PHPUNIT="lowest"'
|
||||
|
||||
before_script:
|
||||
- composer install --prefer-dist
|
||||
- if [ "$COMPOSER_PHPUNIT" = "lowest" ]; then composer update --prefer-lowest --with-dependencies phpunit/phpunit; fi;
|
||||
- vendor/bin/koharness
|
||||
|
||||
script:
|
||||
- cd /tmp/koharness && ./vendor/bin/phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php
|
||||
|
||||
notifications:
|
||||
email: false
|
6
modules/database/README.md
Normal file
6
modules/database/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Kohana - database access module
|
||||
|
||||
| ver | Stable | Develop |
|
||||
|-------|--------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 3.3.x | [](https://travis-ci.org/kohana/database) | [](https://travis-ci.org/kohana/database) |
|
||||
| 3.4.x | [](https://travis-ci.org/kohana/database) | [](https://travis-ci.org/kohana/database) |
|
3
modules/database/classes/Database/MySQLi.php
Normal file
3
modules/database/classes/Database/MySQLi.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_MySQLi extends Kohana_Database_MySQLi {}
|
3
modules/database/classes/Database/MySQLi/Result.php
Normal file
3
modules/database/classes/Database/MySQLi/Result.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_MySQLi_Result extends Kohana_Database_MySQLi_Result {}
|
@@ -9,7 +9,7 @@
|
||||
* @copyright (c) 2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Config_Database extends Kohana_Config_Database_Writer
|
||||
class Kohana_Config_Database extends Config_Database_Writer
|
||||
{
|
||||
|
||||
}
|
||||
|
@@ -3,6 +3,15 @@
|
||||
/**
|
||||
* Database writer for the config system
|
||||
*
|
||||
* Schema for configuration table:
|
||||
*
|
||||
* CREATE TABLE IF NOT EXISTS `config` (
|
||||
* `group_name` varchar(128) NOT NULL,
|
||||
* `config_key` varchar(128) NOT NULL,
|
||||
* `config_value` text,
|
||||
* PRIMARY KEY (`group_name`,`config_key`)
|
||||
* ) ENGINE=InnoDB;
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
|
@@ -51,6 +51,9 @@ class Kohana_Database_MySQL_Result extends Database_Result {
|
||||
// Increment internal row for optimization assuming rows are fetched in order
|
||||
$this->_internal_row++;
|
||||
|
||||
// FIXME mysql_fetch_object has been deprecated as of php 5.5!
|
||||
// Please use mysqli_fetch_object or PDOStatement::fetch(PDO::FETCH_OBJ) instead.
|
||||
|
||||
if ($this->_as_object === TRUE)
|
||||
{
|
||||
// Return an stdClass
|
||||
@@ -58,8 +61,32 @@ class Kohana_Database_MySQL_Result extends Database_Result {
|
||||
}
|
||||
elseif (is_string($this->_as_object))
|
||||
{
|
||||
// Return an object of given class name
|
||||
return mysql_fetch_object($this->_result, $this->_as_object, $this->_object_params);
|
||||
/* The second and third argument for mysql_fetch_object are optional, but do
|
||||
* not have default values defined. Passing _object_params with a non-array value results
|
||||
* in undefined behavior that varies by PHP version. For example, if NULL is supplied on
|
||||
* PHP 5.3, the resulting behavior is identical to calling with array(), which results in the
|
||||
* classes __construct function being called with no arguments. This is only an issue when
|
||||
* the _as_object class does not have an explicit __construct method resulting in the
|
||||
* cryptic error "Class %s does not have a constructor hence you cannot use ctor_params."
|
||||
* In contrast, the same function call on PHP 5.5 will 'functionally' interpret
|
||||
* _object_params == NULL as an omission of the third argument, resulting in the original
|
||||
* intended functionally.
|
||||
*
|
||||
* Because the backing code for the mysql_fetch_object has not changed between 5.3 and 5.5,
|
||||
* I suspect this discrepancy is due to the way the classes are instantiated on a boarder
|
||||
* level. Additionally, mysql_fetch_object has been deprecated in 5.5 and should probably be
|
||||
* replaced by mysqli_fetch_object or PDOStatement::fetch(PDO::FETCH_OBJ) in Kohana 3.4.
|
||||
*/
|
||||
if ($this->_object_params !== NULL)
|
||||
{
|
||||
// Return an object of given class name with constructor params
|
||||
return mysql_fetch_object($this->_result, $this->_as_object, $this->_object_params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return an object of given class name without constructor params
|
||||
return mysql_fetch_object($this->_result, $this->_as_object);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
422
modules/database/classes/Kohana/Database/MySQLi.php
Normal file
422
modules/database/classes/Kohana/Database/MySQLi.php
Normal file
@@ -0,0 +1,422 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* MySQLi database connection.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Drivers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_MySQLi extends Database {
|
||||
|
||||
// Database in use by each connection
|
||||
protected static $_current_databases = array();
|
||||
|
||||
// Use SET NAMES to set the character set
|
||||
protected static $_set_names;
|
||||
|
||||
// Identifier for this connection within the PHP driver
|
||||
protected $_connection_id;
|
||||
|
||||
// MySQL uses a backtick for identifiers
|
||||
protected $_identifier = '`';
|
||||
|
||||
public function connect()
|
||||
{
|
||||
if ($this->_connection)
|
||||
return;
|
||||
|
||||
if (Database_MySQLi::$_set_names === NULL)
|
||||
{
|
||||
// Determine if we can use mysqli_set_charset(), which is only
|
||||
// available on PHP 5.2.3+ when compiled against MySQL 5.0+
|
||||
Database_MySQLi::$_set_names = ! function_exists('mysqli_set_charset');
|
||||
}
|
||||
|
||||
// Extract the connection parameters, adding required variabels
|
||||
extract($this->_config['connection'] + array(
|
||||
'database' => '',
|
||||
'hostname' => '',
|
||||
'username' => '',
|
||||
'password' => '',
|
||||
'socket' => '',
|
||||
'port' => 3306,
|
||||
'ssl' => NULL,
|
||||
));
|
||||
|
||||
// Prevent this information from showing up in traces
|
||||
unset($this->_config['connection']['username'], $this->_config['connection']['password']);
|
||||
|
||||
try
|
||||
{
|
||||
if(is_array($ssl))
|
||||
{
|
||||
$this->_connection = mysqli_init();
|
||||
$this->_connection->ssl_set(
|
||||
Arr::get($ssl, 'client_key_path'),
|
||||
Arr::get($ssl, 'client_cert_path'),
|
||||
Arr::get($ssl, 'ca_cert_path'),
|
||||
Arr::get($ssl, 'ca_dir_path'),
|
||||
Arr::get($ssl, 'cipher')
|
||||
);
|
||||
$this->_connection->real_connect($hostname, $username, $password, $database, $port, $socket, MYSQLI_CLIENT_SSL);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_connection = new mysqli($hostname, $username, $password, $database, $port, $socket);
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// No connection exists
|
||||
$this->_connection = NULL;
|
||||
|
||||
throw new Database_Exception(':error', array(':error' => $e->getMessage()), $e->getCode());
|
||||
}
|
||||
|
||||
// \xFF is a better delimiter, but the PHP driver uses underscore
|
||||
$this->_connection_id = sha1($hostname.'_'.$username.'_'.$password);
|
||||
|
||||
if ( ! empty($this->_config['charset']))
|
||||
{
|
||||
// Set the character set
|
||||
$this->set_charset($this->_config['charset']);
|
||||
}
|
||||
|
||||
if ( ! empty($this->_config['connection']['variables']))
|
||||
{
|
||||
// Set session variables
|
||||
$variables = array();
|
||||
|
||||
foreach ($this->_config['connection']['variables'] as $var => $val)
|
||||
{
|
||||
$variables[] = 'SESSION '.$var.' = '.$this->quote($val);
|
||||
}
|
||||
|
||||
$this->_connection->query('SET '.implode(', ', $variables));
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Database is assumed disconnected
|
||||
$status = TRUE;
|
||||
|
||||
if (is_resource($this->_connection))
|
||||
{
|
||||
if ($status = $this->_connection->close())
|
||||
{
|
||||
// Clear the connection
|
||||
$this->_connection = NULL;
|
||||
|
||||
// Clear the instance
|
||||
parent::disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Database is probably not disconnected
|
||||
$status = ! is_resource($this->_connection);
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function set_charset($charset)
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
if (Database_MySQLi::$_set_names === TRUE)
|
||||
{
|
||||
// PHP is compiled against MySQL 4.x
|
||||
$status = (bool) $this->_connection->query('SET NAMES '.$this->quote($charset));
|
||||
}
|
||||
else
|
||||
{
|
||||
// PHP is compiled against MySQL 5.x
|
||||
$status = $this->_connection->set_charset($charset);
|
||||
}
|
||||
|
||||
if ($status === FALSE)
|
||||
{
|
||||
throw new Database_Exception(':error', array(':error' => $this->_connection->error), $this->_connection->errno);
|
||||
}
|
||||
}
|
||||
|
||||
public function query($type, $sql, $as_object = FALSE, array $params = NULL)
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
if (Kohana::$profiling)
|
||||
{
|
||||
// Benchmark this query for the current instance
|
||||
$benchmark = Profiler::start("Database ({$this->_instance})", $sql);
|
||||
}
|
||||
|
||||
// Execute the query
|
||||
if (($result = $this->_connection->query($sql)) === FALSE)
|
||||
{
|
||||
if (isset($benchmark))
|
||||
{
|
||||
// This benchmark is worthless
|
||||
Profiler::delete($benchmark);
|
||||
}
|
||||
|
||||
throw new Database_Exception(':error [ :query ]', array(
|
||||
':error' => $this->_connection->error,
|
||||
':query' => $sql
|
||||
), $this->_connection->errno);
|
||||
}
|
||||
|
||||
if (isset($benchmark))
|
||||
{
|
||||
Profiler::stop($benchmark);
|
||||
}
|
||||
|
||||
// Set the last query
|
||||
$this->last_query = $sql;
|
||||
|
||||
if ($type === Database::SELECT)
|
||||
{
|
||||
// Return an iterator of results
|
||||
return new Database_MySQLi_Result($result, $sql, $as_object, $params);
|
||||
}
|
||||
elseif ($type === Database::INSERT)
|
||||
{
|
||||
// Return a list of insert id and rows created
|
||||
return array(
|
||||
$this->_connection->insert_id,
|
||||
$this->_connection->affected_rows,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return the number of rows affected
|
||||
return $this->_connection->affected_rows;
|
||||
}
|
||||
}
|
||||
|
||||
public function datatype($type)
|
||||
{
|
||||
static $types = array
|
||||
(
|
||||
'blob' => array('type' => 'string', 'binary' => TRUE, 'character_maximum_length' => '65535'),
|
||||
'bool' => array('type' => 'bool'),
|
||||
'bigint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '18446744073709551615'),
|
||||
'datetime' => array('type' => 'string'),
|
||||
'decimal unsigned' => array('type' => 'float', 'exact' => TRUE, 'min' => '0'),
|
||||
'double' => array('type' => 'float'),
|
||||
'double precision unsigned' => array('type' => 'float', 'min' => '0'),
|
||||
'double unsigned' => array('type' => 'float', 'min' => '0'),
|
||||
'enum' => array('type' => 'string'),
|
||||
'fixed' => array('type' => 'float', 'exact' => TRUE),
|
||||
'fixed unsigned' => array('type' => 'float', 'exact' => TRUE, 'min' => '0'),
|
||||
'float unsigned' => array('type' => 'float', 'min' => '0'),
|
||||
'geometry' => array('type' => 'string', 'binary' => TRUE),
|
||||
'int unsigned' => array('type' => 'int', 'min' => '0', 'max' => '4294967295'),
|
||||
'integer unsigned' => array('type' => 'int', 'min' => '0', 'max' => '4294967295'),
|
||||
'longblob' => array('type' => 'string', 'binary' => TRUE, 'character_maximum_length' => '4294967295'),
|
||||
'longtext' => array('type' => 'string', 'character_maximum_length' => '4294967295'),
|
||||
'mediumblob' => array('type' => 'string', 'binary' => TRUE, 'character_maximum_length' => '16777215'),
|
||||
'mediumint' => array('type' => 'int', 'min' => '-8388608', 'max' => '8388607'),
|
||||
'mediumint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '16777215'),
|
||||
'mediumtext' => array('type' => 'string', 'character_maximum_length' => '16777215'),
|
||||
'national varchar' => array('type' => 'string'),
|
||||
'numeric unsigned' => array('type' => 'float', 'exact' => TRUE, 'min' => '0'),
|
||||
'nvarchar' => array('type' => 'string'),
|
||||
'point' => array('type' => 'string', 'binary' => TRUE),
|
||||
'real unsigned' => array('type' => 'float', 'min' => '0'),
|
||||
'set' => array('type' => 'string'),
|
||||
'smallint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '65535'),
|
||||
'text' => array('type' => 'string', 'character_maximum_length' => '65535'),
|
||||
'tinyblob' => array('type' => 'string', 'binary' => TRUE, 'character_maximum_length' => '255'),
|
||||
'tinyint' => array('type' => 'int', 'min' => '-128', 'max' => '127'),
|
||||
'tinyint unsigned' => array('type' => 'int', 'min' => '0', 'max' => '255'),
|
||||
'tinytext' => array('type' => 'string', 'character_maximum_length' => '255'),
|
||||
'year' => array('type' => 'string'),
|
||||
);
|
||||
|
||||
$type = str_replace(' zerofill', '', $type);
|
||||
|
||||
if (isset($types[$type]))
|
||||
return $types[$type];
|
||||
|
||||
return parent::datatype($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a SQL transaction
|
||||
*
|
||||
* @link http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
|
||||
*
|
||||
* @param string $mode Isolation level
|
||||
* @return boolean
|
||||
*/
|
||||
public function begin($mode = NULL)
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
if ($mode AND ! $this->_connection->query("SET TRANSACTION ISOLATION LEVEL $mode"))
|
||||
{
|
||||
throw new Database_Exception(':error', array(
|
||||
':error' => $this->_connection->error
|
||||
), $this->_connection->errno);
|
||||
}
|
||||
|
||||
return (bool) $this->_connection->query('START TRANSACTION');
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a SQL transaction
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return (bool) $this->_connection->query('COMMIT');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback a SQL transaction
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
return (bool) $this->_connection->query('ROLLBACK');
|
||||
}
|
||||
|
||||
public function list_tables($like = NULL)
|
||||
{
|
||||
if (is_string($like))
|
||||
{
|
||||
// Search for table names
|
||||
$result = $this->query(Database::SELECT, 'SHOW TABLES LIKE '.$this->quote($like), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find all table names
|
||||
$result = $this->query(Database::SELECT, 'SHOW TABLES', FALSE);
|
||||
}
|
||||
|
||||
$tables = array();
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$tables[] = reset($row);
|
||||
}
|
||||
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public function list_columns($table, $like = NULL, $add_prefix = TRUE)
|
||||
{
|
||||
// Quote the table name
|
||||
$table = ($add_prefix === TRUE) ? $this->quote_table($table) : $table;
|
||||
|
||||
if (is_string($like))
|
||||
{
|
||||
// Search for column names
|
||||
$result = $this->query(Database::SELECT, 'SHOW FULL COLUMNS FROM '.$table.' LIKE '.$this->quote($like), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find all column names
|
||||
$result = $this->query(Database::SELECT, 'SHOW FULL COLUMNS FROM '.$table, FALSE);
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
$columns = array();
|
||||
foreach ($result as $row)
|
||||
{
|
||||
list($type, $length) = $this->_parse_type($row['Type']);
|
||||
|
||||
$column = $this->datatype($type);
|
||||
|
||||
$column['column_name'] = $row['Field'];
|
||||
$column['column_default'] = $row['Default'];
|
||||
$column['data_type'] = $type;
|
||||
$column['is_nullable'] = ($row['Null'] == 'YES');
|
||||
$column['ordinal_position'] = ++$count;
|
||||
|
||||
switch ($column['type'])
|
||||
{
|
||||
case 'float':
|
||||
if (isset($length))
|
||||
{
|
||||
list($column['numeric_precision'], $column['numeric_scale']) = explode(',', $length);
|
||||
}
|
||||
break;
|
||||
case 'int':
|
||||
if (isset($length))
|
||||
{
|
||||
// MySQL attribute
|
||||
$column['display'] = $length;
|
||||
}
|
||||
break;
|
||||
case 'string':
|
||||
switch ($column['data_type'])
|
||||
{
|
||||
case 'binary':
|
||||
case 'varbinary':
|
||||
$column['character_maximum_length'] = $length;
|
||||
break;
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
$column['character_maximum_length'] = $length;
|
||||
case 'text':
|
||||
case 'tinytext':
|
||||
case 'mediumtext':
|
||||
case 'longtext':
|
||||
$column['collation_name'] = $row['Collation'];
|
||||
break;
|
||||
case 'enum':
|
||||
case 'set':
|
||||
$column['collation_name'] = $row['Collation'];
|
||||
$column['options'] = explode('\',\'', substr($length, 1, -1));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// MySQL attributes
|
||||
$column['comment'] = $row['Comment'];
|
||||
$column['extra'] = $row['Extra'];
|
||||
$column['key'] = $row['Key'];
|
||||
$column['privileges'] = $row['Privileges'];
|
||||
|
||||
$columns[$row['Field']] = $column;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function escape($value)
|
||||
{
|
||||
// Make sure the database is connected
|
||||
$this->_connection or $this->connect();
|
||||
|
||||
if (($value = $this->_connection->real_escape_string( (string) $value)) === FALSE)
|
||||
{
|
||||
throw new Database_Exception(':error', array(
|
||||
':error' => $this->_connection->error,
|
||||
), $this->_connection->errno);
|
||||
}
|
||||
|
||||
// SQL standard is to use single-quotes for all values
|
||||
return "'$value'";
|
||||
}
|
||||
|
||||
} // End Database_MySQLi
|
71
modules/database/classes/Kohana/Database/MySQLi/Result.php
Normal file
71
modules/database/classes/Kohana/Database/MySQLi/Result.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
/**
|
||||
* MySQLi database result. See [Results](/database/results) for usage and examples.
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Query/Result
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Database_MySQLi_Result extends Database_Result {
|
||||
|
||||
protected $_internal_row = 0;
|
||||
|
||||
public function __construct($result, $sql, $as_object = FALSE, array $params = NULL)
|
||||
{
|
||||
parent::__construct($result, $sql, $as_object, $params);
|
||||
|
||||
// Find the number of rows in the result
|
||||
$this->_total_rows = $result->num_rows;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (is_resource($this->_result))
|
||||
{
|
||||
$this->_result->free();
|
||||
}
|
||||
}
|
||||
|
||||
public function seek($offset)
|
||||
{
|
||||
if ($this->offsetExists($offset) AND $this->_result->data_seek($offset))
|
||||
{
|
||||
// Set the current row to the offset
|
||||
$this->_current_row = $this->_internal_row = $offset;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public function current()
|
||||
{
|
||||
if ($this->_current_row !== $this->_internal_row AND ! $this->seek($this->_current_row))
|
||||
return NULL;
|
||||
|
||||
// Increment internal row for optimization assuming rows are fetched in order
|
||||
$this->_internal_row++;
|
||||
|
||||
if ($this->_as_object === TRUE)
|
||||
{
|
||||
// Return an stdClass
|
||||
return $this->_result->fetch_object();
|
||||
}
|
||||
elseif (is_string($this->_as_object))
|
||||
{
|
||||
// Return an object of given class name
|
||||
return $this->_result->fetch_object($this->_as_object, (array) $this->_object_params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return an array of the row
|
||||
return $this->_result->fetch_assoc();
|
||||
}
|
||||
}
|
||||
|
||||
} // End Database_MySQLi_Result_Select
|
@@ -60,6 +60,12 @@ class Kohana_Database_PDO extends Database {
|
||||
array(':error' => $e->getMessage()),
|
||||
$e->getCode());
|
||||
}
|
||||
|
||||
if ( ! empty($this->_config['charset']))
|
||||
{
|
||||
// Set the character set
|
||||
$this->set_charset($this->_config['charset']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -80,7 +80,7 @@ abstract class Kohana_Database_Query_Builder extends Database_Query {
|
||||
// Convert "val = NULL" to "val IS NULL"
|
||||
$op = 'IS';
|
||||
}
|
||||
elseif ($op === '!=')
|
||||
elseif ($op === '!=' OR $op === '<>')
|
||||
{
|
||||
// Convert "val != NULL" to "valu IS NOT NULL"
|
||||
$op = 'IS NOT';
|
||||
|
@@ -31,7 +31,7 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
if ($table)
|
||||
{
|
||||
// Set the inital table name
|
||||
$this->_table = $table;
|
||||
$this->table($table);
|
||||
}
|
||||
|
||||
if ($columns)
|
||||
@@ -47,11 +47,14 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
/**
|
||||
* Sets the table to insert into.
|
||||
*
|
||||
* @param mixed $table table name or array($table, $alias) or object
|
||||
* @param string $table table name
|
||||
* @return $this
|
||||
*/
|
||||
public function table($table)
|
||||
{
|
||||
if ( ! is_string($table))
|
||||
throw new Kohana_Exception('INSERT INTO syntax does not allow table aliasing');
|
||||
|
||||
$this->_table = $table;
|
||||
|
||||
return $this;
|
||||
@@ -86,8 +89,11 @@ class Kohana_Database_Query_Builder_Insert extends Database_Query_Builder {
|
||||
|
||||
// Get all of the passed values
|
||||
$values = func_get_args();
|
||||
|
||||
$this->_values = array_merge($this->_values, $values);
|
||||
|
||||
foreach ($values as $value)
|
||||
{
|
||||
$this->_values[] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@@ -309,7 +309,7 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
*/
|
||||
public function offset($number)
|
||||
{
|
||||
$this->_offset = $number;
|
||||
$this->_offset = ($number === NULL) ? NULL : (int) $number;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -404,13 +404,14 @@ class Kohana_Database_Query_Builder_Select extends Database_Query_Builder_Where
|
||||
|
||||
if ( ! empty($this->_union))
|
||||
{
|
||||
$query = '('.$query.')';
|
||||
foreach ($this->_union as $u) {
|
||||
$query .= ' UNION ';
|
||||
if ($u['all'] === TRUE)
|
||||
{
|
||||
$query .= 'ALL ';
|
||||
}
|
||||
$query .= $u['select']->compile($db);
|
||||
$query .= '('.$u['select']->compile($db).')';
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -172,7 +172,7 @@ abstract class Kohana_Database_Query_Builder_Where extends Database_Query_Builde
|
||||
*/
|
||||
public function limit($number)
|
||||
{
|
||||
$this->_limit = $number;
|
||||
$this->_limit = ($number === NULL) ? NULL : (int) $number;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@@ -204,6 +204,9 @@ class Kohana_Session_Database extends Session {
|
||||
// Execute the query
|
||||
$query->execute($this->_db);
|
||||
|
||||
// Delete the old session id
|
||||
$this->_update_id = NULL;
|
||||
|
||||
// Delete the cookie
|
||||
Cookie::delete($this->_name);
|
||||
}
|
||||
|
@@ -22,8 +22,13 @@
|
||||
"require": {
|
||||
"composer/installers": "~1.0",
|
||||
"kohana/core": ">=3.3",
|
||||
"php": ">=5.3.3"
|
||||
"php": ">=5.3.6"
|
||||
},
|
||||
"require-dev": {
|
||||
"kohana/core": "3.3.*@dev",
|
||||
"kohana/unittest": "3.3.*@dev",
|
||||
"kohana/koharness": "*@dev"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mysql": "*",
|
||||
"ext-pdo": "*"
|
||||
@@ -32,6 +37,9 @@
|
||||
"branch-alias": {
|
||||
"dev-3.3/develop": "3.3.x-dev",
|
||||
"dev-3.4/develop": "3.4.x-dev"
|
||||
}
|
||||
},
|
||||
"installer-paths": {
|
||||
"vendor/{$vendor}/{$name}": ["type:kohana-module"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -53,4 +53,38 @@ return array
|
||||
'charset' => 'utf8',
|
||||
'caching' => FALSE,
|
||||
),
|
||||
/**
|
||||
* MySQLi driver config information
|
||||
*
|
||||
* The following options are available for MySQLi:
|
||||
*
|
||||
* string hostname server hostname, or socket
|
||||
* string database database name
|
||||
* string username database username
|
||||
* string password database password
|
||||
* boolean persistent use persistent connections?
|
||||
* array ssl ssl parameters as "key => value" pairs.
|
||||
* Available keys: client_key_path, client_cert_path, ca_cert_path, ca_dir_path, cipher
|
||||
* array variables system variables as "key => value" pairs
|
||||
*
|
||||
* Ports and sockets may be appended to the hostname.
|
||||
*
|
||||
* MySQLi driver config example:
|
||||
*
|
||||
*/
|
||||
// 'alternate_mysqli' => array
|
||||
// (
|
||||
// 'type' => 'MySQLi',
|
||||
// 'connection' => array(
|
||||
// 'hostname' => 'localhost',
|
||||
// 'database' => 'kohana',
|
||||
// 'username' => FALSE,
|
||||
// 'password' => FALSE,
|
||||
// 'persistent' => FALSE,
|
||||
// 'ssl' => NULL,
|
||||
// ),
|
||||
// 'table_prefix' => '',
|
||||
// 'charset' => 'utf8',
|
||||
// 'caching' => FALSE,
|
||||
// ),
|
||||
);
|
||||
|
@@ -10,6 +10,7 @@ The database configuration file contains an array of configuration groups. The s
|
||||
'table_prefix' => string TABLE_PREFIX,
|
||||
'charset' => string CHARACTER_SET,
|
||||
),
|
||||
|
||||
|
||||
Understanding each of these settings is important.
|
||||
|
||||
@@ -17,7 +18,7 @@ INSTANCE_NAME
|
||||
: Connections can be named anything you want, but you should always have at least one connection called "default".
|
||||
|
||||
DATABASE_TYPE
|
||||
: One of the installed database drivers. Kohana comes with "mysql" and "pdo" drivers. Drivers must extend the Database class.
|
||||
: One of the installed database drivers. Kohana comes with "MySQL", "MySQLi", and "PDO" drivers. Drivers must extend the Database class. This parameter is case sensitive. Note the mysql php extension used by the MySQL driver is deprecated as of PHP 5.5 and you should look to use an alternative driver.
|
||||
|
||||
CONNECTION_ARRAY
|
||||
: Specific driver options for connecting to your database. (Driver options are explained [below](#connection-settings).)
|
||||
@@ -49,7 +50,7 @@ The example file below shows 2 MySQL connections, one local and one remote.
|
||||
(
|
||||
'default' => array
|
||||
(
|
||||
'type' => 'mysql',
|
||||
'type' => 'MySQL',
|
||||
'connection' => array(
|
||||
'hostname' => 'localhost',
|
||||
'username' => 'dbuser',
|
||||
@@ -61,7 +62,7 @@ The example file below shows 2 MySQL connections, one local and one remote.
|
||||
'charset' => 'utf8',
|
||||
),
|
||||
'remote' => array(
|
||||
'type' => 'mysql',
|
||||
'type' => 'MySQL',
|
||||
'connection' => array(
|
||||
'hostname' => '55.55.55.55',
|
||||
'username' => 'remote_user',
|
||||
@@ -74,6 +75,8 @@ The example file below shows 2 MySQL connections, one local and one remote.
|
||||
),
|
||||
);
|
||||
|
||||
[!!] Note that the 'type' parameter is case sensitive (eg 'MySQL', 'PDO').
|
||||
|
||||
## Connections and Instances
|
||||
|
||||
Each configuration group is referred to as a database instance. Each instance can be accessed by calling [Database::instance]. If you don't provide a parameter, the default instance is used.
|
||||
@@ -114,6 +117,24 @@ Type | Option | Description | Default value
|
||||
`boolean` | persistent | Persistent connections | `FALSE`
|
||||
`string` | database | Database name | `kohana`
|
||||
|
||||
### MySQLi
|
||||
|
||||
A [MySQL database](http://php.net/manual/en/book.mysqli.php) can accept the following options in the `connection` array:
|
||||
|
||||
Type | Option | Description | Default value
|
||||
----------|------------|----------------------------| -------------------------
|
||||
`string` | hostname | Hostname of the database | `localhost`
|
||||
`integer` | port | Port number | `NULL`
|
||||
`string` | socket | UNIX socket | `NULL`
|
||||
`string` | username | Database username | `NULL`
|
||||
`string` | password | Database password | `NULL`
|
||||
`boolean` | persistent | Persistent connections | `FALSE`
|
||||
`string` | database | Database name | `kohana`
|
||||
`array` | ssl | SSL parameters | `NULL`
|
||||
|
||||
SSL parameters should be specified as `key` => `value` pairs.
|
||||
Available keys: client_key_path, client_cert_path, ca_cert_path, ca_dir_path, cipher
|
||||
|
||||
### PDO
|
||||
|
||||
A [PDO database](http://php.net/manual/en/book.pdo.php) can accept these options in the `connection` array:
|
||||
@@ -128,4 +149,4 @@ Type | Option | Description | Default value
|
||||
|
||||
The connection character set should be configured using the DSN string or `options` array.
|
||||
|
||||
[!!] If you are using PDO and are not sure what to use for the `dsn` option, review [PDO::__construct](http://php.net/pdo.construct).
|
||||
[!!] If you are using PDO and are not sure what to use for the `dsn` option, review [PDO::__construct](http://php.net/pdo.construct).
|
||||
|
@@ -25,7 +25,7 @@ In this example, we loop through an array of whitelisted input fields and for ea
|
||||
|
||||
//copy the query & execute it
|
||||
$pagination_query = clone $query;
|
||||
$count = $pagination_query->select(DB::expr('COUNT(*)) AS mycount')->execute()->get('mycount');
|
||||
$count = $pagination_query->select(DB::expr('COUNT(*) AS mycount'))->execute()->get('mycount');
|
||||
|
||||
//pass the total item count to Pagination
|
||||
$config = Kohana::$config->load('pagination');
|
||||
@@ -49,4 +49,4 @@ In this example, we loop through an array of whitelisted input fields and for ea
|
||||
|
||||
TODO: example goes here
|
||||
|
||||
[!!] We could use more examples on this page.
|
||||
[!!] We could use more examples on this page.
|
||||
|
@@ -76,7 +76,7 @@ This query would generate the following SQL:
|
||||
|
||||
Often you will want the results in a particular order and rather than sorting the results, it's better to have the results returned to you in the correct order. You can do this by using the order_by() method. It takes the column name and an optional direction string as the parameters. Multiple `order_by()` methods can be used to add additional sorting capability.
|
||||
|
||||
$query = DB::select()->from(`posts`)->order_by(`published`, `DESC`);
|
||||
$query = DB::select()->from('posts')->order_by('published', 'DESC');
|
||||
|
||||
This query would generate the following SQL:
|
||||
|
||||
@@ -248,4 +248,4 @@ Once you are done building, you can execute the query using `execute()` and use
|
||||
|
||||
To use a different database [config group](config) pass either the name or the config object to `execute()`.
|
||||
|
||||
$result = $query->execute('config_name')
|
||||
$result = $query->execute('config_name')
|
||||
|
8
modules/database/koharness.php
Normal file
8
modules/database/koharness.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
// Configuration for koharness - builds a standalone skeleton Kohana app for running unit tests
|
||||
return array(
|
||||
'modules' => array(
|
||||
'database' => __DIR__,
|
||||
'unittest' => __DIR__ . '/vendor/kohana/unittest'
|
||||
),
|
||||
);
|
Reference in New Issue
Block a user