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  */
23 package test.rowset.cachedrowset;
24 
25 import java.math.BigDecimal;
26 import java.sql.Array;
27 import java.sql.Date;
28 import java.sql.JDBCType;
29 import java.sql.Ref;
30 import java.sql.ResultSet;
31 import java.sql.ResultSetMetaData;
32 import java.sql.SQLException;
33 import java.sql.Time;
34 import java.sql.Timestamp;
35 import java.sql.Types;
36 import java.time.LocalDate;
37 import java.time.LocalDateTime;
38 import java.time.LocalTime;
39 import java.util.Collection;
40 import javax.sql.RowSet;
41 import javax.sql.rowset.CachedRowSet;
42 import javax.sql.rowset.RowSetMetaDataImpl;
43 import javax.sql.rowset.serial.SerialRef;
44 import javax.sql.rowset.spi.SyncFactory;
45 import javax.sql.rowset.spi.SyncProvider;
46 import javax.sql.rowset.spi.SyncProviderException;
47 import static org.testng.Assert.assertEquals;
48 import static org.testng.Assert.assertFalse;
49 import static org.testng.Assert.assertNull;
50 import static org.testng.Assert.assertTrue;
51 import org.testng.annotations.DataProvider;
52 import org.testng.annotations.Test;
53 import test.rowset.CommonRowSetTests;
54 import util.StubArray;
55 import util.StubRef;
56 import util.StubSyncProvider;
57 import util.TestRowSetListener;
58 
59 public 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      */
createDataTypesRowSet()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")
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")
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")
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      */
initDataTypesMetaData(CachedRowSet crs)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      */
createDataTypesRows(RowSet crs)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      */
findRowByPrimaryKey(RowSet rs, int id, int idPos, boolean deleteRow)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      */
findRowByPrimaryKey(RowSet rs, int id, int idPos)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      */
deleteRowByPrimaryKey(RowSet rs, int id, int idPos)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      */
compareMetaData(ResultSetMetaData rsmd, ResultSetMetaData rsmd1)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      */
compareRowSets(CachedRowSet crs, CachedRowSet crs1)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      */
compareColumnValue(JDBCType type, ResultSet rs, ResultSet rs1, int col)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)
commonCachedRowSetTest0000(CachedRowSet rs)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)
commonCachedRowSetTest0001(CachedRowSet rs)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")
commonCachedRowSetTest0002(CachedRowSet rs)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")
commonCachedRowSetTest0003(CachedRowSet rs)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")
commonCachedRowSetTest0004(CachedRowSet rs)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")
commonCachedRowSetTest0005(CachedRowSet rs)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")
commonCachedRowSetTest0006(RowSet rs)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")
commonCachedRowSetTest0007(RowSet rs)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")
commonCachedRowSetTest0008(CachedRowSet rs)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")
commonCachedRowSetTest0009(RowSet rs)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")
commonCachedRowSetTest0010(CachedRowSet rs)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")
commonCachedRowSetTest0011(CachedRowSet rs)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)
commonCachedRowSetTest0012(CachedRowSet rs)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)
commonCachedRowSetTest0013(CachedRowSet rs)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)
commonCachedRowSetTest0014(CachedRowSet rs)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)
commonCachedRowSetTest0015(CachedRowSet rs)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)
commonCachedRowSetTest0016(CachedRowSet rs)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)
commonCachedRowSetTest0017(CachedRowSet rs)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)
commonCachedRowSetTest0018(CachedRowSet rs)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)
commonCachedRowSetTest0019(CachedRowSet rs)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)
commonCachedRowSetTest0020(CachedRowSet rs)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)
commonCachedRowSetTest0021(CachedRowSet rs)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)
commonCachedRowSetTest0022(CachedRowSet rs)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)
commonCachedRowSetTest0023(CachedRowSet rs)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")
commonCachedRowSetTest0024(CachedRowSet rs)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")
commonCachedRowSetTest0025(RowSet rs)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")
commonCachedRowSetTest0026(CachedRowSet rs)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")
commonCachedRowSetTest0027(CachedRowSet rs)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")
commonCachedRowSetTest0028(CachedRowSet rs)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)
commonCachedRowSetTest0029(CachedRowSet rs)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)
commonCachedRowSetTest0030(CachedRowSet rs)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)
commonCachedRowSetTest0031(CachedRowSet rs)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)
commonCachedRowSetTest0032(CachedRowSet rs)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)
commonCachedRowSetTest0033(CachedRowSet rs)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")
commonCachedRowSetTest0034(CachedRowSet rs)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")
commonCachedRowSetTest0035(CachedRowSet rs)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")
commonCachedRowSetTest0036(CachedRowSet rs)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")
commonCachedRowSetTest0037(CachedRowSet rs)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")
commonCachedRowSetTest0038(CachedRowSet rs)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")
commonCachedRowSetTest0039(CachedRowSet rs)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")
commonCachedRowSetTest0040(CachedRowSet rs, JDBCType type)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")
commonCachedRowSetTest0041(CachedRowSet rs, JDBCType type)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")
commonCachedRowSetTest0042(RowSet rs)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")
commonCachedRowSetTest0043(RowSet rs)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)
commonCachedRowSetTest0044(CachedRowSet rs)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)
commonCachedRowSetTest0045(CachedRowSet rs)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)
commonCachedRowSetTest0046(CachedRowSet rs)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)
commonCachedRowSetTest0047(CachedRowSet rs)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)
commonCachedRowSetTest0048(CachedRowSet rs)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)
commonCachedRowSetTest0049(CachedRowSet rs)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)
commonCachedRowSetTest0050(CachedRowSet rs)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)
commonCachedRowSetTest0051(CachedRowSet rs)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)
commonCachedRowSetTest0052(CachedRowSet rs)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")
commonCachedRowSetTest0053(CachedRowSet rs)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")
commonCachedRowSetTest0054(CachedRowSet rs)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")
commonCachedRowSetTest0055(CachedRowSet rs)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")
commonCachedRowSetTest0056(CachedRowSet rs)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")
commonCachedRowSetTest0057(CachedRowSet rs)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")
commonCachedRowSetTest0058(CachedRowSet rs)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)
commonCachedRowSetTest0059(CachedRowSet rs)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)
commonCachedRowSetTest0060(CachedRowSet rs)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")
commonCachedRowSetTest0061(CachedRowSet rs)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")
commonCachedRowSetTest0062(CachedRowSet rs)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