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 по дате отправления:

Предыдущее
От: Kris Jurka
Дата:
Сообщение: Re: Hstore PGObject class
Следующее
От: Andreas
Дата:
Сообщение: Re: keeping Connection alive