/library/Shanty/Mongo/Collection.php
PHP | 521 lines | 258 code | 74 blank | 189 comment | 34 complexity | 2bf0f381687c3e8e998cb65e0a637ee3 MD5 | raw file
- <?php
- require_once 'Shanty/Mongo/Document.php';
- require_once 'Shanty/Mongo/Exception.php';
- require_once 'Shanty/Mongo/Iterator/Cursor.php';
- /**
- * @category Shanty
- * @package Shanty_Mongo
- * @copyright Shanty Tech Pty Ltd
- * @license New BSD License
- * @author Coen Hyde
- */
- abstract class Shanty_Mongo_Collection
- {
- protected static $_connectionGroup = 'default';
- protected static $_db = null;
- protected static $_collection = null;
- protected static $_requirements = array();
- protected static $_cachedCollectionInheritance = array();
- protected static $_cachedCollectionRequirements = array();
- protected static $_documentSetClass = 'Shanty_Mongo_DocumentSet';
-
- /**
- * Get the name of the mongo db
- *
- * @return string
- */
- public static function getDbName()
- {
- $db = static::$_db;
- if (is_null($db)) {
- $db = static::getConnection()->getDatabase();
- }
- return $db;
- }
-
- /**
- * Get the name of the mongo collection
- *
- * @return string
- */
- public static function getCollectionName()
- {
- return static::$_collection;
- }
-
- /**
- * Get the name of the connection group
- *
- * @return string
- */
- public static function getConnectionGroupName()
- {
- return static::$_connectionGroup;
- }
- /**
- * Determine if this collection has a database name set
- *
- * @return boolean
- */
- public static function hasDbName()
- {
- return !is_null(static::getDbName());
- }
-
- /**
- * Determine if this collection has a collection name set
- *
- * @return boolean
- */
- public static function hasCollectionName()
- {
- return !is_null(static::getCollectionName());
- }
-
- /**
- * Is this class a document class
- *
- * @return boolean
- */
- public static function isDocumentClass()
- {
- return is_subclass_of(get_called_class(), 'Shanty_Mongo_Document');
- }
-
- /**
- * Get the name of the document class
- *
- * @return string
- */
- public static function getDocumentClass()
- {
- if (!static::isDocumentClass()) {
- throw new Shanty_Mongo_Exception(get_called_class().' is not a document. Please extend Shanty_Mongo_Document');
- }
-
- return get_called_class();
- }
-
- /**
- * Get the name of the document set class
- *
- * @return string
- */
- public static function getDocumentSetClass()
- {
- return static::$_documentSetClass;
- }
-
- /**
- * Get the inheritance of this collection
- */
- public static function getCollectionInheritance()
- {
- $calledClass = get_called_class();
-
- // Have we already computed this collections inheritance?
- if (array_key_exists($calledClass, static::$_cachedCollectionInheritance)) {
- return static::$_cachedCollectionInheritance[$calledClass];
- }
-
- $parentClass = get_parent_class($calledClass);
-
- if (is_null($parentClass::getCollectionName())) {
- $inheritance = array($calledClass);
- }
- else {
- $inheritance = $parentClass::getCollectionInheritance();
- array_unshift($inheritance, $calledClass);
- }
-
- static::$_cachedCollectionInheritance[$calledClass] = $inheritance;
- return $inheritance;
- }
-
- /**
- * Get requirements
- *
- * @param bolean $inherited Include inherited requirements
- * @return array
- */
- public static function getCollectionRequirements($inherited = true)
- {
- $calledClass = get_called_class();
-
- // Return if we only need direct requirements. ie no inherited requirements
- if (!$inherited || $calledClass === __CLASS__) {
- $reflector = new ReflectionProperty($calledClass, '_requirements');
- if ($reflector->getDeclaringClass()->getName() !== $calledClass) return array();
-
- return static::makeRequirementsTidy($calledClass::$_requirements);
- }
-
- // Have we already computed this collections requirements?
- if (array_key_exists($calledClass, self::$_cachedCollectionRequirements)) {
- return self::$_cachedCollectionRequirements[$calledClass];
- }
-
- // Get parent collections requirements
- $parentClass = get_parent_class($calledClass);
- $parentRequirements = $parentClass::getCollectionRequirements();
-
- // Merge those requirements with this collections requirements
- $requirements = static::mergeRequirements($parentRequirements, $calledClass::getCollectionRequirements(false));
- self::$_cachedCollectionRequirements[$calledClass] = $requirements;
-
- return $requirements;
- }
-
- /**
- * Process requirements to make sure they are in the correct format
- *
- * @param array $requirements
- * @return array
- */
- public static function makeRequirementsTidy(array $requirements) {
- foreach ($requirements as $property => $requirementList) {
- if (!is_array($requirementList)) {
- $requirements[$property] = array($requirementList);
- }
-
- $newRequirementList = array();
- foreach ($requirements[$property] as $key => $requirement) {
- if (is_numeric($key)) $newRequirementList[$requirement] = null;
- else $newRequirementList[$key] = $requirement;
- }
-
- $requirements[$property] = $newRequirementList;
- }
-
- return $requirements;
- }
-
- /**
- * Merge a two sets of requirements together
- *
- * @param array $requirements
- * @return array
- */
- public static function mergeRequirements($requirements1, $requirements2)
- {
- $requirements = $requirements1;
-
- foreach ($requirements2 as $property => $requirementList) {
- if (!array_key_exists($property, $requirements)) {
- $requirements[$property] = $requirementList;
- continue;
- }
-
- foreach ($requirementList as $requirement => $options) {
- // Find out if this is a Document or DocumentSet requirement
- $matches = array();
- preg_match("/^(Document|DocumentSet)(?::[A-Za-z][\w\-]*)?$/", $requirement, $matches);
-
- if (empty($matches)) {
- $requirements[$property][$requirement] = $options;
- continue;
- }
- // If requirement exists in existing requirements then unset it and replace it with the new requirements
- foreach ($requirements[$property] as $innerRequirement => $innerOptions) {
- $innerMatches = array();
-
- preg_match("/^{$matches[1]}(:[A-Za-z][\w\-]*)?/", $innerRequirement, $innerMatches);
-
- if (empty($innerMatches)) {
- continue;
- }
-
- unset($requirements[$property][$innerRequirement]);
- $requirements[$property][$requirement] = $options;
- break;
- }
- }
- }
-
- return $requirements;
- }
- /*
- * Get a connection
- *
- * @param $writable should the connection be writable
- * @return Shanty_Mongo_Connection
- */
- public static function getConnection($writable = true)
- {
- if ($writable) $connection = Shanty_Mongo::getWriteConnection(static::getConnectionGroupName());
- else $connection = Shanty_Mongo::getReadConnection(static::getConnectionGroupName());
- return $connection;
- }
- /**
- * Get an instance of MongoDb
- *
- * @return MongoDb
- * @param boolean $useSlave
- */
- public static function getMongoDb($writable = true)
- {
- if (!static::hasDbName()) {
- require_once 'Shanty/Mongo/Exception.php';
- throw new Shanty_Mongo_Exception(get_called_class().'::$_db is null');
- }
- return static::getConnection($writable)->selectDB(static::getDbName());
- }
-
- /**
- * Get an instance of MongoCollection
- *
- * @return MongoCollection
- * @param boolean $useSlave
- */
- public static function getMongoCollection($writable = true)
- {
- if (!static::hasCollectionName()) {
- throw new Shanty_Mongo_Exception(get_called_class().'::$_collection is null');
- }
-
- return static::getMongoDb($writable)->selectCollection(static::getCollectionName());
- }
-
- /**
- * Create a new document belonging to this collection
- * @param $data
- * @param boolean $new
- */
- public static function create(array $data = array(), $new = true)
- {
- if (isset($data['_type']) && is_array($data['_type']) && class_exists($data['_type'][0]) && is_subclass_of($data['_type'][0], 'Shanty_Mongo_Document')) {
- $documentClass = $data['_type'][0];
- }
- else {
- $documentClass = static::getDocumentClass();
- }
-
- $config = array();
- $config['new'] = ($new);
- $config['hasId'] = true;
- $config['connectionGroup'] = static::getConnectionGroupName();
- $config['db'] = static::getDbName();
- $config['collection'] = static::getCollectionName();
- return new $documentClass($data, $config);
- }
-
- /**
- * Find a document by id
- *
- * @param MongoId|String $id
- * @param array $fields
- * @return Shanty_Mongo_Document
- */
- public static function find($id, array $fields = array())
- {
- if (!($id instanceof MongoId)) {
- $id = new MongoId($id);
- }
-
- $query = array('_id' => $id);
-
- return static::one($query, $fields);
- }
-
- /**
- * Find one document
- *
- * @param array $query
- * @param array $fields
- * @return Shanty_Mongo_Document
- */
- public static function one(array $query = array(), array $fields = array())
- {
- $inheritance = static::getCollectionInheritance();
- if (count($inheritance) > 1) {
- $query['_type'] = $inheritance[0];
- }
- // If we are selecting specific fields make sure _type is always there
- if (!empty($fields) && !isset($fields['_type'])) {
- $fields['_type'] = 1;
- }
- $data = static::getMongoCollection(false)->findOne($query, $fields);
-
- if (is_null($data)) return null;
-
- return static::create($data, false);
- }
-
- /**
- * Find many documents
- *
- * @param array $query
- * @param array $fields
- * @return Shanty_Mongo_Iterator_Cursor
- */
- public static function all(array $query = array(), array $fields = array())
- {
- $inheritance = static::getCollectionInheritance();
- if (count($inheritance) > 1) {
- $query['_type'] = $inheritance[0];
- }
- // If we are selecting specific fields make sure _type is always there
- if (!empty($fields) && !isset($fields['_type'])) {
- $fields['_type'] = 1;
- }
-
- $cursor = static::getMongoCollection(false)->find($query, $fields);
- $config = array();
- $config['connectionGroup'] = static::getConnectionGroupName();
- $config['db'] = static::getDbName();
- $config['collection'] = static::getCollectionName();
- $config['documentClass'] = static::getDocumentClass();
- $config['documentSetClass'] = static::getDocumentSetClass();
- return new Shanty_Mongo_Iterator_Cursor($cursor, $config);
- }
- /**
- * Alias for one
- *
- * @param array $query
- * @param array $fields
- * @return Shanty_Mongo_Document
- */
- public static function fetchOne($query = array(), array $fields = array())
- {
- return static::one($query, $fields);
- }
-
- /**
- * Alias for all
- *
- * @param array $query
- * @param array $fields
- * @return Shanty_Mongo_Iterator_Cursor
- */
- public static function fetchAll($query = array(), array $fields = array())
- {
- return static::all($query, $fields);
- }
-
- /**
- * Select distinct values for a property
- *
- * @param String $property
- * @return array
- */
- public static function distinct($property)
- {
- $results = static::getMongoDb(false)->command(array('distinct' => static::getCollectionName(), 'key' => $property));
-
- return $results['values'];
- }
-
- /**
- * Insert a document
- *
- * @param array $document
- * @param array $options
- */
- public static function insert(array $document, array $options = array())
- {
- return static::getMongoCollection(true)->insert($document, $options);
- }
- /**
- * Insert a batch of documents
- *
- * @param array $documents
- * @param unknown_type $options
- */
- public static function insertBatch(array $documents, array $options = array())
- {
- return static::getMongoCollection(true)->batchInsert($documents, $options);
- }
-
- /**
- * Update documents from this collection
- *
- * @param $criteria
- * @param $object
- * @param $options
- */
- public static function update(array $criteria, array $object, array $options = array())
- {
- return static::getMongoCollection(true)->update($criteria, $object, $options);
- }
-
- /**
- * Remove documents from this collection
- *
- * @param array $criteria
- * @param unknown_type $justone
- */
- public static function remove(array $criteria, array $options = array())
- {
- // if you want to remove a document by MongoId
- if (array_key_exists('_id', $criteria) && !($criteria["_id"] instanceof MongoId)) {
- $criteria["_id"] = new MongoId($criteria["_id"]);
- }
-
- return static::getMongoCollection(true)->remove($criteria, $options);
- }
-
- /**
- * Drop this collection
- */
- public static function drop()
- {
- return static::getMongoCollection(true)->drop();
- }
-
- /**
- * Ensure an index
- *
- * @param array $keys
- * @param array $options
- */
- public static function ensureIndex(array $keys, $options = array())
- {
- return static::getMongoCollection(true)->ensureIndex($keys, $options);
- }
-
- /**
- * Delete an index
- *
- * @param string|array $keys
- */
- public static function deleteIndex($keys)
- {
- return static::getMongoCollection(true)->deleteIndex($keys);
- }
-
- /**
- * Remove all indexes from this collection
- */
- public static function deleteIndexes()
- {
- return static::getMongoCollection(true)->deleteIndexes();
- }
-
- /**
- * Get index information for this collection
- *
- * @return array
- */
- public static function getIndexInfo()
- {
- return static::getMongoCollection(false)->getIndexInfo();
- }
- }