1 package com.workingdogs.village;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.sql.Connection;
23 import java.sql.DriverManager;
24 import java.sql.PreparedStatement;
25 import java.sql.SQLException;
26
27 import junit.framework.TestCase;
28
29 /***
30 * This class is used for testing the functionality of this product. While
31 * creating this code, I have closed many potential bugs, but I'm sure that
32 * others still exist. Thus, if you find a bug in Village, please add to this
33 * test suite so that the bug will be sure to be fixed in future versions.
34 *
35 * <p>
36 * In order to do the testing, you will need to be able to connect via JDBC to
37 * your database. Since I use <a href="http://www.mysql.com/">MySQL</a>, this
38 * testing suite is best for that database. I also use the mm MySQL drivers
39 * <a href="http://mmmysql.sourceforge.net/">mm MySQL drivers</a> because it
40 * is the best driver that I have found for MySQL.
41 * </p>
42 *
43 * <P>
44 * Note that Village should work with <strong>any</strong> JDBC compliant driver.
45 * </p>
46 *
47 * <p>
48 * Here is the schema that this test expects (you should be able to copy and
49 * paste it into your MySQL database that you want to use):
50 * <pre>
51 * CREATE TABLE test
52 * (
53 * a TINYINT null,
54 * b SMALLINT null,
55 * c MEDIUMINT null,
56 * d INT null,
57 * e INTEGER null,
58 * f BIGINT null,
59 * g REAL null,
60 * h DOUBLE null,
61 * i FLOAT null,
62 * j DECIMAL(8,1) null,
63 * k NUMERIC(8,1) null,
64 * l CHAR(255) null,
65 * m VARCHAR(255) null,
66 * n DATE null,
67 * o TIME null,
68 * p TIMESTAMP null,
69 * q DATETIME null,
70 * r TINYBLOB null,
71 * s BLOB null,
72 * t MEDIUMBLOB null,
73 * u LONGBLOB null,
74 * v TINYTEXT null,
75 * w TEXT null,
76 * x MEDIUMTEXT null
77 * );
78 * </pre>
79 * </p>
80 *
81 * <p>
82 * Note that presently this class is hardcoded to use a MySQL database named
83 * "village" with a username of "village" and a password of "village". It is
84 * a modified version of Jon's original Unit test that apparently pre-dated
85 * JUnit!
86 * </p>
87 *
88 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
89 * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
90 * @version $Revision: 565 $
91 */
92 public class TestMySQL extends TestCase
93 {
94 /*** The database connection */
95 static Connection conn;
96
97 /*** This is the name of the database. Created with mysqladmin create */
98 private static String DB_NAME = "village";
99
100 /*** This is the name of the table in the DB_NAME */
101 private static String DB_TABLE = "test";
102
103 /*** This is the name of the machine that is hosting the MySQL server */
104 private static String DB_HOST = "localhost";
105
106 /***
107 * This is the user to log into the database as. For this test, the user
108 * must have insert/update/delete access to the database.
109 */
110 private static String DB_USER = "village";
111
112 /*** the password for the user */
113 private static String DB_PASS = "village";
114
115 /*** mm MySQL Driver setup */
116 private static String DB_DRIVER = "org.gjt.mm.mysql.Driver";
117
118
119 /*** mm MySQL Driver setup */
120 private static String DB_CONNECTION = "jdbc:mysql://" + DB_HOST + "/"
121 + DB_NAME + "?user=" + DB_USER + "&password=" + DB_PASS;
122
123 /*** used for debugging */
124 private static boolean debugging = true;
125
126 /*** used for debugging */
127 private static int num = 1;
128
129 /*** used for debugging */
130 private static int TDS = 1;
131
132 /*** used for debugging */
133 private static int QDS = 2;
134
135 /*** used for debugging */
136 private static int PASSED = 1;
137
138 /*** used for debugging */
139 private static int FAILED = 2;
140
141 /*** The number of times to hit the schema to try and reach a connection
142 * limit. */
143 private static int SCHEMA_LOOPS = 2000;
144
145 /***
146 * Creates a new instance.
147 *
148 * @param name the name of the test case to run
149 */
150 public TestMySQL(String name)
151 {
152 super(name);
153 }
154
155 /***
156 // * @TODO DOCUMENT ME!
157 // *
158 // * @param argv
159 // */
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190 public void setUp()
191 {
192 try
193 {
194 getConnection();
195 }
196 catch (ClassNotFoundException e)
197 {
198 System.out.println("\n\nConnection failed : " + e.getMessage());
199 }
200 catch (SQLException e)
201 {
202 System.out.println("\n\nConnection failed : " + e.getMessage());
203 }
204 }
205
206 protected void tearDown() throws Exception
207 {
208
209 PreparedStatement ps = conn.prepareStatement("delete from test");
210 ps.execute();
211
212 conn.close();
213 }
214
215 /***
216 * This test verifies that deleting multiple records actually works. after
217 * execution, there should be no more records in the database.
218 */
219 public static void testDeleteSomeRecords()
220 throws SQLException, DataSetException
221 {
222 KeyDef kd = new KeyDef().addAttrib("e");
223 TableDataSet tds = new TableDataSet(conn, DB_TABLE, kd);
224 tds.where("e > 100");
225
226
227 Record newRec = tds.addRecord();
228 newRec.setValue("e", "200");
229
230 Record newRec2 = tds.addRecord();
231 newRec2.setValue("e", "300");
232 tds.save();
233
234
235 tds.fetchRecords();
236
237 for (int i = 0; i < tds.size(); i++)
238 {
239 Record rec = tds.getRecord(i);
240
241
242 rec.markToBeDeleted();
243 System.out.println("here " + i + ": " + rec.toString());
244 }
245
246 tds.save();
247 tds.close();
248 }
249
250 /***
251 * This test checks that a DataSetException is thrown when appropriate.
252 */
253 public static void testRemoveRecord()
254 throws SQLException, DataSetException
255 {
256 TableDataSet tds = new TableDataSet(conn, DB_TABLE);
257 tds.addRecord();
258
259 Record rec = tds.getRecord(0);
260 tds.removeRecord(rec);
261
262 try
263 {
264 Record foo = tds.getRecord(0);
265 }
266 catch (DataSetException e)
267 {
268
269 }
270 tds.close();
271 }
272
273 public static void testTableDataSet2()
274 throws SQLException, DataSetException
275 {
276 TableDataSet tds = new TableDataSet(conn, DB_TABLE);
277 Record rec = tds.addRecord();
278 rec.setValue("b", 2);
279 tds.save();
280 tds.close();
281 }
282
283 public static void testTableDataSet3()
284 throws SQLException, DataSetException
285 {
286 TableDataSet tds = new TableDataSet(conn, DB_TABLE);
287 Record rec = tds.addRecord();
288 rec.setValue("b", 2);
289 rec.save();
290 tds.close();
291 }
292
293 public static void testTableDataSet4()
294 throws SQLException, DataSetException
295 {
296 KeyDef kd = new KeyDef().addAttrib("b");
297 TableDataSet tds = new TableDataSet(conn, DB_TABLE, kd);
298 Record rec = tds.addRecord();
299 rec.setValueNull("b");
300 System.out.println(rec.getSaveString());
301 rec.save();
302 rec.markToBeDeleted();
303 System.out.println(rec.getSaveString());
304 rec.save();
305 tds.close();
306 }
307
308 public static void testTableDataSet()
309 throws SQLException, DataSetException
310 {
311 KeyDef kd = new KeyDef().addAttrib("a");
312 TableDataSet tds = new TableDataSet(conn, DB_TABLE, kd);
313 tds.order("a");
314 tds.fetchRecords();
315
316 int size = tds.size();
317 assertEquals(0, size);
318
319 debug(TDS, "size of fetchRecords", size);
320 debug(TDS, "getSelectString()", tds.getSelectString());
321 assertEquals("SELECT * FROM test ORDER BY a", tds.getSelectString());
322
323
324 Record addRec = tds.addRecord();
325 addRec.setValue("a", 1);
326 addRec.setValue("b", 2);
327 addRec.setValue("c", 2343);
328 addRec.setValue("d", 33333);
329 addRec.setValue("e", 22222);
330 addRec.setValue("f", 234324);
331 addRec.setValue("g", 3434);
332 addRec.setValue("h", 2343.30);
333 addRec.setValue("i", 2343.22);
334 addRec.setValue("j", 333.3);
335 addRec.setValue("k", 333.3);
336 addRec.setValue("l", "lskdfsd");
337 addRec.setValue("m", "lksdflkjsldf");
338 addRec.setValue("n", new java.util.Date());
339 addRec.setValue("o", new java.util.Date());
340 addRec.setValue("p", new java.util.Date());
341 addRec.setValue("q", new java.util.Date());
342 addRec.setValue("r", "lksdflkjsldf");
343 addRec.setValue("s", "lksdflkjsldf");
344 addRec.setValue("t", "lksdflkjsldf");
345 addRec.setValue("u", "lksdflkjsldf");
346 addRec.setValue("v", "lksdflkjsldf");
347 addRec.setValue("w", "lksdflkjsldf");
348 addRec.setValue("x", "lksdflkjsldf");
349
350 debug(TDS, "getSaveString() for insert", addRec.getSaveString());
351 assertEquals("INSERT INTO test ( a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )",
352 addRec.getSaveString());
353
354
355 addRec.save();
356
357 debug(TDS, "size of TDS after save()", tds.size());
358 assertEquals(1, tds.size());
359
360 Record updateRec = tds.getRecord(0);
361 updateRec.setValue("b", 234);
362 updateRec.setValue("c", 4);
363 updateRec.setValue("d", 4);
364 updateRec.setValue("e", 5);
365 updateRec.setValue("f", 6);
366 updateRec.setValue("g", 3);
367 updateRec.setValue("h", 3.4);
368 updateRec.setValue("i", 33.44);
369 updateRec.setValue("j", 33.55);
370 updateRec.setValue("k", 3333.7);
371 updateRec.setValue("l", "qweqwe");
372 updateRec.setValue("m", "qweqwe");
373 updateRec.setValue("n", new java.util.Date());
374 updateRec.setValue("o", new java.util.Date());
375 updateRec.setValue("p", new java.util.Date());
376 updateRec.setValue("q", new java.util.Date());
377 updateRec.setValue("r", "qweqwe");
378 updateRec.setValue("s", "qweqwe");
379 updateRec.setValue("t", "qweqwe");
380 updateRec.setValue("u", "qweqwe");
381 updateRec.setValue("v", "qweqwe");
382 updateRec.setValue("w", "qweqwe");
383 updateRec.setValue("x", "qweqwe");
384
385 debug(TDS, "updateRec.getRefreshQueryString()", updateRec.getRefreshQueryString());
386
387 debug(TDS, "updateRec.getSaveString() for update", updateRec.getSaveString());
388 assertEquals("UPDATE test SET b = ?, c = ?, d = ?, e = ?, f = ?, g = ?, h = ?, i = ?, j = ?, k = ?, l = ?, m = ?, n = ?, o = ?, p = ?, q = ?, r = ?, s = ?, t = ?, u = ?, v = ?, w = ?, x = ? WHERE a = ?",
389 updateRec.getSaveString());
390
391 updateRec.save();
392 assertEquals(1, tds.size());
393
394
395 addRec.markToBeDeleted();
396 assertEquals(1, addRec.getValue(1).asInt());
397
398 debug(TDS, "addRec.getSaveString() for delete", addRec.getSaveString());
399 assertEquals("DELETE FROM test WHERE a = ?", addRec.getSaveString());
400
401
402 assertEquals(1, addRec.save());
403
404 assertEquals(Enums.ZOMBIE, addRec.getSaveType());
405 assertEquals(1, tds.size());
406
407 tds.save();
408 assertEquals(0, tds.size());
409
410 tds.close();
411
412
413 tds = new TableDataSet(conn, DB_TABLE, kd);
414 tds.fetchRecords();
415 addRec = tds.addRecord();
416 addRec.setValue("a", 1);
417 addRec.save();
418 assertEquals(1, tds.size());
419
420 tds = new TableDataSet(conn, DB_TABLE, kd);
421 tds.fetchRecords();
422 assertEquals(1, tds.size());
423
424 Record getRec = tds.getRecord(0);
425
426 debug(TDS, "getRec.asString() 1a:", getRec.getValue("a").asString());
427 assertEquals("1", getRec.getValue("a").asString());
428 debug(TDS, "getRec.asString() 1b:", getRec.getValue("b").asString());
429
430 assertNull(getRec.getValue("b").asString());
431
432
433
434 getRec.setValue("b", 5);
435
436 debug(TDS, "getRec.asString() 2b:", getRec.getValue("b").asString());
437 assertEquals("5", getRec.getValue("b").asString());
438
439
440
441
442 getRec.refresh(conn);
443
444 debug(TDS, "getRec.asString() 3b:", getRec.getValue("b").asString());
445
446 assertNull(getRec.getValue("b").asString());
447 debug(TDS, "getRec.asString() 2a:", getRec.getValue("a").asString());
448 assertEquals("1", getRec.getValue("a").asString());
449
450 getRec.markToBeDeleted();
451 getRec.save();
452
453 System.out.println(tds.toString());
454 System.out.println(getRec.toString());
455 System.out.println(tds.schema().toString());
456
457 tds.close();
458 }
459
460 /***
461 * @throws DataSetException
462 * @throws SQLException
463 */
464 public static void testQueryDataSet()
465 throws SQLException, DataSetException
466 {
467 KeyDef kd = new KeyDef().addAttrib("a");
468 TableDataSet tds = new TableDataSet(conn, DB_TABLE, kd);
469 tds.fetchRecords();
470
471
472 Record addRec = tds.addRecord();
473 addRec.setValue("a", 1);
474 addRec.setValue("b", 2);
475 debug(TDS, "addRec.getSaveString()", addRec.getSaveString());
476 assertEquals("INSERT INTO test ( a, b ) VALUES ( ?, ? )", addRec.getSaveString());
477
478
479 addRec.save();
480 tds.close();
481
482
483 QueryDataSet qds = new QueryDataSet(conn, "SELECT * FROM " + DB_TABLE);
484 qds.fetchRecords();
485
486 debug(QDS, "qds.getSelectString()", qds.getSelectString());
487 assertEquals("SELECT * FROM test", qds.getSelectString());
488
489 debug(QDS, "qds.size()", qds.size());
490
491 Record rec = qds.getRecord(0);
492 debug(QDS, "rec.size()", rec.size());
493
494 debug(QDS, "rec.getValue(\"a\").asString()", rec.getValue("a").asString());
495 debug(QDS, "rec.getValue(\"b\").asString()", rec.getValue("b").asString());
496 debug(QDS, "rec.getValue(\"c\").asString()", rec.getValue("c").asString());
497 debug(QDS, "rec.getValue(\"d\").asString()", rec.getValue("d").asString());
498
499
500
501
502
503
504 assertNull(rec.getValue("d").asString());
505 qds.close();
506
507
508 kd = new KeyDef().addAttrib("a");
509 tds = new TableDataSet(conn, DB_TABLE, kd);
510 tds.fetchRecords();
511
512 Record getRec = tds.getRecord(0);
513 getRec.markToBeDeleted();
514 getRec.save();
515 tds.close();
516 }
517
518 /***
519 * This is a test for TORQUE-8.
520 *
521 * @throws DataSetException
522 * @throws SQLException
523 */
524 public static void testSchemaResultSet()
525 throws SQLException, DataSetException
526 {
527 for (int i = 0; i < SCHEMA_LOOPS; i++)
528 {
529 System.out.println("testSchemaResultSet() run " + i + " of " + SCHEMA_LOOPS);
530 Schema schema = new Schema().schema(conn, "test", "a");
531 assertEquals(schema.getTableName(), "test");
532 }
533 }
534
535 /***
536 * Get a connection.
537 */
538 public static void getConnection()
539 throws ClassNotFoundException, SQLException
540 {
541 Class.forName(DB_DRIVER);
542 conn = DriverManager.getConnection(DB_CONNECTION);
543 }
544
545 /***
546 * Print some debug info.
547 *
548 * @param type
549 * @param e
550 */
551 public static void debug(int type, Exception e)
552 {
553 debug(TDS, e.getMessage());
554 e.printStackTrace();
555 System.out.println("\n");
556 }
557
558 /***
559 * Print some debug info.
560 *
561 * @param type
562 * @param method
563 */
564 public static void debug(int type, String method)
565 {
566 debug(type, method, null);
567 }
568
569 /***
570 * Print some debug info.
571 *
572 * @param type
573 * @param method
574 * @param value
575 */
576 public static void debug(int type, String method, int value)
577 {
578 debug(type, method, String.valueOf(value));
579 }
580
581 /***
582 * Print some debug info.
583 *
584 * @param type
585 * @param method
586 * @param value
587 */
588 public static void debug(int type, String method, String value)
589 {
590 if (debugging)
591 {
592 String name = "";
593
594 if (type == TDS)
595 {
596 name = "TableDataSet";
597 }
598 else
599 {
600 name = "QueryDataSet";
601 }
602
603 if (value != null)
604 {
605 System.out.print("[" + num++ + "] " + name + " - " + method + " = " + value + "\n");
606 }
607 else
608 {
609 System.out.print("[" + num++ + "] " + name + " - " + method + "\n");
610 }
611
612 System.out.flush();
613 }
614 }
615 }