1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package test.rowset.cachedrowset;
24
25import java.math.BigDecimal;
26import java.sql.Array;
27import java.sql.Date;
28import java.sql.JDBCType;
29import java.sql.Ref;
30import java.sql.ResultSet;
31import java.sql.ResultSetMetaData;
32import java.sql.SQLException;
33import java.sql.Time;
34import java.sql.Timestamp;
35import java.sql.Types;
36import java.time.LocalDate;
37import java.time.LocalDateTime;
38import java.time.LocalTime;
39import java.util.Collection;
40import javax.sql.RowSet;
41import javax.sql.rowset.CachedRowSet;
42import javax.sql.rowset.RowSetMetaDataImpl;
43import javax.sql.rowset.serial.SerialRef;
44import javax.sql.rowset.spi.SyncFactory;
45import javax.sql.rowset.spi.SyncProvider;
46import javax.sql.rowset.spi.SyncProviderException;
47import static org.testng.Assert.assertEquals;
48import static org.testng.Assert.assertFalse;
49import static org.testng.Assert.assertNull;
50import static org.testng.Assert.assertTrue;
51import org.testng.annotations.DataProvider;
52import org.testng.annotations.Test;
53import test.rowset.CommonRowSetTests;
54import util.StubArray;
55import util.StubRef;
56import util.StubSyncProvider;
57import util.TestRowSetListener;
58
59public abstract class CommonCachedRowSetTests extends CommonRowSetTests {
60
61    /*
62     * DATATYPES Table column names
63     */
64    private final String[] DATATYPES_COLUMN_NAMES = {"AINTEGER", "ACHAR",
65        "AVARCHAR", "ALONG", "ABOOLEAN", "ASHORT", "ADOUBLE", "ABIGDECIMAL",
66        "AREAL", "ABYTE", "ADATE", "ATIME", "ATIMESTAMP", "ABYTES", "ARRAY",
67        "AREF", "AFLOAT"};
68
69    /*
70     * Initializes a RowSet containing the DATAYPES data
71     */
72    protected <T extends RowSet> T createDataTypesRowSet() throws SQLException {
73        T rs = (T) newInstance();
74        initDataTypesMetaData((CachedRowSet) rs);
75        createDataTypesRows(rs);
76        // Make sure you are not on the insertRow
77        rs.moveToCurrentRow();
78        return rs;
79    }
80
81    //DataProviders to use for common tests
82
83    /*
84     * DataProvider that uses a RowSet with the COFFEE_HOUSES Table
85     */
86    @DataProvider(name = "rowsetUsingCoffeeHouses")
87    protected Object[][] rowsetUsingCoffeeHouses() throws Exception {
88        RowSet rs = createCoffeeHousesRowSet();
89        return new Object[][]{
90            {rs}
91        };
92    }
93
94    /*
95     * DataProvider that uses a RowSet with the COFFEES Table
96     */
97    @DataProvider(name = "rowsetUsingCoffees")
98    protected Object[][] rowsetUsingCoffees() throws Exception {
99        RowSet rs = createCoffeesRowSet();
100        return new Object[][]{
101            {rs}
102        };
103    }
104
105    /*
106     * DataProvider that uses a RowSet with the DATAYPES Table and
107     * used to validate the various supported data types
108     */
109    @DataProvider(name = "rowsetUsingDataTypes")
110    protected Object[][] rowsetUsingDataTypes() throws Exception {
111
112        CachedRowSet rs = createDataTypesRowSet();
113        return new Object[][]{
114            {rs, JDBCType.INTEGER},
115            {rs, JDBCType.CHAR},
116            {rs, JDBCType.VARCHAR},
117            {rs, JDBCType.BIGINT},
118            {rs, JDBCType.BOOLEAN},
119            {rs, JDBCType.SMALLINT},
120            {rs, JDBCType.DOUBLE},
121            {rs, JDBCType.DECIMAL},
122            {rs, JDBCType.REAL},
123            {rs, JDBCType.TINYINT},
124            {rs, JDBCType.DATE},
125            {rs, JDBCType.TIME},
126            {rs, JDBCType.TIMESTAMP},
127            {rs, JDBCType.VARBINARY},
128            {rs, JDBCType.ARRAY},
129            {rs, JDBCType.REF},
130            {rs, JDBCType.FLOAT}
131        };
132    }
133
134    /*
135     * Initializes the DATAYPES table metadata
136     */
137    protected void initDataTypesMetaData(CachedRowSet crs) throws SQLException {
138        RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl();
139        crs.setType(RowSet.TYPE_SCROLL_INSENSITIVE);
140
141        rsmd.setColumnCount(DATATYPES_COLUMN_NAMES.length);
142
143        for (int i = 1; i <= DATATYPES_COLUMN_NAMES.length; i++) {
144            rsmd.setColumnName(i, DATATYPES_COLUMN_NAMES[i - 1]);
145            rsmd.setColumnLabel(i, rsmd.getColumnName(i));
146        }
147
148        rsmd.setColumnType(1, Types.INTEGER);
149        rsmd.setColumnType(2, Types.CHAR);
150        rsmd.setColumnType(3, Types.VARCHAR);
151        rsmd.setColumnType(4, Types.BIGINT);
152        rsmd.setColumnType(5, Types.BOOLEAN);
153        rsmd.setColumnType(6, Types.SMALLINT);
154        rsmd.setColumnType(7, Types.DOUBLE);
155        rsmd.setColumnType(8, Types.DECIMAL);
156        rsmd.setColumnType(9, Types.REAL);
157        rsmd.setColumnType(10, Types.TINYINT);
158        rsmd.setColumnType(11, Types.DATE);
159        rsmd.setColumnType(12, Types.TIME);
160        rsmd.setColumnType(13, Types.TIMESTAMP);
161        rsmd.setColumnType(14, Types.VARBINARY);
162        rsmd.setColumnType(15, Types.ARRAY);
163        rsmd.setColumnType(16, Types.REF);
164        rsmd.setColumnType(17, Types.FLOAT);
165        crs.setMetaData(rsmd);
166
167    }
168
169    /*
170     * Add rows to DATAYPES table
171     */
172    protected void createDataTypesRows(RowSet crs) throws SQLException {
173
174        Integer aInteger = 100;
175        String aChar = "Oswald Cobblepot";
176        Long aLong = Long.MAX_VALUE;
177        Short aShort = Short.MAX_VALUE;
178        Double aDouble = Double.MAX_VALUE;
179        BigDecimal aBigDecimal = BigDecimal.ONE;
180        Boolean aBoolean = false;
181        Float aFloat = Float.MAX_VALUE;
182        Byte aByte = Byte.MAX_VALUE;
183        Date aDate = Date.valueOf(LocalDate.now());
184        Time aTime = Time.valueOf(LocalTime.now());
185        Timestamp aTimeStamp = Timestamp.valueOf(LocalDateTime.now());
186        Array aArray = new StubArray("INTEGER", new Object[1]);
187        Ref aRef = new SerialRef(new StubRef("INTEGER", query));
188        byte[] bytes = new byte[10];
189        crs.moveToInsertRow();
190        crs.updateInt(1, aInteger);
191        crs.updateString(2, aChar);
192        crs.updateString(3, aChar);
193        crs.updateLong(4, aLong);
194        crs.updateBoolean(5, aBoolean);
195        crs.updateShort(6, aShort);
196        crs.updateDouble(7, aDouble);
197        crs.updateBigDecimal(8, aBigDecimal);
198        crs.updateFloat(9, aFloat);
199        crs.updateByte(10, aByte);
200        crs.updateDate(11, aDate);
201        crs.updateTime(12, aTime);
202        crs.updateTimestamp(13, aTimeStamp);
203        crs.updateBytes(14, bytes);
204        crs.updateArray(15, aArray);
205        crs.updateRef(16, aRef);
206        crs.updateDouble(17, aDouble);
207        crs.insertRow();
208        crs.moveToCurrentRow();
209
210    }
211
212    /*
213     * Dermine if a Row exists in a ResultSet by its primary key
214     * If the parameter deleteRow is true, delete the row and validate
215     * the RowSet indicates it is deleted
216     */
217    protected boolean findRowByPrimaryKey(RowSet rs, int id, int idPos,
218            boolean deleteRow) throws Exception {
219        boolean foundRow = false;
220        rs.beforeFirst();
221        while (rs.next()) {
222            if (rs.getInt(idPos) == id) {
223                foundRow = true;
224                if (deleteRow) {
225                    rs.deleteRow();
226                    // validate row is marked as deleted
227                    assertTrue(rs.rowDeleted());
228                }
229                break;
230            }
231        }
232        return foundRow;
233    }
234
235    /*
236     * Wrapper method to find if a row exists within a RowSet by its primary key
237     */
238    protected boolean findRowByPrimaryKey(RowSet rs, int id, int idPos) throws Exception {
239        return findRowByPrimaryKey(rs, id, idPos, false);
240    }
241
242    /*
243     * Wrapper method to find if a row exists within a RowSet by its primary key
244     * and delete it
245     */
246    protected boolean deleteRowByPrimaryKey(RowSet rs, int id, int idPos) throws Exception {
247        return findRowByPrimaryKey(rs, id, idPos, true);
248    }
249
250    /*
251     * Utility method that compares two ResultSetMetaDataImpls for containing
252     * the same values
253     */
254    private void compareMetaData(ResultSetMetaData rsmd,
255            ResultSetMetaData rsmd1) throws SQLException {
256
257        assertEquals(rsmd1.getColumnCount(), rsmd.getColumnCount());
258        int cols = rsmd.getColumnCount();
259        for (int i = 1; i <= cols; i++) {
260            assertTrue(rsmd1.getCatalogName(i).equals(rsmd.getCatalogName(i)));
261            assertTrue(rsmd1.getColumnClassName(i).equals(rsmd.getColumnClassName(i)));
262            assertTrue(rsmd1.getColumnDisplaySize(i) == rsmd.getColumnDisplaySize(i));
263            assertTrue(rsmd1.getColumnLabel(i).equals(rsmd.getColumnLabel(i)));
264            assertTrue(rsmd1.getColumnName(i).equals(rsmd.getColumnName(i)));
265            assertTrue(rsmd1.getColumnType(i) == rsmd.getColumnType(i));
266            assertTrue(rsmd1.getPrecision(i) == rsmd.getPrecision(i));
267            assertTrue(rsmd1.getScale(i) == rsmd.getScale(i));
268            assertTrue(rsmd1.getSchemaName(i).equals(rsmd.getSchemaName(i)));
269            assertTrue(rsmd1.getTableName(i).equals(rsmd.getTableName(i)));
270            assertTrue(rsmd1.isAutoIncrement(i) == rsmd.isAutoIncrement(i));
271            assertTrue(rsmd1.isCaseSensitive(i) == rsmd.isCaseSensitive(i));
272            assertTrue(rsmd1.isCurrency(i) == rsmd.isCurrency(i));
273            assertTrue(rsmd1.isDefinitelyWritable(i) == rsmd.isDefinitelyWritable(i));
274            assertTrue(rsmd1.isNullable(i) == rsmd.isNullable(i));
275            assertTrue(rsmd1.isReadOnly(i) == rsmd.isReadOnly(i));
276            assertTrue(rsmd1.isSearchable(i) == rsmd.isSearchable(i));
277            assertTrue(rsmd1.isSigned(i) == rsmd.isSigned(i));
278            assertTrue(rsmd1.isWritable(i) == rsmd.isWritable(i));
279
280        }
281    }
282
283    /*
284     * Utility method to compare two rowsets
285     */
286    private void compareRowSets(CachedRowSet crs, CachedRowSet crs1) throws Exception {
287
288        int rows = crs.size();
289        assertTrue(rows == crs1.size());
290
291        ResultSetMetaData rsmd = crs.getMetaData();
292
293        compareMetaData(rsmd, crs1.getMetaData());
294        int cols = rsmd.getColumnCount();
295
296        for (int row = 1; row <= rows; row++) {
297            crs.absolute((row));
298            crs1.absolute(row);
299            for (int col = 1; col <= cols; col++) {
300                compareColumnValue(JDBCType.valueOf(rsmd.getColumnType(col)),
301                        crs, crs1, col);
302            }
303        }
304
305    }
306
307    /*
308     * Utility method to compare two columns
309     */
310    private void compareColumnValue(JDBCType type, ResultSet rs, ResultSet rs1,
311            int col) throws SQLException {
312
313        switch (type) {
314            case INTEGER:
315                assertTrue(rs.getInt(col) == rs1.getInt(col));
316                break;
317            case CHAR:
318            case VARCHAR:
319                assertTrue(rs.getString(col).equals(rs1.getString(col)));
320                break;
321            case BIGINT:
322                assertTrue(rs.getLong(col) == rs1.getLong(col));
323                break;
324            case BOOLEAN:
325                assertTrue(rs.getBoolean(col) == rs1.getBoolean(col));
326                break;
327            case SMALLINT:
328                assertTrue(rs.getShort(col) == rs1.getShort(col));
329                break;
330            case DOUBLE:
331            case FLOAT:
332                assertTrue(rs.getDouble(col) == rs1.getDouble(col));
333                break;
334            case DECIMAL:
335                assertTrue(rs.getBigDecimal(col).equals(rs1.getBigDecimal(col)));
336                break;
337            case REAL:
338                assertTrue(rs.getFloat(col) == rs1.getFloat(col));
339                break;
340            case TINYINT:
341                assertTrue(rs.getByte(col) == rs1.getByte(col));
342                break;
343            case DATE:
344                assertTrue(rs.getDate(col).equals(rs1.getDate(col)));
345                break;
346            case TIME:
347                assertTrue(rs.getTime(col).equals(rs1.getTime(col)));
348                break;
349            case TIMESTAMP:
350                assertTrue(rs.getTimestamp(col).equals(rs1.getTimestamp(col)));
351                break;
352        }
353    }
354
355    /*
356     * Validate SyncProviderException is thrown when acceptChanges is called
357     * but there is not a way to make a connection to the datasource
358     */
359    @Test(dataProvider = "rowSetType", expectedExceptions = SyncProviderException.class)
360    public void commonCachedRowSetTest0000(CachedRowSet rs) throws Exception {
361        rs.acceptChanges();
362        rs.close();
363    }
364
365    /*
366     * Validate SyncProviderException is thrown when acceptChanges is called
367     * when null is passed as the datasource
368     */
369    @Test(dataProvider = "rowSetType", expectedExceptions = SyncProviderException.class)
370    public void commonCachedRowSetTest0001(CachedRowSet rs) throws Exception {
371        rs.acceptChanges(null);
372        rs.close();
373    }
374
375    /*
376     * Validate that that RIOPtimsticProvider is the default SyncProvider
377     */
378    @Test(dataProvider = "rowSetType")
379    public void commonCachedRowSetTest0002(CachedRowSet rs) throws SQLException {
380        SyncProvider sp = rs.getSyncProvider();
381        assertTrue(sp instanceof com.sun.rowset.providers.RIOptimisticProvider);
382        rs.close();
383    }
384
385    /*
386     * Validate that you can specify a SyncProvider
387     */
388    @Test(dataProvider = "rowSetType")
389    public void commonCachedRowSetTest0003(CachedRowSet rs) throws SQLException {
390
391        // Register a provider and make sure it is avaiable
392        SyncFactory.registerProvider(stubProvider);
393        rs.setSyncProvider(stubProvider);
394        SyncProvider sp = rs.getSyncProvider();
395        assertTrue(sp instanceof StubSyncProvider);
396        SyncFactory.unregisterProvider(stubProvider);
397        rs.close();
398    }
399
400    /*
401     * Create a RowSetListener and validate that notifyRowSetChanged is called
402     */
403    @Test(dataProvider = "rowSetType")
404    public void commonCachedRowSetTest0004(CachedRowSet rs) throws Exception {
405        TestRowSetListener rsl = new TestRowSetListener();
406        rs.addRowSetListener(rsl);
407        rs.release();
408        assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
409        rs.close();
410    }
411
412    /*
413     * Create a RowSetListener and validate that notifyRowSetChanged is called
414     */
415    @Test(dataProvider = "rowSetType")
416    public void commonCachedRowSetTest0005(CachedRowSet rs) throws Exception {
417        TestRowSetListener rsl = new TestRowSetListener();
418        rs.addRowSetListener(rsl);
419        rs.restoreOriginal();
420        assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
421        rs.close();
422    }
423
424    /*
425     * Create a RowSetListener and validate that notifyRowChanged is called
426     */
427    @Test(dataProvider = "rowsetUsingCoffeeHouses")
428    public void commonCachedRowSetTest0006(RowSet rs) throws Exception {
429        TestRowSetListener rsl = new TestRowSetListener();
430        rs.addRowSetListener(rsl);
431        rs.moveToInsertRow();
432        rs.updateInt(1, 10024);
433        rs.updateString(2, "Sacramento");
434        rs.updateInt(3, 1987);
435        rs.updateInt(4, 2341);
436        rs.updateInt(5, 4328);
437        rs.insertRow();
438        assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
439        rs.close();
440    }
441
442    /*
443     * Create a multiple RowSetListeners and validate that notifyRowChanged,
444     * notifiyMoved is called on all listners
445     */
446    @Test(dataProvider = "rowsetUsingCoffeeHouses")
447    public void commonCachedRowSetTest0007(RowSet rs) throws Exception {
448        TestRowSetListener rsl = new TestRowSetListener();
449        TestRowSetListener rsl2 = new TestRowSetListener();
450        rs.addRowSetListener(rsl);
451        rs.addRowSetListener(rsl2);
452        rs.first();
453        rs.updateInt(1, 1961);
454        rs.updateString(2, "Pittsburgh");
455        rs.updateInt(3, 1987);
456        rs.updateInt(4, 2341);
457        rs.updateInt(5, 6689);
458        rs.updateRow();
459        assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED
460                | TestRowSetListener.ROW_CHANGED));
461        assertTrue(rsl2.isNotified(TestRowSetListener.CURSOR_MOVED
462                | TestRowSetListener.ROW_CHANGED));
463        rs.close();
464    }
465
466    /*
467     * Create a RowSetListener and validate that notifyRowChanged  and
468     * notifyCursorMoved are  called
469     */
470    @Test(dataProvider = "rowsetUsingCoffeeHouses")
471    public void commonCachedRowSetTest0008(CachedRowSet rs) throws Exception {
472        TestRowSetListener rsl = new TestRowSetListener();
473        rs.addRowSetListener(rsl);
474
475        rs.first();
476        assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
477        rs.deleteRow();
478        assertTrue(
479                rsl.isNotified(TestRowSetListener.ROW_CHANGED | TestRowSetListener.CURSOR_MOVED));
480        rsl.resetFlag();
481        rs.setShowDeleted(true);
482        rs.undoDelete();
483        assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
484        rs.close();
485    }
486
487    /*
488     * Create a RowSetListener and validate that notifyCursorMoved is called
489     */
490    @Test(dataProvider = "rowSetType")
491    public void commonCachedRowSetTest0009(RowSet rs) throws Exception {
492        TestRowSetListener rsl = new TestRowSetListener();
493        rs.addRowSetListener(rsl);
494        rs.beforeFirst();
495        assertTrue(rsl.isNotified(TestRowSetListener.CURSOR_MOVED));
496        rs.close();
497    }
498
499    /*
500     * Validate that getTableName() returns the proper values
501     */
502    @Test(dataProvider = "rowSetType")
503    public void commonCachedRowSetTest0010(CachedRowSet rs) throws Exception {
504        assertNull(rs.getTableName());
505        rs.setTableName(COFFEE_HOUSES_TABLE);
506        assertTrue(rs.getTableName().equals(COFFEE_HOUSES_TABLE));
507        rs.close();
508    }
509
510    /*
511     * Validate that getKeyColumns() returns the proper values
512     */
513    @Test(dataProvider = "rowSetType")
514    public void commonCachedRowSetTest0011(CachedRowSet rs) throws Exception {
515        int[] pkeys = {1, 3};
516        assertNull(rs.getKeyColumns());
517        rs.setKeyColumns(pkeys);
518        assertEquals(rs.getKeyColumns(), pkeys);
519        rs.close();
520    }
521
522    /*
523     * Validate that setMatchColumn throws a SQLException if the column
524     * index specified is out of range
525     */
526    @Test(dataProvider = "rowsetUsingCoffeeHouses",
527            expectedExceptions = SQLException.class)
528    public void commonCachedRowSetTest0012(CachedRowSet rs) throws Exception {
529        rs.setMatchColumn(-1);
530        rs.close();
531    }
532
533    /*
534     * Validate that setMatchColumn throws a SQLException if the column
535     * index specified is out of range
536     */
537    @Test(dataProvider = "rowsetUsingCoffeeHouses",
538            expectedExceptions = SQLException.class)
539    public void commonCachedRowSetTest0013(CachedRowSet rs) throws Exception {
540        int[] cols = {1, -1};
541        rs.setMatchColumn(cols);
542        rs.close();
543    }
544
545    /*
546     * Validate that setMatchColumn throws a SQLException if the column
547     * index specified is out of range
548     */
549    @Test(dataProvider = "rowsetUsingCoffeeHouses",
550            expectedExceptions = SQLException.class)
551    public void commonCachedRowSetTest0014(CachedRowSet rs) throws Exception {
552        rs.setMatchColumn((String) null);
553        rs.close();
554    }
555
556    /*
557     * Validate that setMatchColumn throws a SQLException if the column
558     * index specified is out of range
559     */
560    @Test(dataProvider = "rowsetUsingCoffeeHouses",
561            expectedExceptions = SQLException.class)
562    public void commonCachedRowSetTest0015(CachedRowSet rs) throws Exception {
563        String[] cols = {"ID", null};
564        rs.setMatchColumn(cols);
565    }
566
567    /*
568     * Validate that getMatchColumn returns the same value specified by
569     * setMatchColumn
570     */
571    @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
572    public void commonCachedRowSetTest0016(CachedRowSet rs) throws Exception {
573        int[] expectedCols = {1};
574        String[] expectedColNames = {"ID"};
575        rs.setMatchColumn(1);
576        int[] actualCols = rs.getMatchColumnIndexes();
577        String[] actualColNames = rs.getMatchColumnNames();
578        for (int i = 0; i < actualCols.length; i++) {
579            System.out.println(actualCols[i]);
580        }
581        assertEquals(actualCols, expectedCols);
582        assertEquals(actualColNames, expectedColNames);
583        rs.close();
584    }
585
586    /*
587     * Validate that getMatchColumn returns the same value specified by
588     * setMatchColumn
589     */
590    @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
591    public void commonCachedRowSetTest0017(CachedRowSet rs) throws Exception {
592        int[] expectedCols = {1};
593        String[] expectedColNames = {"ID"};
594        rs.setMatchColumn(expectedColNames[0]);
595        int[] actualCols = rs.getMatchColumnIndexes();
596        String[] actualColNames = rs.getMatchColumnNames();
597        assertEquals(actualCols, expectedCols);
598        assertEquals(actualColNames, expectedColNames);
599        rs.close();
600    }
601
602    /*
603     * Validate that getMatchColumn returns the same valid value specified by
604     * setMatchColumn
605     */
606    @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
607    public void commonCachedRowSetTest0018(CachedRowSet rs) throws Exception {
608        int[] expectedCols = {1, 3};
609        String[] expectedColNames = {"COF_ID", "SUP_ID"};
610        rs.setMatchColumn(expectedCols);
611        int[] actualCols = rs.getMatchColumnIndexes();
612        String[] actualColNames = rs.getMatchColumnNames();
613        assertEquals(actualCols, expectedCols);
614        assertEquals(actualColNames, expectedColNames);
615        assertEquals(actualCols, expectedCols);
616        rs.close();
617    }
618
619    /*
620     * Validate that getMatchColumn returns the same valid value specified by
621     * setMatchColumn
622     */
623    @Test(dataProvider = "rowsetUsingCoffeeHouses", enabled = false)
624    public void commonCachedRowSetTest0019(CachedRowSet rs) throws Exception {
625        int[] expectedCols = {1, 3};
626        String[] expectedColNames = {"COF_ID", "SUP_ID"};
627        rs.setMatchColumn(expectedColNames);
628        int[] actualCols = rs.getMatchColumnIndexes();
629        String[] actualColNames = rs.getMatchColumnNames();
630        assertEquals(actualCols, expectedCols);
631        assertEquals(actualColNames, expectedColNames);
632        rs.close();
633    }
634
635    /*
636     * Validate that getMatchColumnIndexes throws a SQLException if
637     * unsetMatchColumn has been called
638     */
639    @Test(dataProvider = "rowsetUsingCoffeeHouses",
640            expectedExceptions = SQLException.class)
641    public void commonCachedRowSetTest0020(CachedRowSet rs) throws Exception {
642        rs.setMatchColumn(1);
643        int[] actualCols = rs.getMatchColumnIndexes();
644        assertTrue(actualCols != null);
645        rs.unsetMatchColumn(1);
646        actualCols = rs.getMatchColumnIndexes();
647        rs.close();
648    }
649
650    /*
651     * Validate that getMatchColumnNames throws a SQLException if
652     * unsetMatchColumn has been called
653     */
654    @Test(dataProvider = "rowsetUsingCoffeeHouses",
655            expectedExceptions = SQLException.class)
656    public void commonCachedRowSetTest0021(CachedRowSet rs) throws Exception {
657        String matchColumn = "ID";
658        rs.setMatchColumn(matchColumn);
659        String[] actualColNames = rs.getMatchColumnNames();
660        assertTrue(actualColNames != null);
661        rs.unsetMatchColumn(matchColumn);
662        actualColNames = rs.getMatchColumnNames();
663        rs.close();
664    }
665
666    /*
667     * Validate that getMatchColumnIndexes throws a SQLException if
668     * unsetMatchColumn has been called
669     */
670    @Test(dataProvider = "rowsetUsingCoffeeHouses",
671            expectedExceptions = SQLException.class)
672    public void commonCachedRowSetTest0022(CachedRowSet rs) throws Exception {
673        int[] expectedCols = {1, 3};
674        rs.setMatchColumn(expectedCols);
675        int[] actualCols = rs.getMatchColumnIndexes();
676        assertTrue(actualCols != null);
677        rs.unsetMatchColumn(expectedCols);
678        actualCols = rs.getMatchColumnIndexes();
679        rs.close();
680    }
681
682    /*
683     * Validate that getMatchColumnNames throws a SQLException if
684     * unsetMatchColumn has been called
685     */
686    @Test(dataProvider = "rowsetUsingCoffeeHouses",
687            expectedExceptions = SQLException.class)
688    public void commonCachedRowSetTest0023(CachedRowSet rs) throws Exception {
689        String[] expectedColNames = {"COF_ID", "SUP_ID"};
690        rs.setMatchColumn(expectedColNames);
691        String[] actualColNames = rs.getMatchColumnNames();
692        assertTrue(actualColNames != null);
693        rs.unsetMatchColumn(expectedColNames);
694        actualColNames = rs.getMatchColumnNames();
695        rs.close();
696    }
697
698    /*
699     * Validate size() returns the correct number of rows
700     */
701    @Test(dataProvider = "rowsetUsingCoffeeHouses")
702    public void commonCachedRowSetTest0024(CachedRowSet rs) throws Exception {
703        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
704        rs.close();
705    }
706
707    /*
708     * Validate that the correct rows are returned comparing the primary
709     * keys
710     */
711    @Test(dataProvider = "rowsetUsingCoffeeHouses")
712    public void commonCachedRowSetTest0025(RowSet rs) throws SQLException {
713        assertEquals(getPrimaryKeys(rs), COFFEE_HOUSES_PRIMARY_KEYS);
714        rs.close();
715    }
716
717    /*
718     * Delete a row within the RowSet using its primary key
719     * Validate the visibility of the row depending on the value of
720     * setShowdelete
721     */
722    @Test(dataProvider = "rowsetUsingCoffeeHouses")
723    public void commonCachedRowSetTest0026(CachedRowSet rs) throws Exception {
724        Object[] afterDelete = {
725            10023, 33002, 10040, 32001, 10042, 10024, 10039, 10041,
726            33005, 33010, 10037, 10034, 32004
727        };
728        int rowToDelete = 10035;
729        // All rows should be found
730        assertEquals(getPrimaryKeys(rs), COFFEE_HOUSES_PRIMARY_KEYS);
731        // Delete the row
732        assertTrue(deleteRowByPrimaryKey(rs, rowToDelete, 1));
733        // With setShowDeleted(false) which is the default,
734        // the deleted row should not be visible
735        assertFalse(findRowByPrimaryKey(rs, rowToDelete, 1));
736        assertEquals(getPrimaryKeys(rs), afterDelete);
737        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
738        // With setShowDeleted(true), the deleted row should be visible
739        rs.setShowDeleted(true);
740        assertTrue(findRowByPrimaryKey(rs, rowToDelete, 1));
741        rs.close();
742    }
743
744    /*
745     * Validate that there is no page size by default
746     */
747    @Test(dataProvider = "rowSetType")
748    public void commonCachedRowSetTest0027(CachedRowSet rs) throws Exception {
749        assertTrue(rs.getPageSize() == 0);
750        rs.close();
751    }
752
753    /*
754     * Validate the value you set via setPageSize is returned by getPageSize
755     * then reset to having no limit
756     */
757    @Test(dataProvider = "rowSetType")
758    public void commonCachedRowSetTest0028(CachedRowSet rs) throws Exception {
759        int rows = 100;
760        rs.setPageSize(rows);
761        assertTrue(rows == rs.getPageSize());
762        rs.setPageSize(0);
763        assertTrue(rs.getPageSize() == 0);
764        rs.close();
765    }
766
767    /*
768     * Validate SQLException is thrown when an invalid value is specified
769     * for setPageSize
770     */
771    @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
772    public void commonCachedRowSetTest0029(CachedRowSet rs) throws Exception {
773        rs.setPageSize(-1);
774        rs.close();
775    }
776
777    /*
778     * Validate SQLException is thrown when nextPage is called without a
779     * call to populate or execute
780     */
781    @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
782    public void commonCachedRowSetTest0030(CachedRowSet rs) throws Exception {
783        rs.nextPage();
784        rs.close();
785    }
786
787    /*
788     * Validate SQLException is thrown when previousPage is called without a
789     * call to populate or execute
790     */
791    @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
792    public void commonCachedRowSetTest0031(CachedRowSet rs) throws Exception {
793        rs.previousPage();
794        rs.close();
795    }
796
797
798    /*
799     * Validate SQLException is thrown when execute is called
800     * but there is not a way to make a connection to the datasource
801     */
802    @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
803    public void commonCachedRowSetTest0032(CachedRowSet rs) throws Exception {
804        rs.execute(null);
805        rs.close();
806    }
807
808    /*
809     * Validate SQLException is thrown when execute is called
810     * but there is not a way to make a connection to the datasource
811     */
812    @Test(dataProvider = "rowSetType", expectedExceptions = SQLException.class)
813    public void commonCachedRowSetTest0033(CachedRowSet rs) throws Exception {
814        rs.execute();
815        rs.close();
816    }
817
818    /*
819     * Validate that toCollection(<column>) returns the proper values
820     */
821    @Test(dataProvider = "rowsetUsingCoffeeHouses")
822    public void commonCachedRowSetTest0034(CachedRowSet rs) throws Exception {
823        Object[] cities = {"Mendocino", "Seattle", "SF", "Portland", "SF",
824            "Sacramento", "Carmel", "LA", "Olympia", "Seattle", "SF",
825            "LA", "San Jose", "Eugene"};
826        rs.beforeFirst();
827        assertEquals(rs.toCollection(2).toArray(), cities);
828        assertEquals(rs.toCollection("CITY").toArray(), cities);
829        rs.close();
830    }
831
832    /*
833     * Validate that toCollection() returns the proper values
834     */
835    @Test(dataProvider = "rowsetUsingCoffeeHouses")
836    public void commonCachedRowSetTest0035(CachedRowSet rs) throws Exception {
837        Collection<?> col = rs.toCollection();
838        assertTrue(rs.size() == col.size());
839        assertTrue(rs.toCollection().containsAll(col)
840                && col.containsAll(rs.toCollection()));
841        try ( // Validate that False is returned when compared to a different RowSet;
842                CachedRowSet crs1 = createCoffeesRowSet()) {
843            assertFalse(crs1.toCollection().containsAll(col)
844                    && col.containsAll(crs1.toCollection()));
845        }
846        rs.close();
847
848    }
849
850    /*
851     * Validate that createCopy() returns the proper values
852     */
853    @Test(dataProvider = "rowsetUsingCoffeeHouses")
854    public void commonCachedRowSetTest0036(CachedRowSet rs) throws Exception {
855        try (CachedRowSet crs1 = rs.createCopy()) {
856            compareRowSets(rs, crs1);
857        }
858        rs.close();
859    }
860
861    /*
862     * Validate that createCopySchema() returns the proper values
863     */
864    @Test(dataProvider = "rowsetUsingCoffeeHouses")
865    public void commonCachedRowSetTest0037(CachedRowSet rs) throws Exception {
866        try (CachedRowSet crs1 = rs.createCopySchema()) {
867            assertTrue(crs1.size() == 0);
868            compareMetaData(crs1.getMetaData(), rs.getMetaData());
869        }
870        rs.close();
871    }
872
873    /*
874     * Validate that createCopyNoConstraints() returns the proper values
875     * and getMatchColumnIndexes should throw a SQLException. This test
876     * specifies setMatchColumn(int)
877     */
878    @Test(dataProvider = "rowsetUsingCoffeeHouses")
879    public void commonCachedRowSetTest0038(CachedRowSet rs) throws Exception {
880        rs.setMatchColumn(1);
881        try (CachedRowSet crs1 = rs.createCopyNoConstraints()) {
882            assertTrue(crs1.size() == COFFEE_HOUSES_ROWS);
883            compareRowSets(rs, crs1);
884            boolean recievedSQE = false;
885            try {
886                int[] indexes = crs1.getMatchColumnIndexes();
887            } catch (SQLException e) {
888                recievedSQE = true;
889            }
890            assertTrue(recievedSQE);
891            recievedSQE = false;
892            try {
893                String[] colNames = crs1.getMatchColumnNames();
894            } catch (SQLException e) {
895                recievedSQE = true;
896            }
897            assertTrue(recievedSQE);
898        }
899        rs.close();
900    }
901
902    /*
903     * Validate that createCopyNoConstraints() returns the proper values
904     * and getMatchColumnIndexes should throw a SQLException. This test
905     * specifies setMatchColumn(String)
906     */
907    @Test(dataProvider = "rowsetUsingCoffeeHouses")
908    public void commonCachedRowSetTest0039(CachedRowSet rs) throws Exception {
909        rs.setMatchColumn("ID");
910        try (CachedRowSet crs1 = rs.createCopyNoConstraints()) {
911            assertTrue(crs1.size() == COFFEE_HOUSES_ROWS);
912            compareRowSets(rs, crs1);
913            boolean recievedSQE = false;
914            try {
915                int[] indexes = crs1.getMatchColumnIndexes();
916            } catch (SQLException e) {
917                recievedSQE = true;
918            }
919            assertTrue(recievedSQE);
920            recievedSQE = false;
921            try {
922                String[] colNames = crs1.getMatchColumnNames();
923            } catch (SQLException e) {
924                recievedSQE = true;
925            }
926            assertTrue(recievedSQE);
927        }
928        rs.close();
929    }
930
931    /*
932     * Validate that columnUpdated works with the various datatypes specifying
933     * the column index
934     */
935    @Test(dataProvider = "rowsetUsingDataTypes")
936    public void commonCachedRowSetTest0040(CachedRowSet rs, JDBCType type) throws Exception {
937        rs.beforeFirst();
938        assertTrue(rs.next());
939        switch (type) {
940            case INTEGER:
941                assertFalse(rs.columnUpdated(1));
942                rs.updateInt(1, Integer.MIN_VALUE);
943                assertTrue(rs.columnUpdated(1));
944                break;
945            case CHAR:
946                assertFalse(rs.columnUpdated(2));
947                rs.updateString(2, "foo");
948                assertTrue(rs.columnUpdated(2));
949                break;
950            case VARCHAR:
951                assertFalse(rs.columnUpdated(3));
952                rs.updateString(3, "foo");
953                assertTrue(rs.columnUpdated(3));
954                break;
955            case BIGINT:
956                assertFalse(rs.columnUpdated(4));
957                rs.updateLong(4, Long.MIN_VALUE);
958                assertTrue(rs.columnUpdated(4));
959                break;
960            case BOOLEAN:
961                assertFalse(rs.columnUpdated(5));
962                rs.updateBoolean(5, false);
963                assertTrue(rs.columnUpdated(5));
964                break;
965            case SMALLINT:
966                assertFalse(rs.columnUpdated(6));
967                rs.updateShort(6, Short.MIN_VALUE);
968                assertTrue(rs.columnUpdated(6));
969                break;
970            case DOUBLE:
971                assertFalse(rs.columnUpdated(7));
972                rs.updateDouble(7, Double.MIN_VALUE);
973                assertTrue(rs.columnUpdated(7));
974                break;
975            case DECIMAL:
976                assertFalse(rs.columnUpdated(8));
977                rs.updateBigDecimal(8, BigDecimal.TEN);
978                assertTrue(rs.columnUpdated(8));
979                break;
980            case REAL:
981                assertFalse(rs.columnUpdated(9));
982                rs.updateFloat(9, Float.MIN_VALUE);
983                assertTrue(rs.columnUpdated(9));
984                break;
985            case TINYINT:
986                assertFalse(rs.columnUpdated(10));
987                rs.updateByte(10, Byte.MIN_VALUE);
988                assertTrue(rs.columnUpdated(10));
989                break;
990            case DATE:
991                assertFalse(rs.columnUpdated(11));
992                rs.updateDate(11, Date.valueOf(LocalDate.now()));
993                assertTrue(rs.columnUpdated(11));
994                break;
995            case TIME:
996                assertFalse(rs.columnUpdated(12));
997                rs.updateTime(12, Time.valueOf(LocalTime.now()));
998                assertTrue(rs.columnUpdated(12));
999                break;
1000            case TIMESTAMP:
1001                assertFalse(rs.columnUpdated(13));
1002                rs.updateTimestamp(13, Timestamp.valueOf(LocalDateTime.now()));
1003                assertTrue(rs.columnUpdated(13));
1004                break;
1005            case VARBINARY:
1006                assertFalse(rs.columnUpdated(14));
1007                rs.updateBytes(14, new byte[1]);
1008                assertTrue(rs.columnUpdated(14));
1009                break;
1010            case ARRAY:
1011                assertFalse(rs.columnUpdated(15));
1012                rs.updateArray(15, new StubArray("VARCHAR", new Object[10]));
1013                assertTrue(rs.columnUpdated(15));
1014                break;
1015            case REF:
1016                assertFalse(rs.columnUpdated(16));
1017                rs.updateRef(16, new StubRef("INTEGER", query));
1018                assertTrue(rs.columnUpdated(16));
1019                break;
1020            case FLOAT:
1021                assertFalse(rs.columnUpdated(17));
1022                rs.updateDouble(17, Double.MIN_NORMAL);
1023                assertTrue(rs.columnUpdated(17));
1024        }
1025
1026    }
1027
1028    /*
1029     * Validate that columnUpdated works with the various datatypes specifying
1030     * the column name
1031     */
1032    @Test(dataProvider = "rowsetUsingDataTypes")
1033    public void commonCachedRowSetTest0041(CachedRowSet rs, JDBCType type) throws Exception {
1034        rs.beforeFirst();
1035        assertTrue(rs.next());
1036        switch (type) {
1037            case INTEGER:
1038                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[0]));
1039                rs.updateInt(DATATYPES_COLUMN_NAMES[0], Integer.MIN_VALUE);
1040                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[0]));
1041                break;
1042            case CHAR:
1043                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[1]));
1044                rs.updateString(DATATYPES_COLUMN_NAMES[1], "foo");
1045                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[1]));
1046                break;
1047            case VARCHAR:
1048                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[2]));
1049                rs.updateString(DATATYPES_COLUMN_NAMES[2], "foo");
1050                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[2]));
1051                break;
1052            case BIGINT:
1053                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[3]));
1054                rs.updateLong(DATATYPES_COLUMN_NAMES[3], Long.MIN_VALUE);
1055                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[3]));
1056                break;
1057            case BOOLEAN:
1058                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[4]));
1059                rs.updateBoolean(DATATYPES_COLUMN_NAMES[4], false);
1060                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[4]));
1061                break;
1062            case SMALLINT:
1063                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[5]));
1064                rs.updateShort(DATATYPES_COLUMN_NAMES[5], Short.MIN_VALUE);
1065                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[5]));
1066                break;
1067            case DOUBLE:
1068                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[6]));
1069                rs.updateDouble(DATATYPES_COLUMN_NAMES[6], Double.MIN_VALUE);
1070                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[6]));
1071                break;
1072            case DECIMAL:
1073                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[7]));
1074                rs.updateBigDecimal(DATATYPES_COLUMN_NAMES[7], BigDecimal.TEN);
1075                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[7]));
1076                break;
1077            case REAL:
1078                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[8]));
1079                rs.updateFloat(DATATYPES_COLUMN_NAMES[8], Float.MIN_VALUE);
1080                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[8]));
1081                break;
1082            case TINYINT:
1083                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[9]));
1084                rs.updateByte(DATATYPES_COLUMN_NAMES[9], Byte.MIN_VALUE);
1085                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[9]));
1086                break;
1087            case DATE:
1088                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[10]));
1089                rs.updateDate(DATATYPES_COLUMN_NAMES[10], Date.valueOf(LocalDate.now()));
1090                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[10]));
1091                break;
1092            case TIME:
1093                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[11]));
1094                rs.updateTime(DATATYPES_COLUMN_NAMES[11], Time.valueOf(LocalTime.now()));
1095                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[11]));
1096                break;
1097            case TIMESTAMP:
1098                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[12]));
1099                rs.updateTimestamp(DATATYPES_COLUMN_NAMES[12], Timestamp.valueOf(LocalDateTime.now()));
1100                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[12]));
1101                break;
1102            case VARBINARY:
1103                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[13]));
1104                rs.updateBytes(DATATYPES_COLUMN_NAMES[13], new byte[1]);
1105                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[13]));
1106                break;
1107            case ARRAY:
1108                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[14]));
1109                rs.updateArray(DATATYPES_COLUMN_NAMES[14], new StubArray("VARCHAR", new Object[10]));
1110                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[14]));
1111                break;
1112            case REF:
1113                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[15]));
1114                rs.updateRef(DATATYPES_COLUMN_NAMES[15], new StubRef("INTEGER", query));
1115                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[15]));
1116                break;
1117            case FLOAT:
1118                assertFalse(rs.columnUpdated(DATATYPES_COLUMN_NAMES[16]));
1119                rs.updateDouble(DATATYPES_COLUMN_NAMES[16], Double.MIN_NORMAL);
1120                assertTrue(rs.columnUpdated(DATATYPES_COLUMN_NAMES[16]));
1121                break;
1122        }
1123
1124    }
1125
1126    /*
1127     * Validate isBeforeFirst(), isFirst() and first() return the correct
1128     * results
1129     */
1130    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1131    public void commonCachedRowSetTest0042(RowSet rs) throws Exception {
1132        assertFalse(rs.isBeforeFirst());
1133        assertFalse(rs.isFirst());
1134        rs.beforeFirst();
1135        assertTrue(rs.isBeforeFirst());
1136        assertFalse(rs.isFirst());
1137        rs.next();
1138        assertFalse(rs.isBeforeFirst());
1139        assertTrue(rs.isFirst());
1140        rs.next();
1141        assertFalse(rs.isBeforeFirst());
1142        assertFalse(rs.isFirst());
1143        rs.first();
1144        assertFalse(rs.isBeforeFirst());
1145        assertTrue(rs.isFirst());
1146        rs.close();
1147    }
1148
1149    /*
1150     * Validate isAfterLast(), isLast() and last() return the correct
1151     * results
1152     */
1153    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1154    public void commonCachedRowSetTest0043(RowSet rs) throws Exception {
1155        assertFalse(rs.isAfterLast());
1156        assertFalse(rs.isLast());
1157        rs.afterLast();
1158        assertTrue(rs.isAfterLast());
1159        assertFalse(rs.isLast());
1160        rs.previous();
1161        assertFalse(rs.isAfterLast());
1162        assertTrue(rs.isLast());
1163        rs.previous();
1164        assertFalse(rs.isAfterLast());
1165        assertFalse(rs.isLast());
1166        rs.last();
1167        assertFalse(rs.isAfterLast());
1168        assertTrue(rs.isLast());
1169        rs.close();
1170    }
1171
1172    /*
1173     * Validate a SQLException is thrown when undoDelete is called on the
1174     * insertRow
1175     */
1176    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1177            expectedExceptions = SQLException.class)
1178    public void commonCachedRowSetTest0044(CachedRowSet rs) throws Exception {
1179        rs.insertRow();
1180        rs.undoDelete();
1181        rs.close();
1182    }
1183
1184    /*
1185     * Validate a SQLException is thrown when undoDelete is called when
1186     * cursor is before the first row
1187     */
1188    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1189            expectedExceptions = SQLException.class)
1190    public void commonCachedRowSetTest0045(CachedRowSet rs) throws Exception {
1191        rs.setShowDeleted(true);
1192        rs.beforeFirst();
1193        rs.undoDelete();
1194        rs.close();
1195    }
1196
1197    /*
1198     * Validate a SQLException is thrown when undoDelete is called when
1199     * cursor is after the last row
1200     */
1201    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1202            expectedExceptions = SQLException.class)
1203    public void commonCachedRowSetTest0046(CachedRowSet rs) throws Exception {
1204        rs.setShowDeleted(true);
1205        rs.afterLast();
1206        rs.undoDelete();
1207        rs.close();
1208    }
1209
1210    /*
1211     * Validate a SQLException is thrown when undoUpdate is called on the
1212     * insertRow
1213     */
1214    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1215            expectedExceptions = SQLException.class)
1216    public void commonCachedRowSetTest0047(CachedRowSet rs) throws Exception {
1217        rs.insertRow();
1218        rs.undoUpdate();
1219        rs.close();
1220    }
1221
1222    /*
1223     * Validate a SQLException is thrown when undoUpdate is called when
1224     * cursor is before the first row
1225     */
1226    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1227            expectedExceptions = SQLException.class)
1228    public void commonCachedRowSetTest0048(CachedRowSet rs) throws Exception {
1229        rs.setShowDeleted(true);
1230        rs.beforeFirst();
1231        rs.undoUpdate();
1232        rs.close();
1233    }
1234
1235    /*
1236     * Validate a SQLException is thrown when undoUpdate is called when
1237     * cursor is after the last row
1238     */
1239    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1240            expectedExceptions = SQLException.class)
1241    public void commonCachedRowSetTest0049(CachedRowSet rs) throws Exception {
1242        rs.setShowDeleted(true);
1243        rs.afterLast();
1244        rs.undoUpdate();
1245        rs.close();
1246    }
1247
1248    /*
1249     * Validate a SQLException is thrown when undoInsert is called on the
1250     * insertRow
1251     */
1252    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1253            expectedExceptions = SQLException.class)
1254    public void commonCachedRowSetTest0050(CachedRowSet rs) throws Exception {
1255        rs.insertRow();
1256        rs.undoInsert();
1257        rs.close();
1258    }
1259
1260    /*
1261     * Validate a SQLException is thrown when undoInsert is called when
1262     * cursor is before the first row
1263     */
1264    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1265            expectedExceptions = SQLException.class)
1266    public void commonCachedRowSetTest0051(CachedRowSet rs) throws Exception {
1267        rs.setShowDeleted(true);
1268        rs.beforeFirst();
1269        rs.undoInsert();
1270        rs.close();
1271    }
1272
1273    /*
1274     * Validate a SQLException is thrown when undoInsert is called when
1275     * cursor is after the last row
1276     */
1277    @Test(dataProvider = "rowsetUsingCoffeeHouses",
1278            expectedExceptions = SQLException.class)
1279    public void commonCachedRowSetTest0052(CachedRowSet rs) throws Exception {
1280        rs.setShowDeleted(true);
1281        rs.afterLast();
1282        rs.undoInsert();
1283        rs.close();
1284    }
1285
1286    /*
1287     * Insert a row, then call undoInsert to roll back the insert and validate
1288     * the row is not there
1289     */
1290    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1291    public void commonCachedRowSetTest0053(CachedRowSet rs) throws Exception {
1292        int rowToInsert = 1961;
1293        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
1294        // Add new row
1295        rs.moveToInsertRow();
1296        rs.updateInt(1, rowToInsert);
1297        rs.updateString(2, "GOTHAM");
1298        rs.updateInt(3, 3450);
1299        rs.updateInt(4, 2005);
1300        rs.updateInt(5, 5455);
1301        rs.insertRow();
1302        rs.moveToCurrentRow();
1303        // check that the number of rows has increased
1304        assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
1305        assertTrue(findRowByPrimaryKey(rs, rowToInsert, 1));
1306        rs.undoInsert();
1307        // Check to make sure the row is no longer there
1308        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
1309        assertFalse(findRowByPrimaryKey(rs, rowToInsert, 1));
1310        rs.close();
1311    }
1312
1313    /*
1314     * Insert a row, delete the row and then call undoDelete to make sure it
1315     * is comes back
1316     */
1317    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1318    public void commonCachedRowSetTest0054(CachedRowSet rs) throws Exception {
1319        int rowToDelete = 1961;
1320        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
1321        // Add new row
1322        rs.moveToInsertRow();
1323        rs.updateInt(1, rowToDelete);
1324        rs.updateString(2, "GOTHAM");
1325        rs.updateInt(3, 3450);
1326        rs.updateInt(4, 2005);
1327        rs.updateInt(5, 5455);
1328        rs.insertRow();
1329        rs.moveToCurrentRow();
1330        // check that the number of rows has increased
1331        assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
1332        assertTrue(findRowByPrimaryKey(rs, rowToDelete, 1));
1333        rs.absolute(COFFEE_HOUSES_ROWS + 1);
1334        rs.deleteRow();
1335        // Check to make sure the row is no longer there
1336        //assertTrue(rs.size() ==  COFFEE_HOUSES_ROWS);
1337        assertFalse(findRowByPrimaryKey(rs, rowToDelete, 1));
1338        rs.setShowDeleted(true);
1339        rs.absolute(COFFEE_HOUSES_ROWS + 1);
1340        rs.undoDelete();
1341        // check that the row is back
1342        assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
1343        assertTrue(findRowByPrimaryKey(rs, rowToDelete, 1));
1344        rs.close();
1345    }
1346
1347    /*
1348     * Insert a row, modify a field and then call undoUpdate to revert the
1349     * insert
1350     */
1351    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1352    public void commonCachedRowSetTest0055(CachedRowSet rs) throws Exception {
1353        int rowToInsert = 1961;
1354        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
1355        // Add new row
1356        rs.moveToInsertRow();
1357        rs.updateInt(1, rowToInsert);
1358        rs.updateString(2, "GOTHAM");
1359        rs.updateInt(3, 3450);
1360        rs.updateInt(4, 2005);
1361        rs.updateInt(5, 5455);
1362        rs.insertRow();
1363        rs.moveToCurrentRow();
1364        // check that the number of rows has increased
1365        assertTrue(rs.size() == COFFEE_HOUSES_ROWS + 1);
1366        assertTrue(findRowByPrimaryKey(rs, rowToInsert, 1));
1367        rs.absolute(COFFEE_HOUSES_ROWS + 1);
1368        // Save off the original column values
1369        String f2 = rs.getString(2);
1370        int f3 = rs.getInt(3);
1371        rs.updateString(2, "SMALLVILLE");
1372        rs.updateInt(3, 500);
1373        // Validate the columns have been updated
1374        assertTrue(rs.columnUpdated(2));
1375        assertTrue(rs.columnUpdated(3));
1376        // Undo the update and validate it has taken place
1377        rs.absolute(COFFEE_HOUSES_ROWS + 1);
1378        rs.undoUpdate();
1379        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
1380        assertFalse(findRowByPrimaryKey(rs, rowToInsert, 1));
1381        rs.close();
1382    }
1383
1384    /*
1385     * Validate getOriginal returns a ResultSet which is a copy of the original
1386     * RowSet
1387     */
1388    @Test(dataProvider = "rowsetUsingCoffees")
1389    public void commonCachedRowSetTest0056(CachedRowSet rs) throws Exception {
1390        String coffee = "Hazelnut";
1391        int sales = 100;
1392        int id = 200;
1393        Object[] updatedPkeys = {1, id, 3, 4, 5};
1394        // Change the coffee name and sales total for row 2 and save the
1395        // previous values
1396        rs.absolute(2);
1397        int origId = rs.getInt(1);
1398        String origCoffee = rs.getString(2);
1399        int origSales = rs.getInt(5);
1400        rs.updateInt(1, id);
1401        rs.updateString(2, coffee);
1402        rs.updateInt(5, sales);
1403        // MetaData should match
1404        try ( // Get the original original RowSet and validate that the changes
1405                // are only made to the current, not the original
1406                ResultSet rs1 = rs.getOriginal()) {
1407            // MetaData should match
1408            compareMetaData(rs.getMetaData(), rs1.getMetaData());
1409            assertTrue(rs1.isBeforeFirst());
1410            assertTrue(rs1.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
1411            assertTrue(rs1.getType() == ResultSet.TYPE_SCROLL_INSENSITIVE);
1412            rs1.absolute(2);
1413            // Check original rowset is not changed
1414            assertTrue(rs1.getInt(1) == origId);
1415            assertTrue(rs1.getString(2).equals(origCoffee));
1416            assertTrue(rs1.getInt(5) == origSales);
1417            assertEquals(getPrimaryKeys(rs1), COFFEES_PRIMARY_KEYS);
1418            // Check current rowset
1419            assertTrue(rs.getInt(1) == id);
1420            assertTrue(rs.getString(2).equals(coffee));
1421            assertTrue(rs.getInt(5) == sales);
1422            assertEquals(getPrimaryKeys(rs), updatedPkeys);
1423        }
1424        rs.close();
1425    }
1426
1427    /*
1428     * Validate getOriginalRow returns a ResultSet which is a copy of the
1429     * original row that was modified
1430     */
1431    @Test(dataProvider = "rowsetUsingCoffees")
1432    public void commonCachedRowSetTest0057(CachedRowSet rs) throws Exception {
1433        String coffee = "Hazelnut";
1434        int sales = 100;
1435        int id = 200;
1436        Object[] updatedPkeys = {1, id, 3, 4, 5};
1437        // Change the coffee name and sales total for row 2 and save the
1438        // previous values
1439        rs.absolute(2);
1440        int origId = rs.getInt(1);
1441        String origCoffee = rs.getString(2);
1442        int origSales = rs.getInt(5);
1443        rs.updateInt(1, id);
1444        rs.updateString(2, coffee);
1445        rs.updateInt(5, sales);
1446        // MetaData should match
1447        try ( // Get the original original row and validate that the changes
1448                // are only made to the current, not the original
1449                ResultSet rs1 = rs.getOriginalRow()) {
1450            // MetaData should match
1451            compareMetaData(rs.getMetaData(), rs1.getMetaData());
1452            assertTrue(rs1.isBeforeFirst());
1453            assertTrue(rs1.getConcurrency() == ResultSet.CONCUR_UPDATABLE);
1454            assertTrue(rs1.getType() == ResultSet.TYPE_SCROLL_INSENSITIVE);
1455            rs1.next();
1456            assertTrue(rs1.isFirst() && rs1.isLast());
1457            assertTrue(rs1.getRow() == 1);
1458            // Check original row is not changed
1459            assertTrue(rs1.getInt(1) == origId);
1460            assertTrue(rs1.getString(2).equals(origCoffee));
1461            assertTrue(rs1.getInt(5) == origSales);
1462            // Check current row
1463            assertTrue(rs.getInt(1) == id);
1464            assertTrue(rs.getString(2).equals(coffee));
1465            assertTrue(rs.getInt(5) == sales);
1466            assertEquals(getPrimaryKeys(rs), updatedPkeys);
1467        }
1468        rs.close();
1469    }
1470
1471    /*
1472     * Validate that restoreOrginal will restore the RowSet to its
1473     * state prior to the insert of a row
1474     */
1475    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1476    public void commonCachedRowSetTest0058(CachedRowSet rs) throws Exception {
1477        int rowToInsert = 1961;
1478        assertTrue(rs.size() == COFFEE_HOUSES_ROWS);
1479        try ( // Add new row
1480                CachedRowSet crs1 = rsf.createCachedRowSet()) {
1481            rs.beforeFirst();
1482            crs1.populate(rs);
1483            TestRowSetListener rsl = new TestRowSetListener();
1484            crs1.addRowSetListener(rsl);
1485            crs1.moveToInsertRow();
1486            crs1.updateInt(1, rowToInsert);
1487            crs1.updateString(2, "GOTHAM");
1488            crs1.updateInt(3, 3450);
1489            crs1.updateInt(4, 2005);
1490            crs1.updateInt(5, 5455);
1491            crs1.insertRow();
1492            assertTrue(rsl.isNotified(TestRowSetListener.ROW_CHANGED));
1493            crs1.moveToCurrentRow();
1494            assertTrue(findRowByPrimaryKey(crs1, rowToInsert, 1));
1495            // Restore back to our original state and the
1496            // previously inserted row should not be there
1497            rsl.resetFlag();
1498            crs1.restoreOriginal();
1499            assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
1500            assertTrue(crs1.isBeforeFirst());
1501            crs1.last();
1502            assertFalse(crs1.rowInserted());
1503            assertFalse(findRowByPrimaryKey(crs1, rowToInsert, 1));
1504        }
1505        rs.close();
1506    }
1507
1508    /*
1509     * Validate that restoreOrginal will restore the RowSet to its
1510     * state prior to deleting a row
1511     */
1512    @Test(dataProvider = "rowsetUsingCoffees", enabled = true)
1513    public void commonCachedRowSetTest0059(CachedRowSet rs) throws Exception {
1514        int rowToDelete = 2;
1515        try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
1516            rs.beforeFirst();
1517            crs1.populate(rs);
1518            TestRowSetListener rsl = new TestRowSetListener();
1519            crs1.addRowSetListener(rsl);
1520            // Delete a row, the PK is also the absolute position as a List
1521            // backs the RowSet
1522            crs1.absolute(rowToDelete);
1523            crs1.deleteRow();
1524            assertTrue(crs1.rowDeleted());
1525            assertFalse(findRowByPrimaryKey(crs1, rowToDelete, 1));
1526            // Restore back to our original state and the
1527            // previously deleted row should be there
1528            rsl.resetFlag();
1529            crs1.restoreOriginal();
1530            assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
1531            assertTrue(crs1.isBeforeFirst());
1532            crs1.absolute(rowToDelete);
1533            assertFalse(crs1.rowDeleted());
1534            assertTrue(findRowByPrimaryKey(crs1, rowToDelete, 1));
1535        }
1536        rs.close();
1537    }
1538
1539    /*
1540     * Validate that restoreOrginal will restore the RowSet to its
1541     * state prior to updating a row
1542     */
1543    @Test(dataProvider = "rowsetUsingCoffees", enabled = true)
1544    public void commonCachedRowSetTest0060(CachedRowSet rs) throws Exception {
1545        int rowToUpdate = 2;
1546        String coffee = "Hazelnut";
1547        try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
1548            rs.beforeFirst();
1549            crs1.populate(rs);
1550            TestRowSetListener rsl = new TestRowSetListener();
1551            crs1.addRowSetListener(rsl);
1552            // Delete a row, the PK is also the absolute position as a List
1553            // backs the RowSet
1554            crs1.absolute(rowToUpdate);
1555            String origCoffee = crs1.getString(2);
1556            crs1.updateString(2, coffee);
1557            assertTrue(crs1.columnUpdated(2));
1558            crs1.updateRow();
1559            assertTrue(crs1.rowUpdated());
1560            assertFalse(origCoffee.equals(crs1.getString(2)));
1561            // Restore back to our original state and the
1562            // previous value for the column within the row should be there
1563            rsl.resetFlag();
1564            crs1.restoreOriginal();
1565            assertTrue(rsl.isNotified(TestRowSetListener.ROWSET_CHANGED));
1566            assertTrue(crs1.isBeforeFirst());
1567            // absolute() is failing for some reason so need to look at this later
1568            crs1.next();
1569            crs1.next();
1570            assertFalse(crs1.columnUpdated(2));
1571            assertFalse(crs1.rowUpdated());
1572            assertTrue(origCoffee.equals(crs1.getString(2)));
1573        }
1574        rs.close();
1575    }
1576
1577    /*
1578     * Initialize a RowSet via the populate method. Validate it matches
1579     * the original ResultSet
1580     */
1581    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1582    public void commonCachedRowSetTest0061(CachedRowSet rs) throws Exception {
1583        try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
1584            rs.beforeFirst();
1585            crs1.populate(rs);
1586            compareRowSets(rs, crs1);
1587        }
1588        rs.close();
1589    }
1590
1591    /*
1592     * Initialize a RowSet via the populate method specifying a starting row.
1593     * Validate it matches the original ResultSet starting for the specofied
1594     * offset
1595     */
1596    @Test(dataProvider = "rowsetUsingCoffeeHouses")
1597    public void commonCachedRowSetTest0062(CachedRowSet rs) throws Exception {
1598        Object[] expectedRows = {
1599            32001, 10042, 10024, 10039, 10041, 33005, 33010, 10035, 10037,
1600            10034, 32004
1601        };
1602        int startingRow = 4;
1603        try (CachedRowSet crs1 = rsf.createCachedRowSet()) {
1604            rs.beforeFirst();
1605            crs1.populate(rs, startingRow);
1606            assertEquals(crs1.size(), COFFEE_HOUSES_ROWS - startingRow + 1);
1607            assertEquals(getPrimaryKeys(crs1), expectedRows);
1608        }
1609        rs.close();
1610    }
1611
1612}
1613