001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.jdbc;
007:
008: import java.sql.Array;
009: import java.sql.ResultSet;
010: import java.sql.SQLException;
011: import java.sql.Types;
012: import java.util.Map;
013:
014: import org.h2.constant.ErrorCode;
015: import org.h2.engine.SessionInterface;
016: import org.h2.message.Message;
017: import org.h2.message.TraceObject;
018: import org.h2.tools.SimpleResultSet;
019: import org.h2.util.ObjectUtils;
020: import org.h2.value.Value;
021:
022: /**
023: * Represents an ARRAY value.
024: */
025: public class JdbcArray extends TraceObject implements Array {
026:
027: private Value value;
028: private JdbcConnection conn;
029:
030: /**
031: * INTERNAL
032: */
033: public JdbcArray(SessionInterface session, JdbcConnection conn,
034: Value value, int id) {
035: setTrace(session.getTrace(), TraceObject.ARRAY, id);
036: this .conn = conn;
037: this .value = value;
038: }
039:
040: /**
041: * Returns the value as a Java array.
042: * This method always returns an Object[].
043: *
044: * @return the Object array
045: */
046: public Object getArray() throws SQLException {
047: try {
048: debugCodeCall("getArray");
049: checkClosed();
050: return get();
051: } catch (Throwable e) {
052: throw logAndConvert(e);
053: }
054: }
055:
056: /**
057: * Returns the value as a Java array.
058: * This method always returns an Object[].
059: *
060: * @param map is ignored. Only empty or null maps are supported
061: * @return the Object array
062: */
063: public Object getArray(Map map) throws SQLException {
064: try {
065: debugCode("getArray(" + quoteMap(map) + ");");
066: checkMap(map);
067: checkClosed();
068: return get();
069: } catch (Throwable e) {
070: throw logAndConvert(e);
071: }
072: }
073:
074: /**
075: * Returns the value as a Java array. A subset of the array is returned,
076: * starting from the index (1 meaning the first element) and up to the given
077: * object count. This method always returns an Object[].
078: *
079: * @param index the start index of the subset (starting with 1)
080: * @param count the maximum number of values
081: * @return the Object array
082: */
083: public Object getArray(long index, int count) throws SQLException {
084: try {
085: debugCode("getArray(" + index + ", " + count + ");");
086: checkClosed();
087: return get(index, count);
088: } catch (Throwable e) {
089: throw logAndConvert(e);
090: }
091: }
092:
093: /**
094: * Returns the value as a Java array. A subset of the array is returned,
095: * starting from the index (1 meaning the first element) and up to the given
096: * object count. This method always returns an Object[].
097: *
098: * @param index the start index of the subset (starting with 1)
099: * @param count the maximum number of values
100: * @param map is ignored. Only empty or null maps are supported
101: * @return the Object array
102: */
103: public Object getArray(long index, int count, Map map)
104: throws SQLException {
105: try {
106: debugCode("getArray(" + index + ", " + count + ", "
107: + quoteMap(map) + ");");
108: checkClosed();
109: checkMap(map);
110: return get(index, count);
111: } catch (Throwable e) {
112: throw logAndConvert(e);
113: }
114: }
115:
116: /**
117: * Returns the base type of the array. This database does support mixed type
118: * arrays and therefore there is no base type.
119: *
120: * @return Types.NULL
121: */
122: public int getBaseType() throws SQLException {
123: try {
124: debugCodeCall("getBaseType");
125: checkClosed();
126: return Types.NULL;
127: } catch (Throwable e) {
128: throw logAndConvert(e);
129: }
130: }
131:
132: /**
133: * Returns the base type name of the array. This database does support mixed
134: * type arrays and therefore there is no base type.
135: *
136: * @return "NULL"
137: */
138: public String getBaseTypeName() throws SQLException {
139: try {
140: debugCodeCall("getBaseTypeName");
141: checkClosed();
142: return "NULL";
143: } catch (Throwable e) {
144: throw logAndConvert(e);
145: }
146: }
147:
148: /**
149: * Returns the value as a result set.
150: * The first column contains the index
151: * (starting with 1) and the second column the value.
152: *
153: * @return the result set
154: */
155: public ResultSet getResultSet() throws SQLException {
156: try {
157: debugCodeCall("getResultSet");
158: checkClosed();
159: return getResultSet(get(), 0);
160: } catch (Throwable e) {
161: throw logAndConvert(e);
162: }
163: }
164:
165: /**
166: * Returns the value as a result set. The first column contains the index
167: * (starting with 1) and the second column the value.
168: *
169: * @param map is ignored. Only empty or null maps are supported
170: * @return the result set
171: */
172: public ResultSet getResultSet(Map map) throws SQLException {
173: try {
174: debugCode("getResultSet(" + quoteMap(map) + ");");
175: checkClosed();
176: checkMap(map);
177: return getResultSet(get(), 0);
178: } catch (Throwable e) {
179: throw logAndConvert(e);
180: }
181: }
182:
183: /**
184: * Returns the value as a result set. The first column contains the index
185: * (starting with 1) and the second column the value. A subset of the array
186: * is returned, starting from the index (1 meaning the first element) and
187: * up to the given object count.
188: *
189: * @param index the start index of the subset (starting with 1)
190: * @param count the maximum number of values
191: * @return the result set
192: */
193: public ResultSet getResultSet(long index, int count)
194: throws SQLException {
195: try {
196: debugCode("getResultSet(" + index + ", " + count + ");");
197: checkClosed();
198: return getResultSet(get(index, count), index);
199: } catch (Throwable e) {
200: throw logAndConvert(e);
201: }
202: }
203:
204: /**
205: * Returns the value as a result set.
206: * The first column contains the index
207: * (starting with 1) and the second column the value.
208: * A subset of the array is returned, starting from the index
209: * (1 meaning the first element) and up to the given object count.
210: *
211: * @param index the start index of the subset (starting with 1)
212: * @param count the maximum number of values
213: * @param map is ignored. Only empty or null maps are supported
214: * @return the result set
215: */
216: public ResultSet getResultSet(long index, int count, Map map)
217: throws SQLException {
218: try {
219: debugCode("getResultSet(" + index + ", " + count + ", "
220: + quoteMap(map) + ");");
221: checkClosed();
222: checkMap(map);
223: return getResultSet(get(index, count), index);
224: } catch (Throwable e) {
225: throw logAndConvert(e);
226: }
227: }
228:
229: /**
230: * Release all resources of this object.
231: */
232: public void free() throws SQLException {
233: debugCodeCall("free");
234: value = null;
235: }
236:
237: private ResultSet getResultSet(Object[] array, long offset)
238: throws SQLException {
239: SimpleResultSet rs = new SimpleResultSet();
240: rs.addColumn("INDEX", Types.BIGINT, 0, 0);
241: // TODO array result set: there are multiple data types possible
242: rs.addColumn("VALUE", Types.NULL, 0, 0);
243: for (int i = 0; i < array.length; i++) {
244: Object[] row = new Object[2];
245: row[0] = ObjectUtils.getLong(offset + i + 1);
246: row[1] = array[i];
247: rs.addRow(row);
248: }
249: return rs;
250: }
251:
252: private void checkClosed() throws SQLException {
253: conn.checkClosed();
254: if (value == null) {
255: throw Message.getSQLException(ErrorCode.OBJECT_CLOSED);
256: }
257: }
258:
259: private Object[] get() throws SQLException {
260: return (Object[]) value.convertTo(Value.ARRAY).getObject();
261: }
262:
263: private Object[] get(long index, int count) throws SQLException {
264: Object[] array = get();
265: if (count < 0 || count > array.length) {
266: throw Message.getInvalidValueException("" + count,
267: "count (1.." + array.length + ")");
268: }
269: if (index < 1 || index > array.length) {
270: throw Message.getInvalidValueException("" + index,
271: "index (1.." + array.length + ")");
272: }
273: Object[] subset = new Object[count];
274: System.arraycopy(array, (int) (index - 1), subset, 0, count);
275: return subset;
276: }
277:
278: private void checkMap(Map map) throws SQLException {
279: if (map != null && map.size() > 0) {
280: throw Message.getUnsupportedException();
281: }
282: }
283:
284: /**
285: * INTERNAL
286: */
287: public String toString() {
288: return getTraceObjectName() + ": " + value.getSQL();
289: }
290: }
|