/* * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, * Version 1.0, and under the Eclipse Public License, Version 1.0 * (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.value; import java.lang.reflect.Array; import java.sql.PreparedStatement; import java.util.ArrayList; import org.h2.engine.Constants; import org.h2.util.MathUtils; import org.h2.util.New; import org.h2.util.StatementBuilder; /** * Implementation of the ARRAY data type. */ public class ValueArray extends Value { private final Class<?> componentType; private final Value[] values; private int hash; private ValueArray(Class<?> componentType, Value[] list) { this.componentType = componentType; this.values = list; } private ValueArray(Value[] list) { this(Object.class, list); } /** * Get or create a array value for the given value array. * Do not clone the data. * * @param list the value array * @return the value */ public static ValueArray get(Value[] list) { return new ValueArray(list); } /** * Get or create a array value for the given value array. * Do not clone the data. * * @param componentType the array class (null for Object[]) * @param list the value array * @return the value */ public static ValueArray get(Class<?> componentType, Value[] list) { return new ValueArray(componentType, list); } public int hashCode() { if (hash != 0) { return hash; } int h = 1; for (Value v : values) { h = h * 31 + v.hashCode(); } hash = h; return h; } public Value[] getList() { return values; } public int getType() { return Value.ARRAY; } public Class<?> getComponentType() { return componentType; } public long getPrecision() { long p = 0; for (Value v : values) { p += v.getPrecision(); } return p; } public String getString() { StatementBuilder buff = new StatementBuilder("("); for (Value v : values) { buff.appendExceptFirst(", "); buff.append(v.getString()); } return buff.append(')').toString(); } protected int compareSecure(Value o, CompareMode mode) { ValueArray v = (ValueArray) o; if (values == v.values) { return 0; } int l = values.length; int ol = v.values.length; int len = Math.min(l, ol); for (int i = 0; i < len; i++) { Value v1 = values[i]; Value v2 = v.values[i]; int comp = v1.compareTo(v2, mode); if (comp != 0) { return comp; } } return l > ol ? 1 : l == ol ? 0 : -1; } public Object getObject() { int len = values.length; Object[] list = (Object[]) Array.newInstance(componentType, len); for (int i = 0; i < len; i++) { list[i] = values[i].getObject(); } return list; } public void set(PreparedStatement prep, int parameterIndex) { throw throwUnsupportedExceptionForType("PreparedStatement.set"); } public String getSQL() { StatementBuilder buff = new StatementBuilder("("); for (Value v : values) { buff.appendExceptFirst(", "); buff.append(v.getSQL()); } if (values.length == 1) { buff.append(','); } return buff.append(')').toString(); } public String getTraceSQL() { StatementBuilder buff = new StatementBuilder("("); for (Value v : values) { buff.appendExceptFirst(", "); buff.append(v.getTraceSQL()); } return buff.append(')').toString(); } public int getDisplaySize() { long size = 0; for (Value v : values) { size += v.getDisplaySize(); } return MathUtils.convertLongToInt(size); } public boolean equals(Object other) { if (!(other instanceof ValueArray)) { return false; } ValueArray v = (ValueArray) other; if (values == v.values) { return true; } int len = values.length; if (len != v.values.length) { return false; } for (int i = 0; i < len; i++) { if (!values[i].equals(v.values[i])) { return false; } } return true; } public int getMemory() { int memory = 32; for (Value v : values) { memory += v.getMemory() + Constants.MEMORY_POINTER; } return memory; } public Value convertPrecision(long precision, boolean force) { if (!force) { return this; } ArrayList<Value> list = New.arrayList(); for (Value v : values) { v = v.convertPrecision(precision, true); // empty byte arrays or strings have precision 0 // they count as precision 1 here precision -= Math.max(1, v.getPrecision()); if (precision < 0) { break; } list.add(v); } Value[] array = new Value[list.size()]; list.toArray(array); return get(array); } }