Source Code Cross Referenced for BaseTable.java in  » Database-ORM » TJDO » com » triactive » jdo » store » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » TJDO » com.triactive.jdo.store 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002 (C) TJDO.
003:         * All rights reserved.
004:         *
005:         * This software is distributed under the terms of the TJDO License version 1.0.
006:         * See the terms of the TJDO License in the documentation provided with this software.
007:         *
008:         * $Id: BaseTable.java,v 1.8 2003/04/28 00:52:17 jackknifebarber Exp $
009:         */
010:
011:        package com.triactive.jdo.store;
012:
013:        import com.triactive.jdo.model.ClassMetaData;
014:        import java.sql.Connection;
015:        import java.sql.DatabaseMetaData;
016:        import java.sql.ResultSet;
017:        import java.sql.SQLException;
018:        import java.sql.Statement;
019:        import java.util.ArrayList;
020:        import java.util.Collection;
021:        import java.util.HashMap;
022:        import java.util.HashSet;
023:        import java.util.Iterator;
024:        import java.util.List;
025:        import java.util.Map;
026:        import java.util.Set;
027:        import org.apache.log4j.Category;
028:
029:        abstract class BaseTable extends AbstractTable {
030:            private static final Category LOG = Category
031:                    .getInstance(BaseTable.class);
032:
033:            public BaseTable(StoreManager storeMgr) {
034:                super (storeMgr);
035:            }
036:
037:            public BaseTable(SQLIdentifier name, StoreManager storeMgr) {
038:                super (name, storeMgr);
039:            }
040:
041:            public PrimaryKey getExpectedPrimaryKey() {
042:                PrimaryKey pk = null;
043:
044:                Iterator i = columns.iterator();
045:
046:                while (i.hasNext()) {
047:                    Column col = (Column) i.next();
048:
049:                    if (col.isPrimaryKeyPart()) {
050:                        if (pk == null)
051:                            pk = new PrimaryKey(this );
052:
053:                        pk.addColumn(col);
054:                    }
055:                }
056:
057:                return pk;
058:            }
059:
060:            public void create(Connection conn) throws SQLException {
061:                LOG.info("Creating table: " + this );
062:
063:                super .create(conn);
064:            }
065:
066:            public boolean validate(int flags, Connection conn)
067:                    throws SQLException {
068:                assertIsInitialized();
069:
070:                boolean dbWasModified = false;
071:
072:                if ((flags & VALIDATE) != 0) {
073:                    int tableType = storeMgr.getTableType(name, conn);
074:
075:                    if (tableType == TABLE_TYPE_MISSING) {
076:                        if ((flags & AUTO_CREATE) == 0)
077:                            throw new MissingTableException(this );
078:
079:                        create(conn);
080:                        dbWasModified = true;
081:                    } else {
082:                        LOG.info("Validating table: " + this );
083:
084:                        if (tableType != TABLE_TYPE_BASE_TABLE)
085:                            throw new NotABaseTableException(this );
086:
087:                        HashMap unvalidated = new HashMap(columnsByName);
088:                        Iterator i = storeMgr.getColumnInfo(name, conn)
089:                                .iterator();
090:
091:                        while (i.hasNext()) {
092:                            ColumnInfo ci = (ColumnInfo) i.next();
093:                            SQLIdentifier colName = new SQLIdentifier(dba,
094:                                    ci.columnName);
095:
096:                            Column col = (Column) unvalidated.get(colName);
097:
098:                            if (col == null) {
099:                                if (!hasColumnName(colName))
100:                                    throw new UnexpectedColumnException(this ,
101:                                            colName);
102:                                /*
103:                                 * Otherwise it's a duplicate column name in the
104:                                 * metadata and we ignore it.  Cloudscape is known to
105:                                 * do this, although I think that's probably a bug.
106:                                 */
107:                            } else {
108:                                col.validate(ci);
109:                                unvalidated.remove(colName);
110:                            }
111:                        }
112:
113:                        if (unvalidated.size() > 0)
114:                            throw new MissingColumnException(this , unvalidated
115:                                    .values());
116:
117:                        PrimaryKey expectedPK = getExpectedPrimaryKey();
118:                        Map actualPKs = getExistingPrimaryKeys(conn);
119:
120:                        if (expectedPK == null) {
121:                            if (!actualPKs.isEmpty())
122:                                throw new WrongPrimaryKeyException(this ,
123:                                        expectedPK, actualPKs.values());
124:                        } else {
125:                            if (actualPKs.size() != 1
126:                                    || !actualPKs.values().contains(expectedPK))
127:                                throw new WrongPrimaryKeyException(this ,
128:                                        expectedPK, actualPKs.values());
129:                        }
130:                    }
131:                }
132:
133:                state = TABLE_STATE_VALIDATED;
134:
135:                return dbWasModified;
136:            }
137:
138:            public boolean validateConstraints(int flags, Connection conn)
139:                    throws SQLException {
140:                assertIsInitialized();
141:
142:                boolean dbWasModified = false;
143:
144:                if ((flags & VALIDATE) != 0) {
145:                    boolean fksWereModified;
146:                    boolean idxsWereModified;
147:
148:                    if (dba.createIndexesBeforeForeignKeys()) {
149:                        idxsWereModified = validateIndices(flags, conn);
150:                        fksWereModified = validateForeignKeys(flags, conn);
151:                    } else {
152:                        fksWereModified = validateForeignKeys(flags, conn);
153:                        idxsWereModified = validateIndices(flags, conn);
154:                    }
155:
156:                    dbWasModified = fksWereModified || idxsWereModified;
157:                }
158:
159:                return dbWasModified;
160:            }
161:
162:            private boolean validateForeignKeys(int flags, Connection conn)
163:                    throws SQLException {
164:                boolean dbWasModified = false;
165:
166:                /*
167:                 * Validate and/or create all foreign keys.
168:                 */
169:                Map actualForeignKeysByName = getExistingForeignKeys(conn);
170:                int numActualFKs = actualForeignKeysByName.size();
171:
172:                Map stmtsByFKName = getSQLAddFKStatements(actualForeignKeysByName);
173:
174:                if (stmtsByFKName.isEmpty()) {
175:                    if (numActualFKs > 0)
176:                        LOG.info("Validated " + numActualFKs
177:                                + " foreign key(s) for table: " + this );
178:                } else {
179:                    if ((flags & AUTO_CREATE) == 0)
180:                        throw new MissingForeignKeysException(this ,
181:                                stmtsByFKName.values());
182:
183:                    Statement stmt = conn.createStatement();
184:
185:                    try {
186:                        Iterator i = stmtsByFKName.entrySet().iterator();
187:
188:                        while (i.hasNext()) {
189:                            Map.Entry e = (Map.Entry) i.next();
190:                            String fkName = (String) e.getKey();
191:                            String stmtText = (String) e.getValue();
192:
193:                            LOG.info("Creating foreign key constraint: "
194:                                    + getSchemaName() + '.' + fkName);
195:
196:                            long startTime = System.currentTimeMillis();
197:
198:                            stmt.execute(stmtText);
199:
200:                            if (LOG.isDebugEnabled())
201:                                LOG
202:                                        .debug("Time = "
203:                                                + (System.currentTimeMillis() - startTime)
204:                                                + " ms: " + stmtText);
205:
206:                            storeMgr.logSQLWarnings(stmt);
207:                        }
208:                    } finally {
209:                        stmt.close();
210:                    }
211:
212:                    dbWasModified = true;
213:                }
214:
215:                return dbWasModified;
216:            }
217:
218:            private boolean validateIndices(int flags, Connection conn)
219:                    throws SQLException {
220:                boolean dbWasModified = false;
221:
222:                /*
223:                 * Validate and/or create all indices.
224:                 */
225:                Map actualIndicesByName = getExistingIndices(conn);
226:
227:                /*
228:                 * Compute the number of existing indices *created by us*, which are
229:                 * recognized by having a name that starts with the table name.  This
230:                 * number is only used to control what gets logged below.  There are
231:                 * often other system-generated indices.
232:                 */
233:                int numActualIdxs = 0;
234:                Iterator names = actualIndicesByName.keySet().iterator();
235:
236:                while (names.hasNext()) {
237:                    SQLIdentifier idxName = (SQLIdentifier) names.next();
238:
239:                    if (idxName.toString().startsWith(name.toString()))
240:                        ++numActualIdxs;
241:                }
242:
243:                Map stmtsByIdxName = getSQLCreateIndexStatements(actualIndicesByName);
244:
245:                if (stmtsByIdxName.isEmpty()) {
246:                    if (numActualIdxs > 0)
247:                        LOG.info("Validated " + numActualIdxs
248:                                + " index(s) for table: " + this );
249:                } else {
250:                    if ((flags & AUTO_CREATE) == 0)
251:                        throw new MissingIndicesException(this , stmtsByIdxName
252:                                .values());
253:
254:                    Statement stmt = conn.createStatement();
255:
256:                    try {
257:                        Iterator i = stmtsByIdxName.entrySet().iterator();
258:
259:                        while (i.hasNext()) {
260:                            Map.Entry e = (Map.Entry) i.next();
261:                            String idxName = (String) e.getKey();
262:                            String stmtText = (String) e.getValue();
263:
264:                            LOG.info("Creating index: " + getSchemaName() + '.'
265:                                    + idxName);
266:
267:                            long startTime = System.currentTimeMillis();
268:
269:                            stmt.execute(stmtText);
270:
271:                            if (LOG.isDebugEnabled())
272:                                LOG
273:                                        .debug("Time = "
274:                                                + (System.currentTimeMillis() - startTime)
275:                                                + " ms: " + stmtText);
276:
277:                            storeMgr.logSQLWarnings(stmt);
278:                        }
279:                    } finally {
280:                        stmt.close();
281:                    }
282:
283:                    dbWasModified = true;
284:                }
285:
286:                return dbWasModified;
287:            }
288:
289:            public void drop(Connection conn) throws SQLException {
290:                LOG.info("Dropping table: " + this );
291:
292:                super .drop(conn);
293:            }
294:
295:            public void dropConstraints(Connection conn) throws SQLException {
296:                assertIsInitialized();
297:
298:                if (!dba.supportsAlterTableDropConstraint())
299:                    return;
300:
301:                /*
302:                 * There's no need to drop indices; we assume they'll go away quietly
303:                 * when the table is dropped.
304:                 */
305:                DatabaseMetaData dmd = conn.getMetaData();
306:
307:                HashSet fkNames = new HashSet();
308:                Iterator i = storeMgr.getForeignKeyInfo(name, conn).iterator();
309:
310:                while (i.hasNext()) {
311:                    ForeignKeyInfo fki = (ForeignKeyInfo) i.next();
312:
313:                    /*
314:                     * Legally, JDBC drivers are allowed to return null names for
315:                     * foreign keys.  If they do, we simply have to skip DROP
316:                     * CONSTRAINT.
317:                     */
318:                    if (fki.fkName != null)
319:                        fkNames.add(fki.fkName);
320:                }
321:
322:                int numFKs = fkNames.size();
323:
324:                if (numFKs > 0) {
325:                    LOG.info("Dropping " + numFKs
326:                            + " foreign key(s) for table: " + this );
327:
328:                    i = fkNames.iterator();
329:                    Statement stmt = conn.createStatement();
330:
331:                    try {
332:                        while (i.hasNext()) {
333:                            String constraintName = (String) i.next();
334:                            String stmtText = "ALTER TABLE " + name
335:                                    + " DROP CONSTRAINT " + constraintName;
336:
337:                            long startTime = System.currentTimeMillis();
338:
339:                            stmt.execute(stmtText);
340:
341:                            if (LOG.isDebugEnabled())
342:                                LOG
343:                                        .debug("Time = "
344:                                                + (System.currentTimeMillis() - startTime)
345:                                                + " ms: " + stmtText);
346:
347:                            storeMgr.logSQLWarnings(stmt);
348:                        }
349:                    } finally {
350:                        stmt.close();
351:                    }
352:                }
353:            }
354:
355:            protected List getExpectedForeignKeys() {
356:                assertIsInitialized();
357:
358:                ArrayList foreignKeys = new ArrayList();
359:                Iterator i = columns.iterator();
360:
361:                while (i.hasNext()) {
362:                    Column col = (Column) i.next();
363:
364:                    ClassMetaData cmd = ClassMetaData.forClass(col.getType());
365:
366:                    if (cmd != null) {
367:                        ClassBaseTable referencedTable = (ClassBaseTable) storeMgr
368:                                .getTable(cmd);
369:
370:                        if (referencedTable != null)
371:                            foreignKeys.add(new ForeignKey(col,
372:                                    referencedTable, true));
373:                    }
374:                }
375:
376:                return foreignKeys;
377:            }
378:
379:            protected Set getExpectedIndices() {
380:                assertIsInitialized();
381:
382:                HashSet indices = new HashSet();
383:                PrimaryKey pk = getExpectedPrimaryKey();
384:                Iterator i = getExpectedForeignKeys().iterator();
385:
386:                /*
387:                 * For each foreign key, add to the list an index made up of the "from"
388:                 * column(s) of the key, *unless* those columns also happen to be the
389:                 * leading columns of the primary key.  If they are, we're assuming that
390:                 * they're going to be indexed anyway, regardless of whether that fact
391:                 * gets reflected by getIndexInfo().
392:                 */
393:                while (i.hasNext()) {
394:                    ForeignKey fk = (ForeignKey) i.next();
395:
396:                    if (!pk.startsWith(fk))
397:                        indices.add(new Index(fk));
398:                }
399:
400:                return indices;
401:            }
402:
403:            private Map getExistingPrimaryKeys(Connection conn)
404:                    throws SQLException {
405:                DatabaseMetaData dmd = conn.getMetaData();
406:
407:                HashMap primaryKeysByName = new HashMap();
408:                ResultSet rs = dmd.getPrimaryKeys(null, getSchemaName(), name
409:                        .getSQLIdentifier());
410:
411:                try {
412:                    while (rs.next()) {
413:                        SQLIdentifier pkName;
414:                        String s = rs.getString(6);
415:
416:                        if (s == null)
417:                            pkName = new PrimaryKeyIdentifier(this );
418:                        else
419:                            pkName = new SQLIdentifier(dba, s);
420:
421:                        PrimaryKey pk = (PrimaryKey) primaryKeysByName
422:                                .get(pkName);
423:
424:                        if (pk == null) {
425:                            pk = new PrimaryKey(this );
426:                            primaryKeysByName.put(pkName, pk);
427:                        }
428:
429:                        int keySeq = rs.getInt(5) - 1;
430:                        SQLIdentifier colName = new SQLIdentifier(dba, rs
431:                                .getString(4));
432:
433:                        Column col = (Column) columnsByName.get(colName);
434:
435:                        if (col == null)
436:                            throw new UnexpectedColumnException(this , colName);
437:
438:                        pk.setColumn(keySeq, col);
439:                    }
440:                } finally {
441:                    rs.close();
442:                }
443:
444:                return primaryKeysByName;
445:            }
446:
447:            private Map getExistingForeignKeys(Connection conn)
448:                    throws SQLException {
449:                DatabaseMetaData dmd = conn.getMetaData();
450:
451:                HashMap foreignKeysByName = new HashMap();
452:                Iterator i = storeMgr.getForeignKeyInfo(name, conn).iterator();
453:
454:                while (i.hasNext()) {
455:                    ForeignKeyInfo fki = (ForeignKeyInfo) i.next();
456:                    SQLIdentifier fkName;
457:
458:                    if (fki.fkName == null)
459:                        fkName = new ForeignKeyIdentifier(this ,
460:                                foreignKeysByName.size());
461:                    else
462:                        fkName = new SQLIdentifier(dba, fki.fkName);
463:
464:                    boolean initiallyDeferred = fki.deferrability == DatabaseMetaData.importedKeyInitiallyDeferred;
465:
466:                    ForeignKey fk = (ForeignKey) foreignKeysByName.get(fkName);
467:
468:                    if (fk == null) {
469:                        fk = new ForeignKey(initiallyDeferred);
470:                        foreignKeysByName.put(fkName, fk);
471:                    }
472:
473:                    BaseTable refTable = (BaseTable) storeMgr
474:                            .getTable(new SQLIdentifier(dba, fki.pkTableName));
475:
476:                    if (refTable != null) {
477:                        SQLIdentifier colName = new SQLIdentifier(dba,
478:                                fki.fkColumnName);
479:                        SQLIdentifier refColName = new SQLIdentifier(dba,
480:                                fki.pkColumnName);
481:
482:                        Column col = (Column) columnsByName.get(colName);
483:                        Column refCol = (Column) refTable.columnsByName
484:                                .get(refColName);
485:
486:                        if (col == null)
487:                            throw new UnexpectedColumnException(this , colName);
488:                        if (refCol == null)
489:                            throw new UnexpectedColumnException(this ,
490:                                    refColName);
491:
492:                        fk.addColumn(col, refCol);
493:                    }
494:                }
495:
496:                return foreignKeysByName;
497:            }
498:
499:            private Map getExistingIndices(Connection conn) throws SQLException {
500:                DatabaseMetaData dmd = conn.getMetaData();
501:
502:                HashMap indicesByName = new HashMap();
503:                ResultSet rs = dmd.getIndexInfo(null, getSchemaName(), name
504:                        .getSQLIdentifier(), false, true);
505:
506:                try {
507:                    while (rs.next()) {
508:                        short idxType = rs.getShort(7);
509:
510:                        if (idxType == DatabaseMetaData.tableIndexStatistic)
511:                            continue;
512:
513:                        SQLIdentifier idxName = new SQLIdentifier(dba, rs
514:                                .getString(6));
515:                        Index idx = (Index) indicesByName.get(idxName);
516:
517:                        if (idx == null) {
518:                            boolean isUnique = !rs.getBoolean(4);
519:                            idx = new Index(this , isUnique);
520:                            indicesByName.put(idxName, idx);
521:                        }
522:
523:                        int colSeq = rs.getShort(8) - 1;
524:                        SQLIdentifier colName = new SQLIdentifier(dba, rs
525:                                .getString(9));
526:
527:                        Column col = (Column) columnsByName.get(colName);
528:                        if (col == null)
529:                            throw new UnexpectedColumnException(this , colName);
530:
531:                        idx.setColumn(colSeq, col);
532:                    }
533:                } finally {
534:                    rs.close();
535:                }
536:
537:                return indicesByName;
538:            }
539:
540:            protected List getSQLCreateStatements() {
541:                assertIsInitialized();
542:
543:                ArrayList stmts = new ArrayList();
544:
545:                stmts.add(dba.getCreateTableStatement(this , (Column[]) columns
546:                        .toArray(new Column[columns.size()])));
547:
548:                PrimaryKey pk = getExpectedPrimaryKey();
549:
550:                if (pk != null)
551:                    stmts.add(dba.getAddPrimaryKeyStatement(
552:                            new PrimaryKeyIdentifier(this ), pk));
553:
554:                return stmts;
555:            }
556:
557:            protected Map getSQLAddFKStatements(Map actualForeignKeysByName) {
558:                assertIsInitialized();
559:
560:                HashMap stmtsByFKName = new HashMap();
561:
562:                List expectedForeignKeys = getExpectedForeignKeys();
563:
564:                Iterator i = expectedForeignKeys.iterator();
565:                int n = 1;
566:
567:                while (i.hasNext()) {
568:                    ForeignKey fk = (ForeignKey) i.next();
569:
570:                    if (!actualForeignKeysByName.containsValue(fk)) {
571:                        ForeignKeyIdentifier fkName;
572:
573:                        do {
574:                            fkName = new ForeignKeyIdentifier(this , n++);
575:                        } while (actualForeignKeysByName.containsKey(fkName));
576:
577:                        String stmtText = dba.getAddForeignKeyStatement(fkName,
578:                                fk);
579:
580:                        stmtsByFKName.put(fkName.getSQLIdentifier(), stmtText);
581:                    }
582:                }
583:
584:                return stmtsByFKName;
585:            }
586:
587:            private boolean isIndexReallyNeeded(Index requiredIdx,
588:                    Collection actualIndices) {
589:                Iterator i = actualIndices.iterator();
590:
591:                while (i.hasNext()) {
592:                    Index actualIdx = (Index) i.next();
593:
594:                    if (actualIdx.startsWith(requiredIdx))
595:                        return false;
596:                }
597:
598:                return true;
599:            }
600:
601:            protected Map getSQLCreateIndexStatements(Map actualIndicesByName) {
602:                assertIsInitialized();
603:
604:                HashMap stmtsByIdxName = new HashMap();
605:
606:                Set expectedIndices = getExpectedIndices();
607:
608:                Iterator i = expectedIndices.iterator();
609:                int n = 1;
610:
611:                while (i.hasNext()) {
612:                    Index idx = (Index) i.next();
613:
614:                    if (isIndexReallyNeeded(idx, actualIndicesByName.values())) {
615:                        IndexIdentifier idxName;
616:
617:                        do {
618:                            idxName = new IndexIdentifier(this ,
619:                                    idx.getUnique(), n++);
620:                        } while (actualIndicesByName.containsKey(idxName));
621:
622:                        String stmtText = dba.getCreateIndexStatement(idxName,
623:                                idx);
624:
625:                        stmtsByIdxName
626:                                .put(idxName.getSQLIdentifier(), stmtText);
627:                    }
628:                }
629:
630:                return stmtsByIdxName;
631:            }
632:
633:            protected List getSQLDropStatements() {
634:                assertIsInitialized();
635:
636:                ArrayList stmts = new ArrayList();
637:                stmts.add(dba.getDropTableStatement(this));
638:
639:                return stmts;
640:            }
641:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.