Skip to content

Commit

Permalink
Implemented id generator strategies and got rid of the old custom id …
Browse files Browse the repository at this point in the history
…stuff. Also implemented uuid and increment id generator.
  • Loading branch information
jwage committed Nov 27, 2010
1 parent 57e4042 commit 4645bab
Show file tree
Hide file tree
Showing 23 changed files with 666 additions and 132 deletions.
2 changes: 1 addition & 1 deletion lib/Doctrine/ODM/MongoDB/DocumentManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public function getDocumentCollection($className)
} else {
$collection = $db->selectCollection($collection);
}
$mongoCollection = new MongoCollection($collection, $db, $metadata, $this->eventManager, $this->config);
$mongoCollection = new MongoCollection($this, $collection, $db, $metadata, $this->eventManager, $this->config);
$this->documentCollections[$key] = $mongoCollection;
}
if ( ! isset($this->documentCollections[$key])) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Doctrine/ODM/MongoDB/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public function hydrate($document, &$data)
// Set the document identifier
if (isset($data['_id'])) {
$metadata->setIdentifierValue($document, $data['_id']);
$data[$metadata->identifier] = $data['_id'];
$data[$metadata->identifier] = Type::getType($metadata->fieldMappings[$metadata->identifier]['type'])->convertToPHPValue($data['_id']);
unset($data['_id']);
}

Expand Down
41 changes: 41 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Id/AbstractIdGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ODM\MongoDB\Id;

use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

abstract class AbstractIdGenerator
{
protected $class;

public function __construct(ClassMetadata $class)
{
$this->class = $class;
}

/**
* Generates an identifier for a document.
*
* @param Doctrine\ORM\Document $document
* @return mixed
*/
abstract public function generate(DocumentManager $dm, $document);
}
32 changes: 32 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Id/AutoGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ODM\MongoDB\Id;

use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

class AutoGenerator extends AbstractIdGenerator
{
/** @inheritDoc */
public function generate(DocumentManager $dm, $document)
{
return new \MongoId();
}
}
56 changes: 56 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Id/IncrementGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ODM\MongoDB\Id;

use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

/**
* IncrementGenerator is responsible for generating auto increment identifiers. It uses
* a collection named "doctrine_increment_ids" which stores a document for each document
* type and generates the next id by using $inc on a field named "current_id".
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 1.0
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
class IncrementGenerator extends AbstractIdGenerator
{
/** @inheritDoc */
public function generate(DocumentManager $dm, $document)
{
$className = get_class($document);
$db = $dm->getDocumentDB($className);
$coll = $dm->getDocumentCollection($className);

$query = array('_id' => $coll->getName());
$newObj = array('$inc' => array('current_id' => 1));

$command = array();
$command['findandmodify'] = 'doctrine_increment_ids';
$command['query'] = $query;
$command['update'] = $newObj;
$command['upsert'] = true;
$command['new'] = true;
$result = $db->command($command);
return $result['value']['current_id'];
}
}
156 changes: 156 additions & 0 deletions lib/Doctrine/ODM/MongoDB/Id/UuidGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/

namespace Doctrine\ODM\MongoDB\Id;

use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

class UuidGenerator extends AbstractIdGenerator
{
/**
* A unique environment value to salt each GUID with.
*
* @var string
*/
protected $salt = null;

/**
* Used to set the salt that will be applied to each id
*
* @param string $salt The sale to use
*/
public function setSalt($salt)
{
$this->salt = $salt;
}

/**
* Returns the current salt value
*
* @return string $salt The current salt
*/
public function getSalt()
{
return $this->salt;
}

/**
* Checks that a given string is a valid uuid.
*
* @param string $uuid The string to check.
* @return boolean
*/
public function isValid($guid)
{
return preg_match('/^\{?[0-9a-f]{8}\-?[0-9a-f]{4}\-?[0-9a-f]{4}\-?[0-9a-f]{4}\-?[0-9a-f]{12}\}?$/i', $guid) === 1;
}

/**
* Generates a new GUID
*
* @return string
*/
public function generate(DocumentManager $dm, $document)
{
if (!$this->salt) {
throw new \Exception('Guid Generator requires a salt to be provided.');
}

$guid = $this->generateV4();
return $this->generateV5($guid, $this->salt);
}

/**
* Generates a v4 GUID
*
* @return string
*/
public function generateV4()
{
return sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff), mt_rand(0, 0xffff),

// 16 bits for "time_mid"
mt_rand(0, 0xffff),

// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand(0, 0x0fff) | 0x4000,

// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,

// 48 bits for "node"
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
}

/**
* Generates a v5 GUID
*
* @param string $namespace The GUID to seed with
* @param string $salt The string to salt this new UUID with
* @return string
*/
public function generateV5($namespace, $salt)
{
if (!$this->isValid($namespace)) {
throw new \Exception('Provided $namespace is invalid: ' . $namespace);
}

// Get hexadecimal components of namespace
$nhex = str_replace(array('-','{','}'), '', $namespace);

// Binary Value
$nstr = '';

// Convert Namespace UUID to bits
for ($i = 0; $i < strlen($nhex); $i += 2) {
$nstr .= chr(hexdec($nhex[$i] . $nhex[$i+1]));
}

// Calculate hash value
$hash = sha1($nstr . $salt);

$guid = sprintf('%08s%04s%04x%04x%12s',
// 32 bits for "time_low"
substr($hash, 0, 8),

// 16 bits for "time_mid"
substr($hash, 8, 4),

// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 3
(hexdec(substr($hash, 12, 4)) & 0x0fff) | 0x3000,

// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
(hexdec(substr($hash, 16, 4)) & 0x3fff) | 0x8000,

// 48 bits for "node"
substr($hash, 20, 12)
);

return $guid;
}
}
Loading

0 comments on commit 4645bab

Please sign in to comment.