1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package libcore.java.sql;
18 
19 import java.sql.BatchUpdateException;
20 import java.sql.PreparedStatement;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.sql.SQLFeatureNotSupportedException;
24 import java.sql.SQLWarning;
25 import java.sql.Statement;
26 import java.util.Vector;
27 import java.util.logging.Logger;
28 
29 public final class OldStatementTest extends OldSQLTest {
30 
testAddBatch()31     public void testAddBatch() throws SQLException {
32         Statement st = null;
33         try {
34             st = conn.createStatement();
35             st.addBatch("INSERT INTO zoo VALUES (3,'Tuzik','dog')");
36             st.addBatch("INSERT INTO zoo VALUES (4,'Mashka','cat')");
37 
38             int[] updateCounts = st.executeBatch();
39             assertEquals(2, updateCounts.length);
40             assertEquals(1, updateCounts[0]);
41             assertEquals(1, updateCounts[1]);
42         } finally {
43             try {
44                 st.close();
45             } catch (SQLException ee) {
46             }
47         }
48 
49         try {
50             st = conn.createStatement();
51             st.addBatch("");
52             st.executeBatch();
53             fail("SQLException is not thrown");
54         } catch (SQLException e) {
55             // expected
56         } finally {
57             try {
58                 st.close();
59             } catch (SQLException ee) {
60             }
61         }
62 
63         try {
64             st = conn.createStatement();
65             st.addBatch(null);
66             st.executeBatch();
67         } catch (SQLException e) {
68             // expected
69         } finally {
70             try {
71                 st.close();
72             } catch (SQLException ee) {
73             }
74         }
75     }
76 
testClearWarnings()77     public void testClearWarnings() throws SQLException {
78         Statement st = null;
79         try {
80             st = conn.createStatement();
81             st.execute("select animals from zoo");
82         } catch (SQLException e) {
83             // expected
84         } finally {
85             try {
86                 st.close();
87             } catch (SQLException ee) {
88             }
89         }
90         try {
91             st = conn.createStatement();
92             st.clearWarnings();
93             SQLWarning w = st.getWarnings();
94             assertNull(w);
95         } finally {
96             try {
97                 st.close();
98             } catch (SQLException ee) {
99             }
100         }
101     }
102 
testGetWarnings()103     public void testGetWarnings() throws SQLException {
104 
105         Statement st = null;
106         int errorCode1 = -1;
107         int errorCode2 = -1;
108 
109         try {
110             st = conn.createStatement();
111             st.execute("select animals from zoooo");
112             fail("SQLException was not thrown");
113         } catch (SQLException e) {
114             // expected
115             errorCode1 = e.getErrorCode();
116         }
117 
118         SQLWarning wrs = st.getWarnings();
119         assertNull(wrs);
120 
121         /*
122         Statement st = null;
123         int errorCode1 = -1;
124         int errorCode2 = -1;
125 
126         try {
127             st = conn.createStatement();
128             st.execute("select animals from zoooo");
129         } catch (SQLException e) {
130             // expected
131             errorCode1 = e.getErrorCode();
132         }
133         try {
134             SQLWarning wrs = st.getWarnings();
135             assertNull(wrs);
136         } catch (Exception e) {
137             fail("Unexpected Exception: " + e.getMessage());
138         }
139         try {
140             st.execute("select horse from zoooooo");
141         } catch (SQLException e) {
142             // expected
143             errorCode2 = e.getErrorCode();
144         }
145 
146         try {
147             SQLWarning wrs = st.getWarnings();
148             assertEquals(errorCode1, wrs.getErrorCode());
149             assertNotNull(wrs.getNextWarning());
150             assertEquals(errorCode2, wrs.getErrorCode());
151         } catch (Exception e) {
152             fail("Unexpected Exception: " + e.getMessage());
153         }
154 
155         try {
156             st.close();
157         } catch (SQLException ee) {
158         }
159         */
160 
161     }
162 
testClearBatch()163     public void testClearBatch() throws SQLException {
164         Statement st = null;
165 
166         try {
167             st = conn.createStatement();
168             st.addBatch("INSERT INTO zoo VALUES (3,'Tuzik','dog'); ");
169             st.addBatch("INSERT INTO zoo VALUES (4,'Mashka','cat')");
170 
171             st.clearBatch();
172 
173             int[] updateCounts = st.executeBatch();
174 
175             for (int i = 0; i < updateCounts.length; i++) {
176                 assertEquals(0, updateCounts[i]);
177             }
178         } finally {
179             try {
180                 st.close();
181             } catch (SQLException ee) {
182             }
183         }
184 
185         try {
186             st = conn.createStatement();
187             st.addBatch("");
188             st.executeBatch();
189             fail("SQLException is not thrown");
190         } catch (SQLException e) {
191             // expected
192         } finally {
193             try {
194                 st.close();
195             } catch (SQLException ee) {
196             }
197         }
198 
199         try {
200             st = conn.createStatement();
201             st.addBatch(null);
202             st.executeBatch();
203         } catch (SQLException e) {
204             // expected
205         } finally {
206             try {
207                 st.close();
208             } catch (SQLException ee) {
209             }
210         }
211     }
212 
213     // TODO not pass on SQLite and RI.
testExecute()214     public void testExecute() throws SQLException {
215 
216         String[] queries = {
217                 "update zoo set name='Masha', family='cat' where id=2;",
218                 "drop table if exists hutch",
219                 "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
220                 "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
221                 "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
222                 "select animal_id, address from hutch where animal_id=1;",
223                 "create view address as select address from hutch where animal_id=2",
224                 "drop view address;", "drop table hutch;" };
225         boolean[] results = {false, false, false, false, false, true, false,
226                 false, false};
227 
228         for (int i = 0; i < queries.length; i++) {
229             Statement st = null;
230             try {
231                 st = conn.createStatement();
232                 boolean res = st.execute(queries[i]);
233                 assertEquals("different result for statement no. "+i, results[i], res);
234             } catch (SQLException e) {
235                 fail("SQLException is thrown: " + e.getMessage());
236             } finally {
237                 try {
238                     st.close();
239                 } catch (Exception ee) {
240                 }
241             }
242         }
243 
244         String[] inc_queries = {
245                 "update zoo_zoo set name='Masha', family='cat' where id=5;",
246                 "drop table hutchNO",
247                 "insert into hutch (id, animal_id, address) values (1, 2, 10);",
248                 "select animal_id, from hutch where animal_id=1;",
249                 "drop view address;", "drop table hutch;", "", null };
250 
251         for (int i = 0; i < inc_queries.length; i++) {
252             Statement st = null;
253             try {
254                 st = conn.createStatement();
255                 st.execute(inc_queries[i]);
256                 fail("SQLException is not thrown for query: " + inc_queries[i]);
257             } catch (SQLException e) {
258                 // expected
259             } finally {
260                 try {
261                     st.close();
262                 } catch (SQLException ee) {
263                 }
264             }
265         }
266     }
267 
268     // TODO not supported
testExecute_String_int()269    public void testExecute_String_int() {
270         String[] queries = {
271                 "update zoo set name='Masha', family='cat' where id=2;",
272                 "drop table if exists hutch",
273                 "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
274                 "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
275                 "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
276                 "select animal_id, address from hutch where animal_id=1;",
277                 "create view address as select address from hutch where animal_id=2",
278                 "drop view address;", "drop table hutch;" };
279 
280         for (int i = 0; i < queries.length; i++) {
281             Statement st = null;
282             try {
283                 st = conn.createStatement();
284                 st.execute(queries[i], Statement.NO_GENERATED_KEYS);
285 
286                 ResultSet rs = st.getGeneratedKeys();
287                 assertFalse(rs.next());
288 
289             } catch (SQLException e) {
290                 // ok
291             } finally {
292                 try {
293                     st.close();
294                 } catch (SQLException ee) {
295                 }
296             }
297         }
298 
299         for (int i = 0; i < queries.length; i++) {
300             Statement st = null;
301             try {
302                 st = conn.createStatement();
303                 st.execute(queries[i], Statement.RETURN_GENERATED_KEYS);
304                 fail("Exception expected: Not supported");
305                 /*
306                 ResultSet rs = st.getGeneratedKeys();
307                 fail("Revise test implemenation for feature impl. has changed");
308                 assertFalse(rs.next());
309                 */
310             } catch (SQLException e) {
311                 //ok
312             } finally {
313                 try {
314                     st.close();
315                 } catch (SQLException ee) {
316                 }
317             }
318         }
319     }
320 
321     // statement.close() does not wrap up
testGetConnection()322     public void testGetConnection() throws SQLException {
323         Statement st = null;
324         try {
325             st = conn.createStatement();
326             assertSame(conn, st.getConnection());
327         } finally {
328             try {
329                 st.close();
330             } catch (SQLException ee) {
331             }
332         }
333 
334         try {
335             st.close();
336             st.getConnection();
337             fail("Exception expected");
338         } catch (SQLException e) {
339             //ok
340         }
341     }
342 
343     // statement.close() does not wrap up
testGetFetchDirection()344     public void testGetFetchDirection() throws SQLException {
345         Statement st = null;
346         try {
347             st = conn.createStatement();
348             assertEquals(ResultSet.FETCH_UNKNOWN, st.getFetchDirection());
349         }  finally {
350             try {
351                 st.close();
352             } catch (SQLException ee) {
353             }
354         }
355 
356         try {
357             st = conn.createStatement();
358             st.setFetchDirection(ResultSet.FETCH_FORWARD);
359             assertEquals(ResultSet.FETCH_FORWARD, st.getFetchDirection());
360             fail("Exception expected: not supported");
361         } catch (SQLException e) {
362             // ok
363         }  finally {
364             try {
365                 st.close();
366             } catch (SQLException ee) {
367             }
368         }
369 
370         try {
371             st.getFetchDirection();
372             fail("Exception expected");
373         } catch (SQLException e) {
374             //ok
375         }
376     }
377 
378     // TODO not supported
testSetFetchDirection()379     public void testSetFetchDirection() {
380         Statement st = null;
381         try {
382             st = conn.createStatement();
383             st.setFetchDirection(ResultSet.FETCH_FORWARD);
384             st.executeQuery("select * from zoo;");
385             fail("Revise test implemenation for feature impl. has changed");
386 //            assertEquals(ResultSet.FETCH_FORWARD, st.getFetchDirection());
387         } catch (SQLException e) {
388 //            fail("SQLException is thrown: " + e.getMessage());
389             //ok
390         } finally {
391             try {
392                 st.close();
393             } catch (SQLException ee) {
394             }
395         }
396     }
397 
398     // statement.close() does not wrap up
testGetFetchSize()399     public void testGetFetchSize() throws SQLException {
400         Statement st = null;
401         try {
402             st = conn.createStatement();
403             st.execute("select * from zoo;");
404             assertEquals(1, st.getFetchSize());
405         } finally {
406             try {
407                 st.close();
408             } catch (SQLException ee) {
409             }
410         }
411 
412         try {
413             st.close();
414             st.getFetchSize();
415             fail("Exception expected");
416         } catch (SQLException e) {
417             //ok
418         }
419     }
420 
421     // TODO not supported
testSetFetchSize()422     public void testSetFetchSize() throws SQLException {
423         Statement st = null;
424         try {
425             st = conn.createStatement();
426             int rows = 100;
427             for (int i = 0; i < rows; i++) {
428                 try {
429                     st.setFetchSize(i);
430                     assertEquals(i, st.getFetchSize());
431                 } catch (SQLException sqle) {
432                     // getFetchSize() hardcoded to 1.
433                     assertEquals("fetch size not 1", sqle.getMessage());
434                 }
435             }
436             /*
437             try {
438                 st.setFetchSize(-1);
439                 fail("SQLException is not thrown");
440             } catch (SQLException sqle) {
441                 // expected
442             }
443             */
444 
445         } finally {
446             try {
447                 st.close();
448             } catch (SQLException ee) {
449             }
450         }
451     }
452 
453     // TODO not supported
testSetMaxFieldSize()454     public void testSetMaxFieldSize() throws SQLException {
455         Statement st = null;
456         try {
457             st = conn.createStatement();
458             for (int i = 0; i < 300; i += 50) {
459                 try {
460                     st.setMaxFieldSize(i);
461                     assertEquals(i, st.getMaxFieldSize());
462                     fail("Revise test implemenation for feature impl. has changed");
463                 } catch (SQLException sqle) {
464                     assertEquals("not supported", sqle.getMessage());
465                 }
466             }
467         } finally {
468             try {
469                 st.close();
470             } catch (SQLException ee) {
471             }
472         }
473     }
474 
475     // TODO not supported
testGetMaxFieldSize()476     public void testGetMaxFieldSize() throws SQLException {
477         Statement st = null;
478         try {
479             st = conn.createStatement();
480             for (int i = 200; i < 500; i += 50) {
481                 try {
482                     st.setMaxFieldSize(i);
483                     fail("Revise test implemenation for feature impl. has changed");
484                 } catch (SQLException sqle) {
485                     assertEquals("not supported", sqle.getMessage());
486                 }
487             }
488         } finally {
489             try {
490                 st.close();
491             } catch (SQLException ee) {
492             }
493         }
494     }
495 
testMaxRows()496     public void testMaxRows() throws SQLException {
497         Statement st = null;
498         try {
499             st = conn.createStatement();
500             for (int i = 0; i < 300; i += 50) {
501                 st.setMaxRows(i);
502                 assertEquals(i, st.getMaxRows());
503                 ResultSet r = st.executeQuery("select * from zoo;");
504                 int rowCount = 0;
505                 while (r.next()) {
506                     ++rowCount;
507                 }
508                 if (i == 0) {
509                     // 0 means unlimited.
510                     assertTrue("rowCount=" + rowCount + " i=" + i, rowCount > i);
511                 } else {
512                     assertTrue("rowCount=" + rowCount + " i=" + i, rowCount <= i);
513                 }
514                 r.close();
515             }
516             try {
517                 st.setMaxRows(-1);
518                 fail("SQLException isn't thrown");
519             } catch (SQLException sqle) {
520                 // expecteds
521             }
522         } finally {
523             try {
524                 st.close();
525             } catch (SQLException ee) {
526             }
527         }
528     }
529 
530     /** not passed according to spec; should release resources immediately */
testClose()531     public void testClose() throws SQLException {
532         Statement st = null;
533         ResultSet res = null;
534         try {
535             String[] queries = {
536                     "update zoo set name='Masha', family='cat' where id=2;",
537                     "insert into zoo (id, name, family) values (3, 'Vorobey', 'sparrow');",
538                     "insert into zoo (id, name, family) values (4, 'Slon', 'elephant');",
539                     "select * from zoo"};
540             st = conn.createStatement();
541             for (int i = 0; i < queries.length; i++) {
542                 st.execute(queries[i]);
543             }
544             res = st.getResultSet();
545             assertNotNull(res);
546             assertTrue(res.next());
547             st.close();
548         } finally {
549             try {
550                 st.close();
551             } catch (SQLException ee) {
552             }
553         }
554 
555         // test release of resources:
556         // this code should throw an exception as the db is not available
557         // anymore in fact every resource which is used afterwards should throw
558         // an SQLException.
559         try {
560             res.next();
561             fail("Exception expected");
562         } catch (SQLException e) {
563             // ok
564         }
565     }
566 
567     // TODO not supported
testExecute_String_intArray()568     public void testExecute_String_intArray() {
569         Statement st = null;
570         try {
571             String[] queries = {
572                     "update zoo set name='Masha', family='cat' where id=2;",
573                     "insert zoo(id, name, family) values (3, 'Vorobey', 'sparrow');",
574                     "insert zoo(id, name, family) values (4, 'Slon', 'elephant');",
575                     "select * from zoo" };
576             Vector<int[]> array = new Vector<int[]>();
577             array.addElement(null);
578             array.addElement(new int[] { 1, 2, 3 });
579             array.addElement(new int[] { 1, 2, 10, 100 });
580             array.addElement(new int[] {});
581 
582             st = conn.createStatement();
583             for (int i = 0; i < queries.length; i++) {
584                 st.execute(queries[i], (int[]) array.elementAt(i));
585                 fail("SQLException expected: not supported");
586             }
587             /*
588             fail("Revise test implemenation for feature impl. has changed");
589             assertNotNull(st.getResultSet());
590             st.close();
591             assertNull(st.getResultSet());
592             */
593         } catch (SQLException e) {
594             // ok: not supported
595 //            fail("SQLException is thrown: " + e.getMessage());
596         } finally {
597             try {
598                 st.close();
599             } catch (SQLException ee) {
600             }
601         }
602     }
603 
testExecute_String_StringArray()604     public void testExecute_String_StringArray() {
605         Statement st = null;
606         try {
607             String[] queries = {
608                     "update zoo set name='Masha', family='cat' where id=2;",
609                     "insert zoo(id, name, family) values (3, 'Vorobey', 'sparrow');",
610                     "insert zoo(id, name, family) values (4, 'Slon', 'elephant');",
611                     "select * from zoo" };
612             Vector<String[]> array = new Vector<String[]>();
613             array.addElement(null);
614             array.addElement(new String[] { "", "", "", "", "", "", "", "" });
615             array.addElement(new String[] { "field 1", "", "field2" });
616             array.addElement(new String[] { "id", "family", "name" });
617 
618             st = conn.createStatement();
619             for (int i = 0; i < queries.length; i++) {
620                 st.execute(queries[i], (String[]) array.elementAt(i));
621                 fail("Exception expected: not supported");
622             }
623             fail("Revise test implemenation for feature impl. has changed");
624             assertNotNull(st.getResultSet());
625             st.close();
626             assertNull(st.getResultSet());
627         } catch (SQLException e) {
628             // ok: not supported
629             try {
630                 st.close();
631             } catch (SQLException ee) {
632             }
633         }
634     }
635 
636     // always returns 1 for no. of updates
testExecuteBatch()637     public void testExecuteBatch() throws SQLException {
638 
639         String[] queries = {
640                 "update zoo set name='Masha', family='cat' where id=2;",
641                 "drop table if exists hutch",
642                 "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
643                 "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
644                 "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
645                 "create view address as select address from hutch where animal_id=2",
646                 "drop view address;", "drop table hutch;" };
647 
648         String[] wrongQueries = {
649                 "update zoo set name='Masha', family='cat' where;",
650                 "drop table if exists hutch;",
651                 "create view address as select address from hutch where animal_id=2;",
652                 "drop view address;", "drop table hutch;" };
653 
654         int[] result = { 1, 1, 1, 1, 1, 1, 1, 1 };
655         Statement st = null;
656 
657         //Exception test
658         try {
659             st = conn.createStatement();
660             assertEquals(0, st.executeBatch().length);
661             for (int i = 0; i < wrongQueries.length; i++) {
662                 st.addBatch(wrongQueries[i]);
663             }
664             st.executeBatch();
665             fail("BatchupdateException expected");
666         } catch (BatchUpdateException e) {
667             //ok
668         } finally {
669             try {
670                 st.close();
671             } catch (SQLException ee) {
672             }
673         }
674 
675         try {
676             st = conn.createStatement();
677             assertEquals(0, st.executeBatch().length);
678             for (int i = 0; i < queries.length; i++) {
679                 st.addBatch(queries[i]);
680             }
681             int[] resArray = st.executeBatch();
682             assertTrue(java.util.Arrays.equals(result, resArray));
683         } finally {
684             try {
685                 st.close();
686             } catch (SQLException ee) {
687             }
688         }
689 
690         try {
691             st = conn.createStatement();
692             st.addBatch("select * from zoo");
693             st.executeBatch();
694             fail("Exception expected");
695         } catch (BatchUpdateException bue) {
696             // ok select returns a resultSet
697         } finally {
698             try {
699                 st.close();
700             } catch (SQLException ee) {
701             }
702         }
703         //Exception test
704         try {
705             st.close();
706             st.executeBatch();
707             fail("SQLException not thrown");
708         } catch (SQLException e) {
709             //ok
710         }
711     }
712 
713     // Does throw an exception on non select statement.
testExecuteQuery_String()714     public void testExecuteQuery_String() throws SQLException {
715 
716         String[] queries1 = { "select * from zoo",
717                 "select name, family from zoo where id = 1" };
718 
719         String[] queries2 = {
720                 "update zoo set name='Masha', family='cat' where id=2;",
721                 "drop table if exists hutch",
722                 "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
723                 "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
724                 "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
725                 "create view address as select address from hutch where animal_id=2",
726                 "drop view address;", "drop table hutch;", "select from zoo" };
727 
728         Statement st = null;
729 
730         try {
731             st = conn.createStatement();
732             for (int i = 0; i < queries1.length; i++) {
733                 try {
734                     ResultSet rs = st.executeQuery(queries1[i]);
735                     assertNotNull(rs);
736                 } catch (SQLException sqle) {
737                     fail("SQLException is thrown for query: " + queries1[i]);
738                 }
739             }
740         } finally {
741             try {
742                 st.close();
743             } catch (Exception ee) {
744             }
745         }
746 
747         // queries which do not produce a ResultSet -> exception testing
748 
749         try {
750             st = conn.createStatement();
751             for (int i = 0; i < queries2.length; i++) {
752                 try {
753                     ResultSet rs = st.executeQuery(queries2[i]);
754                     assertNotNull(rs);
755                     fail("SQLException is not thrown for query: " + queries2[i]);
756                 } catch (SQLException sqle) {
757                     // expected
758                 }
759             }
760         } finally {
761             try {
762                 st.close();
763             } catch (Exception ee) {
764             }
765         }
766     }
767 
768     /**
769      * Spec is not precise enough: should be: number of rows affected. eg. to be
770      * consistent for deletes: 'delete from s1;' should be different from
771      * 'delete from s1 where c1 = 1;'
772      */
testExecuteUpdate_String()773     public void testExecuteUpdate_String() throws SQLException {
774 
775         String[] queries1 = {
776                 "update zoo set name='Masha', family='cat' where id=2;",
777                 "drop table if exists hutch",
778                 "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
779                 "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
780                 "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
781                 "create view address as select address from hutch where animal_id=2;",
782                 "drop view address;", "drop table hutch;"};
783 
784         String queries2 = "select * from zoo;";
785 
786         Statement st = null;
787         try {
788             st = conn.createStatement();
789             for (int i = 0; i < queries1.length; i++) {
790                 int count = st.executeUpdate(queries1[i]);
791                 assertTrue(count > 0);
792             }
793 
794             assertEquals(0, st.executeUpdate(queries2));
795 
796         } finally {
797             try {
798                 st.close();
799             } catch (Exception ee) {
800             }
801         }
802 
803         // test return value for specific numbers
804 
805         Statement stat = conn.createStatement();
806 
807         // there are 0 rows created therefore 0 should be returned.
808         assertEquals(0 ,stat.executeUpdate("create table s1 (c1);"));
809 
810         assertEquals(1, stat.executeUpdate("insert into s1 values (0);"));
811         assertEquals(1, stat.executeUpdate("insert into s1 values (1);"));
812         assertEquals(1, stat.executeUpdate("insert into s1 values (2);"));
813         assertEquals(1,stat.executeUpdate("delete from s1 where c1 = 1;"));
814         assertEquals(2, stat.executeUpdate("update s1 set c1 = 5;"));
815 
816         // analogous to statement before, delete all should return 2
817         assertEquals(2,stat.executeUpdate("delete from s1;"));
818 
819         // there are no rows in table: 0 should be returned
820         assertEquals(0, stat.executeUpdate("drop table s1;"));
821 
822         stat.executeUpdate("create table s1 (c1);");
823         stat.executeUpdate("insert into s1 values (0);");
824         stat.executeUpdate("insert into s1 values (1);");
825         stat.executeUpdate("insert into s1 values (2);");
826 
827         // there are 3 rows in table: 3 should be returned
828         assertEquals(3, stat.executeUpdate("drop table s1;"));
829 
830         stat.close();
831     }
832 
833     // TODO executeUpdate(String sql, int[] columnIndexes) is not supported
testExecuteUpdate_String_intArray()834     public void testExecuteUpdate_String_intArray() throws SQLException {
835         Statement st = null;
836         try {
837             String[] queries1 = {
838                     "update zoo set name='Masha', family='cat' where id=2;",
839                     "drop table if exists hutch",
840                     "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
841                     "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
842                     "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
843                     "create view address as select address from hutch where animal_id=2",
844                     "drop view address;", "drop table hutch;" };
845 
846             Vector<int[]> array = new Vector<int[]>();
847             array.addElement(null);
848             array.addElement(new int[] { 1, 2, 3 });
849             array.addElement(new int[] { 1, 2, 10, 100 });
850             array.addElement(new int[] {});
851             array.addElement(new int[] { 100, 200 });
852             array.addElement(new int[] { -1, 0 });
853             array.addElement(new int[] { 0, 0, 0, 1, 2, 3 });
854             array.addElement(new int[] { -100, -200 });
855 
856             st = conn.createStatement();
857             for (int i = 0; i < queries1.length; i++) {
858                 st.executeUpdate(queries1[i], (int[]) array.elementAt(i));
859                 fail("Exception expected");
860             }
861         } catch (SQLFeatureNotSupportedException e) {
862             // expected
863         } finally {
864             try {
865                 st.close();
866             } catch (SQLException ee) {
867             }
868         }
869     }
870 
871     // executeUpdate(String sql, int autoGeneratedKeys) is not supported
testExecuteUpdate_String_int()872     public void testExecuteUpdate_String_int() {
873         String[] queries = {
874                 "update zoo set name='Masha', family='cat' where id=2;",
875                 "drop table if exists hutch",
876                 "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
877                 "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
878                 "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
879                 "select animal_id, address from hutch where animal_id=1;",
880                 "create view address as select address from hutch where animal_id=2",
881                 "drop view address;", "drop table hutch;" };
882 
883             Statement st = null;
884             ResultSet rs = null;
885             try {
886                 st = conn.createStatement();
887                 st.executeUpdate(queries[1], Statement.NO_GENERATED_KEYS);
888                 rs = st.getGeneratedKeys();
889                 assertFalse(rs.next());
890                 fail("Exception expected: not supported");
891             } catch (SQLException e) {
892                 //ok
893             } finally {
894                 try {
895                     rs.close();
896                     st.close();
897                 } catch (Exception ee) {
898                 }
899             }
900 
901             try {
902                 st = conn.createStatement();
903                 st.executeUpdate(queries[1], Statement.RETURN_GENERATED_KEYS);
904                 rs = st.getGeneratedKeys();
905                 assertTrue(rs.next());
906                 fail("Exception expected: not supported");
907             } catch (SQLException e) {
908                 //ok
909             } finally {
910                 try {
911                     rs.close();
912                     st.close();
913                 } catch (Exception ee) {
914                 }
915             }
916     }
917 
918     // TODO executeUpdate(String sql, String[] columnNames) is not supported
testExecuteUpdate_String_StringArray()919     public void testExecuteUpdate_String_StringArray() throws SQLException {
920         Statement st = null;
921         try {
922             String[] queries = {
923                     "update zoo set name='Masha', family='cat' where id=2;",
924                     "drop table if exists hutch",
925                     "create table hutch (id integer not null, animal_id integer, address char(20), primary key (id));",
926                     "insert into hutch (id, animal_id, address) values (1, 2, 'Birds-house, 1');",
927                     "insert into hutch (id, animal_id, address) values (2, 1, 'Horse-house, 5');",
928                     "create view address as select address from hutch where animal_id=2",
929                     "drop view address;", "drop table hutch;" };
930 
931             Vector<String[]> array = new Vector<String[]>();
932             array.addElement(null);
933             array.addElement(new String[] { "", "", "", "", "", "", "", "" });
934             array.addElement(new String[] { "field 1", "", "field2" });
935             array.addElement(new String[] { "id", "family", "name" });
936             array
937                     .addElement(new String[] { "id", null, "family", null,
938                             "name" });
939             array.addElement(new String[] { "id", " ", "name" });
940             array.addElement(new String[] { null, null, null, null });
941             array.addElement(new String[] { " ", "123 21", "~!@#$%^&*()_+ ",
942                     null });
943 
944             st = conn.createStatement();
945             for (int i = 0; i < queries.length; i++) {
946                 st.executeUpdate(queries[i], (String[]) array.elementAt(i));
947                 fail("Revise test implemenation for feature impl. has changed");
948             }
949         } catch (SQLFeatureNotSupportedException e) {
950             // expected
951         } finally {
952             try {
953                 st.close();
954             } catch (SQLException ee) {
955             }
956         }
957     }
958 
959     // statement.close() does not wrap up
testGetUpdateCount()960     public void testGetUpdateCount() throws SQLException {
961         Statement st = null;
962         try {
963             String query = "update zoo set name='Masha', family='cat' where id=2;";
964             st = conn.createStatement();
965             st.executeUpdate(query);
966             assertEquals(1, st.getUpdateCount());
967             query = "update zoo set name='Masha', family='cat' where id=5;";
968             st.executeUpdate(query);
969             assertEquals(0, st.getUpdateCount());
970         } finally {
971             try {
972                 st.close();
973             } catch (SQLException ee) {
974             }
975         }
976         // statment closed : Exception test
977         try {
978             st.getUpdateCount();
979             fail("Exception expected");
980         } catch (SQLException e) {
981             //ok
982         }
983     }
984 
testGeneratedKeys()985     public void testGeneratedKeys() throws SQLException {
986         Statement st = null;
987         try {
988             String insert = "insert into zoo (id, name, family) values (8, 'Tuzik', 'dog');";
989             st = conn.createStatement();
990             assertNull(st.getGeneratedKeys());
991             fail("Fail: statement does not fail");
992         } catch (SQLFeatureNotSupportedException e) {
993             // expected
994         }
995     }
996 
997     // TODO setCursorName() is not supported
testSetCursorName()998     public void testSetCursorName() throws SQLException {
999         Statement st = null;
1000         try {
1001             String select = "select * from zoo";
1002             st = conn.createStatement();
1003             st.setCursorName("test");
1004             fail("Fail: statement does not fail");
1005         } catch (SQLFeatureNotSupportedException e) {
1006             // expected
1007         }
1008     }
1009 
1010     // TODO setEscapeProcessing() is not supported
testSetEscapeProcessing()1011     public void testSetEscapeProcessing() {
1012         Statement st = null;
1013         try {
1014             String select = "select * from zoo";
1015             st = conn.createStatement();
1016             st.setEscapeProcessing(true);
1017             fail("Fail: statement does not fail");
1018         } catch (SQLException e) {
1019           assertEquals("not supported", e.getMessage());
1020         }
1021     }
1022 
testSetQueryTimeout()1023     public void testSetQueryTimeout() throws SQLException {
1024         Statement st = conn.createStatement();
1025         st.setQueryTimeout(2);
1026         assertEquals(2, st.getQueryTimeout());
1027 
1028         try {
1029             st = conn.createStatement();
1030             st.setQueryTimeout(-1);
1031             fail("SQLException not thrown");
1032         } catch (SQLException expected) {
1033             // expected
1034         }
1035 
1036         try {
1037             st = conn.createStatement();
1038             st.close();
1039             st.setQueryTimeout(3);
1040             fail("SQLException not thrown");
1041         } catch (SQLException expected) {
1042             // expected
1043         }
1044     }
1045 
1046     // not fully supported
testGetResultSetType()1047     public void testGetResultSetType() {
1048         Statement st = null;
1049         // test default value
1050         try {
1051             st = conn.createStatement();
1052             st.getResultSetType();
1053             assertEquals(ResultSet.TYPE_SCROLL_INSENSITIVE, st
1054                     .getResultSetType());
1055         } catch (SQLException e) {
1056             assertEquals("not supported", e.getMessage());
1057         }
1058 
1059         // failing tests
1060         try {
1061             st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
1062                     ResultSet.CONCUR_UPDATABLE);
1063             st.getResultSetType();
1064             assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE, st.getResultSetType());
1065         } catch (SQLException e) {
1066             assertEquals("not supported", e.getMessage());
1067         }
1068 
1069         try {
1070             st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
1071                     ResultSet.CONCUR_UPDATABLE);
1072             st.getResultSetType();
1073             assertEquals(ResultSet.TYPE_SCROLL_SENSITIVE, st.getResultSetType());
1074         } catch (SQLException e) {
1075             assertEquals("not supported", e.getMessage());
1076         }
1077 
1078         try {
1079             st = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
1080                     ResultSet.CONCUR_UPDATABLE);
1081             st.getResultSetType();
1082             assertEquals(ResultSet.TYPE_FORWARD_ONLY, st.getResultSetType());
1083         } catch (SQLException e) {
1084             assertEquals("not supported", e.getMessage());
1085         }
1086     }
1087 
1088     // Test for default value fails
testGetResultSetHoldability()1089     public void testGetResultSetHoldability() {
1090 
1091         // test default value
1092         Statement st = null;
1093         try {
1094             st = conn.createStatement();
1095             assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, st
1096                     .getResultSetHoldability());
1097         } catch (SQLException e) {
1098             assertEquals("not supported", e.getMessage());
1099         }
1100 
1101         // failing tests
1102         try {
1103             conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
1104                     ResultSet.CONCUR_READ_ONLY,
1105                     ResultSet.HOLD_CURSORS_OVER_COMMIT);
1106             fail("Exception expected: not supported");
1107         } catch (SQLException e) {
1108             // ok: not supported
1109         }
1110 
1111         try {
1112             conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
1113                     ResultSet.CONCUR_READ_ONLY,
1114                     ResultSet.CLOSE_CURSORS_AT_COMMIT);
1115             fail("Exception expected: not supported");
1116             /*
1117             st.getResultSetHoldability();
1118             assertEquals(ResultSet.CLOSE_CURSORS_AT_COMMIT, st
1119                     .getResultSetHoldability());
1120             */
1121         } catch (SQLException expected) {
1122         }
1123     }
1124 
1125     // Not supported
testGetResultSetConcurrency()1126     public void testGetResultSetConcurrency() {
1127         Statement st = null;
1128 
1129         // test default value
1130         try {
1131             st = conn.createStatement();
1132             st.getResultSetConcurrency();
1133             assertEquals(ResultSet.CONCUR_READ_ONLY, st
1134                     .getResultSetConcurrency());
1135         } catch (SQLException e) {
1136             assertEquals("not supported", e.getMessage());
1137         }
1138 
1139      // failing tests
1140 
1141         try {
1142             st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
1143                     ResultSet.CONCUR_UPDATABLE);
1144             st.getResultSetConcurrency();
1145             assertEquals(ResultSet.CONCUR_UPDATABLE, st.getResultSetConcurrency());
1146             fail("Exception expected: not supported");
1147         } catch (SQLException e) {
1148             //ok
1149 
1150         }
1151 
1152         try {
1153             st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
1154                     ResultSet.CONCUR_READ_ONLY);
1155             st.getResultSetConcurrency();
1156             assertEquals(ResultSet.CONCUR_READ_ONLY, st.getResultSetConcurrency());
1157             fail("Exception expected: not supported");
1158         } catch (SQLException e) {
1159             //ok;
1160         }
1161     }
1162 
1163     // Does not return null on update count > 0 (not a select statement)
testGetResultSet()1164     public void testGetResultSet() throws SQLException {
1165         Statement st = null;
1166         ResultSet res = null;
1167 
1168         st = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
1169                 ResultSet.CONCUR_READ_ONLY,
1170                 ResultSet.CLOSE_CURSORS_AT_COMMIT);
1171         st.execute("create table test (c1);");
1172         res = st.getResultSet();
1173         assertNull(res);
1174 
1175         st = conn.createStatement();
1176         String select = "select * from zoo where id == 4;";
1177         String insert =  "insert into zoo (id, name, family) values (4, 'Vorobuy', 'bear');";
1178         st.execute(insert);
1179         st.execute(select);
1180         assertEquals(-1, st.getUpdateCount());
1181         res = st.getResultSet();
1182         assertNotNull(res);
1183         res.next();
1184         assertEquals(4,res.getInt(1));
1185         assertEquals("Vorobuy",res.getString(2));
1186         assertEquals("bear",res.getString(3));
1187 //            assertEquals(0, st.getUpdateCount()); not supported
1188         assertFalse(res.next());
1189 
1190         st = conn.createStatement();
1191         insert = "insert into zoo (id, name, family) values (3, 'Vorobey', 'sparrow');";
1192         st.execute(insert);
1193         res = st.getResultSet();
1194         // statement is an update and should return null according to spec.
1195         if (st.getUpdateCount() > 0)  {
1196             assertNull(res);
1197         }
1198 
1199         try {
1200             st.close();
1201             st.getResultSet();
1202             fail("Exception expected");
1203         } catch (SQLException e) {
1204             //ok
1205         }
1206     }
1207 
1208     // An other value is returned than was set (X * 1000)
testGetQueryTimeout()1209     public void testGetQueryTimeout() throws SQLException {
1210         Statement st = null;
1211         st = conn.createStatement();
1212         st.setQueryTimeout(2000);
1213         assertEquals(2000, st.getQueryTimeout());
1214 
1215         st = conn.createStatement();
1216         assertEquals(0,st.getQueryTimeout());
1217 
1218         try {
1219             st.close();
1220             st.getQueryTimeout();
1221             fail("Exception expected");
1222         } catch (SQLException e) {
1223             //ok
1224         }
1225     }
1226 
1227     // not supported
testGetMoreResults()1228     public void testGetMoreResults() throws SQLException {
1229         Statement st = null;
1230         ResultSet res1 = null;
1231         ResultSet res2 = null;
1232         String[] queries = {
1233                 "insert into zoo values (3,'John','bird');",
1234                 "update zoo set name='Masha', family='cat' where id=3;",
1235                 "update zoo set name='Masha', family='bear' where id=3;"};
1236 
1237        try {
1238             st = conn.createStatement();
1239             st.execute(queries[0]);
1240             assertFalse(st.getMoreResults());
1241 
1242             try {
1243                 st.getResultSet();
1244                 fail("Exception expected");
1245             } catch (SQLException e) {
1246                 //ok
1247             }
1248         } finally {
1249             try {
1250                 st.close();
1251             } catch (SQLException ee) {
1252             }
1253         }
1254 
1255         try {
1256             st.getMoreResults();
1257             fail("Exception expected");
1258         } catch (SQLException e) {
1259             //ok
1260         }
1261     }
1262 
1263     // Bug in implementation of cancel: Does not fulfill spec.
testCancel()1264     public void testCancel() throws SQLException {
1265         Statement st = null;
1266         st = conn.prepareStatement("insert into zoo values (7,'Speedy Gonzales','Mouse');");
1267 
1268         CancelThread c = new CancelThread(st);
1269         InsertThread ins = new InsertThread((PreparedStatement)st);
1270 
1271         try {
1272             ins.t.join();
1273             c.t.join();
1274         } catch (InterruptedException e) {
1275             fail("Error in test setup: ");
1276         } catch (Exception e){
1277             // Insert thread may throw an exception
1278             // that it could not complete statement
1279         }
1280 
1281         // both threads have terminated and cancel should have cancelled the insert statement.
1282         ResultSet res = st.executeQuery("select * from zoo where id=7");
1283         assertFalse(res.next());
1284 
1285         try {
1286             st.close();
1287             st.cancel();
1288             fail("Exception expected");
1289         } catch (SQLException e) {
1290             //ok
1291         }
1292     }
1293 
1294     class CancelThread implements Runnable{
1295         Thread t;
1296         Statement stmt;
CancelThread(Statement aSt)1297         CancelThread (Statement aSt) {
1298            this.stmt = aSt;
1299            t = new Thread(this,"Cancel thread");
1300            t.start();
1301         }
1302 
run()1303         public void run() {
1304             Logger.global.info("*Cancel* thread started");
1305             try {
1306                 Thread.sleep(1500);
1307             } catch (InterruptedException e1) {
1308                 fail("Error in test setup");
1309                 e1.printStackTrace();
1310             }
1311             try {
1312                 Logger.global.info("*Cancel* thread, about to do stmt.cancel()");
1313                 stmt.cancel();
1314                 Logger.global.info("*Cancel* thread, stmt.cancel() done");
1315             } catch (SQLException e) {
1316                 fail("Error in test setup");
1317                 e.printStackTrace();
1318             }
1319             Logger.global.info("*Cancel* thread terminated");
1320         }
1321     }
1322 
1323     class InsertThread implements Runnable{
1324         Thread t;
1325         PreparedStatement stmt;
InsertThread(PreparedStatement aSt)1326         InsertThread (PreparedStatement aSt) {
1327            this.stmt = aSt;
1328            t = new Thread(this,"Insert thread");
1329            t.start();
1330         }
1331 
run()1332         public void run() {
1333             Logger.global.info("*Insert* thread started");
1334             try {
1335                 Thread.sleep(1500);
1336             } catch (InterruptedException e1) {
1337                 fail("Error in test setup");
1338                 e1.printStackTrace();
1339             }
1340             try {
1341                 Logger.global.info("*Insert* thread, about to do insertion");
1342                 stmt.execute();
1343                 stmt.execute();
1344                 Logger.global.info("*Insert* thread inserted");
1345             } catch (SQLException e) {
1346                 fail("Error in test setup");
1347                 e.printStackTrace();
1348             }
1349             Logger.global.info("*Insert* thread terminated");
1350         }
1351     }
1352 }
1353