[prev in list] [next in list] [prev in thread] [next in thread]
List: avro-commits
Subject: svn commit: r1196233 - in /avro/trunk: CHANGES.txt lang/php/lib/avro.php lang/php/lib/avro/datum.php
From: cutting () apache ! org
Date: 2011-11-01 19:32:54
Message-ID: 20111101193255.1A70423889FA () eris ! apache ! org
[Download RAW message or body]
Author: cutting
Date: Tue Nov 1 19:32:54 2011
New Revision: 1196233
URL: http://svn.apache.org/viewvc?rev=1196233&view=rev
Log:
AVRO-821. PHP: Add support for parsing protocols. Contributed by Andy Wick, Saleem \
Shafi and A B.
Added:
avro/trunk/lang/php/lib/avro/protocol.php (with props)
avro/trunk/lang/php/test/ProtocolFileTest.php (with props)
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/php/lib/avro.php
avro/trunk/lang/php/lib/avro/datum.php
avro/trunk/lang/php/lib/avro/schema.php
avro/trunk/lang/php/test/AllTests.php
Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1196233&r1=1196232&r2=1196233&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Tue Nov 1 19:32:54 2011
@@ -4,6 +4,9 @@ Avro 1.6.1 (unreleased)
NEW FEATURES
+ AVRO-821. PHP: Add support for parsing protocols. (Andy Wick,
+ Saleem Shafi and A B via cutting)
+
OPTIMIZATIONS
IMPROVEMENTS
Modified: avro/trunk/lang/php/lib/avro.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/lib/avro.php?rev=1196233&r1=1196232&r2=1196233&view=diff
==============================================================================
--- avro/trunk/lang/php/lib/avro.php (original)
+++ avro/trunk/lang/php/lib/avro.php Tue Nov 1 19:32:54 2011
@@ -192,3 +192,4 @@ require_once('avro/io.php');
require_once('avro/gmp.php');
require_once('avro/datum.php');
require_once('avro/data_file.php');
+require_once('avro/protocol.php');
Modified: avro/trunk/lang/php/lib/avro/datum.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/lib/avro/datum.php?rev=1196233&r1=1196232&r2=1196233&view=diff
==============================================================================
--- avro/trunk/lang/php/lib/avro/datum.php (original)
+++ avro/trunk/lang/php/lib/avro/datum.php Tue Nov 1 19:32:54 2011
@@ -92,7 +92,7 @@ class AvroIODatumWriter
* @param AvroIOBinaryEncoder $encoder
* @returns mixed
*
- * @throws AvrioIOTypeException if $datum is invalid for $writers_schema
+ * @throws AvroIOTypeException if $datum is invalid for $writers_schema
*/
function write_data($writers_schema, $datum, $encoder)
{
Added: avro/trunk/lang/php/lib/avro/protocol.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/lib/avro/protocol.php?rev=1196233&view=auto
==============================================================================
--- avro/trunk/lang/php/lib/avro/protocol.php (added)
+++ avro/trunk/lang/php/lib/avro/protocol.php Tue Nov 1 19:32:54 2011
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @package Avro
+ */
+
+/**
+ * Avro library for protocols
+ * @package Avro
+ */
+class AvroProtocol
+{
+ public $name;
+ public $namespace;
+ public $schemata;
+
+ public static function parse($json)
+ {
+ if (is_null($json))
+ throw new AvroProtocolParseException( "Protocol can't be null");
+
+ $protocol = new AvroProtocol();
+ $protocol->real_parse(json_decode($json, true));
+ return $protocol;
+ }
+
+ function real_parse($avro) {
+ $this->protocol = $avro["protocol"];
+ $this->namespace = $avro["namespace"];
+ $this->schemata = new AvroNamedSchemata();
+ $this->name = $avro["protocol"];
+
+ if (!is_null($avro["types"])) {
+ $types = AvroSchema::real_parse($avro["types"], $this->namespace, \
$this->schemata); + }
+
+ if (!is_null($avro["messages"])) {
+ foreach ($avro["messages"] as $messageName => $messageAvro) {
+ $message = new AvroProtocolMessage($messageName, $messageAvro, $this);
+ $this->messages{$messageName} = $message;
+ }
+ }
+ }
+}
+
+class AvroProtocolMessage
+{
+ /**
+ * @var AvroRecordSchema $request
+ */
+
+ public $request;
+
+ public $response;
+
+ public function __construct($name, $avro, $protocol)
+ {
+ $this->name = $name;
+ $this->request = new AvroRecordSchema(new AvroName($name, null, \
$protocol->namespace), null, $avro{'request'}, $protocol->schemata, \
AvroSchema::REQUEST_SCHEMA); +
+ if (array_key_exists('response', $avro)) {
+ $this->response = $protocol->schemata->schema_by_name(new \
AvroName($avro{'response'}, $protocol->namespace, $protocol->namespace)); + if \
($this->response == null) + $this->response = new \
AvroPrimitiveSchema($avro{'response'}); + }
+ }
+}
+
+class AvroProtocolParseException extends AvroException {};
Propchange: avro/trunk/lang/php/lib/avro/protocol.php
------------------------------------------------------------------------------
svn:eol-style = native
Modified: avro/trunk/lang/php/lib/avro/schema.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/lib/avro/schema.php?rev=1196233&r1=1196232&r2=1196233&view=diff
==============================================================================
--- avro/trunk/lang/php/lib/avro/schema.php (original)
+++ avro/trunk/lang/php/lib/avro/schema.php Tue Nov 1 19:32:54 2011
@@ -443,7 +443,7 @@ class AvroSchema
if (is_array($datum))
{
foreach ($expected_schema->fields() as $field)
- if (!self::is_valid_datum($field->type(), $datum[$field->name()]))
+ if (!array_key_exists($field->name(), $datum) || \
!self::is_valid_datum($field->type(), $datum[$field->name()])) return false;
return true;
}
@@ -685,7 +685,7 @@ class AvroUnionSchema extends AvroSchema
* @var int[] list of indices of named schemas which
* are defined in $schemata
*/
- private $schema_from_schemata_indices;
+ public $schema_from_schemata_indices;
/**
* @param AvroSchema[] $schemas list of schemas in the union
@@ -795,7 +795,8 @@ class AvroNamedSchema extends AvroSchema
throw new AvroSchemaParseException('Schema doc attribute must be a string');
$this->doc = $doc;
- $schemata = $schemata->clone_with_new_schema($this);
+ if (!is_null($schemata))
+ $schemata = $schemata->clone_with_new_schema($this);
}
/**
@@ -986,6 +987,12 @@ class AvroNamedSchemata
$this->schemata = $schemata;
}
+ public function list_schemas() {
+ var_export($this->schemata);
+ foreach($this->schemata as $sch)
+ print('Schema '.$sch->__toString()."\n");
+ }
+
/**
* @param string $fullname
* @returns boolean true if there exists a schema with the given name
@@ -1179,7 +1186,7 @@ class AvroRecordSchema extends AvroNamed
* @returns AvroField[]
* @throws AvroSchemaParseException
*/
- private static function parse_fields($field_data, $default_namespace, &$schemata)
+ static function parse_fields($field_data, $default_namespace, &$schemata)
{
$fields = array();
$field_names = array();
@@ -1247,7 +1254,7 @@ class AvroRecordSchema extends AvroNamed
'Record schema requires a non-empty fields attribute');
if (AvroSchema::REQUEST_SCHEMA == $schema_type)
- $this->type = $schema_type;
+ parent::__construct($schema_type, $name);
else
parent::__construct($schema_type, $name, $doc, $schemata);
Modified: avro/trunk/lang/php/test/AllTests.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/AllTests.php?rev=1196233&r1=1196232&r2=1196233&view=diff
==============================================================================
--- avro/trunk/lang/php/test/AllTests.php (original)
+++ avro/trunk/lang/php/test/AllTests.php Tue Nov 1 19:32:54 2011
@@ -25,6 +25,7 @@ require_once('IODatumReaderTest.php');
require_once('LongEncodingTest.php');
require_once('FloatIntEncodingTest.php');
require_once('DatumIOTest.php');
+require_once('ProtocolFileTest.php');
// InterOpTest tests are run separately.
class AllTests
@@ -40,6 +41,7 @@ class AllTests
$suite->addTestSuite('LongEncodingTest');
$suite->addTestSuite('FloatIntEncodingTest');
$suite->addTestSuite('DatumIOTest');
+ $suite->addTestSuite('ProtocolFileTest');
return $suite;
}
}
Added: avro/trunk/lang/php/test/ProtocolFileTest.php
URL: http://svn.apache.org/viewvc/avro/trunk/lang/php/test/ProtocolFileTest.php?rev=1196233&view=auto
==============================================================================
--- avro/trunk/lang/php/test/ProtocolFileTest.php (added)
+++ avro/trunk/lang/php/test/ProtocolFileTest.php Tue Nov 1 19:32:54 2011
@@ -0,0 +1,353 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+require_once('test_helper.php');
+
+// near-verbatim port of test_protocol.py
+class ProtocolFileTest extends PHPUnit_Framework_TestCase
+{
+ protected function setUp() {
+ }
+
+ public function testParsing() {
+ $cnt=count($this->prot_parseable);
+ for ($i=0; $i<$cnt; $i++) {
+ try {
+ //print($i . " " . ($this->prot_parseable[$i]?"true":"false") . " \n");
+ $prot=AvroProtocol::parse($this->prot_data[$i]);
+ } catch (AvroSchemaParseException $x) {
+ // exception ok if we expected this protocol spec to be unparseable
+ $this->assertEquals(false, $this->prot_parseable[$i]);
+ }
+ }
+ }
+
+ // test data
+ private $prot_parseable=array(true, true, true, true, true, true, false, true, \
true); + private $prot_data = array(
+<<<'DATUM'
+{
+ "namespace": "com.acme",
+ "protocol": "HelloWorld",
+
+ "types": [
+ {"name": "Greeting", "type": "record", "fields": [
+ {"name": "message", "type": "string"}]},
+ {"name": "Curse", "type": "error", "fields": [
+ {"name": "message", "type": "string"}]}
+ ],
+
+ "messages": {
+ "hello": {
+ "request": [{"name": "greeting", "type": "Greeting" }],
+ "response": "Greeting",
+ "errors": ["Curse"]
+ }
+ }
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test",
+ "protocol": "Simple",
+
+ "types": [
+ {"name": "Kind", "type": "enum", "symbols": ["FOO","BAR","BAZ"]},
+
+ {"name": "MD5", "type": "fixed", "size": 16},
+
+ {"name": "TestRecord", "type": "record",
+ "fields": [
+ {"name": "name", "type": "string", "order": "ignore"},
+ {"name": "kind", "type": "Kind", "order": "descending"},
+ {"name": "hash", "type": "MD5"}
+ ]
+ },
+
+ {"name": "TestError", "type": "error", "fields": [
+ {"name": "message", "type": "string"}
+ ]
+ }
+
+ ],
+
+ "messages": {
+
+ "hello": {
+ "request": [{"name": "greeting", "type": "string"}],
+ "response": "string"
+ },
+
+ "echo": {
+ "request": [{"name": "record", "type": "TestRecord"}],
+ "response": "TestRecord"
+ },
+
+ "add": {
+ "request": [{"name": "arg1", "type": "int"}, {"name": "arg2", "type": \
"int"}], + "response": "int"
+ },
+
+ "echoBytes": {
+ "request": [{"name": "data", "type": "bytes"}],
+ "response": "bytes"
+ },
+
+ "error": {
+ "request": [],
+ "response": "null",
+ "errors": ["TestError"]
+ }
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test.namespace",
+ "protocol": "TestNamespace",
+
+ "types": [
+ {"name": "org.apache.avro.test.util.MD5", "type": "fixed", "size": 16},
+ {"name": "TestRecord", "type": "record",
+ "fields": [ {"name": "hash", "type": "org.apache.avro.test.util.MD5"} ]
+ },
+ {"name": "TestError", "namespace": "org.apache.avro.test.errors",
+ "type": "error", "fields": [ {"name": "message", "type": "string"} ]
+ }
+ ],
+
+ "messages": {
+ "echo": {
+ "request": [{"name": "record", "type": "TestRecord"}],
+ "response": "TestRecord"
+ },
+
+ "error": {
+ "request": [],
+ "response": "null",
+ "errors": ["org.apache.avro.test.errors.TestError"]
+ }
+
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test.namespace",
+ "protocol": "TestImplicitNamespace",
+
+ "types": [
+ {"name": "org.apache.avro.test.util.MD5", "type": "fixed", "size": 16},
+ {"name": "ReferencedRecord", "type": "record",
+ "fields": [ {"name": "foo", "type": "string"} ] },
+ {"name": "TestRecord", "type": "record",
+ "fields": [ {"name": "hash", "type": "org.apache.avro.test.util.MD5"},
+ {"name": "unqalified", "type": "ReferencedRecord"} ]
+ },
+ {"name": "TestError",
+ "type": "error", "fields": [ {"name": "message", "type": "string"} ]
+ }
+ ],
+
+ "messages": {
+ "echo": {
+ "request": [{"name": "qualified",
+ "type": "org.apache.avro.test.namespace.TestRecord"}],
+ "response": "TestRecord"
+ },
+
+ "error": {
+ "request": [],
+ "response": "null",
+ "errors": ["org.apache.avro.test.namespace.TestError"]
+ }
+
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test.namespace",
+ "protocol": "TestNamespaceTwo",
+
+ "types": [
+ {"name": "org.apache.avro.test.util.MD5", "type": "fixed", "size": 16},
+ {"name": "ReferencedRecord", "type": "record",
+ "namespace": "org.apache.avro.other.namespace",
+ "fields": [ {"name": "foo", "type": "string"} ] },
+ {"name": "TestRecord", "type": "record",
+ "fields": [ {"name": "hash", "type": "org.apache.avro.test.util.MD5"},
+ {"name": "qualified",
+ "type": "org.apache.avro.other.namespace.ReferencedRecord"}
+ ]
+ },
+ {"name": "TestError",
+ "type": "error", "fields": [ {"name": "message", "type": "string"} ]
+ }
+ ],
+
+ "messages": {
+ "echo": {
+ "request": [{"name": "qualified",
+ "type": "org.apache.avro.test.namespace.TestRecord"}],
+ "response": "TestRecord"
+ },
+
+ "error": {
+ "request": [],
+ "response": "null",
+ "errors": ["org.apache.avro.test.namespace.TestError"]
+ }
+
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test.namespace",
+ "protocol": "TestValidRepeatedName",
+
+ "types": [
+ {"name": "org.apache.avro.test.util.MD5", "type": "fixed", "size": 16},
+ {"name": "ReferencedRecord", "type": "record",
+ "namespace": "org.apache.avro.other.namespace",
+ "fields": [ {"name": "foo", "type": "string"} ] },
+ {"name": "ReferencedRecord", "type": "record",
+ "fields": [ {"name": "bar", "type": "double"} ] },
+ {"name": "TestError",
+ "type": "error", "fields": [ {"name": "message", "type": "string"} ]
+ }
+ ],
+
+ "messages": {
+ "echo": {
+ "request": [{"name": "qualified",
+ "type": "ReferencedRecord"}],
+ "response": "org.apache.avro.other.namespace.ReferencedRecord"
+ },
+
+ "error": {
+ "request": [],
+ "response": "null",
+ "errors": ["org.apache.avro.test.namespace.TestError"]
+ }
+
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test.namespace",
+ "protocol": "TestInvalidRepeatedName",
+
+ "types": [
+ {"name": "org.apache.avro.test.util.MD5", "type": "fixed", "size": 16},
+ {"name": "ReferencedRecord", "type": "record",
+ "fields": [ {"name": "foo", "type": "string"} ] },
+ {"name": "ReferencedRecord", "type": "record",
+ "fields": [ {"name": "bar", "type": "double"} ] },
+ {"name": "TestError",
+ "type": "error", "fields": [ {"name": "message", "type": "string"} ]
+ }
+ ],
+
+ "messages": {
+ "echo": {
+ "request": [{"name": "qualified",
+ "type": "ReferencedRecord"}],
+ "response": "org.apache.avro.other.namespace.ReferencedRecord"
+ },
+
+ "error": {
+ "request": [],
+ "response": "null",
+ "errors": ["org.apache.avro.test.namespace.TestError"]
+ }
+
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{"namespace": "org.apache.avro.test",
+ "protocol": "BulkData",
+
+ "types": [],
+
+ "messages": {
+
+ "read": {
+ "request": [],
+ "response": "bytes"
+ },
+
+ "write": {
+ "request": [ {"name": "data", "type": "bytes"} ],
+ "response": "null"
+ }
+
+ }
+
+}
+DATUM
+,
+<<<'DATUM'
+{
+ "protocol" : "API",
+ "namespace" : "xyz.api",
+ "types" : [ {
+ "type" : "enum",
+ "name" : "Symbology",
+ "namespace" : "xyz.api.product",
+ "symbols" : [ "OPRA", "CUSIP", "ISIN", "SEDOL" ]
+ }, {
+ "type" : "record",
+ "name" : "Symbol",
+ "namespace" : "xyz.api.product",
+ "fields" : [ {
+ "name" : "symbology",
+ "type" : "xyz.api.product.Symbology"
+ }, {
+ "name" : "symbol",
+ "type" : "string"
+ } ]
+ }, {
+ "type" : "record",
+ "name" : "MultiSymbol",
+ "namespace" : "xyz.api.product",
+ "fields" : [ {
+ "name" : "symbols",
+ "type" : {
+ "type" : "map",
+ "values" : "xyz.api.product.Symbol"
+ }
+ } ]
+ } ],
+ "messages" : {
+ }
+}
+DATUM
+ );
+}
Propchange: avro/trunk/lang/php/test/ProtocolFileTest.php
------------------------------------------------------------------------------
svn:eol-style = native
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic