Anton Grebnev
13 years ago
30 changed files with 2931 additions and 576 deletions
-
1.gitignore
-
34Load.php
-
2logger/CliLogger.php
-
170model/DbDriver.php
-
117model/DbStatement.php
-
188model/Model.php
-
289model/MongoDbCommand.php
-
168model/MongoDriver.php
-
73model/MongoModel.php
-
169model/MongoStatement.php
-
2model/MySQLiDriver.php
-
100model/MySQLiStatement.php
-
14model/NoSqlDbDriver.php
-
168model/SqlDbDriver.php
-
173model/SqlModel.php
-
BINmodel_class_diadram.png
-
2session/Session.model.php
-
76tests/model/DbStatementTest.php
-
312tests/model/MongoDbCommandTest.php
-
343tests/model/MongoDriverTest.php
-
238tests/model/MongoModelTest.php
-
464tests/model/MongoStatementTest.php
-
60tests/model/MyDbDriver.php
-
1tests/model/MySQLiDriverTest.php
-
118tests/model/MySQLiStatementTest.php
-
9tests/model/SqlDbDriverTest.php
-
86tests/model/SqlModelTest.php
-
110tests/session/SessionModelTest.php
-
BINuml_model.zargo
-
20util/AutoloadBuilder.php
@ -0,0 +1,289 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage db |
|||
* @since 2011-11-15 |
|||
*/ |
|||
|
|||
class MongoCommandBuilder |
|||
{ |
|||
|
|||
const FIND = 'Find'; |
|||
|
|||
const INSERT = 'Insert'; |
|||
|
|||
const UPDATE = 'Update'; |
|||
|
|||
const REMOVE = 'Remove'; |
|||
|
|||
const COMMAND = 'Command'; |
|||
|
|||
static public function factory($type, $collection = null) |
|||
{ |
|||
$class = ucfirst($type) . 'MongoCommand'; |
|||
$command = new $class(); |
|||
$command->setCollection($collection); |
|||
return $command; |
|||
} |
|||
} |
|||
|
|||
abstract class MongoDbCommand |
|||
{ |
|||
protected $collection; |
|||
|
|||
public function execute() |
|||
{ |
|||
if ($this->checkParams()) { |
|||
return $this->concreteExecute(); |
|||
} else { |
|||
throw new GeneralException(get_called_class() . ' error. Bind all required params first.'); |
|||
} |
|||
} |
|||
|
|||
public function bindParam($name, $value) |
|||
{ |
|||
if (property_exists($this, $name)) { |
|||
$this->$name = $value; |
|||
} |
|||
return $this; |
|||
} |
|||
|
|||
public function setCollection($collection) |
|||
{ |
|||
$this->collection = $collection; |
|||
return $this; |
|||
} |
|||
|
|||
abstract protected function concreteExecute(); |
|||
|
|||
abstract protected function checkParams(); |
|||
|
|||
/** |
|||
* @TODO: implement method in subclasses for Profiler |
|||
*/ |
|||
abstract public function __toString(); |
|||
} |
|||
|
|||
class FindMongoCommand extends MongoDbCommand |
|||
{ |
|||
protected $condition; |
|||
|
|||
protected $fields; |
|||
|
|||
protected $multiple = true; |
|||
|
|||
protected function concreteExecute() |
|||
{ |
|||
if ($this->multiple) { |
|||
return $this->collection->find($this->condition, $this->fields); |
|||
} else { |
|||
return $this->collection->findOne($this->condition, $this->fields); |
|||
} |
|||
} |
|||
|
|||
protected function checkParams() |
|||
{ |
|||
if (isset($this->collection) && isset($this->condition) && isset($this->fields)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function __toString() |
|||
{ |
|||
if ($this->checkParams()) { |
|||
$result = 'Collection: ' . $this->collection . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->condition); |
|||
$condition = ob_get_clean(); |
|||
$result .= 'Condition: ' . $condition . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->fields); |
|||
$fields = ob_get_clean(); |
|||
$result .= 'Fields: ' . $fields . PHP_EOL; |
|||
$mult = $this->multiple ? 'TRUE' : 'FALSE'; |
|||
$result .= 'Multiple fields: ' . $mult . PHP_EOL; |
|||
return $result; |
|||
} else { |
|||
return 'Command properties not set'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
class InsertMongoCommand extends MongoDbCommand |
|||
{ |
|||
protected $data; |
|||
|
|||
protected $safe = true; |
|||
|
|||
protected $insertId = false; |
|||
|
|||
protected function concreteExecute() |
|||
{ |
|||
$result = $this->collection->insert($this->data, array('safe' => $this->safe)); |
|||
$this->insertId = $this->data['_id']; |
|||
return $result; |
|||
} |
|||
|
|||
protected function checkParams() |
|||
{ |
|||
if (isset($this->collection) && isset($this->data) && isset($this->safe)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function getInsertId() |
|||
{ |
|||
return $this->insertId; |
|||
} |
|||
|
|||
public function __toString() |
|||
{ |
|||
if ($this->checkParams()) { |
|||
$result = 'Collection: ' . $this->collection . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->data); |
|||
$data = ob_get_clean(); |
|||
$result .= 'Data: ' . $data . PHP_EOL; |
|||
$safe = $this->safe ? 'TRUE' : 'FALSE'; |
|||
$result .= 'Safe operation: ' . $safe . PHP_EOL; |
|||
return $result; |
|||
} else { |
|||
return 'Command properties not set'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
class UpdateMongoCommand extends MongoDbCommand |
|||
{ |
|||
protected $condition; |
|||
|
|||
protected $data; |
|||
|
|||
protected $multiple = true; |
|||
|
|||
protected $upsert = false; |
|||
|
|||
protected $safe = true; |
|||
|
|||
protected function concreteExecute() |
|||
{ |
|||
return $this->collection->update($this->condition, $this->data, |
|||
array('multiple' => $this->multiple, 'upsert' => $this->upsert, 'safe' => $this->safe)); |
|||
} |
|||
|
|||
protected function checkParams() |
|||
{ |
|||
if (isset($this->collection) && isset($this->condition) && isset($this->data) && |
|||
isset($this->upsert) && isset($this->safe) |
|||
) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function __toString() |
|||
{ |
|||
if ($this->checkParams()) { |
|||
$result = 'Collection: ' . $this->collection . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->condition); |
|||
$condition = ob_get_clean(); |
|||
$result .= 'Condition: ' . $condition . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->data); |
|||
$data = ob_get_clean(); |
|||
$result .= 'Data: ' . $data . PHP_EOL; |
|||
$mult = $this->multiple ? 'TRUE' : 'FALSE'; |
|||
$result .= 'Multiple fields: ' . $mult . PHP_EOL; |
|||
$upsert = $this->upsert ? 'TRUE' : 'FALSE'; |
|||
$result .= 'Upsert: ' . $upsert . PHP_EOL; |
|||
$safe = $this->safe ? 'TRUE' : 'FALSE'; |
|||
$result .= 'Safe operation: ' . $safe . PHP_EOL; |
|||
return $result; |
|||
} else { |
|||
return 'Command properties not set'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
class RemoveMongoCommand extends MongoDbCommand |
|||
{ |
|||
protected $condition; |
|||
|
|||
protected $safe = true; |
|||
|
|||
protected function concreteExecute() |
|||
{ |
|||
return $this->collection->remove($this->condition, array('safe' => $this->safe)); |
|||
} |
|||
|
|||
protected function checkParams() |
|||
{ |
|||
if (isset($this->collection) && isset($this->condition) && isset($this->safe)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function __toString() |
|||
{ |
|||
if ($this->checkParams()) { |
|||
$result = 'Collection: ' . $this->collection . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->condition); |
|||
$condition = ob_get_clean(); |
|||
$result .= 'Condition: ' . $condition . PHP_EOL; |
|||
$safe = $this->safe ? 'TRUE' : 'FALSE'; |
|||
$result .= 'Safe operation: ' . $safe . PHP_EOL; |
|||
return $result; |
|||
} else { |
|||
return 'Command properties not set'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
class CommandMongoCommand extends MongoDbCommand |
|||
{ |
|||
protected $command; |
|||
|
|||
protected function concreteExecute() |
|||
{ |
|||
$db = $this->collection->db; |
|||
if ($db instanceof MongoDB) { |
|||
return $db->command($this->command); |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
protected function checkParams() |
|||
{ |
|||
if (isset($this->collection) && isset($this->command)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function __toString() |
|||
{ |
|||
if ($this->checkParams()) { |
|||
$result = 'Collection: ' . $this->collection . PHP_EOL; |
|||
ob_start(); |
|||
var_dump($this->command); |
|||
$command = ob_get_clean(); |
|||
$result .= 'Command: ' . $command . PHP_EOL; |
|||
return $result; |
|||
} else { |
|||
return 'Command properties not set'; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,168 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage db |
|||
* @since 2011-11-10 |
|||
*/ |
|||
|
|||
/** |
|||
* @property Mongo $connection |
|||
*/ |
|||
class MongoDriver extends NoSqlDbDriver |
|||
{ |
|||
protected $last_insert_id = 0; |
|||
|
|||
protected $db_name = 'admin'; |
|||
|
|||
protected $db = null; |
|||
|
|||
protected function getCollection($name) |
|||
{ |
|||
if (!$this->connection) { |
|||
$this->connect(); |
|||
} |
|||
return $this->connection->selectCollection($this->db, $name); |
|||
} |
|||
|
|||
public function count($collection, $query = array(), $limit = 0, $skip = 0) |
|||
{ |
|||
return $this->getCollection($collection)->count($query, $limit, $skip); |
|||
} |
|||
|
|||
public function find($collection, $condition = array(), $fields = array()) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->getCollection($collection)); |
|||
$params = array( |
|||
'condition' => $condition, |
|||
'fields' => $fields |
|||
); |
|||
|
|||
return $this->query($command, $params); |
|||
} |
|||
|
|||
public function get($collection, $condition, $fields = array()) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->getCollection($collection)); |
|||
$params = array( |
|||
'condition' => $condition, |
|||
'fields' => $fields, |
|||
'multiple' => false |
|||
); |
|||
return $this->query($command, $params); |
|||
} |
|||
|
|||
public function findAndModify($collection, $query, $update, $sort = array(), $field = array(), $upsert = false, $new = false, $remove = false) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $this->getCollection($collection)); |
|||
$cmd = array( |
|||
'findAndModify' => $collection, |
|||
'query' => $query, |
|||
'update' => $update, |
|||
'sort' => $sort, |
|||
'fields' => $field, |
|||
'new' => $new, |
|||
'upsert' => $upsert, |
|||
'remove' => $remove |
|||
); |
|||
$params = array('command' => $cmd); |
|||
return $this->query($command, $params); |
|||
} |
|||
|
|||
public function command($collection, $cmd) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $this->getCollection($collection)); |
|||
$params = array('command' => $cmd); |
|||
return $this->query($command, $params); |
|||
} |
|||
|
|||
public function insert($collection, $data, $safe = true) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->getCollection($collection)); |
|||
$params = array( |
|||
'data' => $data, |
|||
'safe' => $safe |
|||
); |
|||
$result = $this->query($command, $params); |
|||
$this->last_insert_id = $result->getInsertId(); |
|||
return $result->affectedRows(); |
|||
} |
|||
|
|||
public function update($collection, $data, $condition = array(), $multiple = true, $upsert = false, $safe = true) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::UPDATE, $this->getCollection($collection)); |
|||
$params = array( |
|||
'data' => $data, |
|||
'condition' => $condition, |
|||
'multiple' => $multiple, |
|||
'upsert' => $upsert, |
|||
'safe' => $safe |
|||
); |
|||
|
|||
return $this->query($command, $params)->affectedRows(); |
|||
} |
|||
|
|||
public function delete($collection, $condition = array(), $safe = true) |
|||
{ |
|||
$command = MongoCommandBuilder::factory(MongoCommandBuilder::REMOVE, $this->getCollection($collection)); |
|||
$params = array( |
|||
'condition' => $condition, |
|||
'safe' => $safe |
|||
); |
|||
|
|||
return $this->query($command, $params)->affectedRows(); |
|||
} |
|||
|
|||
|
|||
|
|||
/** |
|||
* @param mixed $request |
|||
* @return DbStatement |
|||
*/ |
|||
public function prepare($request) |
|||
{ |
|||
return new MongoStatement($this, $request); |
|||
} |
|||
|
|||
public function getInsertId($table = null, $key = null) |
|||
{ |
|||
return $this->last_insert_id; |
|||
} |
|||
|
|||
public function isConnected() |
|||
{ |
|||
if (!is_null($this->connection)) { |
|||
return $this->connection->connected; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
public function disconnect() |
|||
{ |
|||
if ($this->isConnected()) { |
|||
$this->connection->close(); |
|||
} |
|||
$this->connection = null; |
|||
} |
|||
|
|||
protected function connect() |
|||
{ |
|||
if ($this->connection) { |
|||
return; |
|||
} |
|||
|
|||
$host = $this->config['hostname']; |
|||
$port = isset($this->config['port']) ? ':' . (string) $this->config['port'] : ''; |
|||
|
|||
$this->config = array( |
|||
'username' => $this->config['username'], |
|||
'password' => $this->config['password'], |
|||
'db' => $this->config['database'] |
|||
); |
|||
|
|||
$this->connection = new Mongo('mongodb://' . $host . $port, $this->config); |
|||
$this->db = $this->connection->selectDB($this->config['db']); |
|||
} |
|||
} |
@ -0,0 +1,73 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* Класс модели данных |
|||
* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage Model |
|||
* @since 2011-11-15 |
|||
*/ |
|||
|
|||
abstract class MongoModel extends Model |
|||
{ |
|||
|
|||
public function count($query = array(), $limit = 0, $skip = 0) |
|||
{ |
|||
return $this->db->count($this->table(), $query, $limit, $skip); |
|||
} |
|||
|
|||
public function find($condition = array()) |
|||
{ |
|||
return $this->db->find($this->table(), $condition); |
|||
} |
|||
|
|||
public function get($id) |
|||
{ |
|||
return $this->db->get($this->table(), array('_id' => $id))->fetch(); |
|||
} |
|||
|
|||
public function delete($id) |
|||
{ |
|||
return $this->db->delete($this->table(), array('_id' => $id)); |
|||
} |
|||
|
|||
public function deleteAll($query = array()) |
|||
{ |
|||
$this->db->delete($this->table(), $query); |
|||
} |
|||
|
|||
protected function fetchField($data, $params = array(), $field, $cache_key = null) |
|||
{ |
|||
if (!$cache_key || !$result = $cache_key->get()) { |
|||
$result = $this->db->find($this->table(), $data, array($field => 1))->fetchField($field); |
|||
if ($cache_key) { |
|||
$cache_key->set($result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
protected function fetch($data, $params = array(), $cache_key = null) |
|||
{ |
|||
if (!$cache_key || !$result = $cache_key->get()) { |
|||
$result = $this->db->find($this->table(), $data)->fetch(); |
|||
if ($cache_key) { |
|||
$cache_key->set($result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
protected function fetchAll($data, $params = array(), $cache_key = null) |
|||
{ |
|||
if (!$cache_key || !$result = $cache_key->get()) { |
|||
$result = $this->db->find($this->table(), $data)->fetchAll(); |
|||
if ($cache_key) { |
|||
$cache_key->set($result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
} |
@ -0,0 +1,169 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage db |
|||
* @since 2011-11-15 |
|||
*/ |
|||
|
|||
/** |
|||
* @property MongoDriver $driver |
|||
* @property MongoCursor $result |
|||
*/ |
|||
class MongoStatement extends DbStatement |
|||
{ |
|||
|
|||
protected $insertId = false; |
|||
|
|||
public function order($sort = array()) |
|||
{ |
|||
if ($this->result instanceof MongoCursor) { |
|||
$this->result->sort($sort); |
|||
return $this; |
|||
} else { |
|||
throw new GeneralException('MongoStatement error. Impossible order results of opened cursor.'); |
|||
} |
|||
} |
|||
|
|||
public function skip($skip = 0) |
|||
{ |
|||
if ($this->result instanceof MongoCursor) { |
|||
$this->result->skip($skip); |
|||
return $this; |
|||
} else { |
|||
throw new GeneralException('MongoStatement error. Impossible skip results of opened cursor.'); |
|||
} |
|||
} |
|||
|
|||
public function limit($limit = 0) |
|||
{ |
|||
if ($this->result instanceof MongoCursor) { |
|||
$this->result->limit($limit); |
|||
return $this; |
|||
} else { |
|||
throw new GeneralException('MongoStatement error. Impossible limit results of opened cursor.'); |
|||
} |
|||
} |
|||
|
|||
public function fetch($style = Db::FETCH_OBJ) |
|||
{ |
|||
if (!$this->result) { |
|||
return false; |
|||
} |
|||
|
|||
$row = false; |
|||
switch ($style) { |
|||
case Db::FETCH_OBJ: |
|||
$row = $this->fetchObject(); |
|||
break; |
|||
case Db::FETCH_ASSOC: |
|||
if ($this->result instanceof MongoCursor) { |
|||
$row = $this->result->getNext(); |
|||
} else { |
|||
$row = $this->result; |
|||
} |
|||
break; |
|||
default: |
|||
throw new GeneralException('Invalid fetch mode "' . $style . '" specified'); |
|||
} |
|||
return $row; |
|||
} |
|||
|
|||
public function fetchObject($class = 'stdClass') |
|||
{ |
|||
if ($this->result instanceof MongoCursor) { |
|||
$row = $this->result->getNext(); |
|||
} else { |
|||
$row = $this->result; |
|||
} |
|||
if (is_array($row) && isset($row['_id'])) { |
|||
$row = new ArrayObject($row, ArrayObject::ARRAY_AS_PROPS); |
|||
} else { |
|||
$row = false; |
|||
} |
|||
return $row; |
|||
} |
|||
|
|||
public function close() |
|||
{ |
|||
$this->result = null; |
|||
} |
|||
|
|||
/** |
|||
* @return int |
|||
*/ |
|||
public function affectedRows() |
|||
{ |
|||
if (is_array($this->result)) { |
|||
if (isset($this->result['ok']) && $this->result['ok'] == 1) { |
|||
if (isset($this->result['n'])) { |
|||
return $this->result['n']; |
|||
} |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public function numRows() |
|||
{ |
|||
if ($this->result instanceof MongoCursor) { |
|||
return $this->result->count(); |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @param MongoDbCommand $request |
|||
* @return bool |
|||
*/ |
|||
protected function driverExecute($request) |
|||
{ |
|||
$mongo = $this->driver->getConnection(); |
|||
if ($mongo instanceof Mongo) { |
|||
if (DEBUG) { |
|||
$profiler = Profiler::getInstance()->profilerCommand('Mongo', $request); |
|||
$result = $request->execute(); |
|||
$profiler->end(); |
|||
} else { |
|||
$result = $request->execute(); |
|||
} |
|||
if ($result === false) { |
|||
throw new GeneralException('MongoDB request error.'); |
|||
} |
|||
if ($result instanceof MongoCursor || is_array($result)) { |
|||
$this->result = $result; |
|||
if (is_array($result) && isset($result['value'])) { |
|||
$this->result = $result['value']; |
|||
} |
|||
if (is_array($result) && isset($result['values'])) { |
|||
$this->result = $result['values']; |
|||
} |
|||
} |
|||
if ($request instanceof InsertMongoCommand) { |
|||
$this->insertId = $request->getInsertId(); |
|||
} |
|||
return true; |
|||
} else { |
|||
throw new GeneralException('No connection to MongoDB server.'); |
|||
} |
|||
} |
|||
|
|||
public function bindParam($param, &$value) |
|||
{ |
|||
$this->request->bindParam($param, $value); |
|||
} |
|||
|
|||
protected function assemble() |
|||
{ |
|||
return $this->request; |
|||
} |
|||
|
|||
public function getInsertId() |
|||
{ |
|||
return $this->insertId; |
|||
} |
|||
} |
@ -0,0 +1,14 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage db |
|||
* @since 2011-11-11 |
|||
*/ |
|||
|
|||
abstract class NoSqlDbDriver extends DbDriver |
|||
{ |
|||
|
|||
abstract function find($collection, $condition = array(), $fields = array()); |
|||
} |
@ -0,0 +1,168 @@ |
|||
<?php |
|||
/** |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage db |
|||
* @since 2011-11-11 |
|||
*/ |
|||
|
|||
abstract class SqlDbDriver extends DbDriver |
|||
{ |
|||
|
|||
protected $identifier_quote = '`'; |
|||
|
|||
|
|||
|
|||
public function beginTransaction() |
|||
{ |
|||
$this->connect(); |
|||
$this->driverBeginTransaction(); |
|||
return $this; |
|||
} |
|||
|
|||
public function commit() |
|||
{ |
|||
$this->connect(); |
|||
$this->driverCommitTransaction(); |
|||
return $this; |
|||
} |
|||
|
|||
public function rollback() |
|||
{ |
|||
$this->connect(); |
|||
$this->driverRollbackTransaction(); |
|||
return $this; |
|||
} |
|||
|
|||
/** |
|||
* @param string $table |
|||
* @param mixed $bind |
|||
* @param mixed $on_duplicate |
|||
* @return int Affected rows count |
|||
*/ |
|||
public function insert($table, $data, $on_duplicate = array()) |
|||
{ |
|||
$columns = array(); |
|||
foreach ($data as $col => $val) { |
|||
$columns[] = $this->quoteIdentifier($col); |
|||
} |
|||
$values = array_values($data); |
|||
|
|||
$sql = 'INSERT INTO ' . $this->quoteIdentifier($table) |
|||
. ' (' . implode(', ', $columns) . ') VALUES (' . $this->quote($values) . ')'; |
|||
return $this->query($sql)->affectedRows(); |
|||
} |
|||
|
|||
/** |
|||
* @param string $table |
|||
* @param array $bind |
|||
* @param mixed $where |
|||
* @return int |
|||
*/ |
|||
public function update($table, $data, $condition = '') |
|||
{ |
|||
$set = array(); |
|||
foreach ($data as $col => $val) { |
|||
$set[] = $this->quoteIdentifier($col) . '=' . $this->quote($val); |
|||
} |
|||
$where = $this->whereExpr($condition); |
|||
$sql = 'UPDATE ' . $this->quoteIdentifier($table) . ' SET ' . implode(', ', $set) |
|||
. (($where) ? (' WHERE ' . $where) : ''); |
|||
return $this->query($sql)->affectedRows(); |
|||
} |
|||
|
|||
/** |
|||
* @param string $table |
|||
* @param mixed $where |
|||
* @return int |
|||
*/ |
|||
public function delete($table, $condition = '') |
|||
{ |
|||
$where = $this->whereExpr($condition); |
|||
$sql = 'DELETE FROM ' . $this->quoteIdentifier($table) . (($where) ? (' WHERE ' . $where) : ''); |
|||
return $this->query($sql)->affectedRows(); |
|||
} |
|||
|
|||
/** |
|||
* @param mixed $value |
|||
* @return string |
|||
*/ |
|||
public function quote($value) |
|||
{ |
|||
if ($value instanceof DbExpr) { |
|||
return (string) $value; |
|||
} |
|||
if (is_array($value)) { |
|||
foreach ($value as &$val) { |
|||
$val = $this->quote($val); |
|||
} |
|||
return implode(', ', $value); |
|||
} |
|||
return $this->driverQuote($value); |
|||
} |
|||
|
|||
/** |
|||
* @param string $ident |
|||
* @return string |
|||
*/ |
|||
public function quoteIdentifier($ident) |
|||
{ |
|||
$ident = explode('.', $ident); |
|||
if (!is_array($ident)) { |
|||
$ident = array($ident); |
|||
} |
|||
foreach ($ident as &$segment) { |
|||
$segment = $this->identifier_quote . $segment . $this->identifier_quote; |
|||
} |
|||
return implode('.', $ident); |
|||
} |
|||
|
|||
public function quoteInto($text, $value) |
|||
{ |
|||
$pos = mb_strpos($text, '?'); |
|||
if ($pos === false) { |
|||
return $text; |
|||
} |
|||
return mb_substr($text, 0, $pos) . $this->quote($value) . mb_substr($text, $pos + 1); |
|||
} |
|||
|
|||
/** |
|||
* @param mixed $where |
|||
* @return string |
|||
*/ |
|||
protected function whereExpr($where) |
|||
{ |
|||
if (empty($where)) { |
|||
return $where; |
|||
} |
|||
|
|||
if (!is_array($where)) { |
|||
$where = array($where); |
|||
} |
|||
foreach ($where as $cond => &$term) { |
|||
if (is_int($cond)) { |
|||
if ($term instanceof DbExpr) { |
|||
$term = (string) $term; |
|||
} |
|||
} else { |
|||
$term = $this->quoteInto($cond, $term); |
|||
} |
|||
} |
|||
return implode(' AND ', $where); |
|||
} |
|||
|
|||
/** |
|||
* @return DbStatement |
|||
*/ |
|||
|
|||
abstract protected function driverQuote($value); |
|||
|
|||
abstract protected function driverBeginTransaction(); |
|||
|
|||
abstract protected function driverCommitTransaction(); |
|||
|
|||
abstract protected function driverRollbackTransaction(); |
|||
|
|||
} |
|||
|
@ -0,0 +1,173 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* Класс модели данных |
|||
* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage Model |
|||
* @since 2011-11-11 |
|||
*/ |
|||
|
|||
abstract class SqlModel extends Model |
|||
{ |
|||
|
|||
/** |
|||
* @param string $ident |
|||
* @return string Quoted identifier. |
|||
*/ |
|||
public function identify($ident) |
|||
{ |
|||
return $this->db->quoteIdentifier($ident); |
|||
} |
|||
|
|||
/** |
|||
* @param mixed $value |
|||
* @return string Quoted value. |
|||
*/ |
|||
public function quote($value) |
|||
{ |
|||
return $this->db->quote($value); |
|||
} |
|||
|
|||
/** |
|||
* @param int $id |
|||
* @return object |
|||
*/ |
|||
public function get($id) |
|||
{ |
|||
$sql = 'SELECT * FROM :table WHERE :pk=?'; |
|||
return $this->fetch($sql, $id); |
|||
} |
|||
|
|||
/** |
|||
* @param array $data |
|||
* @param mixed $where |
|||
* @return int Number of affected rows |
|||
*/ |
|||
public function update($data, $where) |
|||
{ |
|||
if (is_int($where) || $where === (string) (int) $where) { |
|||
$where = $this->identify($this->key) . '=' . (int) $where; |
|||
} |
|||
return parent::update($data, $where); |
|||
} |
|||
|
|||
/** |
|||
* @param int $id Int id |
|||
* @return int Number of affected rows |
|||
*/ |
|||
public function delete($id) |
|||
{ |
|||
$where = $this->identify($this->key) . '=' . (int) $id; |
|||
return $this->db->delete($this->table(), $where); |
|||
} |
|||
|
|||
/** |
|||
* Creates order sql string |
|||
* |
|||
* @param array $params |
|||
* @param array $sortable |
|||
* @return string |
|||
*/ |
|||
protected function order($params, $sortable = array('id')) |
|||
{ |
|||
$sql = ''; |
|||
if (isset($params['sort'])) { |
|||
$order = (isset($params['order']) && $params['order'] == 'desc') ? 'DESC' : 'ASC'; |
|||
if (in_array($params['sort'], $sortable)) { |
|||
$sql = ' ORDER BY ' . $this->identify($params['sort']) . ' ' . $order; |
|||
} |
|||
} |
|||
return $sql; |
|||
} |
|||
|
|||
/** |
|||
* Searches using like |
|||
* |
|||
* @param array $params |
|||
* @param array $searchable |
|||
* @param string $table_prefix |
|||
* @return string |
|||
*/ |
|||
protected function search($params, $searchable = array('id'), $table_prefix = '') |
|||
{ |
|||
$sql = ''; |
|||
if (isset($params['q']) && isset($params['qt']) && in_array($params['qt'], $searchable)) { |
|||
if ($table_prefix) { |
|||
$sql = $table_prefix . '.'; |
|||
} |
|||
$sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%'); |
|||
} |
|||
return $sql; |
|||
} |
|||
|
|||
/** |
|||
* This method appends to params table and primary key. |
|||
* So they can be accessed thru `:table` and `:pk` placeholders. |
|||
* |
|||
* @return DbStatement |
|||
*/ |
|||
protected function query($sql, $params = array()) |
|||
{ |
|||
if (!is_array($params)) { |
|||
$params = array($params); |
|||
} |
|||
$params = array( |
|||
'table' => new DbExpr($this->identify($this->table())), |
|||
'pk' => new DbExpr($this->identify($this->key)), |
|||
) + $params; |
|||
return $this->db->query($sql, $params); |
|||
} |
|||
|
|||
/** |
|||
* @param string $sql |
|||
* @param array $params |
|||
* @param string $field |
|||
* @param CacheKey $cache_key |
|||
*/ |
|||
protected function fetchField($data, $params = array(), $field, $cache_key = null) |
|||
{ |
|||
if (!$cache_key || !$result = $cache_key->get()) { |
|||
$result = $this->query($data, $params)->fetchField($field); |
|||
if ($cache_key) { |
|||
$cache_key->set($result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* @param string $sql |
|||
* @param array $params |
|||
* @param CacheKey $cache_key |
|||
*/ |
|||
protected function fetch($data, $params = array(), $cache_key = null) |
|||
{ |
|||
if (!$cache_key || !$result = $cache_key->get()) { |
|||
$result = $this->query($data, $params)->fetch(); |
|||
if ($cache_key) { |
|||
$cache_key->set($result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
/** |
|||
* @param string $sql |
|||
* @param array $params |
|||
* @param CacheKey $cache_key |
|||
*/ |
|||
protected function fetchAll($data, $params = array(), $cache_key = null) |
|||
{ |
|||
if (!$cache_key || !$result = $cache_key->get()) { |
|||
$result = $this->query($data, $params)->fetchAll(); |
|||
if ($cache_key) { |
|||
$cache_key->set($result); |
|||
} |
|||
} |
|||
return $result; |
|||
} |
|||
|
|||
} |
After Width: 1743 | Height: 1107 | Size: 42 KiB |
@ -0,0 +1,312 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage UnitTests |
|||
* @since 2011-11-10 |
|||
* |
|||
* Unit tests for MongoDriver class |
|||
*/ |
|||
|
|||
require_once dirname(__FILE__) . '/../../model/DbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/NoSqlDbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoDbCommand.php'; |
|||
require_once dirname(__FILE__) . '/../../exception/GeneralException.php'; |
|||
|
|||
class MongoDbCommandTest extends PHPUnit_Framework_TestCase |
|||
{ |
|||
|
|||
private $conf = array(); |
|||
|
|||
private $driver; |
|||
|
|||
private $collection; |
|||
|
|||
public function setUp() |
|||
{ |
|||
$this->conf = array( |
|||
'hostname' => 'localhost', |
|||
'database' => 'test', |
|||
'username' => 'test', |
|||
'password' => '1234', |
|||
'port' => 27017 |
|||
); |
|||
$this->driver = new MongoDriver($this->conf); |
|||
$connection = $this->driver->getConnection(); |
|||
|
|||
$db = $connection->selectDB($this->conf['database']); |
|||
$db->authenticate($this->conf['username'], $this->conf['password']); |
|||
$collection = 'items'; |
|||
$db->dropCollection($collection); |
|||
$this->collection = $db->selectCollection($collection); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testCommandFactory() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND); |
|||
$this->assertInstanceOf('MongoDbCommand', $cmd); |
|||
$this->assertInstanceOf('FindMongoCommand', $cmd); |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT); |
|||
$this->assertInstanceOf('MongoDbCommand', $cmd); |
|||
$this->assertInstanceOf('InsertMongoCommand', $cmd); |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::UPDATE); |
|||
$this->assertInstanceOf('MongoDbCommand', $cmd); |
|||
$this->assertInstanceOf('UpdateMongoCommand', $cmd); |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::REMOVE); |
|||
$this->assertInstanceOf('MongoDbCommand', $cmd); |
|||
$this->assertInstanceOf('RemoveMongoCommand', $cmd); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testFindCommand() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'bread'))->bindParam('fields', array()); |
|||
$result = $cmd->execute(); |
|||
$this->assertEquals(0, $result->count()); |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
$cmd |
|||
->bindParam('data', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$cmd->execute(); |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
$cmd |
|||
->bindParam('data', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$cmd->execute(); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'insert'))->bindParam('fields', array()); |
|||
$this->assertEquals(2, $cmd->execute()->count()); |
|||
|
|||
$cmd |
|||
->bindParam('condition', array('name' => 'insert')) |
|||
->bindParam('fields', array()) |
|||
->bindParam('multiple', false); |
|||
|
|||
$result = $cmd->execute(); |
|||
$this->assertEquals('insert', $result['name']); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testFindCommandNotAllParamsBinded() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'bread')); |
|||
$this->setExpectedException('GeneralException', 'FindMongoCommand error. Bind all required params first'); |
|||
$cmd->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testInsertCommand() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
|
|||
$cmd |
|||
->bindParam('data', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
|
|||
$this->assertFalse($cmd->getInsertId()); |
|||
|
|||
$this->assertArrayHasKey('n', $cmd->execute()); |
|||
$this->assertNotEmpty($cmd->getInsertId()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'insert'))->bindParam('fields', array()); |
|||
$result = $cmd->execute(); |
|||
$this->assertEquals(1, $result->count()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testInsertCommandNotAllParamsBinded() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
$this->setExpectedException('GeneralException', 'InsertMongoCommand error. Bind all required params first'); |
|||
$cmd->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testUpdateCommand() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
$cmd |
|||
->bindParam('data', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$this->assertArrayHasKey('n', $cmd->execute()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::UPDATE, $this->collection); |
|||
$cmd |
|||
->bindParam('condition', array('name' => 'insert')) |
|||
->bindParam('data', array('$set' => array('name' => 'update'))) |
|||
->bindParam('upsert', false) |
|||
->bindParam('safe', true); |
|||
$this->assertArrayHasKey('n', $cmd->execute()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'insert'))->bindParam('fields', array()); |
|||
$result = $cmd->execute(); |
|||
$this->assertEquals(0, $result->count()); |
|||
$cmd->bindParam('condition', array('name' => 'update'))->bindParam('fields', array()); |
|||
$result = $cmd->execute(); |
|||
$this->assertEquals(1, $result->count()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testUpdateCommandNotAllParamsBinded() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::UPDATE, $this->collection); |
|||
$cmd->bindParam('data', array('name' => 'bread')); |
|||
$this->setExpectedException('GeneralException', 'UpdateMongoCommand error. Bind all required params first'); |
|||
$cmd->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testRemoveCommand() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
$cmd |
|||
->bindParam('data', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$this->assertArrayHasKey('n', $cmd->execute()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'insert'))->bindParam('fields', array()); |
|||
$result = $cmd->execute(); |
|||
$this->assertEquals(1, $result->count()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::REMOVE, $this->collection); |
|||
$cmd |
|||
->bindParam('condition', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$this->assertArrayHasKey('n', $cmd->execute()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$cmd->bindParam('condition', array('name' => 'insert'))->bindParam('fields', array()); |
|||
$result = $cmd->execute(); |
|||
$this->assertEquals(0, $result->count()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testRemoveCommandNotAllParamsBinded() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::REMOVE, $this->collection); |
|||
$this->setExpectedException('GeneralException', 'RemoveMongoCommand error. Bind all required params first.'); |
|||
$cmd->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testCommandCommandNotAllParamsBinded() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $this->collection); |
|||
$this->setExpectedException('GeneralException', 'CommandMongoCommand error. Bind all required params first'); |
|||
$cmd->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testCommandCommandNotMongoDb() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, new CollectionMock()); |
|||
$cmd->bindParam('command', array()); |
|||
$this->assertFalse($cmd->execute()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testCommandCommand() |
|||
{ |
|||
$col = new CollectionMock(); |
|||
$col->db = $this->getMock('MongoDb', array('command'), array(), 'SomeMongoMock', false); |
|||
$col->db |
|||
->expects($this->once()) |
|||
->method('command') |
|||
->will($this->returnValue(true)); |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $col); |
|||
$cmd->bindParam('command', array()); |
|||
$this->assertTrue($cmd->execute()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testToStringParamsNotSet() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, new CollectionMock()); |
|||
$this->assertSame('Command properties not set', $cmd->__toString()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testToString() |
|||
{ |
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, new CollectionMock()); |
|||
$this->assertSame('Command properties not set', $cmd->__toString()); |
|||
$cmd->bindParam('command', array()); |
|||
$this->assertStringStartsWith('Collection: CollectionMock', $cmd->__toString()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->collection); |
|||
$this->assertSame('Command properties not set', $cmd->__toString()); |
|||
$cmd |
|||
->bindParam('data', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$this->assertStringStartsWith('Collection: ', $cmd->__toString()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->collection); |
|||
$this->assertSame('Command properties not set', $cmd->__toString()); |
|||
$cmd->bindParam('condition', array('name' => 'insert'))->bindParam('fields', array()); |
|||
$this->assertStringStartsWith('Collection: ', $cmd->__toString()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::REMOVE, $this->collection); |
|||
$this->assertSame('Command properties not set', $cmd->__toString()); |
|||
$cmd |
|||
->bindParam('condition', array('name' => 'insert')) |
|||
->bindParam('safe', true); |
|||
$this->assertStringStartsWith('Collection: ', $cmd->__toString()); |
|||
|
|||
$cmd = MongoCommandBuilder::factory(MongoCommandBuilder::UPDATE, $this->collection); |
|||
$this->assertSame('Command properties not set', $cmd->__toString()); |
|||
$cmd |
|||
->bindParam('condition', array('name' => 'insert')) |
|||
->bindParam('data', array('$set' => array('name' => 'update'))) |
|||
->bindParam('upsert', false) |
|||
->bindParam('safe', true); |
|||
$this->assertStringStartsWith('Collection: ', $cmd->__toString()); |
|||
} |
|||
} |
|||
|
|||
class CollectionMock |
|||
{ |
|||
public $db = array(); |
|||
|
|||
public function __toString() |
|||
{ |
|||
return 'CollectionMock'; |
|||
} |
|||
} |
@ -0,0 +1,343 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage UnitTests |
|||
* @since 2011-11-10 |
|||
* |
|||
* Unit tests for MongoDriver class |
|||
*/ |
|||
|
|||
require_once dirname(__FILE__) . '/../../model/Db.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/NoSqlDbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoDbCommand.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbStatement.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoStatement.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../exception/GeneralException.php'; |
|||
|
|||
class MongoDriverTest extends PHPUnit_Framework_TestCase |
|||
{ |
|||
|
|||
private $conf = array(); |
|||
|
|||
public function setUp() |
|||
{ |
|||
$this->conf = array( |
|||
'hostname' => 'localhost', |
|||
'database' => 'test', |
|||
'username' => 'test', |
|||
'password' => '1234', |
|||
'port' => 27017 |
|||
); |
|||
|
|||
$data = array( |
|||
array( |
|||
'name' => 'bread', |
|||
'price' => 3.2, |
|||
'quantity' => 10 |
|||
), |
|||
array( |
|||
'name' => 'eggs', |
|||
'price' => 2.1, |
|||
'quantity' => 20 |
|||
), |
|||
array( |
|||
'name' => 'fish', |
|||
'price' => 13.2, |
|||
'quantity' => 2 |
|||
), |
|||
array( |
|||
'name' => 'milk', |
|||
'price' => 3.8, |
|||
'quantity' => 1 |
|||
), |
|||
array( |
|||
'name' => 'eggs', |
|||
'price' => 2.3, |
|||
'quantity' => 5 |
|||
) |
|||
); |
|||
$connection = new Mongo('mongodb://' . $this->conf['hostname'] . ':' . $this->conf['port']); |
|||
$db = $connection->selectDB($this->conf['database']); |
|||
$db->authenticate($this->conf['username'], $this->conf['password']); |
|||
$collection = 'items'; |
|||
$db->dropCollection($collection); |
|||
$collection = $db->selectCollection($collection); |
|||
foreach($data as $document) { |
|||
$collection->insert($document); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testGetConnectionNoHostname() |
|||
{ |
|||
unset($this->conf['hostname']); |
|||
$this->setExpectedException('GeneralException', 'Configuration must have a "hostname"'); |
|||
$mongo = new MongoDriver($this->conf); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testGetConnectionWrongPassword() |
|||
{ |
|||
$this->conf['password'] = 'nopass'; |
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->setExpectedException('MongoConnectionException', 'Couldn\'t authenticate with database'); |
|||
$this->assertInstanceOf('MongoDB', $mongo->getConnection()); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testGetConnection() |
|||
{ |
|||
$mongo = new MongoDriver($this->conf); |
|||
|
|||
$this->assertFalse($mongo->isConnected()); |
|||
$this->assertInstanceOf('Mongo', $mongo->getConnection()); |
|||
$this->assertTrue($mongo->isConnected()); |
|||
$mongo->getConnection(); |
|||
$mongo->disconnect(); |
|||
$this->assertFalse($mongo->isConnected()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFind() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(2, $mongo->find('items', array('name' => 'eggs'))->numRows()); |
|||
$eggs = $mongo->find('items', array('name' => 'eggs')); |
|||
$egg = $eggs->fetch(); |
|||
$this->assertEquals(20, $egg->quantity); |
|||
$egg = $eggs->fetchObject(); |
|||
$this->assertEquals('eggs', $egg->name); |
|||
$this->assertFalse($eggs->fetchObject()); |
|||
|
|||
$this->assertEquals(3, $mongo->find('items', array('price' => array('$lt' => 3.5)))->numRows()); |
|||
$data = $mongo->find('items', array('price' => array('$lt' => 3.5))); |
|||
$count = 0; |
|||
while($row = $data->fetch(Db::FETCH_ASSOC)) { |
|||
$count++; |
|||
$this->assertLessThan(3.5, $row['price']); |
|||
} |
|||
$this->assertEquals(3, $count); |
|||
$this->assertEquals(5, $mongo->find('items', array())->numRows()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testOrderSkipLimit() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
|
|||
$count = $mongo->find('items', array())->numRows(); |
|||
|
|||
$this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(2, $mongo->find('items', array('name' => 'eggs'))->numRows()); |
|||
$mongo->insert('items', array('name' => 'fdsbssc')); |
|||
$mongo->insert('items', array('name' => 'boc')); |
|||
$mongo->insert('items', array('name' => 'abc')); |
|||
$mongo->insert('items', array('name' => 'vcxxc')); |
|||
$mongo->insert('items', array('name' => 'abbc')); |
|||
$mongo->insert('items', array('name' => 'dsbssc')); |
|||
$mongo->insert('items', array('name' => 'bssc')); |
|||
|
|||
$data = $mongo->find('items', array()); |
|||
$this->assertEquals($count + 7, $data->numRows()); |
|||
$data->order(array('name' => 1)); |
|||
$this->assertEquals('abbc', $data->fetch()->name); |
|||
$this->assertEquals('abc', $data->fetch()->name); |
|||
$this->assertEquals('boc', $data->fetch()->name); |
|||
$data = $mongo->find('items', array()); |
|||
$data->order(array('name' => -1)); |
|||
$data->skip(3); |
|||
$data->limit(1); |
|||
while($row = $data->fetch()) { |
|||
$this->assertEquals('fdsbssc', $row->name); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testCount() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->assertEquals(5, $mongo->count('items')); |
|||
$this->assertEquals(2, $mongo->count('items', array('name' => 'eggs'))); |
|||
$this->assertEquals(1, $mongo->count('items', array('name' => 'eggs'), 1)); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testGet() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
$eggs = $mongo->get('items', array('name' => 'eggs'))->fetchObject(); |
|||
$this->assertEquals(20, $eggs->quantity); |
|||
$eggs = $mongo->get('items', array('name' => 'eggs'))->fetch(); |
|||
$this->assertEquals('eggs', $eggs->name); |
|||
$this->assertInstanceOf('MongoId', $eggs->_id); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testRemove() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(0, $mongo->delete('items', array('name' => 'esggs'))); |
|||
$this->assertEquals(2, $mongo->delete('items', array('name' => 'eggs'))); |
|||
$this->assertEquals(1, $mongo->delete('items', array('name' => 'bread'))); |
|||
$this->assertEquals(0, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testInsert() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(0, $mongo->insert('items', array('name' => 'bread'))); |
|||
$this->assertNotEmpty($mongo->getInsertId()); |
|||
$this->assertEquals(2, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(0, $mongo->insert('items', array('name' => 'meat', 'weight' => 230))); |
|||
$this->assertEquals(230, $mongo->get('items', array('name' => 'meat'))->fetch()->weight); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testGetInsertId() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->assertEquals(0, $mongo->getInsertId()); |
|||
$this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(0, $mongo->insert('items', array('name' => 'bread'))); |
|||
$this->assertEquals(2, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$id1 = $mongo->getInsertId(); |
|||
$this->assertNotEmpty($id1); |
|||
$this->assertEquals(0, $mongo->insert('items', array('name' => 'bread'))); |
|||
$id2 = $mongo->getInsertId(); |
|||
$this->assertNotEmpty($id2); |
|||
$this->assertNotEquals($id1, $id2); |
|||
$this->assertEquals(3, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testUpdate() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
$this->assertEquals(1, $mongo->find('items', array('name' => 'bread'))->numRows()); |
|||
$this->assertEquals(1, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'fish'))); |
|||
$this->assertEquals(2, $mongo->update('items', array('$set' => array('price' => 1)), array('name' => 'eggs'))); |
|||
$fish = $mongo->get('items', array('name' => 'fish'))->fetch(); |
|||
$this->assertEquals(200, $fish->price); |
|||
$this->assertEquals('today', $fish->date); |
|||
$this->assertEquals(0, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'ball'))); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testUpsert() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
|
|||
$mongo->insert('items', array('name' => 'bread')); |
|||
$this->assertEquals(1, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'ball'), true, true)); |
|||
$this->assertEquals('today', $mongo->get('items', array('name' => 'ball'))->fetch()->date); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFindAndModify() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mongo = new MongoDriver($this->conf); |
|||
|
|||
$this->assertEquals(10, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity); |
|||
$result = $mongo->findAndModify('items', array('name' => 'bread'), array('$set' => array('quantity' => 20))); |
|||
$this->assertEquals(10, $result->fetch()->quantity); |
|||
$this->assertEquals(20, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testCommand() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$mongo = new MongoDriver($this->conf); |
|||
$result = $mongo->command('items', array('distinct' =>'items', 'key' => 'name')); |
|||
$this->assertEquals(4, count($result->fetch(DB::FETCH_ASSOC))); |
|||
} |
|||
} |
@ -0,0 +1,238 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage UnitTests |
|||
* @since 2011-11-7 |
|||
* |
|||
* Unit tests for MongoModel class |
|||
*/ |
|||
|
|||
require_once dirname(__FILE__) . '/../../Registry.php'; |
|||
require_once dirname(__FILE__) . '/../../Config.php'; |
|||
require_once dirname(__FILE__) . '/../../cache/Cacher.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbExpr.php'; |
|||
require_once dirname(__FILE__) . '/../../model/Db.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoDbCommand.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbStatement.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoStatement.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/NoSqlDbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/Model.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoModel.php'; |
|||
|
|||
class MongoModelTest extends PHPUnit_Framework_TestCase |
|||
{ |
|||
|
|||
private $model; |
|||
|
|||
public function run(PHPUnit_Framework_TestResult $result = NULL) |
|||
{ |
|||
$this->setPreserveGlobalState(false); |
|||
return parent::run($result); |
|||
} |
|||
|
|||
public function setUp() |
|||
{ |
|||
$conf = array('default' => array('driver' => 'MongoDriver', 'hostname' => 'localhost', 'database' => 'test', 'username' => 'test', 'password' => '1234', 'port' => 27017)); |
|||
|
|||
$this->dbSetUp($conf); |
|||
|
|||
Config::set('Db', $conf); |
|||
if (!class_exists('MockModel')) { |
|||
$this->model = $this->getMockForAbstractClass('MongoModel', array(), 'MongoMockModel'); |
|||
} else { |
|||
$this->model = new MongoMockModel(); |
|||
} |
|||
set_new_overload(array($this, 'newCallback')); |
|||
} |
|||
|
|||
/** |
|||
* @group Mongo |
|||
*/ |
|||
public function testModel() |
|||
{ |
|||
$this->assertInstanceOf('MongoMockModel', $this->model); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFind() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$result = $this->model->find(); |
|||
$this->assertInstanceOf('MongoStatement', $result); |
|||
$this->assertEquals('milk', $result->limit(2)->order(array('name' => -1))->fetch()->name); |
|||
$this->assertEquals('fish', $result->fetch()->name); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testGet() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$result = $this->model->find()->limit(1)->order(array('name' => 1)); |
|||
$result = $result->fetch(); |
|||
$this->assertEquals('bread', $result->name); |
|||
$id = $result->_id; |
|||
$this->assertEquals(10, $this->model->get($id)->quantity); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testDelete() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$result = $this->model->find()->limit(1)->order(array('name' => 1)); |
|||
$id = $result->fetch()->_id; |
|||
$this->assertEquals(1, $this->model->delete($id)); |
|||
$this->assertFalse($this->model->find(array('name' => 'bread'))->fetch()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testDeleteAll() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$this->assertEquals(2, $this->model->count(array('name' => 'eggs'))); |
|||
$this->assertEquals(0, $this->model->deleteAll(array('name' => 'eggs'))); |
|||
$this->assertFalse($this->model->find(array('name' => 'eggs'))->fetch()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testCount() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$this->assertEquals(5, $this->model->count()); |
|||
$this->assertEquals(2, $this->model->count(array('name' => 'eggs'))); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFetch() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$mock = $this->getMock('CacheKey', array('set', 'get')); |
|||
$mock->expects($this->exactly(3)) |
|||
->method('set') |
|||
->will($this->returnValue(true)); |
|||
$mock->expects($this->exactly(3)) |
|||
->method('get') |
|||
->will($this->returnValue(false)); |
|||
|
|||
$model = new ReflectionClass('MongoModel'); |
|||
$method = $model->getMethod('fetchField'); |
|||
$method->setAccessible(true); |
|||
|
|||
$result = $method->invoke($this->model, array('name' => 'milk'), array(), 'quantity', $mock); |
|||
$this->assertEquals(1, $result); |
|||
|
|||
$model = new ReflectionClass('MongoModel'); |
|||
$method = $model->getMethod('fetch'); |
|||
$method->setAccessible(true); |
|||
|
|||
$result = $method->invoke($this->model, array('name' => 'bread'), array(), $mock); |
|||
$this->assertEquals('bread', $result->name); |
|||
|
|||
$model = new ReflectionClass('MongoModel'); |
|||
$method = $model->getMethod('fetchAll'); |
|||
$method->setAccessible(true); |
|||
|
|||
$result = $method->invoke($this->model, array('name' => 'eggs'), array(), $mock); |
|||
$this->assertEquals(2, count($result)); |
|||
$this->assertEquals('eggs', $result[0]->name); |
|||
} |
|||
|
|||
public function tearDown() |
|||
{ |
|||
$conf = array('driver' => 'MongoDriver', 'hostname' => 'localhost', 'database' => 'test', 'username' => 'test', 'password' => '1234', 'port' => 27017); |
|||
|
|||
|
|||
$connection = new Mongo('mongodb://' . $conf['hostname'] . ':' . $conf['port']); |
|||
$db = $connection->selectDB($conf['database']); |
|||
$db->authenticate($conf['username'], $conf['password']); |
|||
$collection = 'mongomock'; |
|||
$db->dropCollection($collection); |
|||
} |
|||
|
|||
protected function newCallback($className) |
|||
{ |
|||
switch ($className) { |
|||
case 'CacheKey': |
|||
return 'MockCacheKey'; |
|||
default: |
|||
return $className; |
|||
} |
|||
} |
|||
|
|||
public function dbSetUp($conf) |
|||
{ |
|||
$data = array( |
|||
array( |
|||
'name' => 'bread', |
|||
'price' => 3.2, |
|||
'quantity' => 10 |
|||
), |
|||
array( |
|||
'name' => 'eggs', |
|||
'price' => 2.1, |
|||
'quantity' => 20 |
|||
), |
|||
array( |
|||
'name' => 'fish', |
|||
'price' => 13.2, |
|||
'quantity' => 2 |
|||
), |
|||
array( |
|||
'name' => 'milk', |
|||
'price' => 3.8, |
|||
'quantity' => 1 |
|||
), |
|||
array( |
|||
'name' => 'eggs', |
|||
'price' => 2.3, |
|||
'quantity' => 5 |
|||
) |
|||
); |
|||
$connection = new Mongo('mongodb://' . $conf['default']['hostname'] . ':' . $conf['default']['port']); |
|||
$db = $connection->selectDB($conf['default']['database']); |
|||
$db->authenticate($conf['default']['username'], $conf['default']['password']); |
|||
$collection = 'mongomock'; |
|||
$db->dropCollection($collection); |
|||
$collection = $db->selectCollection($collection); |
|||
foreach($data as $document) { |
|||
$collection->insert($document); |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,464 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage UnitTests |
|||
* @since 2011-11-15 |
|||
* |
|||
* Unit tests for MySQLiStatement class |
|||
*/ |
|||
|
|||
require_once dirname(__FILE__) . '/../../util/profiler/CommandProfiler.php'; |
|||
require_once dirname(__FILE__) . '/../../util/profiler/Profiler.php'; |
|||
require_once dirname(__FILE__) . '/../../model/Db.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbStatement.php'; |
|||
require_once dirname(__FILE__) . '/../../model/MongoStatement.php'; |
|||
require_once dirname(__FILE__) . '/../../exception/GeneralException.php'; |
|||
|
|||
class MongoStatementTest extends PHPUnit_Framework_TestCase |
|||
{ |
|||
|
|||
|
|||
private $driver; |
|||
|
|||
private $stmt; |
|||
|
|||
private $request; |
|||
|
|||
private $testData = array( |
|||
array('one' => 11, 'two' => 12), |
|||
array('one' => 21, 'two' => 22), |
|||
array('one' => 31, 'two' => 32), |
|||
); |
|||
|
|||
public function run(PHPUnit_Framework_TestResult $result = NULL) |
|||
{ |
|||
$this->setPreserveGlobalState(false); |
|||
return parent::run($result); |
|||
} |
|||
|
|||
public function setUp() |
|||
{ |
|||
if (!isset($this->stmt)) { |
|||
$this->driver = $this->getMockBuilder('DbDriverMock') |
|||
->disableOriginalConstructor() |
|||
->setMethods(array('getConnection')) |
|||
->getMock(); |
|||
$this->request = $this->getMockBuilder('MongoDbCommandMock') |
|||
->disableOriginalConstructor() |
|||
->setMethods(array('execute', 'bindParam', 'getInsertId')) |
|||
->getMock(); |
|||
$this->stmt = new MongoStatement($this->driver, $this->request); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testAffectedNumRowsNoResult() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$this->assertFalse($this->stmt->affectedRows()); |
|||
$this->assertFalse($this->stmt->numRows()); |
|||
|
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->any()) |
|||
->method('execute') |
|||
->will($this->returnValue(array())); |
|||
$this->stmt->execute(); |
|||
$this->assertFalse($this->stmt->affectedRows()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testAffectedNumRows() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('n' => 20, 'ok' => 1))); |
|||
$this->stmt->execute(); |
|||
$this->assertEquals(20, $this->stmt->affectedRows()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testGetInsertId() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$this->setDriverGetConnectionMethod(); |
|||
|
|||
$this->request = $this->getMockBuilder('InsertMongoCommand') |
|||
->disableOriginalConstructor() |
|||
->setMethods(array('execute', 'bindParam', 'getInsertId')) |
|||
->getMock(); |
|||
|
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('n' => 20, 'ok' => 1))); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('getInsertId') |
|||
->will($this->returnValue('4b0rrs')); |
|||
|
|||
$this->stmt = new MongoStatement($this->driver, $this->request); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->assertEquals('4b0rrs', $this->stmt->getInsertId()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testExecute() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
|
|||
$this->setDriverGetConnectionMethod()->setRequestExecuteMethod(); |
|||
$this->assertTrue($this->stmt->execute()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testExecuteNoResult() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->any()) |
|||
->method('execute') |
|||
->will($this->returnValue(false)); |
|||
$this->setExpectedException('GeneralException', 'MongoDB request error.'); |
|||
$this->stmt->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testExecuteNoConnection() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', false); |
|||
} |
|||
$this->driver |
|||
->expects($this->any()) |
|||
->method('getConnection') |
|||
->will($this->returnValue(false)); |
|||
$this->setExpectedException('GeneralException', 'No connection to MongoDB server.'); |
|||
$this->stmt->execute(); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testExecuteWithDebug() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->setDriverGetConnectionMethod()->setRequestExecuteMethod(); |
|||
$this->assertTrue($this->stmt->execute()); |
|||
$this->assertEquals(10, $this->stmt->numRows()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testBindParam() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
|
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('bindParam') |
|||
->will($this->returnValue(true)); |
|||
|
|||
$this->setDriverGetConnectionMethod()->setRequestExecuteMethod(); |
|||
$this->assertTrue($this->stmt->execute(array('one' => 'two'))); |
|||
|
|||
$this->assertAttributeNotEquals(null, 'result', $this->stmt); |
|||
$this->stmt->close(); |
|||
$this->assertAttributeEquals(null, 'result', $this->stmt); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFetch() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
|
|||
$this->setDriverGetConnectionMethod()->setRequestForFetch(); |
|||
|
|||
$this->stmt->execute(); |
|||
$result = $this->stmt->fetch(); |
|||
$this->assertEquals('prev', $result->next); |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFetchWithInitialArray() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
|
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('some' => 'val'))); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFetchAssocFromCursor() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
|
|||
$this->setDriverGetConnectionMethod()->setRequestForFetch(); |
|||
|
|||
$this->stmt->execute(); |
|||
$result = $this->stmt->fetch(Db::FETCH_ASSOC); |
|||
$this->assertEquals('prev', $result['next']); |
|||
$this->assertEquals(array(), $this->stmt->fetch(Db::FETCH_ASSOC)); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFetchAssocFromArray() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
|
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('some' => 'val'))); |
|||
|
|||
$this->stmt->execute(); |
|||
$result = $this->stmt->fetch(Db::FETCH_ASSOC); |
|||
$this->assertEquals('val', $result['some']); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testFetchWrongMode() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->assertFalse($this->stmt->fetch()); |
|||
|
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('some' => 'val'))); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->setExpectedException('GeneralException', 'Invalid fetch mode "222" specified'); |
|||
$this->stmt->fetch(222); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testSkipOrderLimit() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->setDriverGetConnectionMethod()->setRequestForFetch(); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->assertInstanceOf('MongoStatement', $this->stmt->order(array('id' => 1))); |
|||
$this->assertInstanceOf('MongoStatement', $this->stmt->limit(10)); |
|||
$this->assertInstanceOf('MongoStatement', $this->stmt->skip(1)); |
|||
|
|||
$this->stmt->fetch(); |
|||
$this->stmt->fetch(); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testOrderException() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('some' => 'val'))); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->setExpectedException('GeneralException', 'MongoStatement error. Impossible order results of opened cursor'); |
|||
$this->stmt->order(array('id' => 1)); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testSkipException() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('some' => 'val'))); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->setExpectedException('GeneralException', 'MongoStatement error. Impossible skip results of opened cursor'); |
|||
$this->stmt->skip(array('id' => 1)); |
|||
} |
|||
|
|||
/** |
|||
* @runInSeparateProcess |
|||
* @group Mongo |
|||
*/ |
|||
public function testLimitException() |
|||
{ |
|||
if (!defined('DEBUG')) { |
|||
define('DEBUG', true); |
|||
} |
|||
$this->setDriverGetConnectionMethod(); |
|||
$this->request |
|||
->expects($this->once()) |
|||
->method('execute') |
|||
->will($this->returnValue(array('some' => 'val'))); |
|||
|
|||
$this->stmt->execute(); |
|||
$this->setExpectedException('GeneralException', 'MongoStatement error. Impossible limit results of opened cursor'); |
|||
$this->stmt->limit(array('id' => 1)); |
|||
} |
|||
|
|||
private function setDriverGetConnectionMethod() |
|||
{ |
|||
$mongoMock = $this->getMock('Mongo'); |
|||
|
|||
$this->driver |
|||
->expects($this->any()) |
|||
->method('getConnection') |
|||
->will($this->returnValue($mongoMock)); |
|||
return $this; |
|||
} |
|||
|
|||
public function setRequestExecuteMethod() |
|||
{ |
|||
$resultMock = $this->getMockBuilder('MongoCursor') |
|||
->setMethods(array('count')) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
|
|||
$resultMock |
|||
->expects($this->any()) |
|||
->method('count') |
|||
->will($this->returnValue(10)); |
|||
|
|||
$this->request |
|||
->expects($this->any()) |
|||
->method('execute') |
|||
->will($this->returnValue($resultMock)); |
|||
|
|||
return $this; |
|||
} |
|||
|
|||
public function setRequestForFetch() |
|||
{ |
|||
$resultMock = $this->getMockBuilder('MongoCursor') |
|||
->setMethods(array('count', 'getNext', 'limit', 'sort', 'skip')) |
|||
->disableOriginalConstructor() |
|||
->getMock(); |
|||
|
|||
$resultMock |
|||
->expects($this->any()) |
|||
->method('limit'); |
|||
$resultMock |
|||
->expects($this->any()) |
|||
->method('sort'); |
|||
$resultMock |
|||
->expects($this->any()) |
|||
->method('skip'); |
|||
$resultMock |
|||
->expects($this->any()) |
|||
->method('count') |
|||
->will($this->returnValue(10)); |
|||
$resultMock |
|||
->expects($this->at(0)) |
|||
->method('getNext') |
|||
->will($this->returnValue(array('next' => 'prev', '_id' => 10))); |
|||
$resultMock |
|||
->expects($this->at(1)) |
|||
->method('getNext') |
|||
->will($this->returnValue(array())); |
|||
|
|||
$this->request |
|||
->expects($this->any()) |
|||
->method('execute') |
|||
->will($this->returnValue($resultMock)); |
|||
|
|||
return $this; |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
<?php |
|||
|
|||
abstract class MyDbDriver extends DbDriver |
|||
{ |
|||
public function getInsertId($table = null, $key = null) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public function quoteIdentifier($param) |
|||
{ |
|||
return $param; |
|||
} |
|||
|
|||
public function quote($param) |
|||
{ |
|||
return $param; |
|||
} |
|||
|
|||
public function insert($table, $bind, $on_duplicate = array()) |
|||
{ |
|||
return $table; |
|||
} |
|||
|
|||
public function update($table, $bind, $where = '') |
|||
{ |
|||
return $table; |
|||
} |
|||
|
|||
public function delete($table, $where = '') |
|||
{ |
|||
return $table; |
|||
} |
|||
|
|||
public function query($sql, $params = array()) |
|||
{ |
|||
$conf = array('driver' => 'MockDbDriver', 'hostname' => 'somehost', 'database' => 'db', 'username' => 'test', 'password' => '1234'); |
|||
return new MockDbDriver($conf); |
|||
} |
|||
|
|||
public function execute() |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public function fetch() |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
public function fetchField($field) |
|||
{ |
|||
return $field; |
|||
} |
|||
|
|||
public function fetchAll() |
|||
{ |
|||
return true; |
|||
} |
|||
} |
@ -0,0 +1,110 @@ |
|||
<?php |
|||
|
|||
/* |
|||
* @copyright NetMonsters <team@netmonsters.ru> |
|||
* @link http://netmonsters.ru |
|||
* @package Majestic |
|||
* @subpackage UnitTests |
|||
* @since 2011-11-15 |
|||
* |
|||
* Unit tests for SessionModel class |
|||
*/ |
|||
|
|||
require_once dirname(__FILE__) . '/../../Registry.php'; |
|||
require_once dirname(__FILE__) . '/../../Config.php'; |
|||
require_once dirname(__FILE__) . '/../../classes/Env.class.php'; |
|||
require_once dirname(__FILE__) . '/../../model/Db.php'; |
|||
require_once dirname(__FILE__) . '/../../model/DbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../model/MyDbDriver.php'; |
|||
require_once dirname(__FILE__) . '/../../model/Model.php'; |
|||
require_once dirname(__FILE__) . '/../../model/SqlModel.php'; |
|||
require_once dirname(__FILE__) . '/../../session/Session.model.php'; |
|||
|
|||
class SessionModelTest extends PHPUnit_Framework_TestCase |
|||
{ |
|||
|
|||
protected $model; |
|||
|
|||
public function setUp() |
|||
{ |
|||
$conf = array('default' => array('driver' => 'MockDbDriver', 'hostname' => 'somehost', 'database' => 'db', 'username' => 'test', 'password' => '1234')); |
|||
if (!class_exists('MockDbDriver')) { |
|||
$this->getMockForAbstractClass('MyDbDriver', array($conf), 'MockDbDriver', false); |
|||
} |
|||
if (!class_exists('MockDbExpr')) { |
|||
$this->getMock('DbExpr', array(), array(), 'MockDbExpr', false); |
|||
} |
|||
|
|||
Config::set('Db', $conf); |
|||
|
|||
set_new_overload(array($this, 'newCallback')); |
|||
} |
|||
|
|||
public function testOpen() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$this->assertTrue($this->model->open('path', 'name')); |
|||
} |
|||
|
|||
public function testClose() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$this->assertTrue($this->model->close()); |
|||
} |
|||
|
|||
public function testRead() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$this->assertEquals('data', $this->model->read(1)); |
|||
} |
|||
|
|||
public function testWrite() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; |
|||
$this->assertEmpty(Env::Server('HTTP_X_FORWARDED_FOR')); |
|||
|
|||
$this->assertTrue($this->model->write(2, 'user|.s:20;id=2;id=2')); |
|||
} |
|||
|
|||
public function testDestroy() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$this->assertTrue($this->model->destroy(2)); |
|||
} |
|||
public function testGc() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$this->assertTrue($this->model->gc(2000)); |
|||
} |
|||
|
|||
public function testDestroyByUserId() |
|||
{ |
|||
$this->model = new SessionModel(); |
|||
$this->assertEquals('session', $this->model->destroyByUserId(12)); |
|||
} |
|||
|
|||
public function tearDown() |
|||
{ |
|||
Config::getInstance()->offsetUnset('Db'); |
|||
$config = new ReflectionClass('Db'); |
|||
$registry = $config->getProperty('connections'); |
|||
$registry->setAccessible(true); |
|||
$registry->setValue('Db', array()); |
|||
unset_new_overload(); |
|||
} |
|||
|
|||
protected function newCallback($className) |
|||
{ |
|||
switch ($className) { |
|||
case 'DbExpr': |
|||
return 'MockDbExpr'; |
|||
case 'MockDbDriver': |
|||
return 'MockDbDriver'; |
|||
case 'CacheKey': |
|||
return 'MockCacheKey'; |
|||
default: |
|||
return $className; |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue