KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > testsuite > simple > MetadataTest


1 /*
2  Copyright (C) 2002-2004 MySQL AB
3
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of version 2 of the GNU General Public License as
6  published by the Free Software Foundation.
7
8  There are special exceptions to the terms and conditions of the GPL
9  as it is applied to this software. View the full text of the
10  exception in file EXCEPTIONS-CONNECTOR-J in the directory of this
11  software distribution.
12
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22
23
24  */

25 package testsuite.simple;
26
27 import testsuite.BaseTestCase;
28
29 import java.sql.Connection JavaDoc;
30 import java.sql.DatabaseMetaData JavaDoc;
31 import java.sql.ResultSet JavaDoc;
32 import java.sql.ResultSetMetaData JavaDoc;
33 import java.sql.SQLException JavaDoc;
34 import java.sql.Types JavaDoc;
35 import java.util.BitSet JavaDoc;
36 import java.util.Properties JavaDoc;
37
38 /**
39  * Tests DatabaseMetaData methods.
40  *
41  * @author Mark Matthews
42  * @version $Id: MetadataTest.java,v 1.1.2.2 2005/05/19 15:52:24 mmatthews Exp $
43  */

44 public class MetadataTest extends BaseTestCase {
45     // ~ Constructors
46
// -----------------------------------------------------------
47

48     /**
49      * Creates a new MetadataTest object.
50      *
51      * @param name
52      * DOCUMENT ME!
53      */

54     public MetadataTest(String JavaDoc name) {
55         super(name);
56     }
57
58     // ~ Methods
59
// ----------------------------------------------------------------
60

61     /**
62      * Runs all test cases in this test suite
63      *
64      * @param args
65      */

66     public static void main(String JavaDoc[] args) {
67         junit.textui.TestRunner.run(MetadataTest.class);
68     }
69
70     /**
71      * DOCUMENT ME!
72      *
73      * @throws Exception
74      * DOCUMENT ME!
75      */

76     public void setUp() throws Exception JavaDoc {
77         super.setUp();
78         createTestTable();
79     }
80
81     /**
82      * DOCUMENT ME!
83      *
84      * @throws SQLException
85      * DOCUMENT ME!
86      */

87     public void testForeignKeys() throws SQLException JavaDoc {
88         DatabaseMetaData JavaDoc dbmd = this.conn.getMetaData();
89         this.rs = dbmd.getImportedKeys(null, null, "child");
90
91         while (this.rs.next()) {
92             String JavaDoc pkColumnName = this.rs.getString("PKCOLUMN_NAME");
93             String JavaDoc fkColumnName = this.rs.getString("FKCOLUMN_NAME");
94             assertTrue("Primary Key not returned correctly ('" + pkColumnName
95                     + "' != 'parent_id')", pkColumnName
96                     .equalsIgnoreCase("parent_id"));
97             assertTrue("Foreign Key not returned correctly ('" + fkColumnName
98                     + "' != 'parent_id_fk')", fkColumnName
99                     .equalsIgnoreCase("parent_id_fk"));
100         }
101
102         this.rs.close();
103         this.rs = dbmd.getExportedKeys(null, null, "parent");
104
105         while (this.rs.next()) {
106             String JavaDoc pkColumnName = this.rs.getString("PKCOLUMN_NAME");
107             String JavaDoc fkColumnName = this.rs.getString("FKCOLUMN_NAME");
108             String JavaDoc fkTableName = this.rs.getString("FKTABLE_NAME");
109             assertTrue("Primary Key not returned correctly ('" + pkColumnName
110                     + "' != 'parent_id')", pkColumnName
111                     .equalsIgnoreCase("parent_id"));
112             assertTrue(
113                     "Foreign Key table not returned correctly for getExportedKeys ('"
114                             + fkTableName + "' != 'child')", fkTableName
115                             .equalsIgnoreCase("child"));
116             assertTrue(
117                     "Foreign Key not returned correctly for getExportedKeys ('"
118                             + fkColumnName + "' != 'parent_id_fk')",
119                     fkColumnName.equalsIgnoreCase("parent_id_fk"));
120         }
121
122         this.rs.close();
123
124         this.rs = dbmd.getCrossReference(null, null, "cpd_foreign_3", null,
125                 null, "cpd_foreign_4");
126
127         while (this.rs.next()) {
128             String JavaDoc pkColumnName = this.rs.getString("PKCOLUMN_NAME");
129             String JavaDoc pkTableName = this.rs.getString("PKTABLE_NAME");
130             String JavaDoc fkColumnName = this.rs.getString("FKCOLUMN_NAME");
131             String JavaDoc fkTableName = this.rs.getString("FKTABLE_NAME");
132             String JavaDoc deleteAction = cascadeOptionToString(this.rs
133                     .getInt("DELETE_RULE"));
134             String JavaDoc updateAction = cascadeOptionToString(this.rs
135                     .getInt("UPDATE_RULE"));
136
137             System.out.println("[D] " + deleteAction);
138             System.out.println("[U] " + updateAction);
139
140             System.out.println(pkTableName + "(" + pkColumnName + ") -> "
141                     + fkTableName + "(" + fkColumnName + ")");
142         }
143
144         this.rs.close();
145
146         this.rs = dbmd.getImportedKeys(null, null, "fktable2");
147     }
148
149     /**
150      * DOCUMENT ME!
151      *
152      * @throws SQLException
153      * DOCUMENT ME!
154      */

155     public void testGetPrimaryKeys() throws SQLException JavaDoc {
156         try {
157             DatabaseMetaData JavaDoc dbmd = this.conn.getMetaData();
158             this.rs = dbmd.getPrimaryKeys(this.conn.getCatalog(), "",
159                     "multikey");
160
161             short[] keySeqs = new short[4];
162             String JavaDoc[] columnNames = new String JavaDoc[4];
163             int i = 0;
164
165             while (this.rs.next()) {
166                 this.rs.getString("TABLE_NAME");
167                 columnNames[i] = this.rs.getString("COLUMN_NAME");
168
169                 this.rs.getString("PK_NAME");
170                 keySeqs[i] = this.rs.getShort("KEY_SEQ");
171                 i++;
172             }
173
174             if ((keySeqs[0] != 3) && (keySeqs[1] != 2) && (keySeqs[2] != 4)
175                     && (keySeqs[4] != 1)) {
176                 fail("Keys returned in wrong order");
177             }
178         } finally {
179             if (this.rs != null) {
180                 try {
181                     this.rs.close();
182                 } catch (SQLException JavaDoc sqlEx) {
183                     /* ignore */
184                 }
185             }
186         }
187     }
188
189     private static String JavaDoc cascadeOptionToString(int option) {
190         switch (option) {
191         case DatabaseMetaData.importedKeyCascade:
192             return "CASCADE";
193
194         case DatabaseMetaData.importedKeySetNull:
195             return "SET NULL";
196
197         case DatabaseMetaData.importedKeyRestrict:
198             return "RESTRICT";
199
200         case DatabaseMetaData.importedKeyNoAction:
201             return "NO ACTION";
202         }
203
204         return "SET DEFAULT";
205     }
206
207     private void createTestTable() throws SQLException JavaDoc {
208         this.stmt.executeUpdate("DROP TABLE IF EXISTS child");
209         this.stmt.executeUpdate("DROP TABLE IF EXISTS parent");
210         this.stmt.executeUpdate("DROP TABLE IF EXISTS multikey");
211         this.stmt.executeUpdate("DROP TABLE IF EXISTS cpd_foreign_4");
212         this.stmt.executeUpdate("DROP TABLE IF EXISTS cpd_foreign_3");
213         this.stmt.executeUpdate("DROP TABLE IF EXISTS cpd_foreign_2");
214         this.stmt.executeUpdate("DROP TABLE IF EXISTS cpd_foreign_1");
215         this.stmt.executeUpdate("DROP TABLE IF EXISTS fktable2");
216         this.stmt.executeUpdate("DROP TABLE IF EXISTS fktable1");
217
218         this.stmt
219                 .executeUpdate("CREATE TABLE parent(parent_id INT NOT NULL, PRIMARY KEY (parent_id)) TYPE=INNODB");
220         this.stmt
221                 .executeUpdate("CREATE TABLE child(child_id INT, parent_id_fk INT, INDEX par_ind (parent_id_fk), "
222                         + "FOREIGN KEY (parent_id_fk) REFERENCES parent(parent_id)) TYPE=INNODB");
223         this.stmt
224                 .executeUpdate("CREATE TABLE multikey(d INT NOT NULL, b INT NOT NULL, a INT NOT NULL, c INT NOT NULL, PRIMARY KEY (d, b, a, c))");
225
226         // Test compound foreign keys
227
this.stmt.executeUpdate("create table cpd_foreign_1("
228                 + "id int(8) not null auto_increment primary key,"
229                 + "name varchar(255) not null unique," + "key (id)"
230                 + ") type=InnoDB");
231         this.stmt.executeUpdate("create table cpd_foreign_2("
232                 + "id int(8) not null auto_increment primary key,"
233                 + "key (id)," + "name varchar(255)" + ") type=InnoDB");
234         this.stmt
235                 .executeUpdate("create table cpd_foreign_3("
236                         + "cpd_foreign_1_id int(8) not null,"
237                         + "cpd_foreign_2_id int(8) not null,"
238                         + "key(cpd_foreign_1_id),"
239                         + "key(cpd_foreign_2_id),"
240                         + "primary key (cpd_foreign_1_id, cpd_foreign_2_id),"
241                         + "foreign key (cpd_foreign_1_id) references cpd_foreign_1(id),"
242                         + "foreign key (cpd_foreign_2_id) references cpd_foreign_2(id)"
243                         + ") type=InnoDB");
244         this.stmt
245                 .executeUpdate("create table cpd_foreign_4("
246                         + "cpd_foreign_1_id int(8) not null,"
247                         + "cpd_foreign_2_id int(8) not null,"
248                         + "key(cpd_foreign_1_id),"
249                         + "key(cpd_foreign_2_id),"
250                         + "primary key (cpd_foreign_1_id, cpd_foreign_2_id),"
251                         + "foreign key (cpd_foreign_1_id, cpd_foreign_2_id) "
252                         + "references cpd_foreign_3(cpd_foreign_1_id, cpd_foreign_2_id) "
253                         + "ON DELETE RESTRICT ON UPDATE CASCADE"
254                         + ") type=InnoDB");
255
256         this.stmt
257                 .executeUpdate("create table fktable1 (TYPE_ID int not null, TYPE_DESC varchar(32), primary key(TYPE_ID)) TYPE=InnoDB");
258         this.stmt
259                 .executeUpdate("create table fktable2 (KEY_ID int not null, COF_NAME varchar(32), PRICE float, TYPE_ID int, primary key(KEY_ID), "
260                         + "index(TYPE_ID), foreign key(TYPE_ID) references fktable1(TYPE_ID)) TYPE=InnoDB");
261     }
262
263     /**
264      * Tests the implementation of metadata for views.
265      *
266      * This test automatically detects whether or not the server it is running
267      * against supports the creation of views.
268      *
269      * @throws SQLException
270      * if the test fails.
271      */

272     public void testViewMetaData() throws SQLException JavaDoc {
273         try {
274             this.rs = this.conn.getMetaData().getTableTypes();
275
276             while (this.rs.next()) {
277                 if ("VIEW".equalsIgnoreCase(this.rs.getString(1))) {
278
279                     this.stmt
280                             .executeUpdate("DROP VIEW IF EXISTS vTestViewMetaData");
281                     this.stmt
282                             .executeUpdate("DROP TABLE IF EXISTS testViewMetaData");
283                     this.stmt
284                             .executeUpdate("CREATE TABLE testViewMetaData (field1 INT)");
285                     this.stmt
286                             .executeUpdate("CREATE VIEW vTestViewMetaData AS SELECT field1 FROM testViewMetaData");
287
288                     ResultSet JavaDoc tablesRs = null;
289
290                     try {
291                         tablesRs = this.conn.getMetaData().getTables(
292                                 this.conn.getCatalog(), null, "%ViewMetaData",
293                                 new String JavaDoc[] { "TABLE", "VIEW" });
294                         assertTrue(tablesRs.next());
295                         assertTrue("testViewMetaData".equalsIgnoreCase(tablesRs
296                                 .getString(3)));
297                         assertTrue(tablesRs.next());
298                         assertTrue("vTestViewMetaData"
299                                 .equalsIgnoreCase(tablesRs.getString(3)));
300
301                     } finally {
302                         if (tablesRs != null) {
303                             tablesRs.close();
304                         }
305                     }
306
307                     try {
308                         tablesRs = this.conn.getMetaData().getTables(
309                                 this.conn.getCatalog(), null, "%ViewMetaData",
310                                 new String JavaDoc[] { "TABLE" });
311                         assertTrue(tablesRs.next());
312                         assertTrue("testViewMetaData".equalsIgnoreCase(tablesRs
313                                 .getString(3)));
314                         assertTrue(!tablesRs.next());
315                     } finally {
316                         if (tablesRs != null) {
317                             tablesRs.close();
318                         }
319                     }
320                     break;
321                 }
322             }
323
324         } finally {
325             if (this.rs != null) {
326                 this.rs.close();
327             }
328         }
329     }
330
331     /**
332      * Tests detection of read-only fields when the server is 4.1.0 or newer.
333      *
334      * @throws Exception
335      * if the test fails.
336      */

337     public void testRSMDIsReadOnly() throws Exception JavaDoc {
338         try {
339             this.rs = this.stmt.executeQuery("SELECT 1");
340
341             ResultSetMetaData JavaDoc rsmd = this.rs.getMetaData();
342
343             if (versionMeetsMinimum(4, 1)) {
344                 assertTrue(rsmd.isReadOnly(1));
345
346                 try {
347                     this.stmt
348                             .executeUpdate("DROP TABLE IF EXISTS testRSMDIsReadOnly");
349                     this.stmt
350                             .executeUpdate("CREATE TABLE testRSMDIsReadOnly (field1 INT)");
351                     this.stmt
352                             .executeUpdate("INSERT INTO testRSMDIsReadOnly VALUES (1)");
353
354                     this.rs = this.stmt
355                             .executeQuery("SELECT 1, field1 + 1, field1 FROM testRSMDIsReadOnly");
356                     rsmd = this.rs.getMetaData();
357
358                     assertTrue(rsmd.isReadOnly(1));
359                     assertTrue(rsmd.isReadOnly(2));
360                     assertTrue(!rsmd.isReadOnly(3));
361                 } finally {
362                     this.stmt
363                             .executeUpdate("DROP TABLE IF EXISTS testRSMDIsReadOnly");
364                 }
365             } else {
366                 assertTrue(rsmd.isReadOnly(1) == false);
367             }
368         } finally {
369             if (this.rs != null) {
370                 this.rs.close();
371             }
372         }
373     }
374
375     public void testBitType() throws Exception JavaDoc {
376         if (versionMeetsMinimum(5, 0, 3)) {
377             try {
378                 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBitType");
379                 this.stmt
380                         .executeUpdate("CREATE TABLE testBitType (field1 BIT, field2 BIT, field3 BIT)");
381                 this.stmt
382                         .executeUpdate("INSERT INTO testBitType VALUES (1, 0, NULL)");
383                 this.rs = this.stmt
384                         .executeQuery("SELECT field1, field2, field3 FROM testBitType");
385                 this.rs.next();
386
387                 assertTrue(((Boolean JavaDoc) this.rs.getObject(1)).booleanValue());
388                 assertTrue(!((Boolean JavaDoc) this.rs.getObject(2)).booleanValue());
389                 assertEquals(this.rs.getObject(3), null);
390
391                 System.out.println(this.rs.getObject(1) + ", "
392                         + this.rs.getObject(2) + ", " + this.rs.getObject(3));
393
394                 this.rs = this.conn.prepareStatement(
395                         "SELECT field1, field2, field3 FROM testBitType")
396                         .executeQuery();
397                 this.rs.next();
398
399                 assertTrue(((Boolean JavaDoc) this.rs.getObject(1)).booleanValue());
400                 assertTrue(!((Boolean JavaDoc) this.rs.getObject(2)).booleanValue());
401
402                 assertEquals(this.rs.getObject(3), null);
403                 byte[] asBytesTrue = this.rs.getBytes(1);
404                 byte[] asBytesFalse = this.rs.getBytes(2);
405                 byte[] asBytesNull = this.rs.getBytes(3);
406
407                 assertEquals(asBytesTrue[0], 1);
408                 assertEquals(asBytesFalse[0], 0);
409                 assertEquals(asBytesNull, null);
410
411                 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBitField");
412                 this.stmt
413                         .executeUpdate("CREATE TABLE testBitField(field1 BIT(9))");
414                 this.rs = this.stmt
415                         .executeQuery("SELECT field1 FROM testBitField");
416                 System.out.println(this.rs.getMetaData().getColumnClassName(1));
417             } finally {
418                 this.stmt.executeUpdate("DROP TABLE IF EXISTS testBitType");
419             }
420         }
421     }
422
423     public void testSupportsSelectForUpdate() throws Exception JavaDoc {
424         boolean supportsForUpdate = this.conn.getMetaData()
425                 .supportsSelectForUpdate();
426
427         if (this.versionMeetsMinimum(4, 0)) {
428             assertTrue(supportsForUpdate);
429         } else {
430             assertTrue(!supportsForUpdate);
431         }
432     }
433
434     public void testTinyint1IsBit() throws Exception JavaDoc {
435         String JavaDoc tableName = "testTinyint1IsBit";
436         // Can't use 'BIT' or boolean
437
createTable(tableName, "(field1 TINYINT(1))");
438         this.stmt.executeUpdate("INSERT INTO " + tableName + " VALUES (1)");
439
440         Properties JavaDoc props = new Properties JavaDoc();
441         props.setProperty("tinyint1IsBit", "true");
442         props.setProperty("transformedBitIsBoolean", "true");
443         Connection JavaDoc boolConn = getConnectionWithProps(props);
444
445         this.rs = boolConn.createStatement().executeQuery(
446                 "SELECT field1 FROM " + tableName);
447         checkBitOrBooleanType(false);
448
449         this.rs = boolConn.prepareStatement("SELECT field1 FROM " + tableName)
450                 .executeQuery();
451         checkBitOrBooleanType(false);
452
453         this.rs = boolConn.getMetaData().getColumns(boolConn.getCatalog(),
454                 null, tableName, "field1");
455         assertTrue(this.rs.next());
456
457         if (versionMeetsMinimum(4, 1)) {
458             assertEquals(Types.BOOLEAN, this.rs.getInt("DATA_TYPE"));
459         } else {
460             assertEquals(Types.BIT, this.rs.getInt("DATA_TYPE"));
461         }
462
463         if (versionMeetsMinimum(4, 1)) {
464             assertEquals("BOOLEAN", this.rs.getString("TYPE_NAME"));
465         } else {
466             assertEquals("BIT", this.rs.getString("TYPE_NAME"));
467         }
468
469         props.clear();
470         props.setProperty("transformedBitIsBoolean", "false");
471         props.setProperty("tinyint1IsBit", "true");
472
473         Connection JavaDoc bitConn = getConnectionWithProps(props);
474
475         this.rs = bitConn.createStatement().executeQuery(
476                 "SELECT field1 FROM " + tableName);
477         checkBitOrBooleanType(true);
478
479         this.rs = bitConn.prepareStatement("SELECT field1 FROM " + tableName)
480                 .executeQuery();
481         checkBitOrBooleanType(true);
482
483         this.rs = bitConn.getMetaData().getColumns(boolConn.getCatalog(), null,
484                 tableName, "field1");
485         assertTrue(this.rs.next());
486
487         assertEquals(Types.BIT, this.rs.getInt("DATA_TYPE"));
488
489         assertEquals("BIT", this.rs.getString("TYPE_NAME"));
490     }
491
492     private void checkBitOrBooleanType(boolean usingBit) throws SQLException JavaDoc {
493
494         assertTrue(this.rs.next());
495         assertEquals("java.lang.Boolean", this.rs.getObject(1).getClass()
496                 .getName());
497         if (!usingBit) {
498             if (versionMeetsMinimum(4, 1)) {
499                 assertEquals(Types.BOOLEAN, this.rs.getMetaData()
500                         .getColumnType(1));
501             } else {
502                 assertEquals(Types.BIT, this.rs.getMetaData().getColumnType(1));
503             }
504         } else {
505             assertEquals(Types.BIT, this.rs.getMetaData().getColumnType(1));
506         }
507
508         assertEquals("java.lang.Boolean", this.rs.getMetaData()
509                 .getColumnClassName(1));
510     }
511 }
512
Popular Tags