[libpostgresql-jdbc-java] 31/93: add uuid array support

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Mon Jan 9 10:18:49 UTC 2017


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to annotated tag REL9_3_1102
in repository libpostgresql-jdbc-java.

commit e56d09d69245825c8ed30d4909f25cd3b68ee93b
Author: tminglei <tmlneu at gmail.com>
Date:   Sat Aug 24 14:14:31 2013 +0800

    add uuid array support
---
 org/postgresql/jdbc2/AbstractJdbc2Array.java       | 112 +++++++++++++--------
 org/postgresql/jdbc2/ArrayElementBuilder.java      |  34 +++++++
 .../jdbc2/ArrayElementBuilderFactory.java          |  20 ++++
 org/postgresql/test/jdbc4/ArrayTest.java           |  45 +++++++++
 4 files changed, 168 insertions(+), 43 deletions(-)

diff --git a/org/postgresql/jdbc2/AbstractJdbc2Array.java b/org/postgresql/jdbc2/AbstractJdbc2Array.java
index 23bc4f7..5d83a95 100644
--- a/org/postgresql/jdbc2/AbstractJdbc2Array.java
+++ b/org/postgresql/jdbc2/AbstractJdbc2Array.java
@@ -19,6 +19,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Types;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -212,26 +213,31 @@ public abstract class AbstractJdbc2Array
                     continue;
                 }
                 switch (elementOid) {
-                case Oid.INT2:
-                    arr[i] = new Short(ByteConverter.int2(fieldBytes, pos));
-                    break;
-                case Oid.INT4:
-                    arr[i] = new Integer(ByteConverter.int4(fieldBytes, pos));
-                    break;
-                case Oid.INT8:
-                    arr[i] = new Long(ByteConverter.int8(fieldBytes, pos));
-                    break;
-                case Oid.FLOAT4:
-                    arr[i] = new Float(ByteConverter.float4(fieldBytes, pos));
-                    break;
-                case Oid.FLOAT8:
-                    arr[i] = new Double(ByteConverter.float8(fieldBytes, pos));
-                    break;
-                case Oid.TEXT:
-                case Oid.VARCHAR:
-                    Encoding encoding = connection.getEncoding();
-                    arr[i] = encoding.decode(fieldBytes, pos, len);
-                    break;
+                    case Oid.INT2:
+                        arr[i] = new Short(ByteConverter.int2(fieldBytes, pos));
+                        break;
+                    case Oid.INT4:
+                        arr[i] = new Integer(ByteConverter.int4(fieldBytes, pos));
+                        break;
+                    case Oid.INT8:
+                        arr[i] = new Long(ByteConverter.int8(fieldBytes, pos));
+                        break;
+                    case Oid.FLOAT4:
+                        arr[i] = new Float(ByteConverter.float4(fieldBytes, pos));
+                        break;
+                    case Oid.FLOAT8:
+                        arr[i] = new Double(ByteConverter.float8(fieldBytes, pos));
+                        break;
+                    case Oid.TEXT:
+                    case Oid.VARCHAR:
+                        Encoding encoding = connection.getEncoding();
+                        arr[i] = encoding.decode(fieldBytes, pos, len);
+                        break;
+                    default:
+                        ArrayElementBuilder arrElemBuilder = ArrayElementBuilderFactory.getArrayElementBuilder(elementOid);
+                        if (arrElemBuilder != null) {
+                            arr[i] = arrElemBuilder.buildElement(fieldBytes, pos, len);
+                        }
                 }
                 pos += len;
             }
@@ -243,7 +249,7 @@ public abstract class AbstractJdbc2Array
         return pos;
     }
 
-    
+
     private ResultSet readBinaryResultSet(int index, int count) throws SQLException {
         int dimensions = ByteConverter.int4(fieldBytes, 0);
         //int flags = ByteConverter.int4(fieldBytes, 4); // bit 0: 0=no-nulls, 1=has-nulls
@@ -337,22 +343,27 @@ public abstract class AbstractJdbc2Array
     private Class elementOidToClass(int oid)
             throws SQLException {
         switch (oid) {
-        case Oid.INT2:
-            return Short.class;
-        case Oid.INT4:
-            return Integer.class;
-        case Oid.INT8:
-            return Long.class;
-        case Oid.FLOAT4:
-            return Float.class;
-        case Oid.FLOAT8:
-            return Double.class;
-        case Oid.TEXT:
-        case Oid.VARCHAR:
-            return String.class;
-        default:
-            throw org.postgresql.Driver.notImplemented(this.getClass(),
-                    "readBinaryArray(data,oid)");
+            case Oid.INT2:
+                return Short.class;
+            case Oid.INT4:
+                return Integer.class;
+            case Oid.INT8:
+                return Long.class;
+            case Oid.FLOAT4:
+                return Float.class;
+            case Oid.FLOAT8:
+                return Double.class;
+            case Oid.TEXT:
+            case Oid.VARCHAR:
+                return String.class;
+            default:
+                ArrayElementBuilder arrElemBuilder = ArrayElementBuilderFactory.getArrayElementBuilder(oid);
+                if (arrElemBuilder != null) {
+                    return arrElemBuilder.getElementClass();
+                }
+
+                throw org.postgresql.Driver.notImplemented(this.getClass(),
+                        "readBinaryArray(data,oid)");
         }
     }
 
@@ -411,7 +422,7 @@ public abstract class AbstractJdbc2Array
                 if (chars[i] == '\\')
                     i++;
 
-                // subarray start
+                    // subarray start
                 else if (!insideString && chars[i] == '{')
                 {
                     if (dims.size() == 0)
@@ -536,7 +547,7 @@ public abstract class AbstractJdbc2Array
 
             if (dims > 1 || useObjects)
             {
-ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Boolean.class : boolean.class, dimsLength) : new Boolean[count]);
+                ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Boolean.class : boolean.class, dimsLength) : new Boolean[count]);
             }
             else
             {
@@ -566,7 +577,7 @@ ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects
 
             if (dims > 1 || useObjects)
             {
-ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Integer.class : int.class, dimsLength) : new Integer[count]);
+                ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Integer.class : int.class, dimsLength) : new Integer[count]);
             }
             else
             {
@@ -595,7 +606,7 @@ ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects
 
             if (dims > 1 || useObjects)
             {
-ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Long.class : long.class, dimsLength) : new Long[count]);
+                ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Long.class : long.class, dimsLength) : new Long[count]);
             }
 
             else
@@ -637,7 +648,7 @@ ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects
 
             if (dims > 1 || useObjects)
             {
-ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Float.class : float.class, dimsLength) : new Float[count]);
+                ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Float.class : float.class, dimsLength) : new Float[count]);
             }
             else
             {
@@ -666,7 +677,7 @@ ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects
 
             if (dims > 1 || useObjects)
             {
-ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Double.class : double.class, dimsLength) : new Double[count]);
+                ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects ? Double.class : double.class, dimsLength) : new Double[count]);
             }
             else
             {
@@ -736,6 +747,21 @@ ret = oa = (dims > 1 ? (Object[]) java.lang.reflect.Array.newInstance(useObjects
             }
         }
 
+        else if (ArrayElementBuilderFactory.getArrayElementBuilder(oid) != null) {
+            ArrayElementBuilder arrElemBuilder = ArrayElementBuilderFactory.getArrayElementBuilder(oid);
+
+            Object[] oa = null;
+            ret = oa = (dims > 1) ? (Object[]) java.lang.reflect.Array.newInstance(arrElemBuilder.getElementClass(), dimsLength)
+                    : (Object[]) java.lang.reflect.Array.newInstance(arrElemBuilder.getElementClass(), count) ;
+
+            for (; count > 0; count--)
+            {
+                Object v = input.get(index++);
+                oa[length++] = (dims > 1 && v != null) ? buildArray((PgArrayList) v, 0, -1)
+                        : (v == null ? null : arrElemBuilder.buildElement((String) v));
+            }
+        }
+
         // other datatypes not currently supported
         else
         {
diff --git a/org/postgresql/jdbc2/ArrayElementBuilder.java b/org/postgresql/jdbc2/ArrayElementBuilder.java
new file mode 100644
index 0000000..04a6893
--- /dev/null
+++ b/org/postgresql/jdbc2/ArrayElementBuilder.java
@@ -0,0 +1,34 @@
+package org.postgresql.jdbc2;
+
+/**
+ * Implement this interface and register the its instance to ArrayElementBuilderFactory,
+ * to let Postgres driver to support more array type
+ *
+ * @author Minglei Tu
+ */
+public interface ArrayElementBuilder {
+    /**
+     * get array base type
+     *
+     * @return
+     */
+    Class getElementClass();
+
+    /**
+     * build a array element from its binary bytes
+     *
+     * @param bytes
+     * @param pos
+     * @param len
+     * @return
+     */
+    Object buildElement(byte[] bytes, int pos, int len);
+
+    /**
+     * build an array element from its literal string
+     *
+     * @param literal
+     * @return
+     */
+    Object buildElement(String literal);
+}
diff --git a/org/postgresql/jdbc2/ArrayElementBuilderFactory.java b/org/postgresql/jdbc2/ArrayElementBuilderFactory.java
new file mode 100644
index 0000000..47f60a1
--- /dev/null
+++ b/org/postgresql/jdbc2/ArrayElementBuilderFactory.java
@@ -0,0 +1,20 @@
+package org.postgresql.jdbc2;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ArrayElementBuilderFactory {
+    private static Map builderMap = new HashMap();
+
+    public static void setArrayElementBuilder(int oid, ArrayElementBuilder builder) {
+        if (builder == null) {
+            builderMap.remove(new Integer(oid));
+        } else {
+            builderMap.put(new Integer(oid), builder);
+        }
+    }
+
+    public static ArrayElementBuilder getArrayElementBuilder(int oid) {
+        return (ArrayElementBuilder) builderMap.get(new Integer(oid));
+    }
+}
diff --git a/org/postgresql/test/jdbc4/ArrayTest.java b/org/postgresql/test/jdbc4/ArrayTest.java
index ae23d5c..827df87 100644
--- a/org/postgresql/test/jdbc4/ArrayTest.java
+++ b/org/postgresql/test/jdbc4/ArrayTest.java
@@ -8,6 +8,8 @@
 package org.postgresql.test.jdbc4;
 
 import java.sql.*;
+import java.util.UUID;
+
 import junit.framework.TestCase;
 import org.postgresql.test.TestUtil;
 import org.postgresql.geometric.PGbox;
@@ -168,6 +170,49 @@ public class ArrayTest extends TestCase {
         assertEquals(77, out[1][1], 0.00001);
     }
 
+    public void testUUIDArray() throws SQLException {
+        UUID uuid1 = UUID.randomUUID();
+        UUID uuid2 = UUID.randomUUID();
+        UUID uuid3 = UUID.randomUUID();
+
+        // insert a uuid array, and check
+        PreparedStatement pstmt1 = _conn.prepareStatement("INSERT INTO arrtest(uuidarr) VALUES (?)");
+        pstmt1.setArray(1, _conn.createArrayOf("uuid", new UUID[]{ uuid1, uuid2, uuid3 }));
+        pstmt1.executeUpdate();
+
+        PreparedStatement pstmt2 = _conn.prepareStatement("SELECT uuidarr FROM arrtest WHERE uuidarr @> ?");
+        pstmt2.setObject(1, _conn.createArrayOf("uuid", new UUID[]{ uuid1 }), Types.OTHER);
+        ResultSet rs = pstmt2.executeQuery();
+        assertTrue(rs.next());
+        Array arr = rs.getArray(1);
+        UUID out[] = (UUID [])arr.getArray();
+
+        assertEquals(3, out.length);
+        assertEquals(uuid1, out[0]);
+        assertEquals(uuid2, out[1]);
+        assertEquals(uuid3, out[2]);
+
+        // concatenate a uuid, and check
+        UUID uuid4 = UUID.randomUUID();
+        PreparedStatement pstmt3 = _conn.prepareStatement("UPDATE arrtest SET uuidarr = uuidarr || ? WHERE uuidarr @> ?");
+        pstmt3.setObject(1, uuid4, Types.OTHER);
+        pstmt3.setArray(2, _conn.createArrayOf("uuid", new UUID[]{ uuid1 }));
+        pstmt3.executeUpdate();
+
+        //--
+        pstmt2.setObject(1, _conn.createArrayOf("uuid", new UUID[]{ uuid4 }), Types.OTHER);
+        rs = pstmt2.executeQuery();
+        assertTrue(rs.next());
+        arr = rs.getArray(1);
+        out = (UUID [])arr.getArray();
+
+        assertEquals(4, out.length);
+        assertEquals(uuid1, out[0]);
+        assertEquals(uuid2, out[1]);
+        assertEquals(uuid3, out[2]);
+        assertEquals(uuid4, out[3]);
+    }
+
     public void testSetObjectFromJavaArray() throws SQLException {
         String[] strArray = new String[]{"a","b","c"};
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git



More information about the pkg-java-commits mailing list