Shifting to that NoSQL life
Dropped the database abstraction layer, added a rudimentary MongoDB class, dopped all of the interface classes for the OAuth2 library and updated the dependencies to use @bshaffer's OAuth2 class as it has MongoDB support out of the box.
This commit is contained in:
parent
76611eb7da
commit
6414644f35
16 changed files with 67 additions and 2279 deletions
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"require": {
|
||||
"php": ">=5.4",
|
||||
"league/oauth2-server": "4.0.x-dev"
|
||||
"bshaffer/oauth2-server-php": "v1.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
221
src/Cache.php
221
src/Cache.php
|
@ -1,221 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Caching System
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistribution of these files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2007-2014, Josh Sherman
|
||||
* @license http://www.opensource.org/licenses/mit-license.html
|
||||
* @link https://github.com/joshtronic/pickles
|
||||
* @package Pickles
|
||||
*/
|
||||
|
||||
namespace Pickles;
|
||||
|
||||
/**
|
||||
* Cache Class
|
||||
*
|
||||
* Wrapper class for Memcache() to allow for better error handling when the
|
||||
* Memcached server is unavailable. Designed around the syntax for Memcached()
|
||||
* to allow for an easier transistion to the aforementioned in the future. I
|
||||
* 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. 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
|
||||
*
|
||||
* @link http://us.php.net/manual/en/book.memcache.php
|
||||
* @link http://packages.ubuntu.com/lucid/php5-memcache
|
||||
* @link http://www.memcached.org/
|
||||
*/
|
||||
class Cache extends Object
|
||||
{
|
||||
/**
|
||||
* Namespace (prefix)
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
private $namespace = '';
|
||||
|
||||
/**
|
||||
* Servers
|
||||
*
|
||||
* @access private
|
||||
* @var integer
|
||||
*/
|
||||
private $servers = 0;
|
||||
|
||||
/**
|
||||
* Connection resource to Memcached
|
||||
*
|
||||
* @access private
|
||||
* @var object
|
||||
*/
|
||||
private $connection = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Sets up our connection variables.
|
||||
*
|
||||
* @param string $hostname optional hostname to connect to
|
||||
* @param string $database optional port to use
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
// @todo Shouldn't need the isset() but Travis is failing some tests
|
||||
if (isset($this->config['pickles']['cache']) && $this->config['pickles']['cache'])
|
||||
{
|
||||
$datasources = $this->config['pickles']['cache'];
|
||||
|
||||
if (!is_array($datasources))
|
||||
{
|
||||
$datasources = [$datasources];
|
||||
}
|
||||
|
||||
$this->connection = new \Memcache();
|
||||
|
||||
foreach ($datasources as $name)
|
||||
{
|
||||
if (isset($this->config['datasources'][$name]))
|
||||
{
|
||||
$datasource = $this->config['datasources'][$name];
|
||||
|
||||
$this->connection->addServer($datasource['hostname'], $datasource['port']);
|
||||
$this->servers++;
|
||||
|
||||
if (isset($datasource['namespace']))
|
||||
{
|
||||
$this->namespace = $datasource['namespace'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->namespace != '')
|
||||
{
|
||||
$this->namespace .= '-';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
* Closes the connection when the object dies.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->servers)
|
||||
{
|
||||
$this->connection->close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Instance
|
||||
*
|
||||
* Let's the parent class do all the work.
|
||||
*
|
||||
* @static
|
||||
* @param string $class name of the class to instantiate
|
||||
* @return object self::$instance instance of the Cache class
|
||||
*/
|
||||
public static function getInstance($class = 'Cache')
|
||||
{
|
||||
return parent::getInstance($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Key
|
||||
*
|
||||
* Gets the value of the key(s) and returns it.
|
||||
*
|
||||
* @param mixed $keys key(s) to retrieve
|
||||
* @return mixed value(s) of the requested key(s), false if not set
|
||||
*/
|
||||
public function get($keys)
|
||||
{
|
||||
if (is_array($keys))
|
||||
{
|
||||
foreach ($keys as $index => $key)
|
||||
{
|
||||
$keys[$index] = strtoupper($this->namespace . $key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$keys = strtoupper($this->namespace . $keys);
|
||||
}
|
||||
|
||||
return $this->connection->get($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Key
|
||||
*
|
||||
* Sets key to the specified value. I've found that compression can lead to
|
||||
* issues with integers and can slow down the storage and retrieval of data
|
||||
* (defeats the purpose of caching if you ask me) and isn't supported. I've
|
||||
* also been burned by data inadvertantly being cached for infinity, but
|
||||
* have had great success caching data for a full day, hence defaulting the
|
||||
* expiration to a full day.
|
||||
*
|
||||
* @param string $key key to set
|
||||
* @param mixed $value value to set
|
||||
* @param integer $expiration optional expiration, defaults to 1 day
|
||||
* @return boolean status of writing the data to the key
|
||||
*/
|
||||
public function set($key, $value, $expire = Time::DAY)
|
||||
{
|
||||
$key = strtoupper($key);
|
||||
|
||||
return $this->connection->set(strtoupper($this->namespace . $key), $value, 0, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Key
|
||||
*
|
||||
* Deletes the specified key(s).
|
||||
*
|
||||
* @param mixed $keys key(s) to delete
|
||||
* @return boolean status of deleting the key
|
||||
*/
|
||||
public function delete($keys)
|
||||
{
|
||||
if (!is_array($keys))
|
||||
{
|
||||
$keys = [$keys];
|
||||
}
|
||||
|
||||
// Memcache() doesn't let you pass an array to delete all records the same way you can with get()
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$this->connection->delete(strtoupper($this->namespace . $key));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment Key
|
||||
*
|
||||
* Increments the value of an existing key.
|
||||
*
|
||||
* @param string $key key to increment
|
||||
* @return boolean status of incrementing the key
|
||||
* @todo Check if it's set as Memcache() doesn't and won't inc if it doesn't exist
|
||||
*/
|
||||
public function increment($key)
|
||||
{
|
||||
return $this->connection->increment(strtoupper($this->namespace . $key));
|
||||
}
|
||||
}
|
||||
|
|
@ -138,9 +138,9 @@ class Config extends \ArrayObject
|
|||
// Defaults expected Pickles variables to false
|
||||
foreach (['auth', 'cache', 'profiler'] as $variable)
|
||||
{
|
||||
if (!isset($config['pickles'][$variable]))
|
||||
if (!isset($config[$variable]))
|
||||
{
|
||||
$config['pickles'][$variable] = false;
|
||||
$config[$variable] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
393
src/Database.php
393
src/Database.php
|
@ -1,393 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Database Abstraction Layer
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistribution of these files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2007-2014, Josh Sherman
|
||||
* @license http://www.opensource.org/licenses/mit-license.html
|
||||
* @link https://github.com/joshtronic/pickles
|
||||
* @package Pickles
|
||||
* @todo Drop driver, hardcode drivers based on the type
|
||||
* @todo More assumptions for the datasource variables
|
||||
*/
|
||||
|
||||
namespace Pickles;
|
||||
|
||||
/**
|
||||
* Database Class
|
||||
*
|
||||
* Database interaction all in one place. Allows for object reuse and contains
|
||||
* functions to ease interacting with databases. Common assumptions about PDO
|
||||
* attributes are baked in. Only support PDO.
|
||||
*/
|
||||
class Database extends Object
|
||||
{
|
||||
/**
|
||||
* DSN format
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $dsn;
|
||||
|
||||
/**
|
||||
* PDO Attributes
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
protected $attributes = [
|
||||
\PDO::ATTR_PERSISTENT => true,
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::NULL_EMPTY_STRING => true,
|
||||
];
|
||||
|
||||
/**
|
||||
* Driver
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $driver = null;
|
||||
|
||||
/**
|
||||
* Hostname for the server
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $hostname = 'localhost';
|
||||
|
||||
/**
|
||||
* Port number for the server
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $port = null;
|
||||
|
||||
/**
|
||||
* UNIX socket for the server
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $socket = null;
|
||||
|
||||
/**
|
||||
* Username for the server
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $username = null;
|
||||
|
||||
/**
|
||||
* Password for the server
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $password = null;
|
||||
|
||||
/**
|
||||
* Database name for the server
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $database = null;
|
||||
|
||||
/**
|
||||
* Whether or not to use caching
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public $cache = false;
|
||||
|
||||
/**
|
||||
* Connection resource
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $connection = null;
|
||||
|
||||
/**
|
||||
* Results object for the executed statement
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $results = null;
|
||||
|
||||
/**
|
||||
* Get Instance
|
||||
*
|
||||
* Instantiates a new instance of the Database class or returns the
|
||||
* previously instantiated copy.
|
||||
*
|
||||
* @static
|
||||
* @param string $datasource_name name of the datasource
|
||||
* @return object instance of the class
|
||||
*/
|
||||
public static function getInstance($datasource_name = false)
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
|
||||
// Tries to load a datasource if one wasn't specified
|
||||
if (!$datasource_name)
|
||||
{
|
||||
if (isset($config['pickles']['datasource']))
|
||||
{
|
||||
$datasource_name = $config['pickles']['datasource'];
|
||||
}
|
||||
elseif (is_array($config['datasources']))
|
||||
{
|
||||
$datasources = $config['datasources'];
|
||||
|
||||
foreach ($datasources as $name => $datasource)
|
||||
{
|
||||
if (isset($datasource['driver']))
|
||||
{
|
||||
$datasource_name = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to validate the datasource
|
||||
if ($datasource_name)
|
||||
{
|
||||
if (!isset(self::$instances['Database'][$datasource_name]))
|
||||
{
|
||||
if (!isset($config['datasources'][$datasource_name]))
|
||||
{
|
||||
throw new \Exception('The specified datasource is not defined in the config.');
|
||||
}
|
||||
|
||||
$datasource = $config['datasources'][$datasource_name];
|
||||
|
||||
if (!isset($datasource['driver']))
|
||||
{
|
||||
throw new \Exception('The specified datasource lacks a driver.');
|
||||
}
|
||||
|
||||
$datasource['driver'] = strtolower($datasource['driver']);
|
||||
|
||||
// Checks the driver is legit and scrubs the name
|
||||
switch ($datasource['driver'])
|
||||
{
|
||||
case 'pdo_mysql':
|
||||
$attributes = [
|
||||
'dsn' => 'mysql:host=[[hostname]];port=[[port]];unix_socket=[[socket]];dbname=[[database]]',
|
||||
'port' => 3306,
|
||||
];
|
||||
break;
|
||||
|
||||
case 'pdo_pgsql':
|
||||
$attributes = [
|
||||
'dsn' => 'pgsql:host=[[hostname]];port=[[port]];dbname=[[database]];user=[[username]];password=[[password]]',
|
||||
'port' => 5432,
|
||||
];
|
||||
break;
|
||||
|
||||
case 'pdo_sqlite':
|
||||
$attributes = ['dsn' => 'sqlite:[[hostname]]'];
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception('Datasource driver "' . $datasource['driver'] . '" is invalid');
|
||||
break;
|
||||
}
|
||||
|
||||
// Instantiates our database class
|
||||
$instance = new Database();
|
||||
|
||||
// Sets our database parameters
|
||||
if (is_array($datasource))
|
||||
{
|
||||
$datasource = array_merge($attributes, $datasource);
|
||||
|
||||
foreach ($datasource as $variable => $value)
|
||||
{
|
||||
$instance->$variable = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Caches the instance for possible reuse later
|
||||
self::$instances['Database'][$datasource_name] = $instance;
|
||||
}
|
||||
|
||||
// Returns the instance
|
||||
return self::$instances['Database'][$datasource_name];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens database connection
|
||||
*
|
||||
* Establishes a connection to the database based on the set configuration
|
||||
* options.
|
||||
*
|
||||
* @return boolean true on success, throws an exception overwise
|
||||
*/
|
||||
public function open()
|
||||
{
|
||||
if ($this->connection === null)
|
||||
{
|
||||
switch ($this->driver)
|
||||
{
|
||||
case 'pdo_mysql':
|
||||
// Resolves "Invalid UTF-8 sequence" issues when encoding as JSON
|
||||
// @todo Didn't resolve that issue, borked some other characters though
|
||||
//$this->attributes[\PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES utf8';
|
||||
break;
|
||||
|
||||
case 'pdo_pgsql':
|
||||
// This combats a bug: https://bugs.php.net/bug.php?id=62571&edit=1
|
||||
$this->attributes[\PDO::ATTR_PERSISTENT] = false;
|
||||
|
||||
// This allows for multiple prepared queries
|
||||
$this->attributes[\PDO::ATTR_EMULATE_PREPARES] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($this->username, $this->password, $this->database))
|
||||
{
|
||||
// Swaps out any variables with values in the DSN
|
||||
$this->dsn = str_replace(
|
||||
['[[hostname]]', '[[port]]', '[[socket]]', '[[username]]', '[[password]]', '[[database]]'],
|
||||
[$this->hostname, $this->port, $this->socket, $this->username, $this->password, $this->database],
|
||||
$this->dsn
|
||||
);
|
||||
|
||||
// Strips any empty parameters in the DSN
|
||||
$this->dsn = str_replace(['host=;', 'port=;', 'unix_socket=;'], '', $this->dsn);
|
||||
|
||||
// Attempts to establish a connection
|
||||
$this->connection = new \PDO(
|
||||
$this->dsn, $this->username, $this->password, $this->attributes
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception('There was an error loading the database configuration.');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes database connection
|
||||
*
|
||||
* Sets the connection to null regardless of state.
|
||||
*
|
||||
* @return boolean always true
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->connection = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL Statement
|
||||
*
|
||||
* Executes a standard or prepared query based on passed parameters. All
|
||||
* queries are logged to a file as well as timed and logged in the
|
||||
* execution time is over 1 second.
|
||||
*
|
||||
* @param string $sql statement to execute
|
||||
* @param array $input_parameters optional key/values to be bound
|
||||
* @return integer ID of the last inserted row or sequence number
|
||||
*/
|
||||
public function execute($sql, $input_parameters = null, $explain = false)
|
||||
{
|
||||
$this->open();
|
||||
|
||||
$sql = trim($sql);
|
||||
|
||||
// Checks if the query is blank
|
||||
if ($sql != '')
|
||||
{
|
||||
// Establishes if we're working on an EXPLAIN
|
||||
if ($this->config['pickles']['profiler'])
|
||||
{
|
||||
$explain_results = preg_match('/^SELECT /i', $sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
$explain_results = false;
|
||||
}
|
||||
|
||||
// Executes a standard query
|
||||
if ($input_parameters === null)
|
||||
{
|
||||
// Explains the query
|
||||
if ($explain_results)
|
||||
{
|
||||
$explain_results = $this->fetch('EXPLAIN ' . $sql, null, true);
|
||||
}
|
||||
|
||||
$start_time = microtime(true);
|
||||
$this->results = $this->connection->query($sql);
|
||||
}
|
||||
// Executes a prepared statement
|
||||
else
|
||||
{
|
||||
// Explains the query
|
||||
if ($explain_results)
|
||||
{
|
||||
$explain_results = $this->fetch('EXPLAIN ' . $sql, $input_parameters, true);
|
||||
}
|
||||
|
||||
$start_time = microtime(true);
|
||||
$this->results = $this->connection->prepare($sql);
|
||||
$this->results->execute($input_parameters);
|
||||
}
|
||||
|
||||
$end_time = microtime(true);
|
||||
$duration = $end_time - $start_time;
|
||||
|
||||
// Logs the information to the profiler
|
||||
if ($this->config['pickles']['profiler'] && !$explain)
|
||||
{
|
||||
Profiler::query(
|
||||
$sql,
|
||||
$input_parameters,
|
||||
$this->results->fetchAll(\PDO::FETCH_ASSOC),
|
||||
$duration,
|
||||
$explain_results
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \Exception('No query to execute.');
|
||||
}
|
||||
|
||||
return $this->connection->lastInsertId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch records from the database
|
||||
*
|
||||
* @param string $sql statement to be executed
|
||||
* @param array $input_parameters optional key/values to be bound
|
||||
* @param string $return_type optional type of return set
|
||||
* @return mixed based on return type
|
||||
*/
|
||||
public function fetch($sql = null, $input_parameters = null, $explain = false)
|
||||
{
|
||||
$this->open();
|
||||
|
||||
if ($sql !== null)
|
||||
{
|
||||
$this->execute($sql, $input_parameters, $explain);
|
||||
}
|
||||
|
||||
// Pulls the results based on the type
|
||||
$results = $this->results->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
50
src/Mongo.php
Normal file
50
src/Mongo.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Mongo Abstraction Layer
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistribution of these files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2007-2014, Josh Sherman
|
||||
* @license http://www.opensource.org/licenses/mit-license.html
|
||||
* @link https://github.com/joshtronic/pickles
|
||||
* @package Pickles
|
||||
*/
|
||||
|
||||
namespace Pickles;
|
||||
|
||||
class Mongo extends Object
|
||||
{
|
||||
public static function getInstance($class = 'Mongo')
|
||||
{
|
||||
$config = Config::getInstance();
|
||||
|
||||
if (!isset(self::$instances['Mongo']))
|
||||
{
|
||||
if (!isset($config['mongo'], $config['mongo']['database']))
|
||||
{
|
||||
throw new \Exception('The “mongo” datasource is not defined in the configuration.', 500);
|
||||
}
|
||||
|
||||
$mongo = $config['mongo'];
|
||||
|
||||
// Defaults to the local server on the default port
|
||||
if (!isset($mongo['server']))
|
||||
{
|
||||
$mongo['server'] = 'mongodb://localhost:27017';
|
||||
}
|
||||
|
||||
// Instantiates our Mongo client
|
||||
$instance = new \MongoClient($mongo['server']);
|
||||
$instance->selectDB($mongo['database']);
|
||||
|
||||
// Caches the instance for possible reuse later
|
||||
self::$instances['Mongo'] = $instance;
|
||||
}
|
||||
|
||||
// Returns the instance
|
||||
return self::$instances['Mongo'];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pickles\OAuth2;
|
||||
|
||||
use \League\OAuth2\Server\Entity\AbstractTokenEntity;
|
||||
use \League\OAuth2\Server\Entity\AccessTokenEntity;
|
||||
use \League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use \League\OAuth2\Server\Storage\AccessTokenInterface;
|
||||
|
||||
class AccessTokenStorage extends StorageAdapter implements AccessTokenInterface
|
||||
{
|
||||
public function get($token)
|
||||
{
|
||||
$sql = 'SELECT oauth_access_tokens.*'
|
||||
. ' FROM oauth_access_tokens'
|
||||
. ' WHERE access_token = ?'
|
||||
. ' AND expires_at >= ?;';
|
||||
|
||||
$results = $this->db->fetch($sql, [$token, time()]);
|
||||
|
||||
if (count($results) === 1)
|
||||
{
|
||||
return (new AccessTokenEntity($this->server))
|
||||
->setId($results[0]['access_token'])
|
||||
->setExpireTime($results[0]['expires_at']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getScopes(AbstractTokenEntity $token)
|
||||
{
|
||||
$sql = 'SELECT oauth_scopes.id, oauth_scopes.description'
|
||||
. ' FROM oauth_access_token_scopes'
|
||||
. ' INNER JOIN oauth_scopes'
|
||||
. ' ON oauth_access_token_scopes.scope_id = oauth_scopes.id'
|
||||
. ' WHERE oauth_access_token_scopes.access_token_id = ?;';
|
||||
|
||||
$results = $this->db->fetch($sql, [$token->getId()]);
|
||||
$response = [];
|
||||
|
||||
if (count($results) > 0)
|
||||
{
|
||||
foreach ($results as $row)
|
||||
{
|
||||
$response[] = (new ScopeEntity($this->server))->hydrate([
|
||||
'id' => $row['id'],
|
||||
'description' => $row['description']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function create($token, $expiration, $session_id)
|
||||
{
|
||||
$sql = 'INSERT INTO oauth_access_tokens'
|
||||
. ' (access_token, session_id, expires_at)'
|
||||
. ' VALUES'
|
||||
. ' (?, ?, ?);';
|
||||
|
||||
$this->db->execute($sql, [$token, $session_id, $expiration]);
|
||||
}
|
||||
|
||||
public function associateScope(AbstractTokenEntity $token, ScopeEntity $scope)
|
||||
{
|
||||
$sql = 'INSERT INTO oauth_access_token_scopes'
|
||||
. ' (access_token, scope)'
|
||||
. ' VALUES'
|
||||
. ' (?, ?);';
|
||||
|
||||
$this->db->execute($sql, [$token->getId(), $scope->getId()]);
|
||||
}
|
||||
|
||||
public function delete(AbstractTokenEntity $token)
|
||||
{
|
||||
$sql = 'DELETE FROM oauth_access_token_scopes'
|
||||
. ' WHERE access_token = ?;';
|
||||
|
||||
$this->db->execute($sql, [$token->getId()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pickles\OAuth2;
|
||||
|
||||
use \League\OAuth2\Server\Entity\ClientEntity;
|
||||
use \League\OAuth2\Server\Entity\SessionEntity;
|
||||
use \League\OAuth2\Server\Storage\Adapter;
|
||||
use \League\OAuth2\Server\Storage\ClientInterface;
|
||||
|
||||
class ClientStorage extends StorageAdapter implements ClientInterface
|
||||
{
|
||||
public function get($client_id, $client_secret = null, $redirect_uri = null, $grant_type = null)
|
||||
{
|
||||
$sql = 'SELECT oauth_clients.*';
|
||||
|
||||
if ($redirect_uri)
|
||||
{
|
||||
$sql .= ', oauth_client_redirect_uris.*'
|
||||
. ' INNER JOIN oauth_redirect_uris'
|
||||
. ' ON oauth_clients.id = oauth_redirect_uris.client_id';
|
||||
}
|
||||
|
||||
$sql .= ' FROM oauth_clients WHERE oauth_clients.id = ?';
|
||||
|
||||
$parameters = [$client_id];
|
||||
|
||||
if ($client_secret)
|
||||
{
|
||||
$sql .= ' AND oauth_clients.secret = ?';
|
||||
$parameters[] = $client_secret;
|
||||
}
|
||||
|
||||
if ($redirect_uri)
|
||||
{
|
||||
$sql .= 'AND oauth_redirect_uris.redirect_uri = ?';
|
||||
$parameters[] = $redirect_uri;
|
||||
}
|
||||
|
||||
$results = $this->db->fetch($sql, $parameters);
|
||||
|
||||
if (count($results) === 1)
|
||||
{
|
||||
$client = new ClientEntity($this->server);
|
||||
|
||||
$client->hydrate([
|
||||
'id' => $results[0]['id'],
|
||||
'name' => $results[0]['name']
|
||||
]);
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getBySession(SessionEntity $session)
|
||||
{
|
||||
$sql = 'SELECT oauth_clients.id, oauth_clients.name'
|
||||
. ' FROM oauth_clients'
|
||||
. ' INNER JOIN oauth_sessions'
|
||||
. ' ON oauth_clients.id = oauth_sessions.client_id'
|
||||
. ' WHERE oauth_sessions.id = ?';
|
||||
|
||||
$results = $this->db->fetch($sql, [$session->getId()]);
|
||||
|
||||
if (count($results) === 1)
|
||||
{
|
||||
$client = new ClientEntity($this->server);
|
||||
|
||||
$client->hydrate([
|
||||
'id' => $results[0]['id'],
|
||||
'name' => $results[0]['name']
|
||||
]);
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pickles\OAuth2;
|
||||
|
||||
use \League\OAuth2\Server\Entity\RefreshTokenEntity;
|
||||
use \League\OAuth2\Server\Storage\RefreshTokenInterface;
|
||||
|
||||
class RefreshTokenStorage extends StorageAdapter implements RefreshTokenInterface
|
||||
{
|
||||
public function get($token)
|
||||
{
|
||||
$sql = 'SELECT oauth_refresh_tokens.*'
|
||||
. ' FROM oauth_refresh_tokens'
|
||||
. ' WHERE refresh_token = ?'
|
||||
. ' AND expires_at >= ?;';
|
||||
|
||||
$results = $this->db->fetch($sql, [$token, time()]);
|
||||
|
||||
if (count($results) === 1)
|
||||
{
|
||||
return (new RefreshTokenEntity($this->server))
|
||||
->setId($results[0]['refresh_token'])
|
||||
->setExpireTime($results[0]['expires_at'])
|
||||
->setAccessTokenId($results[0]['access_token_id']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function create($token, $expiration, $access_token)
|
||||
{
|
||||
$sql = 'SELECT id FROM oauth_access_tokens WHERE access_token = ?;';
|
||||
$results = $this->db->fetch($sql, [$access_token]);
|
||||
$token_id = $results[0]['id'];
|
||||
|
||||
$sql = 'INSERT INTO oauth_refresh_tokens'
|
||||
. ' (refresh_token, access_token_id, expires_at, client_id)'
|
||||
. ' VALUES'
|
||||
. ' (?, ?, ?, ?);';
|
||||
|
||||
$this->db->execute($sql, [
|
||||
$token,
|
||||
$token_id,
|
||||
$expiration,
|
||||
$this->server->getRequest()->request->get('client_id', null),
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete(RefreshTokenEntity $token)
|
||||
{
|
||||
$sql = 'DELETE FROM oauth_refresh_tokens WHERE refresh_token = ?;';
|
||||
|
||||
$this->db->execute($sql, [$token->getId()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pickles\OAuth2;
|
||||
|
||||
use \League\OAuth2\Server\Storage\Adapter;
|
||||
use \League\OAuth2\Server\Storage\ScopeInterface;
|
||||
|
||||
class ScopeStorage extends StorageAdapter implements ScopeInterface
|
||||
{
|
||||
public function get($scope, $grant_type = null, $client_id = null)
|
||||
{
|
||||
$sql = 'SELECT * FROM oauth_scopes WHERE id = ?;';
|
||||
$results = $this->db->fetch($sql, [$scope]);
|
||||
|
||||
if (count($results) === 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return (new ScopeEntity($this->server))->hydrate([
|
||||
'id' => $result[0]['id'],
|
||||
'description' => $result[0]['description'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pickles\OAuth2;
|
||||
|
||||
use \League\OAuth2\Server\Entity\AccessTokenEntity;
|
||||
use \League\OAuth2\Server\Entity\AuthCodeEntity;
|
||||
use \League\OAuth2\Server\Entity\ScopeEntity;
|
||||
use \League\OAuth2\Server\Entity\SessionEntity;
|
||||
use \League\OAuth2\Server\Storage\Adapter;
|
||||
use \League\OAuth2\Server\Storage\SessionInterface;
|
||||
|
||||
class SessionStorage extends StorageAdapter implements SessionInterface
|
||||
{
|
||||
public function getByAccessToken(AccessTokenEntity $access_token)
|
||||
{
|
||||
$sql = 'SELECT oauth_sessions.id, oauth_sessions.owner_type,'
|
||||
. ' oauth_sessions.owner_id, oauth_sessions.client_id,'
|
||||
. ' oauth_sessions.client_redirect_uri'
|
||||
. ' FROM oauth_sessions'
|
||||
. ' INNER JOIN oauth_access_tokens'
|
||||
. ' ON oauth_access_tokens.session_id = oauth_sessions.id'
|
||||
. ' WHERE oauth_access_tokens.access_token = ?;';
|
||||
|
||||
$results = $this->db->fetch($sql, [$access_token->getId()]);
|
||||
|
||||
if (count($results) === 1)
|
||||
{
|
||||
$session = new SessionEntity($this->server);
|
||||
$session->setId($result[0]['id']);
|
||||
$session->setOwner($result[0]['owner_type'], $result[0]['owner_id']);
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getByAuthCode(AuthCodeEntity $auth_code)
|
||||
{
|
||||
$sql = 'SELECT oauth_sessions.id, oauth_sessions.owner_type,'
|
||||
. ' oauth_sessions.owner_id, oauth_sessions.client_id,'
|
||||
. ' oauth_sessions.client_redirect_uri'
|
||||
. ' FROM oauth_sessions'
|
||||
. ' INNER JOIN oauth_authorization_codes'
|
||||
. ' ON oauth_authorization_codes.session_id = oauth_sessions.id'
|
||||
. ' WHERE oauth_authorization_codes.authorization_code = ?;';
|
||||
|
||||
$results = $this->db->fetch($sql, [$auth_code->getId()]);
|
||||
|
||||
if (count($results) === 1)
|
||||
{
|
||||
$session = new SessionEntity($this->server);
|
||||
$session->setId($result[0]['id']);
|
||||
$session->setOwner($result[0]['owner_type'], $result[0]['owner_id']);
|
||||
|
||||
return $session;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getScopes(SessionEntity $session)
|
||||
{
|
||||
$sql = 'SELECT oauth_sessions.*'
|
||||
. ' FROM oauth_sessions'
|
||||
. ' INNER JOIN oauth_access_token_scopes'
|
||||
. ' ON oauth_sessions.id = oauth_access_token_scopes.access_token_id'
|
||||
. ' INNER JOIN oauth_scopes'
|
||||
. ' ON oauth_scopes.id = oauth_access_token_scopes.scope_id'
|
||||
. ' WHERE oauth_sessions.id = ?;';
|
||||
|
||||
$results = $this->db->fetch($sql, [$session->getId()]);
|
||||
$scopes = [];
|
||||
|
||||
foreach ($results as $scope)
|
||||
{
|
||||
$scopes[] = (new ScopeEntity($this->server))->hydrate([
|
||||
'id' => $scope['id'],
|
||||
'description' => $scope['description'],
|
||||
]);
|
||||
}
|
||||
|
||||
return $scopes;
|
||||
}
|
||||
|
||||
public function create($owner_type, $owner_id, $client_id, $client_redirect_uri = null)
|
||||
{
|
||||
$sql = 'INSERT INTO oauth_sessions'
|
||||
. ' (owner_type, owner_id, client_id)'
|
||||
. ' VALUES'
|
||||
. ' (?, ?, ?);';
|
||||
|
||||
return $this->db->execute($sql, [$owner_type, $owner_id, $client_id]);
|
||||
}
|
||||
|
||||
public function associateScope(SessionEntity $session, ScopeEntity $scope)
|
||||
{
|
||||
$sql = 'INSERT INTO oauth_access_token_scopes'
|
||||
. ' (access_token_id, scope_id)'
|
||||
. ' VALUES'
|
||||
. ' (?, ?);';
|
||||
|
||||
$this->db->execute($sql, [$session->getId(), $scope->getId()]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Pickles\OAuth2;
|
||||
|
||||
use \League\OAuth2\Server\Storage\Adapter;
|
||||
use \Pickles\Config;
|
||||
use \Pickles\Database;
|
||||
|
||||
class StorageAdapter extends Adapter
|
||||
{
|
||||
protected $config;
|
||||
protected $db;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = Config::getInstance();
|
||||
$this->db = Database::getInstance();
|
||||
}
|
||||
}
|
||||
|
|
@ -39,47 +39,33 @@ class Object
|
|||
public $config = null;
|
||||
|
||||
/**
|
||||
* Instance of the Cache object
|
||||
* Instance of the Mongo object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $cache = null;
|
||||
public $mongo = null;
|
||||
|
||||
/**
|
||||
* Instance of the Database object
|
||||
* Instance of the Redis object
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public $db = null;
|
||||
public $redis = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Establishes a Config instance for all children to enjoy
|
||||
*/
|
||||
public function __construct($objects = null)
|
||||
public function __construct()
|
||||
{
|
||||
// @todo Lazy load these so we're not loading them on every instance
|
||||
$this->config = Config::getInstance();
|
||||
|
||||
if ($objects)
|
||||
{
|
||||
if (!is_array($objects))
|
||||
{
|
||||
$objects = [$objects];
|
||||
}
|
||||
|
||||
foreach ($objects as $object)
|
||||
{
|
||||
switch ($object)
|
||||
{
|
||||
case 'cache': $this->cache = Cache::getInstance(); break;
|
||||
case 'db': $this->db = Database::getInstance(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->mongo = Mongo::getInstance();
|
||||
//$this->redis = Redis::getInstance();
|
||||
|
||||
// Optionally logs the constructor to the profiler
|
||||
if ($this->config['pickles']['profiler'])
|
||||
if ($this->config['profiler'])
|
||||
{
|
||||
Profiler::log($this, '__construct');
|
||||
}
|
||||
|
@ -119,7 +105,7 @@ class Object
|
|||
public function __destruct()
|
||||
{
|
||||
// Optionally logs the destructor to the profiler
|
||||
if ($this->config['pickles']['profiler'])
|
||||
if ($this->config['profiler'])
|
||||
{
|
||||
Profiler::log($this, '__destruct');
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ class Resource extends Object
|
|||
throw new \Exception('Missing or invalid parameters.', 400);
|
||||
}
|
||||
|
||||
parent::__construct(['cache', 'db']);
|
||||
parent::__construct();
|
||||
|
||||
// Checks if the request method has been implemented
|
||||
if (get_class($this) != 'Pickles\\Resource')
|
||||
|
@ -302,7 +302,7 @@ class Resource extends Object
|
|||
else
|
||||
{
|
||||
// Starts a timer before the resource is executed
|
||||
if ($this->config['pickles']['profiler'])
|
||||
if ($this->config['profiler'])
|
||||
{
|
||||
$timer = get_class($this) . '->' . $method . '()';
|
||||
Profiler::timer($timer);
|
||||
|
@ -311,7 +311,7 @@ class Resource extends Object
|
|||
$this->response = $this->$method();
|
||||
|
||||
// Stops the resource timer
|
||||
if ($this->config['pickles']['profiler'])
|
||||
if ($this->config['profiler'])
|
||||
{
|
||||
Profiler::timer($timer);
|
||||
}
|
||||
|
@ -374,7 +374,7 @@ class Resource extends Object
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->config['pickles']['profiler'])
|
||||
if ($this->config['profiler'])
|
||||
{
|
||||
$response['profiler'] = Profiler::report();
|
||||
}
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
|
||||
class CacheTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $cache;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['SERVER_NAME'] = '127.0.0.1';
|
||||
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"cache" => "mc",
|
||||
],
|
||||
"datasources" => [
|
||||
"mc" => [
|
||||
"type" => "memcache",
|
||||
"hostname" => "localhost",
|
||||
"port" => 11211,
|
||||
"namespace" => "ns",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->cache = Pickles\Cache::getInstance();
|
||||
}
|
||||
|
||||
public function testGetInstance()
|
||||
{
|
||||
$this->assertInstanceOf('Pickles\\Cache', $this->cache);
|
||||
}
|
||||
|
||||
public function testSetAndGet()
|
||||
{
|
||||
$key = Pickles\String::random();
|
||||
$value = Pickles\String::random();
|
||||
|
||||
$this->cache->set($key, $value);
|
||||
|
||||
$this->assertEquals($value, $this->cache->get($key));
|
||||
}
|
||||
|
||||
public function testSetAndGetMultiple()
|
||||
{
|
||||
$keys = $values = $expected = [];
|
||||
|
||||
for ($i = 0; $i < 5; $i++)
|
||||
{
|
||||
$keys[] = Pickles\String::random();
|
||||
$values[] = Pickles\String::random();
|
||||
}
|
||||
|
||||
foreach ($keys as $key => $key_name)
|
||||
{
|
||||
$value = $values[$key];
|
||||
$expected['NS-' . strtoupper($key_name)] = $value;
|
||||
$this->cache->set($key_name, $value);
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, $this->cache->get($keys));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
$key = Pickles\String::random();
|
||||
$value = Pickles\String::random();
|
||||
|
||||
$this->cache->set($key, $value);
|
||||
$this->cache->delete($key);
|
||||
|
||||
$this->assertFalse($this->cache->get($key));
|
||||
}
|
||||
|
||||
public function testIncrement()
|
||||
{
|
||||
$key = Pickles\String::random();
|
||||
|
||||
$this->assertFalse($this->cache->increment($key));
|
||||
|
||||
$this->cache->set($key, 1);
|
||||
|
||||
$this->assertEquals(2, $this->cache->increment($key));
|
||||
$this->assertEquals(3, $this->cache->increment($key));
|
||||
$this->assertEquals(4, $this->cache->increment($key));
|
||||
}
|
||||
|
||||
// Doesn't do much but test that the destructor doesn't explode
|
||||
public function testDestructor()
|
||||
{
|
||||
$this->cache->__destruct();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,526 +0,0 @@
|
|||
<?php
|
||||
|
||||
class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['SERVER_NAME'] = '127.0.0.1';
|
||||
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "mysql",
|
||||
],
|
||||
"datasources" => [
|
||||
"mysql" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
}
|
||||
|
||||
public function testGetInstanceFalse()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"datasources" => [
|
||||
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->assertFalse(Pickles\Database::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage The specified datasource is not defined in the config.
|
||||
*/
|
||||
public function testGetInstanceDatasourceNotDefined()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "bad",
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
Pickles\Database::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage The specified datasource lacks a driver.
|
||||
*/
|
||||
public function testGetInstanceDatasourceLacksDriver()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "bad",
|
||||
],
|
||||
"datasources" => [
|
||||
"bad" => [
|
||||
"type" => "mysql",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->assertInstanceOf('Pickles\\Database', Pickles\Database::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage There was an error loading the database configuration.
|
||||
*/
|
||||
public function testOpenConfigError()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "bad",
|
||||
],
|
||||
"datasources" => [
|
||||
"bad" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->open();
|
||||
}
|
||||
|
||||
public function testGetInstanceDatasourcesArray()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "bad",
|
||||
],
|
||||
"datasources" => [
|
||||
"bad" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->assertInstanceOf('Pickles\\Database', Pickles\Database::getInstance());
|
||||
}
|
||||
|
||||
// Also tests the datasource being missing and selecting the first one
|
||||
public function testGetInstanceMySQL()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
],
|
||||
"datasources" => [
|
||||
"bad" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->assertInstanceOf('Pickles\\Database', Pickles\Database::getInstance());
|
||||
}
|
||||
|
||||
public function testOpenMySQL()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "mysql",
|
||||
],
|
||||
"datasources" => [
|
||||
"mysql" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->open();
|
||||
}
|
||||
|
||||
public function testExecute()
|
||||
{
|
||||
$db = Pickles\Database::getInstance();
|
||||
$this->assertEquals('0', $db->execute('SHOW TABLES'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage No query to execute.
|
||||
*/
|
||||
public function testExecuteNoQuery()
|
||||
{
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->execute(' ');
|
||||
}
|
||||
|
||||
public function testFetch()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "mysql",
|
||||
"profiler" => true,
|
||||
],
|
||||
"datasources" => [
|
||||
"mysql" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$db = Pickles\Database::getInstance();
|
||||
$this->assertEquals([], $db->fetch('SELECT * FROM pickles WHERE id != ?', ['0']));
|
||||
}
|
||||
|
||||
public function testExplainNoInput()
|
||||
{
|
||||
$config = Pickles\Config::getInstance();
|
||||
$db = Pickles\Database::getInstance();
|
||||
$this->assertEquals([], $db->fetch('SELECT * FROM pickles WHERE id != 0'));
|
||||
}
|
||||
|
||||
public function testSlowQuery()
|
||||
{
|
||||
$db = Pickles\Database::getInstance();
|
||||
$this->assertEquals('0', $db->execute('SHOW DATABASES', null, true));
|
||||
}
|
||||
|
||||
public function testCloseMySQL()
|
||||
{
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->open();
|
||||
|
||||
$this->assertTrue($db->close());
|
||||
}
|
||||
|
||||
public function testGetInstancePostgreSQL()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "pgsql",
|
||||
],
|
||||
"datasources" => [
|
||||
"pgsql" => [
|
||||
"type" => "pgsql",
|
||||
"driver" => "pdo_pgsql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->assertInstanceOf('Pickles\\Database', Pickles\Database::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException PDOException
|
||||
* @expectedExceptionCode 7
|
||||
*/
|
||||
public function testOpenPostgreSQL()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "pgsql",
|
||||
],
|
||||
"datasources" => [
|
||||
"pgsql" => [
|
||||
"type" => "pgsql",
|
||||
"driver" => "pdo_pgsql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
// Throws an error because I don't have PostgreSQL installed
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->open();
|
||||
}
|
||||
|
||||
public function testGetInstanceSQLite()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "sqlite",
|
||||
],
|
||||
"datasources" => [
|
||||
"sqlite" => [
|
||||
"type" => "sqlite",
|
||||
"driver" => "pdo_sqlite",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$this->assertInstanceOf('Pickles\\Database', Pickles\Database::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage Datasource driver "pdo_invalid" is invalid
|
||||
*/
|
||||
public function testGetInstanceInvalidDriver()
|
||||
{
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "invalid",
|
||||
],
|
||||
"datasources" => [
|
||||
"invalid" => [
|
||||
"type" => "invalid",
|
||||
"driver" => "pdo_invalid",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
Pickles\Database::getInstance();
|
||||
}
|
||||
|
||||
public function testProfilerWithoutParameters()
|
||||
{
|
||||
// Clears out the Config for ease of testing
|
||||
Pickles\Object::$instances = [];
|
||||
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['SERVER_NAME'] = '127.0.0.1';
|
||||
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"datasource" => "mysql",
|
||||
"profiler" => true,
|
||||
],
|
||||
"datasources" => [
|
||||
"mysql" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->execute('SELECT * FROM `users`');
|
||||
|
||||
$report = Pickles\Profiler::report();
|
||||
$this->assertEquals(7, count($report));
|
||||
$this->assertEquals(2, count($report['logs']));
|
||||
$this->assertTrue(isset($report['logs'][1]['details']['explain']));
|
||||
}
|
||||
|
||||
public function testProfilerWithParameters()
|
||||
{
|
||||
// Clears out the Config for ease of testing
|
||||
Pickles\Object::$instances = [];
|
||||
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['SERVER_NAME'] = '127.0.0.1';
|
||||
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"datasource" => "mysql",
|
||||
"profiler" => true,
|
||||
],
|
||||
"datasources" => [
|
||||
"mysql" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"database" => "test",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
$db = Pickles\Database::getInstance();
|
||||
$db->execute('SELECT * FROM `users` WHERE id = ?', [1000000]);
|
||||
|
||||
$report = Pickles\Profiler::report();
|
||||
$this->assertEquals(7, count($report));
|
||||
$this->assertEquals(3, count($report['logs']));
|
||||
$this->assertEquals([1000000], $report['logs'][2]['details']['parameters']);
|
||||
$this->assertTrue(isset($report['logs'][2]['details']['explain']));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,633 +0,0 @@
|
|||
<?php
|
||||
|
||||
class MockModelWithoutColumns extends Pickles\Model
|
||||
{
|
||||
public $table = 'pickles';
|
||||
public $columns = false;
|
||||
}
|
||||
|
||||
// InnoDB
|
||||
class MockModel extends Pickles\Model
|
||||
{
|
||||
public $table = 'pickles';
|
||||
public $columns = ['created_at' => 'created_at'];
|
||||
}
|
||||
|
||||
// MyISAM
|
||||
class MyMockModel extends Pickles\Model
|
||||
{
|
||||
public $table = 'mypickles';
|
||||
}
|
||||
|
||||
class ModelTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
// Clears out the Config for ease of testing
|
||||
Pickles\Object::$instances = [];
|
||||
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['SERVER_NAME'] = '127.0.0.1';
|
||||
|
||||
file_put_contents('/tmp/pickles.php', '<?php
|
||||
$config = [
|
||||
"environments" => [
|
||||
"local" => "127.0.0.1",
|
||||
"production" => "123.456.789.0",
|
||||
],
|
||||
"pickles" => [
|
||||
"namespace" => "",
|
||||
"datasource" => "mysql",
|
||||
"cache" => "memcache",
|
||||
],
|
||||
"datasources" => [
|
||||
"mysql" => [
|
||||
"type" => "mysql",
|
||||
"driver" => "pdo_mysql",
|
||||
"hostname" => "localhost",
|
||||
"username" => "root",
|
||||
"password" => "",
|
||||
"database" => "test",
|
||||
"cache" => true,
|
||||
],
|
||||
"memcache" => [
|
||||
"type" => "memcache",
|
||||
"hostname" => "localhost",
|
||||
"port" => 11211,
|
||||
"namespace" => "",
|
||||
],
|
||||
],
|
||||
];
|
||||
');
|
||||
|
||||
$config = Pickles\Config::getInstance('/tmp/pickles.php');
|
||||
|
||||
for ($i = 0; $i < 5; $i++)
|
||||
{
|
||||
$model = new MockModel();
|
||||
$model->record['field1'] = 'one';
|
||||
$model->record['field2'] = 'two';
|
||||
$model->record['field3'] = 'three';
|
||||
$model->record['field4'] = 'four';
|
||||
$model->record['field5'] = 'five';
|
||||
$model->commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage You must set the table variable
|
||||
*/
|
||||
public function testNoTable()
|
||||
{
|
||||
new Pickles\Model();
|
||||
}
|
||||
|
||||
public function testWithoutColumns()
|
||||
{
|
||||
$model = new MockModelWithoutColumns();
|
||||
$columns = PHPUnit_Framework_Assert::readAttribute($model, 'columns');
|
||||
|
||||
$this->assertFalse($columns['is_deleted']);
|
||||
}
|
||||
|
||||
public function testWithColumns()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$columns = PHPUnit_Framework_Assert::readAttribute($model, 'columns');
|
||||
|
||||
$this->assertEquals('is_deleted', $columns['is_deleted']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage You cannot pass in 2 query parameter arrays
|
||||
*/
|
||||
public function testDoubleArray()
|
||||
{
|
||||
$model = new MockModel(['foo' => 'bar'], ['test' => 'ing']);
|
||||
}
|
||||
|
||||
public function testFetchInt()
|
||||
{
|
||||
$model = new MockModel(1);
|
||||
$this->assertEquals(1, $model->count());
|
||||
$this->assertEquals(1, $model->record['id']);
|
||||
}
|
||||
|
||||
public function testFetchIntArray()
|
||||
{
|
||||
$model = new MockModel([1, 2, 3]);
|
||||
$this->assertEquals(3, $model->count());
|
||||
}
|
||||
|
||||
/*
|
||||
@todo Acting wonky, passes tests on just this class, fails on all
|
||||
public function testFetchConditionsID()
|
||||
{
|
||||
$model = new MockModel(['conditions' => ['id' => 1]]);
|
||||
var_dump($model->record);
|
||||
$this->assertEquals(1, $model->count());
|
||||
$this->assertEquals(1, $model->record['id']);
|
||||
}
|
||||
*/
|
||||
|
||||
public function testFetchCount()
|
||||
{
|
||||
$model = new MockModel('count');
|
||||
$this->assertEquals(5, $model->record['count']);
|
||||
}
|
||||
|
||||
public function testFetchCountConditions()
|
||||
{
|
||||
$model = new MockModel('count', ['conditions' => ['id' => [1, 3, 5]]]);
|
||||
$this->assertEquals(3, $model->record['count']);
|
||||
}
|
||||
|
||||
public function testFetchIndexed()
|
||||
{
|
||||
$model = new MockModel('indexed', ['conditions' => ['id' => [2, 4]]]);
|
||||
$this->assertEquals(2, $model->count());
|
||||
$this->assertEquals([2, 4], array_keys($model->records));
|
||||
}
|
||||
|
||||
// Also tests against a full cache
|
||||
public function testFetchList()
|
||||
{
|
||||
$model = new MockModel('list', ['conditions' => ['id' => [2, 4]]]);
|
||||
$this->assertEquals(2, $model->count());
|
||||
$this->assertEquals([2, 4], array_keys($model->records));
|
||||
}
|
||||
|
||||
public function testFetchCountWithID()
|
||||
{
|
||||
$model = new MockModel('count', 3);
|
||||
$this->assertEquals(1, $model->record['count']);
|
||||
}
|
||||
|
||||
public function testFetchListWithID()
|
||||
{
|
||||
$model = new MockModel('list', 2);
|
||||
$this->assertEquals(1, $model->count());
|
||||
$this->assertEquals([2 => 'one'], $model->records);
|
||||
}
|
||||
|
||||
public function testFieldValues()
|
||||
{
|
||||
$model = new MockModel('all');
|
||||
|
||||
$fields = $model->fieldValues('id');
|
||||
|
||||
$this->assertEquals('5', count($fields));
|
||||
|
||||
foreach ($fields as $value)
|
||||
{
|
||||
$this->assertTrue(ctype_digit($value));
|
||||
}
|
||||
}
|
||||
|
||||
public function testSort()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$this->assertTrue($model->sort('id'));
|
||||
}
|
||||
|
||||
public function testShuffle()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$this->assertTrue($model->shuffle());
|
||||
}
|
||||
|
||||
public function testNextPrev()
|
||||
{
|
||||
$model = new MockModel('all');
|
||||
$model->next();
|
||||
$this->assertEquals(2, $model->record['id']);
|
||||
$model->prev();
|
||||
$this->assertEquals(1, $model->record['id']);
|
||||
}
|
||||
|
||||
public function testLastFirst()
|
||||
{
|
||||
$model = new MockModel('all');
|
||||
$model->last();
|
||||
$this->assertEquals(5, $model->record['id']);
|
||||
$model->first();
|
||||
$this->assertEquals(1, $model->record['id']);
|
||||
}
|
||||
|
||||
public function testEndReset()
|
||||
{
|
||||
$model = new MockModel('all');
|
||||
$model->end();
|
||||
$this->assertEquals(5, $model->record['id']);
|
||||
$model->reset();
|
||||
$this->assertEquals(1, $model->record['id']);
|
||||
}
|
||||
|
||||
public function testWalk()
|
||||
{
|
||||
$model = new MockModel('all');
|
||||
$expected = 0;
|
||||
|
||||
while ($model->walk())
|
||||
{
|
||||
$expected++;
|
||||
$this->assertEquals($expected, $model->record['id']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testInsert()
|
||||
{
|
||||
$model = new MockModel();
|
||||
|
||||
for ($i = 1; $i <= 5; $i++)
|
||||
{
|
||||
$model->record['field' . $i] = Pickles\String::random();
|
||||
}
|
||||
|
||||
$model->commit();
|
||||
}
|
||||
|
||||
public function testInsertMultiple()
|
||||
{
|
||||
$model = new MockModel();
|
||||
|
||||
for ($i = 1; $i <= 5; $i++)
|
||||
{
|
||||
for ($j = 1; $j <= 5; $j++)
|
||||
{
|
||||
$model->record['field' . $j] = Pickles\String::random();
|
||||
}
|
||||
|
||||
$model->queue();
|
||||
}
|
||||
|
||||
$model->commit();
|
||||
}
|
||||
|
||||
public function testGetFromCache()
|
||||
{
|
||||
$model = new MockModel(1);
|
||||
$this->assertEquals('1', $model->record['id']);
|
||||
}
|
||||
|
||||
public function testGetFromCacheConditionals()
|
||||
{
|
||||
$model = new MockModel(['conditions' => ['id' => 1]]);
|
||||
$this->assertEquals('1', $model->record['id']);
|
||||
}
|
||||
|
||||
public function testCacheKey()
|
||||
{
|
||||
$model = new MockModel('indexed', 1, 'cache-key');
|
||||
$this->assertEquals([1], array_keys($model->records));
|
||||
}
|
||||
|
||||
public function testGenerateQuery()
|
||||
{
|
||||
$model = new MockModelWithoutColumns([
|
||||
'conditions' => [1, 2, 3],
|
||||
'group' => 'id',
|
||||
'having' => '1 = 1',
|
||||
'order' => 'id DESC',
|
||||
'limit' => 5,
|
||||
'offset' => 1,
|
||||
]);
|
||||
$this->assertEquals('2', $model->record['id']);
|
||||
}
|
||||
|
||||
public function testGenerateConditions()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions([
|
||||
'id' => [1, 2, 3],
|
||||
'NOT' => 5,
|
||||
'OR id !=' => 10,
|
||||
'OR NOT' => [15, 20, 25],
|
||||
'id != 30',
|
||||
'id IS NOT' => null,
|
||||
'id !=' => false,
|
||||
'id <' => true,
|
||||
'id >' => null,
|
||||
'id BETWEEN' => [35, 40],
|
||||
]);
|
||||
$this->assertEquals('id in (?, ?, ?) AND NOT = ? OR id != ? OR NOT in (?, ?, ?) AND id != 30 AND id IS NOT NULL AND id IS NOT FALSE AND id IS TRUE AND id > NULL AND id BETWEEN ? AND ?', $conditions);
|
||||
}
|
||||
|
||||
public function testGenerateConditionsInjectValues()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions([
|
||||
'id' => [1, 2, 3],
|
||||
'NOT' => 5,
|
||||
'OR id !=' => 10,
|
||||
'OR NOT' => [15, 20, 25],
|
||||
'id != 30',
|
||||
'id IS NOT' => null,
|
||||
'id !=' => false,
|
||||
'id <' => true,
|
||||
'id >' => null,
|
||||
'id BETWEEN' => [35, 40],
|
||||
], true);
|
||||
$this->assertEquals('id in (1, 2, 3) AND NOT = 5 OR id != 10 OR NOT in (15, 20, 25) AND id != 30 AND id IS NOT NULL AND id IS NOT FALSE AND id IS TRUE AND id > NULL AND id BETWEEN 35 AND 40', $conditions);
|
||||
}
|
||||
|
||||
public function testGenerateConditionsNoOperatorTrue()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions(['id' => true]);
|
||||
$this->assertEquals('id IS TRUE', $conditions);
|
||||
}
|
||||
|
||||
public function testGenerateConditionsNoOperatorFalse()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions(['id' => false]);
|
||||
$this->assertEquals('id IS FALSE', $conditions);
|
||||
}
|
||||
|
||||
public function testGenerateConditionsNoOperatorNull()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions(['id' => null]);
|
||||
$this->assertEquals('id IS NULL', $conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage BETWEEN expects an array with 2 values.
|
||||
*/
|
||||
public function testGenerateConditionsBetweenMissingValue()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions(['id BETWEEN' => [1]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
* @expectedExceptionMessage BETWEEN expects an array.
|
||||
*/
|
||||
public function testGenerateConditionsBetweenNotArray()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$conditions = $model->generateConditions(['id BETWEEN' => '1']);
|
||||
}
|
||||
|
||||
public function testCommitSingleRecord()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel(1);
|
||||
$model->record['field1'] = $value;
|
||||
$model->commit();
|
||||
|
||||
$model = new MockModel(1);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
// Handles filling coverage gaps but isn't a reliable test. Would need to
|
||||
// test against a table without a UID column so we can see this in action,
|
||||
// else it just takes a shit because the ID isn't injected back in.
|
||||
public function testCommitSingleRecordReplace()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel(1);
|
||||
$model->replace = true;
|
||||
$model->record['field1'] = $value;
|
||||
$model->commit();
|
||||
$model = new MockModel(1);
|
||||
}
|
||||
|
||||
public function testCommitInsertPriority()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel();
|
||||
$model->priority = 'low';
|
||||
$model->record['field1'] = $value;
|
||||
$id = $model->commit();
|
||||
$model = new MockModel($id);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitInsertDelayed()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MyMockModel();
|
||||
$model->delayed = true;
|
||||
$model->record['field1'] = $value;
|
||||
$model->commit();
|
||||
$model = new MyMockModel(1);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitInsertIgnore()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel();
|
||||
$model->ignore = true;
|
||||
$model->record['field1'] = $value;
|
||||
$id = $model->commit();
|
||||
$model = new MockModel($id);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitReplacePriority()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel();
|
||||
$model->replace = true;
|
||||
$model->priority = 'low';
|
||||
$model->record['field1'] = $value;
|
||||
$id = $model->commit();
|
||||
$model = new MockModel($id);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitReplaceDelayed()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MyMockModel();
|
||||
$model->replace = true;
|
||||
$model->delayed = true;
|
||||
$model->record['field1'] = $value;
|
||||
$model->commit();
|
||||
$model = new MyMockModel(2);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitReplaceIgnore()
|
||||
{
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel();
|
||||
$model->replace = true;
|
||||
$model->ignore = true;
|
||||
$model->record['field1'] = $value;
|
||||
$id = $model->commit();
|
||||
$model = new MockModel($id);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitMultipleFields()
|
||||
{
|
||||
$value1 = Pickles\String::random();
|
||||
$value2 = Pickles\String::random();
|
||||
$model = new MockModelWithoutColumns(1);
|
||||
$model->record['field1'] = $value1;
|
||||
$model->record['field2'] = $value2;
|
||||
$model->commit();
|
||||
$model = new MockModelWithoutColumns(1);
|
||||
$this->assertEquals($value1, $model->record['field1']);
|
||||
$this->assertEquals($value2, $model->record['field2']);
|
||||
}
|
||||
|
||||
public function testCommitIncrement()
|
||||
{
|
||||
$model = new MockModelWithoutColumns(1);
|
||||
$model->record['field1'] = 100;
|
||||
$model->commit();
|
||||
$model = new MockModelWithoutColumns(1);
|
||||
$model->record['field1'] = '++';
|
||||
$model->commit();
|
||||
$model = new MockModelWithoutColumns(1);
|
||||
$this->assertEquals(101, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitUpdatedID()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel(1);
|
||||
$model->record['field1'] = $value;
|
||||
$model->commit();
|
||||
$model = new MockModel(1);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
$this->assertEquals(1, $model->record['updated_id']);
|
||||
}
|
||||
|
||||
public function testCommitCreatedID()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel();
|
||||
$model->record['field1'] = $value;
|
||||
$id = $model->commit();
|
||||
$model = new MockModel($id);
|
||||
$this->assertEquals(1, $model->record['created_id']);
|
||||
}
|
||||
|
||||
// Doesn't test against actual PostgreSQL instance, just for valid syntax
|
||||
public function testCommitInsertPostgreSQL()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel();
|
||||
$model->mysql = false;
|
||||
$model->postgresql = true;
|
||||
$model->record['field1'] = $value;
|
||||
|
||||
try
|
||||
{
|
||||
$model->commit();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
$this->assertRegExp('/RETURNING id/', $model->db->results->queryString);
|
||||
}
|
||||
|
||||
// Doesn't test against actual PostgreSQL instance, just for valid syntax
|
||||
public function testCommitUpdatePostgreSQL()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$value = Pickles\String::random();
|
||||
$model = new MockModel(1);
|
||||
$model->mysql = false;
|
||||
$model->postgresql = true;
|
||||
$model->record['field1'] = $value;
|
||||
|
||||
try
|
||||
{
|
||||
$model->commit();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
$model = new MockModel(1);
|
||||
$this->assertEquals($value, $model->record['field1']);
|
||||
}
|
||||
|
||||
public function testCommitNothing()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$this->assertFalse($model->commit());
|
||||
}
|
||||
|
||||
public function testDeleteLogical()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$model = new MockModel(1);
|
||||
$model->delete();
|
||||
$model = new MockModel(1);
|
||||
$this->assertEquals([], $model->record);
|
||||
}
|
||||
|
||||
public function testDeleteActual()
|
||||
{
|
||||
$model = new MockModelWithoutColumns(2);
|
||||
$model->delete();
|
||||
$model = new MockModelWithoutColumns(2);
|
||||
$this->assertEquals(0, $model->count());
|
||||
}
|
||||
|
||||
public function testDeleteNothing()
|
||||
{
|
||||
$model = new MockModelWithoutColumns(100);
|
||||
$this->assertFalse($model->delete());
|
||||
}
|
||||
|
||||
public function testLoadParametersWithString()
|
||||
{
|
||||
$model = new MockModel();
|
||||
$this->assertFalse($model->loadParameters(''));
|
||||
}
|
||||
|
||||
public function testMultipleQueueInsert()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$model = new MockModel('count');
|
||||
$count = $model->record['count'];
|
||||
$model = new MockModel();
|
||||
|
||||
for ($i = 0; $i < 5; $i++)
|
||||
{
|
||||
$model->record['field1'] = Pickles\String::random();
|
||||
$model->record['updated_id'] = 1;
|
||||
$model->queue();
|
||||
}
|
||||
|
||||
$model->commit();
|
||||
$model = new MockModel('count');
|
||||
$this->assertEquals($count + 5, $model->record['count']);
|
||||
}
|
||||
|
||||
public function testMultipleQueueUpdate()
|
||||
{
|
||||
$_SESSION['__pickles']['security']['user_id'] = 1;
|
||||
$model = new MockModel();
|
||||
|
||||
for ($i = 3; $i <= 5; $i++)
|
||||
{
|
||||
$model->record['id'] = $i;
|
||||
$model->record['field1'] = Pickles\String::random();
|
||||
$model->record['updated_id'] = 1;
|
||||
$model->queue();
|
||||
}
|
||||
|
||||
$model->commit();
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue