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