//
// $Id$
//
// Depot library - a Java relational persistence library
// Copyright (C) 2006-2008 Michael Bayne and Pär Winzell
// 
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.samskivert.depot.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;

import com.samskivert.depot.DatabaseException;
import com.samskivert.depot.expression.ValueExp;
import com.samskivert.depot.operator.Conditionals.In;

/**
 * Specializes our PostgreSQL builder for JDBC4.
 */
public class PostgreSQL4Builder extends PostgreSQLBuilder
{
    public class PG4BuildVisitor extends PGBuildVisitor
    {
        @Override public Void visit (In in) {
            // if the In() expression is empty, replace it with a 'false'
            final Comparable<?>[] values = in.getValues();
            if (values.length == 0) {
                new ValueExp(false).accept(this);
                return null;
            }
            in.getColumn().accept(this);
            _builder.append(" = any (?)");
            _bindables.add(new Bindable() {
                public void doBind (Connection conn, PreparedStatement stmt, int argIdx)
                    throws Exception {
                    stmt.setObject(argIdx, conn.createArrayOf(getElementType(values[0]),
                                                              (Object[])values));
                }
                protected String getElementType (Object value) {
                    if (value instanceof Integer) {
                        return "integer";
                    } else if (value instanceof String) {
                        return "varchar";
                    } else {
                        throw new DatabaseException(
                            "Don't know how to make Postgres array for " + value.getClass());
                    }
                }
            });
            return null;
        }

        protected PG4BuildVisitor (DepotTypes types)
        {
            super(types);
        }
    }

    public PostgreSQL4Builder (DepotTypes types)
    {
        super(types);
    }

    @Override
    protected BuildVisitor getBuildVisitor ()
    {
        return new PG4BuildVisitor(_types);
    }
}

@@ -896,16 +896,39 @@
 .impl;%0A%0A
+import java.sql.Array;%0A
 import j
@@ -982,16 +982,84 @@
 tement;%0A
+import java.sql.SQLException;%0A%0Aimport com.samskivert.depot.ByteEnum;
 %0Aimport 
@@ -1944,16 +1944,32 @@
 xception
+%0A               
  %7B%0A     
@@ -2010,13 +2010,8 @@
 dx, 
-conn.
 crea
@@ -2021,37 +2021,24 @@
 rray
-Of(getElementType(
+(conn, 
 values
-%5B0%5D),
+));
 %0A   
@@ -2042,32 +2042,34 @@
                 
+%7D%0A
                 
@@ -2072,57 +2072,110 @@
     
-                              (Object%5B%5D)values));
+protected Array createArray (Connection conn, Object%5B%5D values)%0A                    throws SQLException
 %0A   
@@ -2179,33 +2179,33 @@
                 
-%7D
+%7B
 %0A               
@@ -2209,56 +2209,74 @@
     
-protected String getElementType (Object value) %7B
+    String type;%0A                    Object testValue = values%5B0%5D;
 %0A   
@@ -2292,25 +2292,29 @@
         if (
-v
+testV
 alue instanc
@@ -2352,22 +2352,22 @@
         
-return
+type =
  %22intege
@@ -2397,25 +2397,29 @@
  %7D else if (
-v
+testV
 alue instanc
@@ -2460,25 +2460,459 @@
     
-return %22varchar%22;
+type = %22varchar%22;%0A                    %7D else if (testValue instanceof ByteEnum) %7B%0A                        Byte%5B%5D bytes = new Byte%5Bvalues.length%5D;%0A                        for (int ii = 0; ii %3C bytes.length; ii ++) %7B%0A                            bytes%5Bii%5D = ((ByteEnum) values%5Bii%5D).toByte();%0A                        %7D%0A                        values = bytes;%0A                        type = %22smallint%22;  // tinyint is in the spec, but PG doesn't recognize?
 %0A   
@@ -3065,17 +3065,21 @@
 for %22 + 
-v
+testV
 alue.get
@@ -3102,32 +3102,93 @@
               %7D%0A
+                    return conn.createArrayOf(type, values);%0A
                 

Handle ByteEnums. Not actually tested.