diff --git a/lang/c++/api/CustomAttributes.hh b/lang/c++/api/CustomAttributes.hh index 2bd572c57fc..adad6f6de08 100644 --- a/lang/c++/api/CustomAttributes.hh +++ b/lang/c++/api/CustomAttributes.hh @@ -19,6 +19,7 @@ #ifndef avro_CustomAttributes_hh__ #define avro_CustomAttributes_hh__ +#include #include #include #include @@ -33,7 +34,7 @@ class AVRO_DECL CustomAttributes { public: // Retrieves the custom attribute json entity for that attributeName, returns an // null if the attribute doesn't exist. - std::string getAttribute(const std::string &name) const; + boost::optional getAttribute(const std::string &name) const; // Adds a custom attribute. If the attribute already exists, throw an exception. void addAttribute(const std::string &name, const std::string &value); diff --git a/lang/c++/impl/CustomAttributes.cc b/lang/c++/impl/CustomAttributes.cc index bb564385697..1186d9e26ad 100644 --- a/lang/c++/impl/CustomAttributes.cc +++ b/lang/c++/impl/CustomAttributes.cc @@ -23,13 +23,15 @@ namespace avro { -std::string CustomAttributes::getAttribute(const std::string &name) const { +boost::optional CustomAttributes::getAttribute(const std::string &name) const { + boost::optional result; std::map::const_iterator iter = attributes_.find(name); if (iter == attributes_.end()) { - return NULL; + return result; } - return iter->second; + result = iter->second; + return result; } void CustomAttributes::addAttribute(const std::string& name, diff --git a/lang/c++/test/unittest.cc b/lang/c++/test/unittest.cc index 2a5c51786dc..3ed93106861 100644 --- a/lang/c++/test/unittest.cc +++ b/lang/c++/test/unittest.cc @@ -442,7 +442,12 @@ struct TestSchema { concepts::MultiAttribute customAttributes; CustomAttributes cf; - cf.addAttribute("extra field", std::string("1")); + cf.addAttribute("stringField", std::string("\\\"field value with \\\"double quotes\\\"\\\"")); + cf.addAttribute("booleanField", std::string("true")); + cf.addAttribute("numberField", std::string("1.23")); + cf.addAttribute("nullField", std::string("null")); + cf.addAttribute("arrayField", std::string("[1]")); + cf.addAttribute("mapField", std::string("{\\\"key1\\\":\\\"value1\\\", \\\"key2\\\":\\\"value2\\\"}")); fieldNames.add("f1"); fieldValues.add(NodePtr( new NodePrimitive(Type::AVRO_LONG))); customAttributes.add(cf); @@ -452,7 +457,14 @@ struct TestSchema { customAttributes); std::string expectedJsonWithCustomAttribute = "{\"type\": \"record\", \"name\": \"Test\",\"fields\": " - "[{\"name\": \"f1\", \"type\": \"long\",\"extra field\": \"1\"}]}"; + "[{\"name\": \"f1\", \"type\": \"long\", " + "\"arrayField\": \"[1]\", " + "\"booleanField\": \"true\", " + "\"mapField\": \"{\\\"key1\\\":\\\"value1\\\", \\\"key2\\\":\\\"value2\\\"}\", " + "\"nullField\": \"null\", " + "\"numberField\": \"1.23\", " + "\"stringField\": \"\\\"field value with \\\"double quotes\\\"\\\"\"" + "}]}"; testNodeRecord(nodeRecordWithCustomAttribute, expectedJsonWithCustomAttribute); } @@ -467,8 +479,6 @@ struct TestSchema { concepts::MultiAttribute fieldValues; std::vector defaultValues; - CustomAttributes cf; - cf.addAttribute("extra field", std::string("1")); fieldNames.add("f1"); fieldValues.add(NodePtr( new NodePrimitive(Type::AVRO_LONG))); @@ -481,6 +491,15 @@ struct TestSchema { expectedJsonWithoutCustomAttribute); } + void checkCustomAttributes_getAttribute() + { + CustomAttributes cf; + cf.addAttribute("field1", std::string("1")); + + BOOST_CHECK_EQUAL(std::string("1"), *cf.getAttribute("field1")); + BOOST_CHECK_EQUAL(false, cf.getAttribute("not_existing").is_initialized()); + } + void test() { std::cout << "Before\n"; schema_.toJson(std::cout); @@ -505,6 +524,7 @@ struct TestSchema { checkNodeRecordWithoutCustomAttribute(); checkNodeRecordWithCustomAttribute(); + checkCustomAttributes_getAttribute(); } ValidSchema schema_;