diff --git a/lib/phpcassa/Schema/DataType.php b/lib/phpcassa/Schema/DataType.php index 44cd6a86..abd40fc3 100644 --- a/lib/phpcassa/Schema/DataType.php +++ b/lib/phpcassa/Schema/DataType.php @@ -22,6 +22,9 @@ class DataType const LEXICAL_UUID_TYPE = "LexicalUUIDType"; const UUID_TYPE = "UUIDType"; const DATE_TYPE = "DateType"; + const SET_TYPE = "SetType"; + const LIST_TYPE = "ListType"; + const MAP_TYPE = "MapType"; public static $class_map; @@ -39,7 +42,10 @@ public static function init() { 'UUIDType' => 'phpcassa\Schema\DataType\UUIDType', 'BooleanType' => 'phpcassa\Schema\DataType\BooleanType', 'DateType' => 'phpcassa\Schema\DataType\DateType', - 'Int32Type' => 'phpcassa\Schema\DataType\Int32Type', + 'Int32Type' => 'phpcassa\Schema\DataType\Int32Type', + 'SetType' => 'phpcassa\Schema\DataType\SetType', + 'ListType' => 'phpcassa\Schema\DataType\ListType', + 'MapType' => 'phpcassa\Schema\DataType\MapType' ); } @@ -81,6 +87,22 @@ public static function get_type_for($typestr) { return new CompositeType(self::get_inner_types($typestr)); } else if (strpos($typestr, 'ReversedType') !== false) { return self::get_type_for(self::get_inner_type($typestr)); + } else if (preg_match('/(?.+[^\(])(\(((?.+[^\)]),(?.+[^\)]))\))/is',$typestr,$columnType)){ + $type_name = self::extract_type_name($columnType['type']); + $type_class = self::$class_map[$type_name]; + $keytype_name = self::extract_type_name($columnType['keytype']); + $keytype_class = self::$class_map[$keytype_name]; + $valuetype_name = self::extract_type_name($columnType['valuetype']); + $valuetype_class = self::$class_map[$valuetype_name]; + + return new $type_class(new $keytype_class,new $valuetype_class); + } else if (preg_match('/(?.+[^\(])(\(((?.+[^\)]))\))/is',$typestr,$columnType)){ + $type_name = self::extract_type_name($columnType['type']); + $type_class = self::$class_map[$type_name]; + $valuetype_name = self::extract_type_name($columnType['valuetype']); + $valuetype_class = self::$class_map[$valuetype_name]; + + return new $type_class(new $valuetype_class); } else { $type_name = self::extract_type_name($typestr); $type_class = self::$class_map[$type_name]; diff --git a/lib/phpcassa/Schema/DataType/ListType.php b/lib/phpcassa/Schema/DataType/ListType.php new file mode 100644 index 00000000..df1da3ec --- /dev/null +++ b/lib/phpcassa/Schema/DataType/ListType.php @@ -0,0 +1,55 @@ +valueType = $valueType; + } + + private function readUInt16BE($value,$offset) + { + list(, $int) = unpack('s*', strrev(substr($value,$offset,2))); + return $int; + } + + private function writeUInt16BE($value) + { + return strrev(pack('s*', $value)); + } + + public function pack(Array $data) { + $return = $this->writeUInt16BE(count($data)); + + foreach ($data as $value){ + $packed = $this->valueType->pack($value); + $return.= $this->writeUInt16BE(strlen($packed)); + $return.= $packed; + } + + return $return; + } + + public function unpack($data) { + $offset = 0; + $total = $this->readUInt16BE($data,$offset); + $offset += 2; + + $items = []; + for ($i = 0;$i < $total;$i++){ + $length = $this->readUInt16BE($data,$offset); + $offset += 2; + $items[] = $this->valueType->unpack(substr($data,$offset,$length)); + $offset += $length; + } + + return $items; + } +} diff --git a/lib/phpcassa/Schema/DataType/MapType.php b/lib/phpcassa/Schema/DataType/MapType.php new file mode 100644 index 00000000..29932d14 --- /dev/null +++ b/lib/phpcassa/Schema/DataType/MapType.php @@ -0,0 +1,66 @@ +keyType = $keyType; + $this->valueType = $valueType; + } + + private function readUInt16BE($value,$offset) + { + list(, $int) = unpack('s*', strrev(substr($value,$offset,2))); + return $int; + } + + private function writeUInt16BE($value) + { + return strrev(pack('s*', $value)); + } + + public function pack(Array $data) { + $return = $this->writeUInt16BE(count($data)); + + foreach ($data as $key=>$value){ + $packed = $this->keyType->pack($key); + $return.= $this->writeUInt16BE(strlen($packed)); + $return.= $packed; + $packed = $this->valueType->pack($value); + $return.= $this->writeUInt16BE(strlen($packed)); + $return.= $packed; + } + + return $return; + } + + public function unpack($data) { + $offset = 0; + $total = self::readUInt16BE($data,$offset); + $offset += 2; + + $items = []; + for ($i = 0;$i < $total;$i++){ + $keyLength = self::readUInt16BE($data,$offset); + $offset += 2; + $key = $this->keyType->unpack(substr($data,$offset,$keyLength)); + $offset += $keyLength; + $valueLength = self::readUInt16BE($data,$offset); + $offset += 2; + $value = $this->keyType->unpack(substr($data,$offset,$valueLength)); + $offset += $valueLength; + + $items[$key] = $value; + } + + return $items; + } +} diff --git a/lib/phpcassa/Schema/DataType/SetType.php b/lib/phpcassa/Schema/DataType/SetType.php new file mode 100644 index 00000000..f5e3a4d7 --- /dev/null +++ b/lib/phpcassa/Schema/DataType/SetType.php @@ -0,0 +1,12 @@ +