JDBCResultSet.java revision 17c83b1a74c906c9a36257a3a99cd1e3730b002e
1package SQLite.JDBC2z;
2
3import java.sql.*;
4import java.math.BigDecimal;
5
6public class JDBCResultSet implements java.sql.ResultSet {
7
8    /**
9     * Current row to be retrieved.
10     */
11    private int row;
12
13    /**
14     * Table returned by Database.get_table()
15     */
16    protected SQLite.TableResult tr;
17
18    /**
19     * Statement from which result set was produced.
20     */
21    private JDBCStatement s;
22
23    /**
24     * Meta data for result set or null.
25     */
26    private JDBCResultSetMetaData md;
27
28    /**
29     * Last result cell retrieved or null.
30     */
31    private String lastg;
32
33    /**
34     * Updatability of this result set.
35     */
36    private int updatable;
37
38    /**
39     * When updatable this is the table name.
40     */
41    private String uptable;
42
43    /**
44     * When updatable these are the PK column names of uptable.
45     */
46    private String pkcols[];
47
48    /**
49     * When updatable these are the PK column indices (0-based) of uptable.
50     */
51    private int pkcoli[];
52
53    /*
54     * Constants to reflect updateability.
55     */
56    private final static int UPD_UNKNOWN = -1;
57    private final static int UPD_NO = 0;
58    private final static int UPD_INS = 1;
59    private final static int UPD_INSUPDDEL = 2;
60
61    /**
62     * Flag for cursor being (not) on insert row.
63     */
64    private boolean oninsrow;
65
66    /**
67     * Row buffer for insert/update row.
68     */
69    private String rowbuf[];
70
71    private static final boolean nullrepl =
72        SQLite.Database.version().compareTo("2.5.0") < 0;
73
74    public JDBCResultSet(SQLite.TableResult tr, JDBCStatement s) {
75	this.tr = tr;
76	this.s = s;
77	this.md = null;
78	this.lastg = null;
79	this.row = -1;
80	this.updatable = UPD_UNKNOWN;
81	this.oninsrow = false;
82	this.rowbuf = null;
83    }
84
85    public boolean isUpdatable() throws SQLException {
86	if (updatable == UPD_UNKNOWN) {
87	    try {
88		JDBCResultSetMetaData m =
89		    (JDBCResultSetMetaData) getMetaData();
90		java.util.HashSet<String> h = new java.util.HashSet<String>();
91		String lastt = null;
92		for (int i = 1; i <= tr.ncolumns; i++) {
93		    lastt = m.getTableName(i);
94		    h.add(lastt);
95		}
96		if (h.size() > 1 || lastt == null) {
97		    updatable = UPD_NO;
98		    throw new SQLException("view or join");
99		}
100		updatable = UPD_INS;
101		uptable = lastt;
102		JDBCResultSet pk = (JDBCResultSet)
103		    s.conn.getMetaData().getPrimaryKeys(null, null, uptable);
104		if (pk.tr.nrows > 0) {
105		    boolean colnotfound = false;
106		    pkcols = new String[pk.tr.nrows];
107		    pkcoli = new int[pk.tr.nrows];
108		    for (int i = 0; i < pk.tr.nrows; i++) {
109			String rd[] = (String []) pk.tr.rows.elementAt(i);
110			pkcols[i] = rd[3];
111			try {
112			    pkcoli[i] = findColumn(pkcols[i]) - 1;
113			} catch (SQLException ee) {
114			    colnotfound = true;
115			}
116		    }
117		    if (!colnotfound) {
118			updatable = UPD_INSUPDDEL;
119		    }
120		}
121		pk.close();
122	    } catch (SQLException e) {
123		updatable = UPD_NO;
124	    }
125	}
126	if (updatable < UPD_INS) {
127	    throw new SQLException("result set not updatable");
128	}
129	return true;
130    }
131
132    public void fillRowbuf() throws SQLException {
133	if (rowbuf == null) {
134	    if (row < 0) {
135		throw new SQLException("cursor outside of result set");
136	    }
137	    rowbuf = new String[tr.ncolumns];
138	    System.arraycopy((String []) tr.rows.elementAt(row), 0,
139			     rowbuf, 0, tr.ncolumns);
140	}
141    }
142
143    public boolean next() throws SQLException {
144	if (tr == null) {
145	    return false;
146	}
147	row++;
148	return row < tr.nrows;
149    }
150
151    public int findColumn(String columnName) throws SQLException {
152	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
153	return m.findColByName(columnName);
154    }
155
156    public int getRow() throws SQLException {
157	if (tr == null) {
158	    throw new SQLException("no rows");
159	}
160	return row + 1;
161    }
162
163    public boolean previous() throws SQLException {
164	if (tr == null) {
165	    // BEGIN android-changed: throw rather than return false.
166	    throw new SQLException("ResultSet already closed");
167	    // END android-changed
168	}
169	if (row >= 0) {
170	    row--;
171	}
172	return row >= 0;
173    }
174
175    public boolean absolute(int row) throws SQLException {
176	if (tr == null) {
177	    return false;
178	}
179	if (row < 0) {
180	    row = tr.nrows + 1 + row;
181	}
182	row--;
183	if (row < 0 || row > tr.nrows) {
184	    return false;
185	}
186	this.row = row;
187	return true;
188    }
189
190    public boolean relative(int row) throws SQLException {
191	if (tr == null) {
192	    return false;
193	}
194	if (this.row + row < 0 || this.row + row >= tr.nrows) {
195	    return false;
196	}
197	this.row += row;
198	return true;
199    }
200
201    public void setFetchDirection(int dir) throws SQLException {
202	if (dir != ResultSet.FETCH_FORWARD) {
203	    throw new SQLException("only forward fetch direction supported");
204	}
205    }
206
207    public int getFetchDirection() throws SQLException {
208	return ResultSet.FETCH_FORWARD;
209    }
210
211    public void setFetchSize(int fsize) throws SQLException {
212	if (fsize != 1) {
213	    throw new SQLException("fetch size must be 1");
214	}
215    }
216
217    public int getFetchSize() throws SQLException {
218	return 1;
219    }
220
221    public String getString(int columnIndex) throws SQLException {
222	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
223	    throw new SQLException("column " + columnIndex + " not found");
224	}
225	String rd[] = (String []) tr.rows.elementAt(row);
226	lastg = rd[columnIndex - 1];
227	return lastg;
228    }
229
230    public String getString(String columnName) throws SQLException {
231	int col = findColumn(columnName);
232	return getString(col);
233    }
234
235    public int getInt(int columnIndex) throws SQLException {
236	Integer i = internalGetInt(columnIndex);
237	if (i != null) {
238	    return i.intValue();
239	}
240	return 0;
241    }
242
243    private Integer internalGetInt(int columnIndex) throws SQLException {
244	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
245	    throw new SQLException("column " + columnIndex + " not found");
246	}
247	String rd[] = (String []) tr.rows.elementAt(row);
248	lastg = rd[columnIndex - 1];
249	try {
250	    return Integer.valueOf(lastg);
251	} catch (java.lang.Exception e) {
252	    lastg = null;
253	}
254	return null;
255    }
256
257    public int getInt(String columnName) throws SQLException {
258	int col = findColumn(columnName);
259	return getInt(col);
260    }
261
262    public boolean getBoolean(int columnIndex) throws SQLException {
263	return getInt(columnIndex) == 1 ||
264	    Boolean.parseBoolean(getString(columnIndex)); // android-changed: performance
265    }
266
267    public boolean getBoolean(String columnName) throws SQLException {
268	int col = findColumn(columnName);
269	return getBoolean(col);
270    }
271
272    public ResultSetMetaData getMetaData() throws SQLException {
273	if (md == null) {
274	    md = new JDBCResultSetMetaData(this);
275	}
276	return md;
277    }
278
279    public short getShort(int columnIndex) throws SQLException {
280	Short sh = internalGetShort(columnIndex);
281	if (sh != null) {
282	    return sh.shortValue();
283	}
284	return 0;
285    }
286
287    private Short internalGetShort(int columnIndex) throws SQLException {
288	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
289	    throw new SQLException("column " + columnIndex + " not found");
290	}
291	String rd[] = (String []) tr.rows.elementAt(row);
292	lastg = rd[columnIndex - 1];
293	try {
294	    return Short.valueOf(lastg);
295	} catch (java.lang.Exception e) {
296	    lastg = null;
297	}
298	return null;
299    }
300
301    public short getShort(String columnName) throws SQLException {
302	int col = findColumn(columnName);
303	return getShort(col);
304    }
305
306    public java.sql.Time getTime(int columnIndex) throws SQLException {
307	return internalGetTime(columnIndex, null);
308    }
309
310    private java.sql.Time internalGetTime(int columnIndex,
311					  java.util.Calendar cal)
312	throws SQLException {
313	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
314	    throw new SQLException("column " + columnIndex + " not found");
315	}
316	String rd[] = (String []) tr.rows.elementAt(row);
317	lastg = rd[columnIndex - 1];
318	try {
319	    if (s.conn.useJulian) {
320		try {
321		    return new java.sql.Time(SQLite.Database.long_from_julian(lastg));
322		} catch (java.lang.Exception ee) {
323		    return java.sql.Time.valueOf(lastg);
324		}
325	    } else {
326		try {
327		    return java.sql.Time.valueOf(lastg);
328		} catch (java.lang.Exception ee) {
329		    return new java.sql.Time(SQLite.Database.long_from_julian(lastg));
330		}
331	    }
332	} catch (java.lang.Exception e) {
333	    lastg = null;
334	}
335	return null;
336    }
337
338    public java.sql.Time getTime(String columnName) throws SQLException {
339	int col = findColumn(columnName);
340	return getTime(col);
341    }
342
343    public java.sql.Time getTime(int columnIndex, java.util.Calendar cal)
344	throws SQLException {
345	return internalGetTime(columnIndex, cal);
346    }
347
348    public java.sql.Time getTime(String columnName, java.util.Calendar cal)
349	throws SQLException{
350	int col = findColumn(columnName);
351	return getTime(col, cal);
352    }
353
354    public java.sql.Timestamp getTimestamp(int columnIndex)
355	throws SQLException{
356	return internalGetTimestamp(columnIndex, null);
357    }
358
359    private java.sql.Timestamp internalGetTimestamp(int columnIndex,
360						    java.util.Calendar cal)
361	throws SQLException {
362	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
363	    throw new SQLException("column " + columnIndex + " not found");
364	}
365	String rd[] = (String []) tr.rows.elementAt(row);
366	lastg = rd[columnIndex - 1];
367	try {
368	    if (s.conn.useJulian) {
369		try {
370		    return new java.sql.Timestamp(SQLite.Database.long_from_julian(lastg));
371		} catch (java.lang.Exception ee) {
372		    return java.sql.Timestamp.valueOf(lastg);
373		}
374	    } else {
375		try {
376		    return java.sql.Timestamp.valueOf(lastg);
377		} catch (java.lang.Exception ee) {
378		    return new java.sql.Timestamp(SQLite.Database.long_from_julian(lastg));
379		}
380	    }
381	} catch (java.lang.Exception e) {
382	    lastg = null;
383	}
384	return null;
385    }
386
387    public java.sql.Timestamp getTimestamp(String columnName)
388	throws SQLException{
389	int col = findColumn(columnName);
390	return getTimestamp(col);
391    }
392
393    public java.sql.Timestamp getTimestamp(int columnIndex,
394					   java.util.Calendar cal)
395	throws SQLException {
396	return internalGetTimestamp(columnIndex, cal);
397    }
398
399    public java.sql.Timestamp getTimestamp(String columnName,
400					   java.util.Calendar cal)
401	throws SQLException {
402	int col = findColumn(columnName);
403	return getTimestamp(col, cal);
404    }
405
406    public java.sql.Date getDate(int columnIndex) throws SQLException {
407	return internalGetDate(columnIndex, null);
408    }
409
410    private java.sql.Date internalGetDate(int columnIndex,
411					  java.util.Calendar cal)
412	throws SQLException {
413	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
414	    throw new SQLException("column " + columnIndex + " not found");
415	}
416	String rd[] = (String []) tr.rows.elementAt(row);
417	lastg = rd[columnIndex - 1];
418	try {
419	    if (s.conn.useJulian) {
420		try {
421		    return new java.sql.Date(SQLite.Database.long_from_julian(lastg));
422		} catch (java.lang.Exception ee) {
423		    return java.sql.Date.valueOf(lastg);
424		}
425	    } else {
426		try {
427		    return java.sql.Date.valueOf(lastg);
428		} catch (java.lang.Exception ee) {
429		    return new java.sql.Date(SQLite.Database.long_from_julian(lastg));
430		}
431	    }
432	} catch (java.lang.Exception e) {
433	    lastg = null;
434	}
435	return null;
436    }
437
438    public java.sql.Date getDate(String columnName) throws SQLException {
439	int col = findColumn(columnName);
440	return getDate(col);
441    }
442
443    public java.sql.Date getDate(int columnIndex, java.util.Calendar cal)
444	throws SQLException{
445	return internalGetDate(columnIndex, cal);
446    }
447
448    public java.sql.Date getDate(String columnName, java.util.Calendar cal)
449	throws SQLException{
450	int col = findColumn(columnName);
451	return getDate(col, cal);
452    }
453
454    public double getDouble(int columnIndex) throws SQLException {
455	Double d = internalGetDouble(columnIndex);
456	if (d != null) {
457	    return d.doubleValue();
458	}
459	return 0;
460    }
461
462    private Double internalGetDouble(int columnIndex) throws SQLException {
463	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
464	    throw new SQLException("column " + columnIndex + " not found");
465	}
466	String rd[] = (String []) tr.rows.elementAt(row);
467	lastg = rd[columnIndex - 1];
468	try {
469	    return Double.valueOf(lastg);
470	} catch (java.lang.Exception e) {
471	    lastg = null;
472	}
473	return null;
474    }
475
476    public double getDouble(String columnName) throws SQLException {
477	int col = findColumn(columnName);
478	return getDouble(col);
479    }
480
481    public float getFloat(int columnIndex) throws SQLException {
482	Float f = internalGetFloat(columnIndex);
483	if (f != null) {
484	    return f.floatValue();
485	}
486	return 0;
487    }
488
489    private Float internalGetFloat(int columnIndex) throws SQLException {
490	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
491	    throw new SQLException("column " + columnIndex + " not found");
492	}
493	String rd[] = (String []) tr.rows.elementAt(row);
494	lastg = rd[columnIndex - 1];
495	try {
496	    return Float.valueOf(lastg);
497	} catch (java.lang.Exception e) {
498	    lastg = null;
499	}
500	return null;
501    }
502
503    public float getFloat(String columnName) throws SQLException {
504	int col = findColumn(columnName);
505	return getFloat(col);
506    }
507
508    public long getLong(int columnIndex) throws SQLException {
509	Long l = internalGetLong(columnIndex);
510	if (l != null) {
511	    return l.longValue();
512	}
513	return 0;
514    }
515
516    private Long internalGetLong(int columnIndex) throws SQLException {
517	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
518	    throw new SQLException("column " + columnIndex + " not found");
519	}
520	String rd[] = (String []) tr.rows.elementAt(row);
521	lastg = rd[columnIndex - 1];
522	try {
523	    return Long.valueOf(lastg);
524	} catch (java.lang.Exception e) {
525	    lastg = null;
526	}
527	return null;
528    }
529
530    public long getLong(String columnName) throws SQLException {
531	int col = findColumn(columnName);
532	return getLong(col);
533    }
534
535    @Deprecated
536    public java.io.InputStream getUnicodeStream(int columnIndex)
537	throws SQLException {
538	throw new SQLFeatureNotSupportedException();
539    }
540
541    @Deprecated
542    public java.io.InputStream getUnicodeStream(String columnName)
543	throws SQLException {
544	int col = findColumn(columnName);
545	return getUnicodeStream(col);
546    }
547
548    public java.io.InputStream getAsciiStream(String columnName)
549	throws SQLException {
550	int col = findColumn(columnName);
551	return getAsciiStream(col);
552    }
553
554    public java.io.InputStream getAsciiStream(int columnIndex)
555	throws SQLException {
556	throw new SQLException("not supported");
557    }
558
559    public BigDecimal getBigDecimal(String columnName)
560	throws SQLException {
561	int col = findColumn(columnName);
562	return getBigDecimal(col);
563    }
564
565    @Deprecated
566    public BigDecimal getBigDecimal(String columnName, int scale)
567	throws SQLException {
568	int col = findColumn(columnName);
569	return getBigDecimal(col, scale);
570    }
571
572    public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
573	throw new SQLFeatureNotSupportedException();
574    }
575
576    @Deprecated
577    public BigDecimal getBigDecimal(int columnIndex, int scale)
578	throws SQLException {
579	throw new SQLFeatureNotSupportedException();
580    }
581
582    public java.io.InputStream getBinaryStream(int columnIndex)
583	throws SQLException {
584	byte data[] = getBytes(columnIndex);
585	if (data != null) {
586	    return new java.io.ByteArrayInputStream(data);
587	}
588	return null;
589    }
590
591    public java.io.InputStream getBinaryStream(String columnName)
592	throws SQLException {
593	byte data[] = getBytes(columnName);
594	if (data != null) {
595	    return new java.io.ByteArrayInputStream(data);
596	}
597	return null;
598    }
599
600    public byte getByte(int columnIndex) throws SQLException {
601	throw new SQLException("not supported");
602    }
603
604    public byte getByte(String columnName) throws SQLException {
605	int col = findColumn(columnName);
606	return getByte(col);
607    }
608
609    public byte[] getBytes(int columnIndex) throws SQLException {
610	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
611	    throw new SQLException("column " + columnIndex + " not found");
612	}
613	byte ret[] = null;
614	String rd[] = (String []) tr.rows.elementAt(row);
615	lastg = rd[columnIndex - 1];
616	if (lastg != null) {
617	    ret = SQLite.StringEncoder.decode(lastg);
618	}
619	return ret;
620    }
621
622    public byte[] getBytes(String columnName) throws SQLException {
623	int col = findColumn(columnName);
624	return getBytes(col);
625    }
626
627    public String getCursorName() throws SQLException {
628	return null;
629    }
630
631    public Object getObject(int columnIndex) throws SQLException {
632	if (tr == null || columnIndex < 1 || columnIndex > tr.ncolumns) {
633	    throw new SQLException("column " + columnIndex + " not found");
634	}
635	String rd[] = (String []) tr.rows.elementAt(row);
636	lastg = rd[columnIndex - 1];
637	Object ret = lastg;
638	if (tr instanceof TableResultX) {
639	    switch (((TableResultX) tr).sql_type[columnIndex - 1]) {
640	    case Types.SMALLINT:
641		ret = internalGetShort(columnIndex);
642		break;
643	    case Types.INTEGER:
644		ret = internalGetInt(columnIndex);
645		break;
646	    case Types.DOUBLE:
647		ret = internalGetDouble(columnIndex);
648		break;
649	    case Types.FLOAT:
650		ret = internalGetFloat(columnIndex);
651		break;
652	    case Types.BIGINT:
653		ret = internalGetLong(columnIndex);
654		break;
655	    case Types.BINARY:
656	    case Types.VARBINARY:
657	    case Types.LONGVARBINARY:
658		ret = getBytes(columnIndex);
659		break;
660	    case Types.NULL:
661		ret = null;
662		break;
663	    /* defaults to String below */
664	    }
665	}
666	return ret;
667    }
668
669    public Object getObject(String columnName) throws SQLException {
670	int col = findColumn(columnName);
671	return getObject(col);
672    }
673
674    public Object getObject(int columnIndex, java.util.Map map)
675	throws SQLException {
676	throw new SQLFeatureNotSupportedException();
677    }
678
679    public Object getObject(String columnName, java.util.Map map)
680	throws SQLException {
681	int col = findColumn(columnName);
682	return getObject(col, map);
683    }
684
685    public java.sql.Ref getRef(int columnIndex) throws SQLException {
686	throw new SQLFeatureNotSupportedException();
687    }
688
689    public java.sql.Ref getRef(String columnName) throws SQLException {
690	int col = findColumn(columnName);
691	return getRef(col);
692    }
693
694    public java.sql.Blob getBlob(int columnIndex) throws SQLException {
695	throw new SQLFeatureNotSupportedException();
696    }
697
698    public java.sql.Blob getBlob(String columnName) throws SQLException {
699	int col = findColumn(columnName);
700	return getBlob(col);
701    }
702
703    public java.sql.Clob getClob(int columnIndex) throws SQLException {
704	throw new SQLFeatureNotSupportedException();
705    }
706
707    public java.sql.Clob getClob(String columnName) throws SQLException {
708	int col = findColumn(columnName);
709	return getClob(col);
710    }
711
712    public java.sql.Array getArray(int columnIndex) throws SQLException {
713	throw new SQLFeatureNotSupportedException();
714    }
715
716    public java.sql.Array getArray(String columnName) throws SQLException {
717	int col = findColumn(columnName);
718	return getArray(col);
719    }
720
721    public java.io.Reader getCharacterStream(int columnIndex)
722	throws SQLException {
723	String data = getString(columnIndex);
724	if (data != null) {
725	    char[] cdata = data.toCharArray();
726	    return new java.io.CharArrayReader(cdata);
727	}
728	return null;
729    }
730
731    public java.io.Reader getCharacterStream(String columnName)
732	throws SQLException {
733	String data = getString(columnName);
734	if (data != null) {
735	    char[] cdata = data.toCharArray();
736	    return new java.io.CharArrayReader(cdata);
737	}
738	return null;
739    }
740
741    public SQLWarning getWarnings() throws SQLException {
742	throw new SQLException("not supported");
743    }
744
745    public boolean wasNull() throws SQLException {
746	return lastg == null;
747    }
748
749    public void clearWarnings() throws SQLException {
750	throw new SQLException("not supported");
751    }
752
753    public boolean isFirst() throws SQLException {
754	if (tr == null) {
755	    return true;
756	}
757	return row == 0;
758    }
759
760    public boolean isBeforeFirst() throws SQLException {
761	if (tr == null || tr.nrows <= 0) {
762	    return false;
763	}
764	return row < 0;
765    }
766
767    public void beforeFirst() throws SQLException {
768	if (tr == null) {
769	    return;
770	}
771	row = -1;
772    }
773
774    public boolean first() throws SQLException {
775	if (tr == null || tr.nrows <= 0) {
776	    return false;
777	}
778	row = 0;
779	return true;
780    }
781
782    public boolean isAfterLast() throws SQLException {
783	if (tr == null || tr.nrows <= 0) {
784	    return false;
785	}
786	return row >= tr.nrows;
787    }
788
789    public void afterLast() throws SQLException {
790	if (tr == null) {
791	    return;
792	}
793	row = tr.nrows;
794    }
795
796    public boolean isLast() throws SQLException {
797	if (tr == null) {
798	    return true;
799	}
800	return row == tr.nrows - 1;
801    }
802
803    public boolean last() throws SQLException {
804	if (tr == null || tr.nrows <= 0) {
805	    return false;
806	}
807	row = tr.nrows -1;
808	return true;
809    }
810
811    public int getType() throws SQLException {
812	return TYPE_SCROLL_SENSITIVE;
813    }
814
815    public int getConcurrency() throws SQLException {
816	return CONCUR_UPDATABLE;
817    }
818
819    public boolean rowUpdated() throws SQLException {
820	return false;
821    }
822
823    public boolean rowInserted() throws SQLException {
824	return false;
825    }
826
827    public boolean rowDeleted() throws SQLException {
828	return false;
829    }
830
831    public void insertRow() throws SQLException {
832	isUpdatable();
833	if (!oninsrow || rowbuf == null) {
834	    throw new SQLException("no insert data provided");
835	}
836	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
837	StringBuffer sb = new StringBuffer();
838	sb.append("INSERT INTO ");
839	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
840	sb.append("(");
841	for (int i = 0; i < tr.ncolumns; i++) {
842	    sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1)));
843	    if (i < tr.ncolumns - 1) {
844		sb.append(",");
845	    }
846	}
847	sb.append(") VALUES(");
848	for (int i = 0; i < tr.ncolumns; i++) {
849	    sb.append(nullrepl ? "'%q'" : "%Q");
850	    if (i < tr.ncolumns - 1) {
851		sb.append(",");
852	    }
853	}
854	sb.append(")");
855	try {
856	    this.s.conn.db.exec(sb.toString(), null, rowbuf);
857	} catch (SQLite.Exception e) {
858	    throw new SQLException(e.getMessage());
859	}
860	tr.newrow(rowbuf);
861	rowbuf = null;
862	oninsrow = false;
863	last();
864    }
865
866    public void updateRow() throws SQLException {
867	isUpdatable();
868	if (rowbuf == null) {
869	    throw new SQLException("no update data provided");
870	}
871	if (oninsrow) {
872	    throw new SQLException("cursor on insert row");
873	}
874	if (updatable < UPD_INSUPDDEL) {
875	    throw new SQLException("no primary key on table defined");
876	}
877	String rd[] = (String []) tr.rows.elementAt(row);
878	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
879	String args[] = new String[tr.ncolumns + pkcols.length];
880	StringBuffer sb = new StringBuffer();
881	sb.append("UPDATE ");
882	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
883	sb.append(" SET ");
884	int i;
885	for (i = 0; i < tr.ncolumns; i++) {
886	    sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1)));
887	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
888	    if (i < tr.ncolumns - 1) {
889		sb.append(",");
890	    }
891	    args[i] = rowbuf[i];
892	}
893	sb. append(" WHERE ");
894	for (int k = 0; k < pkcols.length; k++, i++) {
895	    sb.append(SQLite.Shell.sql_quote_dbl(pkcols[k]));
896	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
897	    if (k < pkcols.length - 1) {
898		sb.append(" AND ");
899	    }
900	    args[i] = rd[pkcoli[k]];
901	}
902	try {
903	    this.s.conn.db.exec(sb.toString(), null, args);
904	} catch (SQLite.Exception e) {
905	    throw new SQLException(e.getMessage());
906	}
907	System.arraycopy(rowbuf, 0, rd, 0, rowbuf.length);
908	rowbuf = null;
909    }
910
911    public void deleteRow() throws SQLException {
912	isUpdatable();
913	if (oninsrow) {
914	    throw new SQLException("cursor on insert row");
915	}
916	if (updatable < UPD_INSUPDDEL) {
917	    throw new SQLException("no primary key on table defined");
918	}
919	fillRowbuf();
920	StringBuffer sb = new StringBuffer();
921	sb.append("DELETE FROM ");
922	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
923	sb.append(" WHERE ");
924	String args[] = new String[pkcols.length];
925	for (int i = 0; i < pkcols.length; i++) {
926	    sb.append(SQLite.Shell.sql_quote_dbl(pkcols[i]));
927	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
928	    if (i < pkcols.length - 1) {
929		sb.append(" AND ");
930	    }
931	    args[i] = rowbuf[pkcoli[i]];
932	}
933	try {
934	    this.s.conn.db.exec(sb.toString(), null, args);
935	} catch (SQLite.Exception e) {
936	    throw new SQLException(e.getMessage());
937	}
938	rowbuf = null;
939    }
940
941    public void refreshRow() throws SQLException {
942	isUpdatable();
943	if (oninsrow) {
944	    throw new SQLException("cursor on insert row");
945	}
946	if (updatable < UPD_INSUPDDEL) {
947	    throw new SQLException("no primary key on table defined");
948	}
949	JDBCResultSetMetaData m = (JDBCResultSetMetaData) getMetaData();
950	String rd[] = (String []) tr.rows.elementAt(row);
951	StringBuffer sb = new StringBuffer();
952	sb.append("SELECT ");
953	for (int i = 0; i < tr.ncolumns; i++) {
954	    sb.append(SQLite.Shell.sql_quote_dbl(m.getColumnName(i + 1)));
955	    if (i < tr.ncolumns - 1) {
956		sb.append(",");
957	    }
958	}
959	sb.append(" FROM ");
960	sb.append(SQLite.Shell.sql_quote_dbl(uptable));
961	sb.append(" WHERE ");
962	String args[] = new String[pkcols.length];
963	for (int i = 0; i < pkcols.length; i++) {
964	    sb.append(SQLite.Shell.sql_quote_dbl(pkcols[i]));
965	    sb.append(" = " + (nullrepl ? "'%q'" : "%Q"));
966	    if (i < pkcols.length - 1) {
967		sb.append(" AND ");
968	    }
969	    args[i] = rd[pkcoli[i]];
970	}
971	SQLite.TableResult trnew = null;
972	try {
973	    trnew = this.s.conn.db.get_table(sb.toString(), args);
974	} catch (SQLite.Exception e) {
975	    throw new SQLException(e.getMessage());
976	}
977	if (trnew.nrows != 1) {
978	    throw new SQLException("wrong size of result set");
979	}
980	rowbuf = null;
981	tr.rows.setElementAt(trnew.rows.elementAt(0), row);
982    }
983
984    public void cancelRowUpdates() throws SQLException {
985	rowbuf = null;
986    }
987
988    public void moveToInsertRow() throws SQLException {
989	isUpdatable();
990	if (!oninsrow) {
991	    oninsrow = true;
992	    rowbuf = new String[tr.nrows];
993	}
994    }
995
996    public void moveToCurrentRow() throws SQLException {
997	if (oninsrow) {
998	    oninsrow = false;
999	    rowbuf = null;
1000	}
1001    }
1002
1003    public void updateNull(int colIndex) throws SQLException {
1004	isUpdatable();
1005	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1006	    throw new SQLException("column " + colIndex + " not found");
1007	}
1008	fillRowbuf();
1009	rowbuf[colIndex - 1] = null;
1010    }
1011
1012    public void updateBoolean(int colIndex, boolean b) throws SQLException {
1013	updateString(colIndex, b ? "1" : "0");
1014    }
1015
1016    public void updateByte(int colIndex, byte b) throws SQLException {
1017	throw new SQLFeatureNotSupportedException();
1018    }
1019
1020    public void updateShort(int colIndex, short b) throws SQLException {
1021	isUpdatable();
1022	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1023	    throw new SQLException("column " + colIndex + " not found");
1024	}
1025	fillRowbuf();
1026	rowbuf[colIndex - 1] = Short.toString(b);
1027    }
1028
1029    public void updateInt(int colIndex, int b) throws SQLException {
1030	isUpdatable();
1031	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1032	    throw new SQLException("column " + colIndex + " not found");
1033	}
1034	fillRowbuf();
1035	rowbuf[colIndex - 1] = Integer.toString(b);
1036    }
1037
1038    public void updateLong(int colIndex, long b) throws SQLException {
1039	isUpdatable();
1040	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1041	    throw new SQLException("column " + colIndex + " not found");
1042	}
1043	fillRowbuf();
1044	rowbuf[colIndex - 1] = Long.toString(b);
1045    }
1046
1047    public void updateFloat(int colIndex, float f) throws SQLException {
1048	isUpdatable();
1049	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1050	    throw new SQLException("column " + colIndex + " not found");
1051	}
1052	fillRowbuf();
1053	rowbuf[colIndex - 1] = Float.toString(f);
1054    }
1055
1056    public void updateDouble(int colIndex, double f) throws SQLException {
1057	isUpdatable();
1058	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1059	    throw new SQLException("column " + colIndex + " not found");
1060	}
1061	fillRowbuf();
1062	rowbuf[colIndex - 1] = Double.toString(f);
1063    }
1064
1065    public void updateBigDecimal(int colIndex, BigDecimal f)
1066	throws SQLException {
1067	throw new SQLFeatureNotSupportedException();
1068    }
1069
1070    public void updateString(int colIndex, String s) throws SQLException {
1071	isUpdatable();
1072	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1073	    throw new SQLException("column " + colIndex + " not found");
1074	}
1075	fillRowbuf();
1076	rowbuf[colIndex - 1] = s;
1077    }
1078
1079    public void updateBytes(int colIndex, byte[] s) throws SQLException {
1080	isUpdatable();
1081	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1082	    throw new SQLException("column " + colIndex + " not found");
1083	}
1084	fillRowbuf();
1085	if (this.s.conn.db.is3()) {
1086	    rowbuf[colIndex - 1] = SQLite.StringEncoder.encodeX(s);
1087	} else {
1088	    rowbuf[colIndex - 1] = SQLite.StringEncoder.encode(s);
1089	}
1090    }
1091
1092    public void updateDate(int colIndex, java.sql.Date d) throws SQLException {
1093	isUpdatable();
1094	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1095	    throw new SQLException("column " + colIndex + " not found");
1096	}
1097	fillRowbuf();
1098	rowbuf[colIndex - 1] = d.toString();
1099    }
1100
1101    public void updateTime(int colIndex, java.sql.Time t) throws SQLException {
1102	isUpdatable();
1103	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1104	    throw new SQLException("column " + colIndex + " not found");
1105	}
1106	fillRowbuf();
1107	rowbuf[colIndex - 1] = t.toString();
1108    }
1109
1110    public void updateTimestamp(int colIndex, java.sql.Timestamp t)
1111	throws SQLException {
1112	isUpdatable();
1113	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1114	    throw new SQLException("column " + colIndex + " not found");
1115	}
1116	fillRowbuf();
1117	rowbuf[colIndex - 1] = t.toString();
1118    }
1119
1120    public void updateAsciiStream(int colIndex, java.io.InputStream in, int s)
1121	throws SQLException {
1122	throw new SQLFeatureNotSupportedException();
1123    }
1124
1125    public void updateBinaryStream(int colIndex, java.io.InputStream in, int s)
1126	throws SQLException {
1127	throw new SQLFeatureNotSupportedException();
1128    }
1129
1130    public void updateCharacterStream(int colIndex, java.io.Reader in, int s)
1131	throws SQLException {
1132	throw new SQLFeatureNotSupportedException();
1133    }
1134
1135    public void updateObject(int colIndex, Object obj) throws SQLException {
1136	updateString(colIndex, obj.toString());
1137    }
1138
1139    public void updateObject(int colIndex, Object obj, int s)
1140	throws SQLException {
1141	updateString(colIndex, obj.toString());
1142    }
1143
1144    public void updateNull(String colName) throws SQLException {
1145	int col = findColumn(colName);
1146	updateNull(col);
1147    }
1148
1149    public void updateBoolean(String colName, boolean b) throws SQLException {
1150	int col = findColumn(colName);
1151	updateBoolean(col, b);
1152    }
1153
1154    public void updateByte(String colName, byte b) throws SQLException {
1155	int col = findColumn(colName);
1156	updateByte(col, b);
1157    }
1158
1159    public void updateShort(String colName, short b) throws SQLException {
1160	int col = findColumn(colName);
1161	updateShort(col, b);
1162    }
1163
1164    public void updateInt(String colName, int b) throws SQLException {
1165	int col = findColumn(colName);
1166	updateInt(col, b);
1167    }
1168
1169    public void updateLong(String colName, long b) throws SQLException {
1170	int col = findColumn(colName);
1171	updateLong(col, b);
1172    }
1173
1174    public void updateFloat(String colName, float f) throws SQLException {
1175	int col = findColumn(colName);
1176	updateFloat(col, f);
1177    }
1178
1179    public void updateDouble(String colName, double f) throws SQLException {
1180	int col = findColumn(colName);
1181	updateDouble(col, f);
1182    }
1183
1184    public void updateBigDecimal(String colName, BigDecimal f)
1185	throws SQLException {
1186	int col = findColumn(colName);
1187	updateBigDecimal(col, f);
1188    }
1189
1190    public void updateString(String colName, String s) throws SQLException {
1191	int col = findColumn(colName);
1192	updateString(col, s);
1193    }
1194
1195    public void updateBytes(String colName, byte[] s) throws SQLException {
1196	int col = findColumn(colName);
1197	updateBytes(col, s);
1198    }
1199
1200    public void updateDate(String colName, java.sql.Date d)
1201	throws SQLException {
1202	int col = findColumn(colName);
1203	updateDate(col, d);
1204    }
1205
1206    public void updateTime(String colName, java.sql.Time t)
1207	throws SQLException {
1208	int col = findColumn(colName);
1209	updateTime(col, t);
1210    }
1211
1212    public void updateTimestamp(String colName, java.sql.Timestamp t)
1213	throws SQLException {
1214	int col = findColumn(colName);
1215	updateTimestamp(col, t);
1216    }
1217
1218    public void updateAsciiStream(String colName, java.io.InputStream in,
1219				  int s)
1220	throws SQLException {
1221	int col = findColumn(colName);
1222	updateAsciiStream(col, in, s);
1223    }
1224
1225    public void updateBinaryStream(String colName, java.io.InputStream in,
1226				   int s)
1227	throws SQLException {
1228	int col = findColumn(colName);
1229	updateBinaryStream(col, in, s);
1230    }
1231
1232    public void updateCharacterStream(String colName, java.io.Reader in,
1233				      int s)
1234	throws SQLException {
1235	int col = findColumn(colName);
1236	updateCharacterStream(col, in, s);
1237    }
1238
1239    public void updateObject(String colName, Object obj)
1240	throws SQLException {
1241	int col = findColumn(colName);
1242	updateObject(col, obj);
1243    }
1244
1245    public void updateObject(String colName, Object obj, int s)
1246	throws SQLException {
1247	int col = findColumn(colName);
1248	updateObject(col, obj, s);
1249    }
1250
1251    public Statement getStatement() throws SQLException {
1252	if (s == null) {
1253	    throw new SQLException("stale result set");
1254	}
1255	return s;
1256    }
1257
1258    public void close() throws SQLException {
1259	s = null;
1260	tr = null;
1261	lastg = null;
1262	oninsrow = false;
1263	rowbuf = null;
1264	row = -1;
1265    }
1266
1267    public java.net.URL getURL(int colIndex) throws SQLException {
1268	if (tr == null || colIndex < 1 || colIndex > tr.ncolumns) {
1269	    throw new SQLException("column " + colIndex + " not found");
1270	}
1271	String rd[] = (String []) tr.rows.elementAt(row);
1272	lastg = rd[colIndex - 1];
1273	java.net.URL url = null;
1274	if (lastg == null) {
1275	    return url;
1276	}
1277	try {
1278	    url = new java.net.URL(lastg);
1279	} catch (java.lang.Exception e) {
1280	    url = null;
1281	}
1282	return url;
1283    }
1284
1285    public java.net.URL getURL(String colName) throws SQLException {
1286	int col = findColumn(colName);
1287	return getURL(col);
1288    }
1289
1290    public void updateRef(int colIndex, java.sql.Ref x) throws SQLException {
1291	throw new SQLFeatureNotSupportedException();
1292    }
1293
1294    public void updateRef(String colName, java.sql.Ref x)
1295	throws SQLException {
1296	int col = findColumn(colName);
1297	updateRef(col, x);
1298    }
1299
1300    public void updateBlob(int colIndex, java.sql.Blob x)
1301	throws SQLException {
1302	throw new SQLFeatureNotSupportedException();
1303    }
1304
1305    public void updateBlob(String colName, java.sql.Blob x)
1306	throws SQLException {
1307	int col = findColumn(colName);
1308	updateBlob(col, x);
1309    }
1310
1311    public void updateClob(int colIndex, java.sql.Clob x)
1312	throws SQLException {
1313	throw new SQLFeatureNotSupportedException();
1314    }
1315
1316    public void updateClob(String colName, java.sql.Clob x)
1317	throws SQLException {
1318	int col = findColumn(colName);
1319	updateClob(col, x);
1320    }
1321
1322    public void updateArray(int colIndex, java.sql.Array x)
1323	throws SQLException {
1324	throw new SQLFeatureNotSupportedException();
1325    }
1326
1327    public void updateArray(String colName, java.sql.Array x)
1328	throws SQLException {
1329	int col = findColumn(colName);
1330	updateArray(col, x);
1331    }
1332
1333    public RowId getRowId(int colIndex) throws SQLException {
1334	throw new SQLFeatureNotSupportedException();
1335    }
1336
1337    public RowId getRowId(String colName) throws SQLException {
1338	int col = findColumn(colName);
1339	return getRowId(col);
1340    }
1341
1342    public void updateRowId(int colIndex, RowId x) throws SQLException {
1343	throw new SQLFeatureNotSupportedException();
1344    }
1345
1346    public void updateRowId(String colName, RowId x) throws SQLException {
1347	int col = findColumn(colName);
1348	updateRowId(col, x);
1349    }
1350
1351    public int getHoldability() throws SQLException {
1352	return ResultSet.CLOSE_CURSORS_AT_COMMIT;
1353    }
1354
1355    public boolean isClosed() throws SQLException {
1356	return tr == null;
1357    }
1358
1359    public void updateNString(int colIndex, String nString)
1360	throws SQLException {
1361	throw new SQLFeatureNotSupportedException();
1362    }
1363
1364    public void updateNString(String colName, String nString)
1365	throws SQLException {
1366	int col = findColumn(colName);
1367	updateNString(col, nString);
1368    }
1369
1370    public void updateNClob(int colIndex, NClob nclob)
1371	throws SQLException {
1372	throw new SQLFeatureNotSupportedException();
1373    }
1374
1375    public void updateNClob(String colName, NClob nclob)
1376	throws SQLException {
1377	int col = findColumn(colName);
1378	updateNClob(col, nclob);
1379    }
1380
1381    public NClob getNClob(int colIndex) throws SQLException {
1382	throw new SQLFeatureNotSupportedException();
1383    }
1384
1385    public NClob getNClob(String colName) throws SQLException {
1386	int col = findColumn(colName);
1387	return getNClob(col);
1388    }
1389
1390    public SQLXML getSQLXML(int colIndex) throws SQLException {
1391	throw new SQLFeatureNotSupportedException();
1392    }
1393
1394    public SQLXML getSQLXML(String colName) throws SQLException {
1395	int col = findColumn(colName);
1396	return getSQLXML(col);
1397    }
1398
1399    public void updateSQLXML(int colIndex, SQLXML xml)
1400	throws SQLException {
1401	throw new SQLFeatureNotSupportedException();
1402    }
1403
1404    public void updateSQLXML(String colName, SQLXML xml)
1405	throws SQLException {
1406	int col = findColumn(colName);
1407	updateSQLXML(col, xml);
1408    }
1409
1410    public String getNString(int colIndex) throws SQLException {
1411	throw new SQLFeatureNotSupportedException();
1412    }
1413
1414    public String getNString(String colName) throws SQLException {
1415	int col = findColumn(colName);
1416	return getNString(col);
1417    }
1418
1419    public java.io.Reader getNCharacterStream(int colIndex)
1420	throws SQLException {
1421	throw new SQLFeatureNotSupportedException();
1422    }
1423
1424    public java.io.Reader getNCharacterStream(String colName)
1425	throws SQLException {
1426	int col = findColumn(colName);
1427	return getNCharacterStream(col);
1428    }
1429
1430    public void updateNCharacterStream(int colIndex, java.io.Reader x,
1431				       long len)
1432	throws SQLException {
1433	throw new SQLFeatureNotSupportedException();
1434    }
1435
1436    public void updateNCharacterStream(String colName, java.io.Reader x,
1437				       long len)
1438	throws SQLException {
1439	int col = findColumn(colName);
1440	updateNCharacterStream(col, x, len);
1441    }
1442
1443    public void updateAsciiStream(int colIndex, java.io.InputStream x,
1444				  long len)
1445	throws SQLException {
1446	throw new SQLFeatureNotSupportedException();
1447    }
1448
1449    public void updateAsciiStream(String colName, java.io.InputStream x,
1450				  long len)
1451	throws SQLException {
1452	int col = findColumn(colName);
1453	updateAsciiStream(col, x, len);
1454    }
1455
1456    public void updateBinaryStream(int colIndex, java.io.InputStream x,
1457				   long len)
1458	throws SQLException {
1459	throw new SQLFeatureNotSupportedException();
1460    }
1461
1462    public void updateBinaryStream(String colName, java.io.InputStream x,
1463				   long len)
1464	throws SQLException {
1465	int col = findColumn(colName);
1466	updateBinaryStream(col, x, len);
1467    }
1468
1469    public void updateCharacterStream(int colIndex, java.io.Reader x,
1470				   long len)
1471	throws SQLException {
1472	throw new SQLFeatureNotSupportedException();
1473    }
1474
1475    public void updateCharacterStream(String colName, java.io.Reader x,
1476				   long len)
1477	throws SQLException {
1478	int col = findColumn(colName);
1479	updateCharacterStream(col, x, len);
1480    }
1481
1482    public void updateBlob(int colIndex, java.io.InputStream x,
1483			   long len)
1484	throws SQLException {
1485	throw new SQLFeatureNotSupportedException();
1486    }
1487
1488    public void updateBlob(String colName, java.io.InputStream x,
1489			   long len)
1490	throws SQLException {
1491	int col = findColumn(colName);
1492	updateBlob(col, x, len);
1493    }
1494
1495    public void updateClob(int colIndex, java.io.Reader x,
1496			   long len)
1497	throws SQLException {
1498	throw new SQLFeatureNotSupportedException();
1499    }
1500
1501    public void updateClob(String colName, java.io.Reader x,
1502			   long len)
1503	throws SQLException {
1504	int col = findColumn(colName);
1505	updateClob(col, x, len);
1506    }
1507
1508    public void updateNClob(int colIndex, java.io.Reader x,
1509			    long len)
1510	throws SQLException {
1511	throw new SQLFeatureNotSupportedException();
1512    }
1513
1514    public void updateNClob(String colName, java.io.Reader x,
1515			    long len)
1516	throws SQLException {
1517	int col = findColumn(colName);
1518	updateNClob(col, x, len);
1519    }
1520
1521    public void updateNCharacterStream(int colIndex, java.io.Reader x)
1522	throws SQLException {
1523	throw new SQLFeatureNotSupportedException();
1524    }
1525
1526    public void updateNCharacterStream(String colName, java.io.Reader x)
1527	throws SQLException {
1528	int col = findColumn(colName);
1529	updateNCharacterStream(col, x);
1530    }
1531
1532    public void updateAsciiStream(int colIndex, java.io.InputStream x)
1533	throws SQLException {
1534	throw new SQLFeatureNotSupportedException();
1535    }
1536
1537    public void updateAsciiStream(String colName, java.io.InputStream x)
1538	throws SQLException {
1539	int col = findColumn(colName);
1540	updateAsciiStream(col, x);
1541    }
1542
1543    public void updateBinaryStream(int colIndex, java.io.InputStream x)
1544	throws SQLException {
1545	throw new SQLFeatureNotSupportedException();
1546    }
1547
1548    public void updateBinaryStream(String colName, java.io.InputStream x)
1549	throws SQLException {
1550	int col = findColumn(colName);
1551	updateBinaryStream(col, x);
1552    }
1553
1554    public void updateCharacterStream(int colIndex, java.io.Reader x)
1555	throws SQLException {
1556	throw new SQLFeatureNotSupportedException();
1557    }
1558
1559    public void updateCharacterStream(String colName, java.io.Reader x)
1560	throws SQLException {
1561	int col = findColumn(colName);
1562	updateCharacterStream(col, x);
1563    }
1564
1565    public void updateBlob(int colIndex, java.io.InputStream x)
1566	throws SQLException {
1567	throw new SQLFeatureNotSupportedException();
1568    }
1569
1570    public void updateBlob(String colName, java.io.InputStream x)
1571	throws SQLException {
1572	int col = findColumn(colName);
1573	updateBlob(col, x);
1574    }
1575
1576    public void updateClob(int colIndex, java.io.Reader x)
1577	throws SQLException {
1578	throw new SQLFeatureNotSupportedException();
1579    }
1580
1581    public void updateClob(String colName, java.io.Reader x)
1582	throws SQLException {
1583	int col = findColumn(colName);
1584	updateClob(col, x);
1585    }
1586
1587    public void updateNClob(int colIndex, java.io.Reader x)
1588	throws SQLException {
1589	throw new SQLFeatureNotSupportedException();
1590    }
1591
1592    public void updateNClob(String colName, java.io.Reader x)
1593	throws SQLException {
1594	int col = findColumn(colName);
1595	updateNClob(col, x);
1596    }
1597
1598    public <T> T unwrap(java.lang.Class<T> iface) throws SQLException {
1599	throw new SQLException("unsupported");
1600    }
1601
1602    public boolean isWrapperFor(java.lang.Class iface) throws SQLException {
1603	return false;
1604    }
1605
1606}
1607