1   /*
2    * PRELYTIS.
3    * Copyright 2007, PRELYTIS S.A., and individual contributors
4    * as indicated by the @author tags. See the copyright.txt file in the
5    * distribution for a full listing of individual contributors.
6    *
7    * This is free software; you can redistribute it and/or modify it
8    * under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */
22  package org.jdbc4olap.jdbc;
23  
24  import java.io.InputStream;
25  import java.io.Reader;
26  import java.math.BigDecimal;
27  import java.net.URL;
28  import java.sql.Array;
29  import java.sql.Blob;
30  import java.sql.Clob;
31  import java.sql.Date;
32  import java.sql.Ref;
33  import java.sql.ResultSet;
34  import java.sql.ResultSetMetaData;
35  import java.sql.SQLException;
36  import java.sql.SQLWarning;
37  import java.sql.Statement;
38  import java.sql.Time;
39  import java.sql.Timestamp;
40  import java.util.ArrayList;
41  import java.util.Calendar;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.logging.Level;
45  import java.util.logging.Logger;
46  
47  import org.jdbc4olap.xmla.Jdbc4OlapConstants;
48  
49  /**
50   * @author <a href="mailto:fsiberchicot@jdbc4olap.org">Florian SIBERCHICOT</a>
51   * @author Dan Rollo
52   */
53  class OlapResultSet implements ResultSet {
54  
55      private ResultSetMetaData metaData;
56      private List<Object[]> data;
57      private int position;
58      private Statement statement;
59  
60      OlapResultSet() {
61          this.data = new ArrayList<Object[]>();
62          position = -1;
63      }
64  
65      /**
66       * Exists for unit testing only.
67       *
68       * @return the data structure of this result set
69       */
70      List<Object[]> getData() {
71          return data;
72      }
73  
74      void add(final Object[] row) {
75          data.add(row);
76      }
77  
78      public boolean absolute(final int row) throws SQLException {
79          return false;
80      }
81  
82      public void afterLast() throws SQLException {
83          position = data.size() + 1;
84      }
85  
86      public void beforeFirst() throws SQLException {
87          position = -1;
88      }
89  
90      public void cancelRowUpdates() throws SQLException {
91      }
92  
93      public void clearWarnings() throws SQLException {
94      }
95  
96      public void close() throws SQLException {
97          data = null;
98          metaData = null;
99          position = -1;
100         statement = null;
101     }
102 
103     public void deleteRow() throws SQLException {
104     }
105 
106     public int findColumn(final String columnName) throws SQLException {
107         for (int i = 1; i <= metaData.getColumnCount(); i++) {
108             String name = metaData.getColumnName(i);
109             if (name.equals(columnName)) {
110                 return i;
111             }
112         }
113         throw new SQLException("Unknown column name");
114     }
115 
116     public boolean first() throws SQLException {
117         position = 0;
118         return data.size() > 0;
119     }
120 
121     public Array getArray(final int i) throws SQLException {
122         return null;
123     }
124 
125     public Array getArray(final String colName) throws SQLException {
126         return null;
127     }
128 
129     public InputStream getAsciiStream(final int columnIndex) throws SQLException {
130         return null;
131     }
132 
133     public InputStream getAsciiStream(final String columnName) throws SQLException {
134         return null;
135     }
136 
137     public BigDecimal getBigDecimal(final int columnIndex) throws SQLException {
138         Object value = getObject(columnIndex);
139         if (value == null) {
140             return null;
141         }
142         if (value instanceof Number) {
143             return new BigDecimal(((Number) value).doubleValue());
144         }
145         return new BigDecimal(value.toString());
146     }
147 
148     public BigDecimal getBigDecimal(final String columnName) throws SQLException {
149         return getBigDecimal(findColumn(columnName));
150     }
151 
152     public BigDecimal getBigDecimal(final int columnIndex, final int scale) throws SQLException {
153         return getBigDecimal(columnIndex);
154     }
155 
156     public BigDecimal getBigDecimal(final String columnName, final int scale) throws SQLException {
157         return getBigDecimal(findColumn(columnName));
158     }
159 
160     public InputStream getBinaryStream(final int columnIndex) throws SQLException {
161         return null;
162     }
163 
164     public InputStream getBinaryStream(final String columnName) throws SQLException {
165         return null;
166     }
167 
168     public Blob getBlob(final int i) throws SQLException {
169         return null;
170     }
171 
172     public Blob getBlob(final String colName) throws SQLException {
173         return null;
174     }
175 
176     public boolean getBoolean(final int columnIndex) throws SQLException {
177         Object value = getObject(columnIndex);
178         if (value == null) {
179             return false;
180         }
181         if (value instanceof Boolean) {
182             return (Boolean) value;
183         }
184         return Boolean.getBoolean(value.toString());
185     }
186 
187     public boolean getBoolean(final String columnName) throws SQLException {
188         return getBoolean(findColumn(columnName));
189     }
190 
191     public byte getByte(final int columnIndex) throws SQLException {
192         return 0;
193     }
194 
195     public byte getByte(final String columnName) throws SQLException {
196         return 0;
197     }
198 
199     public byte[] getBytes(final int columnIndex) throws SQLException {
200         return null;
201     }
202 
203     public byte[] getBytes(final String columnName) throws SQLException {
204         return null;
205     }
206 
207     public Reader getCharacterStream(final int columnIndex) throws SQLException {
208         return null;
209     }
210 
211     public Reader getCharacterStream(final String columnName) throws SQLException {
212         return null;
213     }
214 
215     public Clob getClob(final int i) throws SQLException {
216         return null;
217     }
218 
219     public Clob getClob(final String colName) throws SQLException {
220         return null;
221     }
222 
223     public int getConcurrency() throws SQLException {
224         return ResultSet.TYPE_FORWARD_ONLY;
225     }
226 
227     public String getCursorName() throws SQLException {
228         return null;
229     }
230 
231     public Date getDate(final int columnIndex) throws SQLException {
232         final Object value = getObject(columnIndex);
233         if (value == null) {
234             return null;
235         }
236         if (value instanceof java.util.Date) {
237             return new Date(((java.util.Date) value).getTime());
238         }
239         throw new SQLException("Conversion Error");
240     }
241 
242     public Date getDate(final String columnName) throws SQLException {
243         return getDate(findColumn(columnName));
244     }
245 
246     public Date getDate(final int columnIndex, final Calendar cal) throws SQLException {
247         return getDate(columnIndex);
248     }
249 
250     public Date getDate(final String columnName, final Calendar cal) throws SQLException {
251         return getDate(findColumn(columnName));
252     }
253 
254     public double getDouble(final int columnIndex) throws SQLException {
255         final Object value = getObject(columnIndex);
256         if (value == null) {
257             return 0;
258         }
259         if (value instanceof Number) {
260             return ((Number) value).doubleValue();
261         }
262         return Double.parseDouble(value.toString());
263     }
264 
265     public double getDouble(final String columnName) throws SQLException {
266         return getDouble(findColumn(columnName));
267     }
268 
269     public int getFetchDirection() throws SQLException {
270         return ResultSet.FETCH_FORWARD;
271     }
272 
273     public int getFetchSize() throws SQLException {
274         return 0;
275     }
276 
277     public float getFloat(final int columnIndex) throws SQLException {
278         final Object value = getObject(columnIndex);
279         if (value == null) {
280             return 0;
281         }
282         if (value instanceof Number) {
283             return ((Number) value).floatValue();
284         }
285         return Float.parseFloat(value.toString());
286     }
287 
288     public float getFloat(final String columnName) throws SQLException {
289         return getFloat(findColumn(columnName));
290     }
291 
292     public int getInt(final int columnIndex) throws SQLException {
293         final Object value = getObject(columnIndex);
294         if (value == null) {
295             return 0;
296         }
297         if (value instanceof Number) {
298             return ((Number) value).intValue();
299         }
300         return Integer.parseInt(value.toString());
301     }
302 
303     public int getInt(final String columnName) throws SQLException {
304         return getInt(findColumn(columnName));
305     }
306 
307     public long getLong(final int columnIndex) throws SQLException {
308         final Object value = getObject(columnIndex);
309         if (value == null) {
310             return 0;
311         }
312         if (value instanceof Number) {
313             return ((Number) value).longValue();
314         }
315         return Long.parseLong(value.toString());
316     }
317 
318     public long getLong(final String columnName) throws SQLException {
319         return getLong(findColumn(columnName));
320     }
321 
322     public ResultSetMetaData getMetaData() throws SQLException {
323         if (metaData == null) {
324             Logger log = Logger.getLogger(Jdbc4OlapConstants.JDBC4OLAP_LOG);
325             final String msg = "Jdbc4Olap: Missing ResultSetMetaData - Please report as driver bug.\n";
326             final IllegalStateException e = new IllegalStateException(msg);
327             log.severe(msg);
328             log.log(Level.FINE, "StackTrace", e);
329             throw e;
330         }
331         return metaData;
332     }
333 
334     public Object getObject(final int columnIndex) throws SQLException {
335         if (position < 0) {
336             throw new SQLException("Before first row");
337         }
338         if (position >= data.size()) {
339             throw new SQLException("After last row");
340         }
341 
342         final Object[] row = data.get(position);
343         return row[columnIndex - 1];
344     }
345 
346     public Object getObject(final String columnName) throws SQLException {
347         return getObject(findColumn(columnName));
348     }
349 
350     public Object getObject(final int i, final Map map) throws SQLException {
351         return getObject(i);
352     }
353 
354     public Object getObject(final String colName, final Map map) throws SQLException {
355         return getObject(colName);
356     }
357 
358     public Ref getRef(final int i) throws SQLException {
359         return null;
360     }
361 
362     public Ref getRef(final String colName) throws SQLException {
363         return null;
364     }
365 
366     public int getRow() throws SQLException {
367         return position + 1;
368     }
369 
370     public short getShort(final int columnIndex) throws SQLException {
371         final Object value = getObject(columnIndex);
372         if (value == null) {
373             return 0;
374         }
375         if (value instanceof Short) {
376             return ((Number) value).shortValue();
377         }
378         return Short.parseShort(value.toString());
379     }
380 
381     public short getShort(final String columnName) throws SQLException {
382         return getShort(findColumn(columnName));
383     }
384 
385     public Statement getStatement() throws SQLException {
386         return statement;
387     }
388 
389     public String getString(final int columnIndex) throws SQLException {
390         final Object value = getObject(columnIndex);
391         if (value == null) {
392             return null;
393         }
394         if (value instanceof String) {
395             return (String) value;
396         }
397         return value.toString();
398     }
399 
400     public String getString(final String columnName) throws SQLException {
401         return getString(findColumn(columnName));
402     }
403 
404     public Time getTime(final int columnIndex) throws SQLException {
405         final Object value = getObject(columnIndex);
406         if (value == null) {
407             return null;
408         }
409         if (value instanceof java.util.Date) {
410             return new Time(((java.util.Date) value).getTime());
411         }
412         throw new SQLException("Conversion Error");
413     }
414 
415     public Time getTime(final String columnName) throws SQLException {
416         return getTime(findColumn(columnName));
417     }
418 
419     public Time getTime(final int columnIndex, final Calendar cal) throws SQLException {
420         return getTime(columnIndex);
421     }
422 
423     public Time getTime(final String columnName, final Calendar cal) throws SQLException {
424         return getTime(findColumn(columnName));
425     }
426 
427     public Timestamp getTimestamp(final int columnIndex) throws SQLException {
428         final Object value = getObject(columnIndex);
429         if (value == null) {
430             return null;
431         }
432         if (value instanceof java.util.Date) {
433             return new Timestamp(((java.util.Date) value).getTime());
434         }
435         throw new SQLException("Conversion Error");
436     }
437 
438     public Timestamp getTimestamp(final String columnName) throws SQLException {
439         return getTimestamp(findColumn(columnName));
440     }
441 
442     public Timestamp getTimestamp(final int columnIndex, final Calendar cal) throws SQLException {
443         return getTimestamp(columnIndex);
444     }
445 
446     public Timestamp getTimestamp(final String columnName, final Calendar cal) throws SQLException {
447         return getTimestamp(findColumn(columnName));
448     }
449 
450     public int getType() throws SQLException {
451         return ResultSet.TYPE_FORWARD_ONLY;
452     }
453 
454     public URL getURL(final int columnIndex) throws SQLException {
455         return null;
456     }
457 
458     public URL getURL(final String columnName) throws SQLException {
459         return null;
460     }
461 
462     public InputStream getUnicodeStream(final int columnIndex) throws SQLException {
463         return null;
464     }
465 
466     public InputStream getUnicodeStream(final String columnName) throws SQLException {
467         return null;
468     }
469 
470     public SQLWarning getWarnings() throws SQLException {
471         return null;
472     }
473 
474     public void insertRow() throws SQLException {
475     }
476 
477     public boolean isAfterLast() throws SQLException {
478         return position > data.size();
479     }
480 
481     public boolean isBeforeFirst() throws SQLException {
482         return position < 0;
483     }
484 
485     public boolean isFirst() throws SQLException {
486         return position == 0;
487     }
488 
489     public boolean isLast() throws SQLException {
490         return position == data.size();
491     }
492 
493     public boolean last() throws SQLException {
494         position = data.size();
495         return true;
496     }
497 
498     public void moveToCurrentRow() throws SQLException {
499     }
500 
501     public void moveToInsertRow() throws SQLException {
502     }
503 
504     public boolean next() throws SQLException {
505         if (position <= data.size()) {
506             position++;
507         }
508         return position < data.size();
509     }
510 
511     public boolean previous() throws SQLException {
512         if (position >= 0) {
513             position--;
514         }
515         return position < 0;
516     }
517 
518     public void refreshRow() throws SQLException {
519     }
520 
521     public boolean relative(final int rows) throws SQLException {
522         return false;
523     }
524 
525     public boolean rowDeleted() throws SQLException {
526         return false;
527     }
528 
529     public boolean rowInserted() throws SQLException {
530         return false;
531     }
532 
533     public boolean rowUpdated() throws SQLException {
534         return false;
535     }
536 
537     public void setFetchDirection(final int direction) throws SQLException {
538     }
539 
540     public void setFetchSize(final int rows) throws SQLException {
541     }
542 
543     public void updateArray(final int columnIndex, final Array x) throws SQLException {
544     }
545 
546     public void updateArray(final String columnName, final Array x) throws SQLException {
547     }
548 
549     public void updateAsciiStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
550     }
551 
552     public void updateAsciiStream(final String columnName, final InputStream x, final int length) throws SQLException {
553     }
554 
555     public void updateBigDecimal(final int columnIndex, final BigDecimal x) throws SQLException {
556     }
557 
558     public void updateBigDecimal(final String columnName, final BigDecimal x) throws SQLException {
559     }
560 
561     public void updateBinaryStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
562     }
563 
564     public void updateBinaryStream(final String columnName, final InputStream x, final int length) throws SQLException {
565     }
566 
567     public void updateBlob(final int columnIndex, final Blob x) throws SQLException {
568     }
569 
570     public void updateBlob(final String columnName, final Blob x) throws SQLException {
571     }
572 
573     public void updateBoolean(final int columnIndex, final boolean x) throws SQLException {
574     }
575 
576     public void updateBoolean(final String columnName, final boolean x) throws SQLException {
577     }
578 
579     public void updateByte(final int columnIndex, final byte x) throws SQLException {
580     }
581 
582     public void updateByte(final String columnName, final byte x) throws SQLException {
583     }
584 
585     public void updateBytes(final int columnIndex, final byte[] x) throws SQLException {
586     }
587 
588     public void updateBytes(final String columnName, final byte[] x) throws SQLException {
589     }
590 
591     public void updateCharacterStream(final int columnIndex, final Reader x, final int length) throws SQLException {
592     }
593 
594     public void updateCharacterStream(final String columnName, final Reader reader, final int length) throws SQLException {
595     }
596 
597     public void updateClob(final int columnIndex, final Clob x) throws SQLException {
598     }
599 
600     public void updateClob(final String columnName, final Clob x) throws SQLException {
601     }
602 
603     public void updateDate(final int columnIndex, final Date x) throws SQLException {
604     }
605 
606     public void updateDate(final String columnName, final Date x) throws SQLException {
607     }
608 
609     public void updateDouble(final int columnIndex, final double x) throws SQLException {
610     }
611 
612     public void updateDouble(final String columnName, final double x) throws SQLException {
613     }
614 
615     public void updateFloat(final int columnIndex, final float x) throws SQLException {
616     }
617 
618     public void updateFloat(final String columnName, final float x) throws SQLException {
619     }
620 
621     public void updateInt(final int columnIndex, final int x) throws SQLException {
622     }
623 
624     public void updateInt(final String columnName, final int x) throws SQLException {
625     }
626 
627     public void updateLong(final int columnIndex, final long x) throws SQLException {
628     }
629 
630     public void updateLong(final String columnName, final long x) throws SQLException {
631     }
632 
633     public void updateNull(final int columnIndex) throws SQLException {
634     }
635 
636     public void updateNull(final String columnName) throws SQLException {
637     }
638 
639     public void updateObject(final int columnIndex, final Object x) throws SQLException {
640     }
641 
642     public void updateObject(final String columnName, final Object x) throws SQLException {
643     }
644 
645     public void updateObject(final int columnIndex, final Object x, final int scale) throws SQLException {
646     }
647 
648     public void updateObject(final String columnName, final Object x, final int scale) throws SQLException {
649     }
650 
651     public void updateRef(final int columnIndex, final Ref x) throws SQLException {
652     }
653 
654     public void updateRef(final String columnName, final Ref x) throws SQLException {
655     }
656 
657     public void updateRow() throws SQLException {
658     }
659 
660     public void updateShort(final int columnIndex, final short x) throws SQLException {
661     }
662 
663     public void updateShort(final String columnName, final short x) throws SQLException {
664     }
665 
666     public void updateString(final int columnIndex, final String x) throws SQLException {
667     }
668 
669     public void updateString(final String columnName, final String x) throws SQLException {
670     }
671 
672     public void updateTime(final int columnIndex, final Time x) throws SQLException {
673     }
674 
675     public void updateTime(final String columnName, final Time x) throws SQLException {
676     }
677 
678     public void updateTimestamp(final int columnIndex, final Timestamp x) throws SQLException {
679     }
680 
681     public void updateTimestamp(final String columnName, final Timestamp x) throws SQLException {
682     }
683 
684     public boolean wasNull() throws SQLException {
685         return false;
686     }
687 
688     void setMetaData(final ResultSetMetaData rsMetaData) {
689         this.metaData = rsMetaData;
690     }
691 
692     void setStatement(final Statement owningStatement) {
693         this.statement = owningStatement;
694     }
695 
696     /**
697      * @return A new, valid, empty resultset (with metadata).
698      */
699     static OlapResultSet createEmptyResultSet() {
700         final OlapResultSet rs = new OlapResultSet();
701         OlapResultSetMetaData.setMetaData(rs, null, null);
702         return rs;
703     }
704 }