diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java b/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java index 12f5825..8d62d63 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java +++ b/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java @@ -18,17 +18,29 @@ public class HstoreParser extends PGobject implements Iterable asMap() { @@ -36,7 +48,7 @@ public Map asMap() { try { for (final HStoreIterator iterator = new HStoreIterator(); iterator.hasNext(); ) { final HStoreEntry entry = iterator.rawNext(); - r.put(entry.key, entry.value); + r.put(replaceEscapePlaceholders(entry.key), replaceEscapePlaceholders(entry.value)); } } catch (HstoreParseException e) { throw new IllegalStateException(e); @@ -44,6 +56,12 @@ public Map asMap() { return r; } + private String replaceEscapePlaceholders(String text) { + return text == null ? null : text + .replace(BACKSLASH_PLACEHOLDER, BACKSLASH) + .replace(DOUBLE_QUOTE_PLACEHOLDER, DOUBLE_QUOTE); + } + private static class HStoreEntry implements Entry { private String key; private String value; diff --git a/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreParserSpec.groovy b/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreParserSpec.groovy new file mode 100644 index 0000000..6705cf8 --- /dev/null +++ b/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreParserSpec.groovy @@ -0,0 +1,64 @@ +package net.kaleidos.hibernate.usertype + +import spock.lang.Specification +import spock.lang.Unroll + +class HstoreParserSpec extends Specification { + @Unroll + void "AsMap with value populated by constructor"() { + expect: + HstoreParser parser = new HstoreParser(input) + def map = parser.asMap() + map[expected_key] == expected_value + + where: + example << escapedCharactersExamples() + input = example.input + expected_key = example.expected_key + expected_value = example.expected_value + } + + @Unroll + void "AsMap with value populated by setValue"() { + expect: + HstoreParser parser = new HstoreParser('') + parser.setValue(input) + def map = parser.asMap() + map[expected_key] == expected_value + + where: + example << escapedCharactersExamples() + input = example.input + expected_key = example.expected_key + expected_value = example.expected_value + } + + def escapedCharactersExamples() { + return [ + // insert into test(hs) values(hstore(ARRAY['key','"value"'])); + [ + input : /"key"=>"\"value\""/, + expected_key : /key/, + expected_value: /"value"/ + ], + // insert into test(hs) values(hstore(ARRAY['\key','value'])); + [ + input : /"\\key"=>"value"/, + expected_key : /\key/, + expected_value: /value/ + ], + // insert into test(hs) values(hstore(ARRAY['''key'''','value'])) + [ + input : /"'key'"=>"value"/, + expected_key : /'key'/, + expected_value: /value/ + ], + // nested hstore + [ + input : /"key"=>"\"nested_key\"=>\"1.1\""/, + expected_key : /key/, + expected_value: /"nested_key"=>"1.1"/ + ] + ] + } +}