Re: Hstore PGObject class
От | Petr Jelinek |
---|---|
Тема | Re: Hstore PGObject class |
Дата | |
Msg-id | 4B263A7A.8000903@pjmodos.net обсуждение исходный текст |
Ответ на | Re: Hstore PGObject class (Kris Jurka <books@ejurka.com>) |
Список | pgsql-jdbc |
Kris Jurka napsal(a): >> I recently implemented hstore class for project I work on and I >> decided to share it with list. > > I did the same thing myself pretty recently, but haven't finished > cleaning it up. A quick look at the differences between our versions > are that your getValue call doesn't handle nulls or strings with > backslashes or quotes correctly. The parsing is a little to tricky to > read through quickly, but I based mine on a pretty literal conversion > of the backend C code. Oh right it didn't this version does ;) Parser should work fine. I am not big fan of literal conversions from one language to another. > Also at the moment the driver is still retaining JDK1.4 compatibility > so generics can't be used. Oh didn't know that (like I said I am new to Java), removed those. -- Regards Petr Jelinek (PJMODOS) package org.postgresql.util; import java.io.Serializable; import java.util.Collection; import java.util.Set; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; /** * Class that handles hstore contrib datatype. */ public class PGhstore extends PGobject implements Serializable, Cloneable, Map { private final static long serialVersionUID = 1; private Map hashList; public PGhstore() { setType("hstore"); } public PGhstore(String value) throws java.sql.SQLException { this(); setValue(value); } public PGhstore(Map value) { this(); hashList = new LinkedHashMap(value); } @Override public void setValue(String s) throws java.sql.SQLException { hashList = new LinkedHashMap(); if (s != null) { char[] chars = s.toCharArray(); String key = null; StringBuffer buffer = new StringBuffer(); boolean insideKey = true; boolean insideVal = false; boolean insideString = false; for (int i = 0; i < chars.length; i++) { // escape character that we need to skip if (chars[i] == '\\') { i++; } // white space else if (!insideString && Character.isWhitespace(chars[i])) { continue; } // the => between key and value else if (!insideString && chars[i] == '=') { i++; if (i == chars.length) throw new PSQLException("Unexpected end of string", PSQLState.DATA_ERROR); if (!insideKey || chars[i] != '>') throw new PSQLException("Syntax error at position "+i, PSQLState.DATA_ERROR); insideKey = false; insideVal = true; key = buffer.toString(); buffer.setLength(0); continue; } // quote, item separator or end of string else if (chars[i] == '"' || (!insideString && chars[i] == ',') || i == chars.length - 1) { if (chars[i] == '"') { insideString = !insideString; if (i != chars.length - 1) continue; } else if (chars[i] != ',' && buffer != null) { buffer.append(chars[i]); } String b = (buffer == null) ? null : buffer.toString(); // end of element, add it to list if (b != null && (b.length() > 0 || insideVal)) { hashList.put(key, b.equalsIgnoreCase("NULL") ? null : b); } insideKey = true; insideVal = false; buffer = new StringBuffer(); continue; } if (buffer != null) buffer.append(chars[i]); } } } @Override public String getValue() { if (hashList == null) return null; Iterator iter = hashList.entrySet().iterator(); if (!iter.hasNext()) return null; Entry e = (Entry)iter.next(); StringBuffer buffer = new StringBuffer(); appendEntry(buffer, e); while (iter.hasNext()) { e = (Entry)iter.next(); buffer.append(','); appendEntry(buffer, e); } return buffer.toString(); } private void appendEntry(StringBuffer buf, Entry e) { appendValue(buf, e.getKey(), true); buf.append("=>"); appendValue(buf, e.getValue(), false); } private void appendValue(StringBuffer buf, Object v, boolean isKey) { if (v == null) { if (isKey) buf.append("\"NULL\""); else buf.append("NULL"); return; } String s = v.toString(); buf.append('"'); for (int i=0; i<s.length(); i++) { char c = s.charAt(i); if (c == '"' || c == '\\') buf.append('\\'); buf.append(c); } buf.append('"'); } public Collection values() { return hashList.values(); } public int size() { return hashList.size(); } public Object remove(Object key) { return hashList.remove(key); } public void putAll(Map m) { hashList.putAll(m); } public Object put(Object key, Object value) { return hashList.put(key, value); } public Set keySet() { return hashList.keySet(); } public boolean isEmpty() { return hashList.isEmpty(); } public Set entrySet() { return hashList.entrySet(); } public boolean containsKey(Object key) { return hashList.containsKey(key); } public Object get(Object key) { return hashList.get(key); } public boolean containsValue(Object value) { return hashList.containsValue(value); } public void clear() { hashList.clear(); } }
В списке pgsql-jdbc по дате отправления: