Skip to content

Commit

Permalink
Upgraded binary protocol to version 15
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonTerekhov committed Sep 9, 2013
1 parent 03cdf63 commit 00e4893
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 29 deletions.
2 changes: 1 addition & 1 deletion OrientDB/OrientDB.php
Expand Up @@ -75,7 +75,7 @@ class OrientDB
* Client protocol version
* @var int
*/
public $clientVersion = 14;
public $clientVersion = 15;

/**
* Server's protocol version.
Expand Down
4 changes: 2 additions & 2 deletions OrientDB/OrientDBRecord.php
Expand Up @@ -2,7 +2,7 @@

/**
* @author Anton Terekhov <anton@netmonsters.ru>
* @copyright Copyright Anton Terekhov, NetMonsters LLC, 2011-2012
* @copyright Copyright Anton Terekhov, NetMonsters LLC, 2011-2013
* @license https://github.com/AntonTerekhov/OrientDB-PHP/blob/master/LICENSE
* @link https://github.com/AntonTerekhov/OrientDB-PHP
* @package OrientDB-PHP
Expand Down Expand Up @@ -322,7 +322,7 @@ public function next()
/**
* Return the key of the current element
* @link http://php.net/manual/en/iterator.key.php
* @return integer scalar on success
* @return int scalar on success
* 0 on failure.
*/
public function key()
Expand Down
100 changes: 78 additions & 22 deletions OrientDB/OrientDBRecordDecoder.php
Expand Up @@ -182,22 +182,32 @@ class OrientDBRecordDecoder
const CCODE_CLOSE_PARENTHESES = 0x29;

/**
* [
* [ Set start
*/
const CCODE_OPEN_ARROW = 0x3C;

/**
* ] Set end
*/
const CCODE_CLOSE_ARROW = 0x3E;

/**
* [ List start
*/
const CCODE_OPEN_SQUARE = 0x5B;

/**
* ]
* ] List end
*/
const CCODE_CLOSE_SQUARE = 0x5D;

/**
* {
* { Map start
*/
const CCODE_OPEN_CURLY = 0x7B;

/**
* }
* } Map end
*/
const CCODE_CLOSE_CURLY = 0x7D;

Expand Down Expand Up @@ -303,12 +313,12 @@ class OrientDBRecordDecoder
/**
* Start of collection
*/
const TTYPE_COLLECTION_START = 5;
const TTYPE_SET_START = 5;

/**
* End of collection
*/
const TTYPE_COLLECTION_END = 6;
const TTYPE_SET_END = 6;

/**
* Link to recordID
Expand Down Expand Up @@ -345,6 +355,16 @@ class OrientDBRecordDecoder
*/
const TTYPE_EMBEDDED = 13;

/**
* Start of list
*/
const TTYPE_LIST_START = 14;

/**
* End of list
*/
const TTYPE_LIST_END = 15;

public function __construct($content)
{
$this->content = $content;
Expand All @@ -363,8 +383,10 @@ protected function decode()
$this->data = new StdClass();
// initial state
$this->state = self::STATE_GUESS;
// is parsing collection
$isCollection = false;
// is parsing set
$isSet = false;
// is parsing list
$isList = false;
// is parsing a map
$isMap = false;
// is escape symbol
Expand Down Expand Up @@ -470,21 +492,37 @@ protected function decode()
// add hash to value
$this->buffer = $char;
$this->i++;
} elseif ($cCode === self::CCODE_OPEN_ARROW) {
// < found, state is still value
$this->state = self::STATE_VALUE;
// token type is set start
$this->stackPush(self::TTYPE_SET_START);
// started set
$isSet = true;
$this->i++;
} elseif ($cCode === self::CCODE_CLOSE_ARROW) {
// > found,
$this->state = self::STATE_COMMA;
// token type is set end
$this->stackPush(self::TTYPE_SET_END);
// stopped set
$isSet = false;
$this->i++;
} elseif ($cCode === self::CCODE_OPEN_SQUARE) {
// [ found, state is still value
$this->state = self::STATE_VALUE;
// token type is collection start
$this->stackPush(self::TTYPE_COLLECTION_START);
// started collection
$isCollection = true;
// token type is list start
$this->stackPush(self::TTYPE_LIST_START);
// started list
$isList = true;
$this->i++;
} elseif ($cCode === self::CCODE_CLOSE_SQUARE) {
// ] found,
$this->state = self::STATE_COMMA;
// token type is collection end
$this->stackPush(self::TTYPE_COLLECTION_END);
// stopped collection
$isCollection = false;
$this->stackPush(self::TTYPE_LIST_END);
// stopped list
$isList = false;
$this->i++;
} elseif ($cCode === self::CCODE_OPEN_CURLY) {
// found { switch state to name
Expand Down Expand Up @@ -551,7 +589,9 @@ protected function decode()
case self::STATE_COMMA:
if ($cCode === self::CCODE_COMMA) {
// Found a comma - switch to
if ($isCollection) {
if ($isSet) {
$this->state = self::STATE_VALUE;
} elseif ($isList) {
$this->state = self::STATE_VALUE;
} elseif ($isMap) {
$this->state = self::STATE_KEY;
Expand Down Expand Up @@ -698,7 +738,8 @@ protected function decode()
case false:
case self::TTYPE_NAME:
case self::TTYPE_KEY:
case self::TTYPE_COLLECTION_START:
case self::TTYPE_SET_START:
case self::TTYPE_LIST_START:
case self::TTYPE_MAP_START:
// some speed up
break;
Expand All @@ -713,30 +754,44 @@ protected function decode()
case self::TTYPE_NUMBER:
case self::TTYPE_BOOLEAN:
case self::TTYPE_EMBEDDED:
if (!$isCollection && !$isMap) {
if (!$isSet && !$isMap && !$isList) {
list (, $value) = $this->stackPop();
list (, $name) = $this->stackPop();
$this->data->$name = $value;
}
break;

case self::TTYPE_NULL:
if (!$isCollection && !$isMap) {
if (!$isSet && !$isMap && !$isList) {
$this->stackPop();
list (, $name) = $this->stackPop();
$this->data->$name = null;
}
break;

case self::TTYPE_COLLECTION_END:
case self::TTYPE_SET_END:
$values = array();
do {
list ($searchToken, $value) = $this->stackPop();

if ($searchToken !== self::TTYPE_SET_START && $searchToken !== self::TTYPE_SET_END) {
$values[] = $value;
}
} while ($searchToken !== self::TTYPE_SET_START);
list (, $name) = $this->stackPop();
$values = array_reverse($values);
$this->data->$name = $values;
break;

case self::TTYPE_LIST_END:
$values = array();
do {
list ($searchToken, $value) = $this->stackPop();

if ($searchToken !== self::TTYPE_COLLECTION_START && $searchToken !== self::TTYPE_COLLECTION_END) {
if ($searchToken !== self::TTYPE_LIST_START && $searchToken !== self::TTYPE_LIST_END) {
$values[] = $value;
}
} while ($searchToken !== self::TTYPE_COLLECTION_START);
} while ($searchToken !== self::TTYPE_LIST_START);
list (, $name) = $this->stackPop();
$values = array_reverse($values);
$this->data->$name = $values;
Expand Down Expand Up @@ -819,5 +874,6 @@ protected function stackGetLastKey()
if ($depth !== false) {
return $this->stackTV[$depth];
}
return null;
}
}
6 changes: 4 additions & 2 deletions OrientDB/OrientDBRecordEncoder.php
Expand Up @@ -2,7 +2,7 @@

/**
* @author Anton Terekhov <anton@netmonsters.ru>
* @copyright Copyright Anton Terekhov, NetMonsters LLC, 2011-2012
* @copyright Copyright Anton Terekhov, NetMonsters LLC, 2011-2013
* @license https://github.com/AntonTerekhov/OrientDB-PHP/blob/master/LICENSE
* @link https://github.com/AntonTerekhov/OrientDB-PHP
* @package OrientDB-PHP
Expand Down Expand Up @@ -114,9 +114,11 @@ protected function process($data, $isAssoc = true, $isArray = false)
case 'array':
$arrayAssoc = self::isAssoc($value);
if ($arrayAssoc === true) {
// This is assoc array, using map
$boundStart = chr(OrientDBRecordDecoder::CCODE_OPEN_CURLY);
$boundEnd = chr(OrientDBRecordDecoder::CCODE_CLOSE_CURLY);
} elseif ($arrayAssoc === false) {
} else {
// Array will always be encoded as a set, as 1) Orient itself converts set to list (and vice-versa too) 2) PHP lacks build-in set type
$boundStart = chr(OrientDBRecordDecoder::CCODE_OPEN_SQUARE);
$boundEnd = chr(OrientDBRecordDecoder::CCODE_CLOSE_SQUARE);
}
Expand Down
23 changes: 23 additions & 0 deletions Tests/OrientDBRecordTest.php
Expand Up @@ -741,4 +741,27 @@ public function testRecordResetDataWithString()
$this->assertNull($record->content);
$this->assertSame($record->data->getKeys(), array());
}

public function testParseRecordContentSetAndList()
{
$content = 'JavaComplexTestClass@children:{"first":#24:4,"The Observer":#24:22},name:"Silvester",list:[#24:0,#24:1,#24:2,#24:3],enumList:["ENUM1","ENUM2"],enumSet:<"ENUM1","ENUM3">,enumMap:{"2":"ENUM3","1":"ENUM2"}';

$record = new OrientDBRecord();
$record->content = $content;
$record->parse();

$this->assertSame('JavaComplexTestClass', $record->className);
$this->assertInternalType('array', $record->data->children);
$this->assertCount(2, $record->data->children);
$this->assertSame('Silvester', $record->data->name);
$this->assertInternalType('array', $record->data->list);
$this->assertCount(4, $record->data->list);
$this->assertInternalType('array', $record->data->enumList);
$this->assertCount(2, $record->data->enumList);
$this->assertInternalType('array', $record->data->enumSet);
$this->assertCount(2, $record->data->enumSet);
$this->assertInternalType('array', $record->data->enumMap);
$this->assertCount(2, $record->data->enumMap);
$this->assertEquals(array('2' => 'ENUM3', '1' => 'ENUM2'), $record->data->enumMap);
}
}
4 changes: 2 additions & 2 deletions readme.markdown
Expand Up @@ -7,12 +7,12 @@ Current status is: *Beta*. (Meaning specs can be changed slightly. However, driv

Code is licensed under New BSD License and provided "as is". For complete license information see file `LICENSE`.

Current OrientDB version to work with is: `1.4.0-RELEASE` (2013-01-29) (revision [9719cea](https://github.com/nuvolabase/orientdb/commit/9719cea)).
Current OrientDB version to work with is: `1.5.0-RELEASE` (2013-07-30) (revision [4d28095](https://github.com/nuvolabase/orientdb/commit/4d28095)).
It can be downloaded from OrientDB's [Wiki Downloads page](https://github.com/nuvolabase/orientdb/wiki/Download).

Code compatible to previous binary releases of OrientDB can be found in repository's tags or in [Downloads](https://github.com/AntonTerekhov/OrientDB-PHP/archives/master) section.

Current protocol version implemented: **14**
Current protocol version implemented: **15**

## Requirements ##

Expand Down

0 comments on commit 00e4893

Please sign in to comment.