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 tests.java.sql; 18 19 import dalvik.annotation.KnownFailure; 20 21 import java.io.CharArrayReader; 22 import java.math.BigDecimal; 23 import java.sql.Connection; 24 import java.sql.Date; 25 import java.sql.PreparedStatement; 26 import java.sql.ResultSet; 27 import java.sql.SQLException; 28 import java.sql.Statement; 29 import java.sql.Time; 30 import java.util.ArrayList; 31 import java.util.Calendar; 32 import java.util.HashMap; 33 import java.util.HashSet; 34 35 import tests.support.DatabaseCreator; 36 import tests.support.Support_SQL; 37 import junit.extensions.TestSetup; 38 import junit.framework.Test; 39 import junit.framework.TestCase; 40 import junit.framework.TestSuite; 41 42 public class SelectFunctionalityTest extends TestCase { 43 44 private static Connection conn; 45 46 private static Statement statement; 47 48 private static Date date; 49 50 private static Time time; 51 setUp()52 public void setUp() throws Exception { 53 super.setUp(); 54 Support_SQL.loadDriver(); 55 try { 56 conn = Support_SQL.getConnection(); 57 statement = conn.createStatement(); 58 createTestTables(); 59 } catch (SQLException e) { 60 fail("Unexpected SQLException " + e.toString()); 61 } 62 } 63 tearDown()64 public void tearDown() throws Exception { 65 deleteTestTables(); 66 conn.close(); 67 statement.close(); 68 super.tearDown(); 69 } 70 createTestTables()71 private void createTestTables() { 72 try { 73 ResultSet userTab = conn.getMetaData().getTables(null, 74 null, null, null); 75 76 while (userTab.next()) { 77 String tableName = userTab.getString("TABLE_NAME"); 78 if (tableName.equals(DatabaseCreator.TEST_TABLE2)) { 79 statement.execute(DatabaseCreator.DROP_TABLE2); 80 } else if (tableName 81 .equals(DatabaseCreator.SALESPEOPLE_TABLE)) { 82 statement 83 .execute(DatabaseCreator.DROP_TABLE_SALESPEOPLE); 84 } else if (tableName 85 .equals(DatabaseCreator.CUSTOMERS_TABLE)) { 86 statement 87 .execute(DatabaseCreator.DROP_TABLE_CUSTOMERS); 88 } else if (tableName 89 .equals(DatabaseCreator.ORDERS_TABLE)) { 90 statement 91 .execute(DatabaseCreator.DROP_TABLE_ORDERS); 92 } 93 } 94 userTab.close(); 95 96 statement.execute(DatabaseCreator.CREATE_TABLE2); 97 statement.execute(DatabaseCreator.CREATE_TABLE_SALESPEOPLE); 98 statement.execute(DatabaseCreator.CREATE_TABLE_CUSTOMERS); 99 statement.execute(DatabaseCreator.CREATE_TABLE_ORDERS); 100 101 long currentTime = Calendar.getInstance().getTimeInMillis(); 102 date = new Date(currentTime); 103 time = new Time(currentTime); 104 105 DatabaseCreator.fillTestTable2(conn, 1, 5, currentTime); 106 DatabaseCreator.fillCustomersTable(conn); 107 DatabaseCreator.fillOrdersTable(conn); 108 DatabaseCreator.fillSalesPeopleTable(conn); 109 110 } catch (SQLException e) { 111 fail("Unexpected SQLException " + e.toString()); 112 } 113 } 114 deleteTestTables()115 private void deleteTestTables() { 116 try { 117 statement.execute(DatabaseCreator.DROP_TABLE2); 118 statement.execute(DatabaseCreator.DROP_TABLE_SALESPEOPLE); 119 statement.execute(DatabaseCreator.DROP_TABLE_CUSTOMERS); 120 statement.execute(DatabaseCreator.DROP_TABLE_ORDERS); 121 } catch (SQLException e) { 122 fail("Unexpected SQLException " + e.toString()); 123 } 124 } 125 126 /** 127 * SelectFunctionalityTest#test_SelectSimple(). Selects all records 128 * from the table 129 */ test_SelectSimple()130 public void test_SelectSimple() throws SQLException { 131 String sql = "SELECT * FROM " + DatabaseCreator.TEST_TABLE2; 132 ResultSet result = statement.executeQuery(sql); 133 int counter = 0; 134 135 while (result.next()) { 136 int id = result.getInt("finteger"); 137 assertEquals("expected value doesn't equal actual", 138 DatabaseCreator.defaultString + id, result 139 .getString("ftext")); 140 assertEquals("expected value doesn't equal actual", 141 DatabaseCreator.defaultCharacter + id, result 142 .getString("fcharacter")); 143 144 // TODO getBigDecimal is not supported 145 // assertEquals("expected value doesn't equal actual", BigDecimal 146 // .valueOf(id + 0.1), result.getBigDecimal("fdecimal")); 147 // assertEquals("expected value doesn't equal actual", BigDecimal 148 // .valueOf(id + 0.1), result.getBigDecimal("fnumeric")); 149 // assertEquals("expected value doesn't equal actual", id, result 150 // .getInt("fsmallint")); 151 assertEquals("expected value doesn't equal actual", BigDecimal 152 .valueOf(id + 0.1).floatValue(), result.getFloat("ffloat")); 153 assertEquals("expected value doesn't equal actual", BigDecimal 154 .valueOf(id + 0.1).doubleValue(), result.getDouble("freal")); 155 assertEquals("expected value doesn't equal actual", BigDecimal 156 .valueOf(id + 0.1).doubleValue(), result 157 .getDouble("fdouble")); 158 assertEquals("expected value doesn't equal actual", 159 date.toString(), result.getDate("fdate").toString()); 160 assertEquals("expected value doesn't equal actual", 161 time.toString(), result.getTime("ftime").toString()); 162 counter++; 163 } 164 165 assertEquals("number of rows in ResultSet is wrong", 5, counter); 166 result.close(); 167 } 168 169 /** 170 * SelectFunctionalityTest#test_SelectPrepared(). Selects all records 171 * from the table using parametric query 172 */ test_SelectPrepared()173 public void test_SelectPrepared() throws SQLException { 174 String sql = "SELECT finteger, ftext, fcharacter, fdecimal, fnumeric," 175 + " fsmallint, ffloat, freal, fdouble, fdate, ftime" + " FROM " 176 + DatabaseCreator.TEST_TABLE2 177 + " WHERE finteger = ? AND ftext = ? AND fcharacter = ? AND" 178 + " fdecimal = ? AND fnumeric = ? AND fsmallint = ? AND" 179 + " freal = ? AND fdouble = ? AND fdate = ?" + " AND ftime = ?"; 180 PreparedStatement prepStatement = conn.prepareStatement(sql); 181 182 CharArrayReader reader = new CharArrayReader(new String( 183 DatabaseCreator.defaultCharacter + "1").toCharArray()); 184 prepStatement.setInt(1, 1); 185 prepStatement.setString(2, DatabaseCreator.defaultString + "1"); 186 // TODO setCharacterStream and setBigDecimal are not supported 187 // prepStatement.setCharacterStream(3, reader, 4); 188 // prepStatement.setBigDecimal(4, BigDecimal.valueOf(1.1)); 189 // prepStatement.setBigDecimal(5, BigDecimal.valueOf(1.1)); 190 prepStatement.setInt(6, 1); 191 prepStatement.setDouble(7, 1.1); 192 prepStatement.setDouble(8, 1.1); 193 prepStatement.setDate(9, date); 194 prepStatement.setTime(10, time); 195 196 int counter = 0; 197 ResultSet result = prepStatement.executeQuery(); 198 while (result.next()) { 199 int id = result.getInt("finteger"); 200 assertEquals("expected value doesn't equal actual", 201 DatabaseCreator.defaultString + id, result 202 .getString("ftext")); 203 assertEquals("expected value doesn't equal actual", 204 DatabaseCreator.defaultCharacter + id, result 205 .getString("fcharacter")); 206 // TODO getBigDecimal is not supported 207 // assertEquals("expected value doesn't equal actual", BigDecimal 208 // .valueOf(1.1), result.getBigDecimal("fdecimal")); 209 // assertEquals("expected value doesn't equal actual", BigDecimal 210 // .valueOf(1.1), result.getBigDecimal("fnumeric")); 211 assertEquals("expected value doesn't equal actual", id, result 212 .getInt("fsmallint")); 213 assertEquals("expected value doesn't equal actual", 214 (float) (id + 0.1), result.getFloat("ffloat")); 215 assertEquals("expected value doesn't equal actual", 216 (double) (id + 0.1), result.getDouble("freal")); 217 assertEquals("expected value doesn't equal actual", 218 (double) (id + 0.1), result.getDouble("fdouble")); 219 assertEquals("expected value doesn't equal actual", 220 date.toString(), result.getDate("fdate").toString()); 221 assertEquals("expected value doesn't equal actual", 222 time.toString(), result.getTime("ftime").toString()); 223 counter++; 224 } 225 // TODO query wasn't executed due to "not supported" methods 226 // assertEquals("number of rows in ResultSet is wrong", 1, counter); 227 prepStatement.close(); 228 result.close(); 229 } 230 231 /** 232 * SelectFunctionalityTest#test_SubSelect(). Selects records from the 233 * table using subselect 234 */ test_SubSelect()235 public void test_SubSelect() throws SQLException { 236 String sql = "SELECT finteger," + " (SELECT ftext FROM " 237 + DatabaseCreator.TEST_TABLE2 + " WHERE finteger = 1) as ftext" 238 + " FROM " + DatabaseCreator.TEST_TABLE2; 239 ResultSet result = statement.executeQuery(sql); 240 241 HashMap<Integer, String> value = new HashMap<Integer, String>(); 242 value.put(1, DatabaseCreator.defaultString + "1"); 243 value.put(2, DatabaseCreator.defaultString + "1"); 244 value.put(3, DatabaseCreator.defaultString + "1"); 245 value.put(4, DatabaseCreator.defaultString + "1"); 246 value.put(5, DatabaseCreator.defaultString + "1"); 247 248 while (result.next()) { 249 int key = result.getInt("finteger"); 250 String val = result.getString("ftext"); 251 assertTrue("wrong value of finteger field", value.containsKey(key)); 252 assertEquals("wrong value of ftext field", value.get(key), val); 253 value.remove(key); 254 } 255 assertTrue("expected rows number doesn't equal actual rows number", 256 value.isEmpty()); 257 result.close(); 258 } 259 260 /** 261 * SelectFunctionalityTest#test_SelectThreeTables(). Selects records 262 * from a few tables 263 */ test_SelectThreeTables()264 public void test_SelectThreeTables() throws SQLException { 265 String sql = "SELECT onum, " + DatabaseCreator.ORDERS_TABLE + ".cnum" 266 + " FROM " + DatabaseCreator.SALESPEOPLE_TABLE + ", " 267 + DatabaseCreator.CUSTOMERS_TABLE + ", " 268 + DatabaseCreator.ORDERS_TABLE + " WHERE " 269 + DatabaseCreator.CUSTOMERS_TABLE + ".city <> " 270 + DatabaseCreator.SALESPEOPLE_TABLE + ".city" + " AND " 271 + DatabaseCreator.ORDERS_TABLE + ".cnum = " 272 + DatabaseCreator.CUSTOMERS_TABLE + ".cnum" + " AND " 273 + DatabaseCreator.ORDERS_TABLE + ".snum = " 274 + DatabaseCreator.SALESPEOPLE_TABLE + ".snum"; 275 ResultSet result = statement.executeQuery(sql); 276 277 HashMap<Integer, Integer> value = new HashMap<Integer, Integer>(); 278 value.put(3001, 2008); 279 value.put(3002, 2007); 280 value.put(3006, 2008); 281 value.put(3009, 2002); 282 value.put(3007, 2004); 283 value.put(3010, 2004); 284 285 while (result.next()) { 286 int key = result.getInt("onum"); 287 int val = result.getInt("cnum"); 288 assertTrue("wrong value of onum field", value.containsKey(key)); 289 assertEquals("wrong value of cnum field", value.get(key), 290 (Integer) val); 291 value.remove(key); 292 } 293 assertTrue("expected rows number doesn't equal actual rows number", 294 value.isEmpty()); 295 result.close(); 296 } 297 298 /** 299 * SelectFunctionalityTest#test_SelectThreeTables(). Selects records 300 * from a table using union 301 */ test_SelectUnionItself()302 public void test_SelectUnionItself() throws SQLException { 303 String sql = "SELECT b.cnum, b.cname" + " FROM " 304 + DatabaseCreator.CUSTOMERS_TABLE + " a, " 305 + DatabaseCreator.CUSTOMERS_TABLE + " b" 306 + " WHERE a.snum = 1002" + " AND b.city = a.city"; 307 ResultSet result = statement.executeQuery(sql); 308 309 HashMap<Integer, String> value = new HashMap<Integer, String>(); 310 value.put(2003, "Liu"); 311 value.put(2004, "Grass"); 312 value.put(2008, "Cisneros"); 313 314 while (result.next()) { 315 int key = result.getInt("cnum"); 316 String val = result.getString("cname"); 317 assertTrue("wrong value of cnum field", value.containsKey(key)); 318 assertEquals("wrong value of cname field", value.get(key), val); 319 value.remove(key); 320 } 321 assertTrue("expected rows number doesn't equal actual rows number", 322 value.isEmpty()); 323 result.close(); 324 } 325 326 /** 327 * SelectFunctionalityTest#test_SelectLeftOuterJoin(). Selects 328 * records from a table using left join 329 */ test_SelectLeftOuterJoin()330 public void test_SelectLeftOuterJoin() throws SQLException { 331 String sql = "SELECT distinct s.snum as ssnum, c.snum as ccnum FROM " 332 + DatabaseCreator.CUSTOMERS_TABLE + " c left outer join " 333 + DatabaseCreator.SALESPEOPLE_TABLE + " s on s.snum=c.snum"; 334 ResultSet result = statement.executeQuery(sql); 335 336 HashMap<Integer, Integer> value = new HashMap<Integer, Integer>(); 337 value.put(1001, 1001); 338 value.put(1002, 1002); 339 value.put(1003, 1003); 340 value.put(1004, 1004); 341 value.put(1007, 1007); 342 343 while (result.next()) { 344 int key = result.getInt("ssnum"); 345 Object val = result.getObject("ccnum"); 346 assertTrue("wrong value of ssnum field", value.containsKey(key)); 347 assertEquals("wrong value of ccnum field", value.get(key), 348 (Integer) val); 349 value.remove(key); 350 } 351 assertTrue("expected rows number doesn't equal actual rows number", 352 value.isEmpty()); 353 result.close(); 354 } 355 356 /** 357 * SelectFunctionalityTest#test_SelectRightOuterJoin(). Selects 358 * records from a table using right join 359 * 360 * TODO RIGHT and FULL OUTER JOINs are not supported 361 */ 362 @KnownFailure("not supported") test_SelectRightOuterJoin()363 public void test_SelectRightOuterJoin() throws SQLException { 364 String sql = "SELECT distinct s.snum as ssnum, c.snum as ccnum FROM " 365 + DatabaseCreator.CUSTOMERS_TABLE + " c right outer join " 366 + DatabaseCreator.SALESPEOPLE_TABLE + " s on s.snum=c.snum"; 367 ResultSet result = statement.executeQuery(sql); 368 369 HashMap<Integer, Integer> value = new HashMap<Integer, Integer>(); 370 value.put(1001, 1001); 371 value.put(1002, 1002); 372 value.put(1003, 1003); 373 value.put(1004, 1004); 374 value.put(1007, 1007); 375 value.put(1013, null); 376 377 while (result.next()) { 378 int key = result.getInt("ssnum"); 379 Object val = result.getObject("ccnum"); 380 assertTrue("wrong value of ssnum field", value.containsKey(key)); 381 assertEquals("wrong value of ccnum field", value.get(key), 382 (Integer) val); 383 value.remove(key); 384 } 385 assertTrue("expected rows number doesn't equal actual rows number", 386 value.isEmpty()); 387 result.close(); 388 } 389 390 /** 391 * SelectFunctionalityTest#test_SelectGroupBy(). Selects records from 392 * a table using group by 393 */ test_SelectGroupBy()394 public void test_SelectGroupBy() throws SQLException { 395 String selectQuery = "SELECT rating, SUM(snum) AS sum FROM " 396 + DatabaseCreator.CUSTOMERS_TABLE + " GROUP BY rating"; 397 ResultSet result = statement.executeQuery(selectQuery); 398 399 HashMap<Integer, Integer> values = new HashMap<Integer, Integer>(); 400 values.put(100, 3006); 401 values.put(200, 2005); 402 values.put(300, 2009); 403 404 while (result.next()) { 405 int rating = result.getInt("rating"); 406 int sum = result.getInt("sum"); 407 assertTrue("Wrong value of rating field", values 408 .containsKey(rating)); 409 assertEquals("Wrong value of sum field", values.get(rating), 410 new Integer(sum)); 411 assertEquals(new Integer(sum), values.remove(rating)); 412 } 413 result.close(); 414 assertTrue("Result set has wrong size", values.isEmpty()); 415 } 416 417 /** 418 * SelectFunctionalityTest#test_SelectOrderBy(). Selects records from 419 * a table using order by 420 */ test_SelectOrderBy()421 public void test_SelectOrderBy() throws SQLException { 422 String selectQuery = "SELECT onum FROM " + DatabaseCreator.ORDERS_TABLE 423 + " ORDER BY onum"; 424 ResultSet result = statement.executeQuery(selectQuery); 425 426 ArrayList<Integer> values = new ArrayList<Integer>(); 427 values.add(Integer.valueOf(3001)); 428 values.add(Integer.valueOf(3002)); 429 values.add(Integer.valueOf(3003)); 430 values.add(Integer.valueOf(3005)); 431 values.add(Integer.valueOf(3006)); 432 values.add(Integer.valueOf(3007)); 433 values.add(Integer.valueOf(3008)); 434 values.add(Integer.valueOf(3009)); 435 values.add(Integer.valueOf(3010)); 436 values.add(Integer.valueOf(3011)); 437 438 int index = 0; 439 while (result.next()) { 440 Integer onum = result.getInt("onum"); 441 assertTrue("result set doesn't contain value", values 442 .contains(onum)); 443 assertEquals("result set is not sorted", index, values 444 .indexOf(onum)); 445 index++; 446 } 447 result.close(); 448 } 449 450 /** 451 * SelectFunctionalityTest#test_SelectDistinct(). Selects records 452 * from a table using distinct 453 */ test_SelectDistinct()454 public void test_SelectDistinct() throws SQLException { 455 String selectQuery = "SELECT DISTINCT rating FROM " 456 + DatabaseCreator.CUSTOMERS_TABLE; 457 ResultSet result = statement.executeQuery(selectQuery); 458 459 HashSet<Integer> values = new HashSet<Integer>(); 460 values.add(Integer.valueOf(100)); 461 values.add(Integer.valueOf(200)); 462 values.add(Integer.valueOf(300)); 463 464 while (result.next()) { 465 Integer rating = result.getInt("rating"); 466 assertTrue("result set doesn't contain value", values 467 .contains(rating)); 468 assertTrue("wrong value in the result set", values.remove(rating)); 469 } 470 result.close(); 471 assertTrue("Result set has wrong size", values.isEmpty()); 472 } 473 474 /** 475 * SelectFunctionalityTest#test_SelectAgregateFunctions(). Selects 476 * records from a table using agregate functions 477 */ test_SelectAgregateFunctions()478 public void test_SelectAgregateFunctions() throws SQLException { 479 String selectCount = "SELECT count(onum) as count FROM " 480 + DatabaseCreator.ORDERS_TABLE; 481 String selectSum = "SELECT sum(onum) as sum FROM " 482 + DatabaseCreator.ORDERS_TABLE; 483 String selectAvg = "SELECT avg(onum) as avg FROM " 484 + DatabaseCreator.ORDERS_TABLE; 485 String selectMax = "SELECT max(onum) as max FROM " 486 + DatabaseCreator.ORDERS_TABLE; 487 String selectMin = "SELECT min(onum) as min FROM " 488 + DatabaseCreator.ORDERS_TABLE; 489 490 func("count", selectCount, 10); 491 func("sum", selectSum, 30062); 492 func("avg", selectAvg, 3006); 493 func("max", selectMax, 3011); 494 func("min", selectMin, 3001); 495 } 496 func(String name, String query, int expected)497 private void func(String name, String query, int expected) { 498 int res = 0; 499 double resDouble = 0.0; 500 try { 501 ResultSet result = statement.executeQuery(query); 502 while (result.next()) { 503 res = result.getInt(name); 504 if (res != 0 ) { 505 assertEquals(expected,res); 506 break; 507 } 508 // for Double: getInt not supported yet 509 resDouble = Double.parseDouble(result.getString(name)); 510 res = (int) Math.rint(resDouble); 511 assertEquals(expected,res); 512 513 } 514 assertFalse("wrong size of result set", result.next()); 515 result.close(); 516 } catch (SQLException e) { 517 fail(e.getMessage()); 518 } 519 } 520 521 /** 522 * SelectFunctionalityTest#test_SelectHaving(). Selects records from 523 * a table using having 524 */ test_SelectHaving()525 public void test_SelectHaving() throws SQLException { 526 String selectQuery = "SELECT snum, max(amt) AS max FROM " 527 + DatabaseCreator.ORDERS_TABLE 528 + " GROUP BY snum HAVING max(amt) > 3000"; 529 ResultSet result = statement.executeQuery(selectQuery); 530 531 HashSet<Double> values = new HashSet<Double>(); 532 values.add(Double.valueOf(9891.88)); 533 values.add(Double.valueOf(5160.45)); 534 535 while (result.next()) { 536 Double max = result.getDouble("max"); 537 assertTrue("result set doesn't contain value", values.contains(max)); 538 assertTrue("wrong value in the result set", values.remove(max)); 539 } 540 result.close(); 541 assertTrue("Result set has wrong size", values.isEmpty()); 542 } 543 } 544