diff --git a/core/Base/Assert.class.php b/core/Base/Assert.class.php
index 1c41da0ffc..08aee64de6 100644
--- a/core/Base/Assert.class.php
+++ b/core/Base/Assert.class.php
@@ -276,6 +276,30 @@ public static function isUnreachable($message = 'unreachable code reached')
{
throw new WrongArgumentException($message);
}
+
+ /**
+ * Checking UUID
+ * @see http://tools.ietf.org/html/rfc4122
+ * @param string $value
+ * @return boolean
+ */
+ public static function checkUuid($value)
+ {
+ return (
+ is_string($value) &&
+ preg_match(PrimitiveUuid::UUID_PATTERN, $value)
+ );
+ }
+
+ public static function isUuid($variable, $message = null)
+ {
+ if(
+ !self::checkUuid($variable)
+ )
+ throw new WrongArgumentException(
+ $message.', '.self::dumpArgument($variable)
+ );
+ }
public static function isObject($object, $message = null)
{
diff --git a/core/DB/PgSQL.class.php b/core/DB/PgSQL.class.php
index 7a450f7c2b..d4e22a63ed 100644
--- a/core/DB/PgSQL.class.php
+++ b/core/DB/PgSQL.class.php
@@ -77,6 +77,9 @@ public function isConnected()
public function obtainSequence($sequence)
{
+ if(UuidUtils::isUuidSequence($sequence))
+ return UuidUtils::make();
+
$res = $this->queryRaw("select nextval('{$sequence}') as seq");
$row = pg_fetch_assoc($res);
pg_free_result($res);
@@ -192,6 +195,7 @@ public function getTableInfo($table)
'int4' => DataType::INTEGER,
'int8' => DataType::BIGINT,
'numeric' => DataType::NUMERIC,
+ 'uuid' => DataType::UUID,
'float4' => DataType::REAL,
'float8' => DataType::DOUBLE,
diff --git a/core/Exceptions/UnsupportedExtensionException.class.php b/core/Exceptions/UnsupportedExtensionException.class.php
new file mode 100644
index 0000000000..950cfab735
--- /dev/null
+++ b/core/Exceptions/UnsupportedExtensionException.class.php
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/core/Form/Primitives/PrimitiveIdentifierList.class.php b/core/Form/Primitives/PrimitiveIdentifierList.class.php
index 726349fc31..e64b45b637 100644
--- a/core/Form/Primitives/PrimitiveIdentifierList.class.php
+++ b/core/Form/Primitives/PrimitiveIdentifierList.class.php
@@ -12,11 +12,11 @@
/**
* @ingroup Primitives
**/
- final class PrimitiveIdentifierList extends PrimitiveIdentifier
+ class PrimitiveIdentifierList extends PrimitiveIdentifier
{
protected $value = array();
private $ignoreEmpty = false;
-
+
/**
* @return PrimitiveIdentifierList
**/
@@ -83,7 +83,20 @@ public function importValue($value)
return parent::importValue($value);
}
-
+
+ /**
+ * Here we check a identifier
+ * @param $id
+ * @return bool
+ */
+ protected function checkIdentifier($id)
+ {
+ return (
+ ($this->scalar && Assert::checkScalar($id))
+ || (!$this->scalar && Assert::checkInteger($id))
+ );
+ }
+
public function import($scope)
{
if (!$this->className)
@@ -106,8 +119,7 @@ public function import($scope)
continue;
if (
- ($this->scalar && !Assert::checkScalar($id))
- || (!$this->scalar && !Assert::checkInteger($id))
+ !$this->checkIdentifier($id)
)
return false;
diff --git a/core/Form/Primitives/PrimitiveUuid.class.php b/core/Form/Primitives/PrimitiveUuid.class.php
new file mode 100644
index 0000000000..18b46af359
--- /dev/null
+++ b/core/Form/Primitives/PrimitiveUuid.class.php
@@ -0,0 +1,43 @@
+ 'TIME',
self::TIMESTAMP => 'TIMESTAMP',
self::INTERVAL => 'INTERVAL',
+ self::UUID => 'UUID',
self::BINARY => 'BINARY',
diff --git a/main/Base/LightMetaProperty.class.php b/main/Base/LightMetaProperty.class.php
index 78bf621ef3..1d8c77cd29 100644
--- a/main/Base/LightMetaProperty.class.php
+++ b/main/Base/LightMetaProperty.class.php
@@ -138,6 +138,7 @@ public static function fill(
($type == 'identifier') // obsoleted
|| ($type == 'integerIdentifier')
|| ($type == 'scalarIdentifier')
+ || ($type == 'uuidIdentifier')
);
return $property;
diff --git a/main/Utils/UuidUtils.class.php b/main/Utils/UuidUtils.class.php
new file mode 100644
index 0000000000..ac82d5fa8d
--- /dev/null
+++ b/main/Utils/UuidUtils.class.php
@@ -0,0 +1,56 @@
+getPattern() instanceof AbstractClassPattern) {
+ $sequenceName = $class->getTableName().'_id';
+
+ if($class->getIdentifier()->getType() instanceof UuidType)
+ $sequenceName = 'uuid';
+
if (
$class->getIdentifier()->getColumnName() !== 'id'
) {
@@ -49,7 +54,7 @@ public function getObjectName()
public function getSequence()
{
- return '{$class->getTableName()}_id';
+ return '{$sequenceName}';
}
EOT;
} elseif ($class->getWithInternalProperties()) {
diff --git a/meta/classes/MetaClassProperty.class.php b/meta/classes/MetaClassProperty.class.php
index b8572961ca..b40744fa53 100644
--- a/meta/classes/MetaClassProperty.class.php
+++ b/meta/classes/MetaClassProperty.class.php
@@ -328,6 +328,9 @@ public function toLightProperty(MetaClass $holder)
if ($this->getType() instanceof IntegerType) {
$primitiveName = 'integerIdentifier';
$className = $holder->getName();
+ } elseif ($this->getType() instanceof UuidType) {
+ $primitiveName = 'uuidIdentifier';
+ $className = $holder->getName();
} elseif ($this->getType() instanceof StringType) {
$primitiveName = 'scalarIdentifier';
$className = $holder->getName();
@@ -350,6 +353,8 @@ public function toLightProperty(MetaClass $holder)
) {
if ($identifier->getType() instanceof IntegerType) {
$primitiveName = 'integerIdentifier';
+ } elseif ($identifier->getType() instanceof UuidType) {
+ $primitiveName = 'uuidIdentifier';
} elseif ($identifier->getType() instanceof StringType) {
$primitiveName = 'scalarIdentifier';
} else
diff --git a/meta/types/UuidType.class.php b/meta/types/UuidType.class.php
new file mode 100644
index 0000000000..cdd8ae939d
--- /dev/null
+++ b/meta/types/UuidType.class.php
@@ -0,0 +1,57 @@
+default = $default;
+
+ return $this;
+ }
+
+ public function getDeclaration()
+ {
+ if ($this->hasDefault())
+ return $this->default;
+
+ return 'null';
+ }
+
+ public function isMeasurable()
+ {
+ return false;
+ }
+
+ public function toColumnType()
+ {
+ return 'DataType::create(DataType::UUID)';
+ }
+ }
+?>
\ No newline at end of file
diff --git a/test/core/AssertTest.class.php b/test/core/AssertTest.class.php
index 3cfb09f2d5..db9d74b26a 100644
--- a/test/core/AssertTest.class.php
+++ b/test/core/AssertTest.class.php
@@ -81,5 +81,24 @@ public function testTernaryBase()
$this->fail();
}
}
+
+ public function testUuid()
+ {
+ $exampleUuid = '550e8400-e29b-41d4-a716-446655440000';
+ try {
+ Assert::isUuid($exampleUuid);
+ Assert::isUuid(strtoupper($exampleUuid));
+ } catch (WrongArgumentException $e) {
+ $this->fail('uuid asserts working uncorrectly!');
+ }
+
+ $uncorrectlyUuid = '550j8400-e29b-41d4-a716-446655440000';
+ try {
+ Assert::isUuid($uncorrectlyUuid);
+
+ $this->fail('uuid asserts working uncorrectly!');
+ } catch (WrongArgumentException $e) {}
+
+ }
}
?>
\ No newline at end of file
diff --git a/test/core/PrimitiveUuidIdentifierTest.class.php b/test/core/PrimitiveUuidIdentifierTest.class.php
new file mode 100644
index 0000000000..dac8e2c9f5
--- /dev/null
+++ b/test/core/PrimitiveUuidIdentifierTest.class.php
@@ -0,0 +1,32 @@
+of('TestUuidObject');
+
+ $nullValues = array(null, '');
+ foreach ($nullValues as $value) {
+ $this->assertNull($prm->import(array('name' => $value)));
+ $this->assertNull($prm->importValue($value));
+ }
+
+ $emptyValues = array(0, '0', false, '550j8400-e29b-41d4-a716-446655440000');
+
+ foreach ($emptyValues as $value) {
+ $this->assertFalse($prm->import(array('name' => $value)));
+ $this->assertFalse($prm->importValue($value));
+ }
+ }
+ }
+?>
\ No newline at end of file
diff --git a/test/core/PrimitiveUuidTest.class.php b/test/core/PrimitiveUuidTest.class.php
new file mode 100644
index 0000000000..b51b444099
--- /dev/null
+++ b/test/core/PrimitiveUuidTest.class.php
@@ -0,0 +1,35 @@
+assertNull($prm->importValue($value));
+
+ $falseValues = array('550j8400-e29b-41d4-a716-446655440000', $prm);
+
+ foreach ($falseValues as $value)
+ $this->assertFalse($prm->importValue($value));
+
+ $trueValues = array('550e8400-e29b-41d4-a716-446655440000', '550f8400-e29b-41d4-A716-446155440000');
+
+ foreach ($trueValues as $value)
+ $this->assertTrue($prm->importValue($value));
+ }
+
+ }
+?>
\ No newline at end of file
diff --git a/test/main/Utils/UuidUtilsTest.class.php b/test/main/Utils/UuidUtilsTest.class.php
new file mode 100644
index 0000000000..52e13a51e4
--- /dev/null
+++ b/test/main/Utils/UuidUtilsTest.class.php
@@ -0,0 +1,35 @@
+markTestSkipped('uuid module is not supported, skipped!');
+ else {
+
+ /*
+ * time based uuid
+ */
+ $uuid = UuidUtils::make();
+
+ try{
+ Assert::isUuid($uuid);
+ } catch(WrongArgumentException $e) {
+ $this->fail('UuidUtils::make generate uncorrectly id "'.$uuid.'"');
+ }
+
+ }
+
+ }
+ }
+?>
\ No newline at end of file
diff --git a/test/meta/config.meta.xml b/test/meta/config.meta.xml
index ba98dc7840..89b57bd263 100644
--- a/test/meta/config.meta.xml
+++ b/test/meta/config.meta.xml
@@ -257,4 +257,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/test/misc/DAOTest.class.php b/test/misc/DAOTest.class.php
index e0e2baaf21..787723ebd7 100644
--- a/test/misc/DAOTest.class.php
+++ b/test/misc/DAOTest.class.php
@@ -358,8 +358,18 @@ public function fill($assertions = true)
$this->getListByIdsTest();
$this->getListByIdsTest();
}
+
+ $testUuidObj = TestUuidObject::create()->setName('test-uuid-name');
+ TestUuidObject::dao()->add($testUuidObj);
+
+ $uuid = UuidUtils::make();
+ $testUuidObj2 = TestUuidObject::create()->setId(
+ $uuid
+ )->setName('test-uuid-name2');
+ TestUuidObject::dao()->import($testUuidObj2);
+
}
-
+
public function criteriaResult()
{
$queryResult = Criteria::create(TestCity::dao())->getResult();
@@ -538,6 +548,24 @@ public function testWorkingWithCache()
$this->drop();
}
+
+ public function testUuid()
+ {
+ $this->create();
+
+ foreach (DBTestPool::me()->getPool() as $connector => $db) {
+ DBPool::me()->setDefault($db);
+ $this->fill();
+
+ $this->uuidTest();
+
+ Cache::me()->clean();
+ }
+
+ $this->deletedCount();
+
+ $this->drop();
+ }
/**
* Install hstore
@@ -735,7 +763,7 @@ public function nonIntegerIdentifier()
{
$id = 'non-integer-one';
$binaryData = "\0!bbq!\0";
-
+
$bin =
TestBinaryStuff::create()->
setId($id)->
@@ -1019,5 +1047,50 @@ private function getByEmptyIdTest($id)
// pass
}
}
+
+ private function uuidTest()
+ {
+ $count = TestUuidObject::dao()->getTotalCount();
+ $list = TestUuidObject::dao()->getPlainList();
+
+ $this->assertEquals(2, $count);
+ $this->assertEquals(2, count($list));
+
+ try{
+ Assert::isUuid($list[0]->getId() );
+ } catch(WrongArgumentException $e) {
+ $this->fail('object::id must be uuid, but is not it!');
+ }
+
+ $ids = ArrayUtils::getIdsArray($list);
+
+ unset($list);
+ $list = TestUuidObject::dao()->getListByIds($ids);
+
+ $this->assertEquals(2, count($list) );
+
+ $prm = Primitive::uuidIdentifierList('ids')->of('TestUuidObject');
+ $prm->import(
+ array(
+ 'ids' => $ids,
+ )
+ );
+
+ $this->assertEquals(2, count($prm->getValue() ) );
+ $this->assertEquals($list, $prm->getValue() );
+
+ unset($prm);
+ $firstId = reset($ids);
+
+ $prm = Primitive::uuidIdentifier('id')->of('TestUuidObject');
+ $prm->import(
+ array(
+ 'id'=> $firstId
+ )
+ );
+
+ $this->assertEquals(reset($list), $prm->getValue() );
+
+ }
}
?>
\ No newline at end of file