Source Code Cross Referenced for Session.java in  » Database-DBMS » hsql » org » hsqldb » 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 DBMS » hsql » org.hsqldb 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
0002:         * All rights reserved.
0003:         *
0004:         * Redistribution and use in source and binary forms, with or without
0005:         * modification, are permitted provided that the following conditions are met:
0006:         *
0007:         * Redistributions of source code must retain the above copyright notice, this
0008:         * list of conditions and the following disclaimer.
0009:         *
0010:         * Redistributions in binary form must reproduce the above copyright notice,
0011:         * this list of conditions and the following disclaimer in the documentation
0012:         * and/or other materials provided with the distribution.
0013:         *
0014:         * Neither the name of the Hypersonic SQL Group nor the names of its
0015:         * contributors may be used to endorse or promote products derived from this
0016:         * software without specific prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
0022:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0025:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0026:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0028:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029:         *
0030:         * This software consists of voluntary contributions made by many individuals 
0031:         * on behalf of the Hypersonic SQL Group.
0032:         *
0033:         *
0034:         * For work added by the HSQL Development Group:
0035:         *
0036:         * Copyright (c) 2001-2005, The HSQL Development Group
0037:         * All rights reserved.
0038:         *
0039:         * Redistribution and use in source and binary forms, with or without
0040:         * modification, are permitted provided that the following conditions are met:
0041:         *
0042:         * Redistributions of source code must retain the above copyright notice, this
0043:         * list of conditions and the following disclaimer.
0044:         *
0045:         * Redistributions in binary form must reproduce the above copyright notice,
0046:         * this list of conditions and the following disclaimer in the documentation
0047:         * and/or other materials provided with the distribution.
0048:         *
0049:         * Neither the name of the HSQL Development Group nor the names of its
0050:         * contributors may be used to endorse or promote products derived from this
0051:         * software without specific prior written permission.
0052:         *
0053:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0054:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0055:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0056:         * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
0057:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0058:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0059:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0060:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0061:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0062:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0063:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0064:         */
0065:
0066:        package org.hsqldb;
0067:
0068:        import java.sql.Date;
0069:        import java.sql.Time;
0070:        import java.sql.Timestamp;
0071:
0072:        import org.hsqldb.HsqlNameManager.HsqlName;
0073:        import org.hsqldb.jdbc.jdbcConnection;
0074:        import org.hsqldb.lib.ArrayUtil;
0075:        import org.hsqldb.lib.HashMappedList;
0076:        import org.hsqldb.lib.HsqlArrayList;
0077:        import org.hsqldb.lib.IntKeyHashMap;
0078:        import org.hsqldb.lib.SimpleLog;
0079:        import org.hsqldb.lib.java.JavaSystem;
0080:        import org.hsqldb.store.ValuePool;
0081:
0082:        // fredt@users 20020320 - doc 1.7.0 - update
0083:        // fredt@users 20020315 - patch 1.7.0 - switch for scripting
0084:        // fredt@users 20020130 - patch 476694 by velichko - transaction savepoints
0085:        // additions in different parts to support savepoint transactions
0086:        // fredt@users 20020910 - patch 1.7.1 by fredt - database readonly enforcement
0087:        // fredt@users 20020912 - patch 1.7.1 by fredt - permanent internal connection
0088:        // boucherb@users 20030512 - patch 1.7.2 - compiled statements
0089:        //                                       - session becomes execution hub
0090:        // boucherb@users 20050510 - patch 1.7.2 - generalized Result packet passing
0091:        //                                         based command execution
0092:        //                                       - batch execution handling
0093:        // fredt@users 20030628 - patch 1.7.2 - session proxy support
0094:        // fredt@users 20040509 - patch 1.7.2 - SQL conformance for CURRENT_TIMESTAMP and other datetime functions
0095:
0096:        /**
0097:         *  Implementation of a user session with the database. In 1.7.2 Session
0098:         *  becomes the public interface to an HSQLDB database, accessed locally or
0099:         *  remotely via SessionInterface.
0100:         *
0101:         *  When as Session is closed, all references to internal engine objects are
0102:         *  set to null. But the session id and scripting mode may still be used for
0103:         *  scripting
0104:         *
0105:         * New class based based on original Hypersonic code.
0106:         * Extensively rewritten and extended in successive versions of HSQLDB.
0107:         *
0108:         * @author Thomas Mueller (Hypersonic SQL Group)
0109:         * @version 1.8.0
0110:         * @since 1.7.0
0111:         */
0112:        public class Session implements  SessionInterface {
0113:
0114:            //
0115:            private volatile boolean isAutoCommit;
0116:            private volatile boolean isReadOnly;
0117:            private volatile boolean isClosed;
0118:
0119:            //
0120:            Database database;
0121:            private User user;
0122:            HsqlArrayList rowActionList;
0123:            private boolean isNestedTransaction;
0124:            private int nestedOldTransIndex;
0125:            int isolationMode = SessionInterface.TX_READ_COMMITTED;
0126:            long actionTimestamp;
0127:            long transactionTimestamp;
0128:            private int currentMaxRows;
0129:            private int sessionMaxRows;
0130:            private Number lastIdentity = ValuePool.getInt(0);
0131:            private final int sessionId;
0132:            HashMappedList savepoints;
0133:            private boolean script;
0134:            private Tokenizer tokenizer;
0135:            private Parser parser;
0136:            static final Result emptyUpdateCount = new Result(
0137:                    ResultConstants.UPDATECOUNT);
0138:
0139:            //
0140:            private jdbcConnection intConnection;
0141:
0142:            // schema
0143:            public HsqlName currentSchema;
0144:            public HsqlName loggedSchema;
0145:            private HsqlName oldSchema;
0146:
0147:            // query processing
0148:            boolean isProcessingScript;
0149:            boolean isProcessingLog;
0150:
0151:            // two types of temp tables
0152:            private IntKeyHashMap indexArrayMap;
0153:            private IntKeyHashMap indexArrayKeepMap;
0154:
0155:            /** @todo fredt - clarify in which circumstances Session has to disconnect */
0156:            Session getSession() {
0157:                return this ;
0158:            }
0159:
0160:            /**
0161:             * Constructs a new Session object.
0162:             *
0163:             * @param  db the database to which this represents a connection
0164:             * @param  user the initial user
0165:             * @param  autocommit the initial autocommit value
0166:             * @param  readonly the initial readonly value
0167:             * @param  id the session identifier, as known to the database
0168:             */
0169:            Session(Database db, User user, boolean autocommit,
0170:                    boolean readonly, int id) {
0171:
0172:                sessionId = id;
0173:                database = db;
0174:                this .user = user;
0175:                rowActionList = new HsqlArrayList(true);
0176:                savepoints = new HashMappedList(4);
0177:                isAutoCommit = autocommit;
0178:                isReadOnly = readonly;
0179:                dbCommandInterpreter = new DatabaseCommandInterpreter(this );
0180:                compiledStatementExecutor = new CompiledStatementExecutor(this );
0181:                compiledStatementManager = db.compiledStatementManager;
0182:                tokenizer = new Tokenizer();
0183:                parser = new Parser(this , database, tokenizer);
0184:
0185:                resetSchema();
0186:            }
0187:
0188:            void resetSchema() {
0189:
0190:                HsqlName initialSchema = user.getInitialSchema();
0191:
0192:                currentSchema = ((initialSchema == null) ? database.schemaManager
0193:                        .getDefaultSchemaHsqlName()
0194:                        : initialSchema);
0195:            }
0196:
0197:            /**
0198:             *  Retrieves the session identifier for this Session.
0199:             *
0200:             * @return the session identifier for this Session
0201:             */
0202:            public int getId() {
0203:                return sessionId;
0204:            }
0205:
0206:            /**
0207:             * Closes this Session.
0208:             */
0209:            public void close() {
0210:
0211:                if (isClosed) {
0212:                    return;
0213:                }
0214:
0215:                synchronized (database) {
0216:
0217:                    // test again inside block
0218:                    if (isClosed) {
0219:                        return;
0220:                    }
0221:
0222:                    database.sessionManager.removeSession(this );
0223:                    rollback();
0224:
0225:                    try {
0226:                        database.logger.writeToLog(this , Token.T_DISCONNECT);
0227:                    } catch (HsqlException e) {
0228:                    }
0229:
0230:                    clearIndexRoots();
0231:                    clearIndexRootsKeep();
0232:                    compiledStatementManager.removeSession(sessionId);
0233:                    database.closeIfLast();
0234:
0235:                    database = null;
0236:                    user = null;
0237:                    rowActionList = null;
0238:                    savepoints = null;
0239:                    intConnection = null;
0240:                    compiledStatementExecutor = null;
0241:                    compiledStatementManager = null;
0242:                    dbCommandInterpreter = null;
0243:                    lastIdentity = null;
0244:                    isClosed = true;
0245:                }
0246:            }
0247:
0248:            /**
0249:             * Retrieves whether this Session is closed.
0250:             *
0251:             * @return true if this Session is closed
0252:             */
0253:            public boolean isClosed() {
0254:                return isClosed;
0255:            }
0256:
0257:            public void setIsolation(int level) throws HsqlException {
0258:                isolationMode = level;
0259:            }
0260:
0261:            public int getIsolation() throws HsqlException {
0262:                return isolationMode;
0263:            }
0264:
0265:            /**
0266:             * Setter for iLastIdentity attribute.
0267:             *
0268:             * @param  i the new value
0269:             */
0270:            void setLastIdentity(Number i) {
0271:                lastIdentity = i;
0272:            }
0273:
0274:            /**
0275:             * Getter for iLastIdentity attribute.
0276:             *
0277:             * @return the current value
0278:             */
0279:            Number getLastIdentity() {
0280:                return lastIdentity;
0281:            }
0282:
0283:            /**
0284:             * Retrieves the Database instance to which this
0285:             * Session represents a connection.
0286:             *
0287:             * @return the Database object to which this Session is connected
0288:             */
0289:            Database getDatabase() {
0290:                return database;
0291:            }
0292:
0293:            /**
0294:             * Retrieves the name, as known to the database, of the
0295:             * user currently controlling this Session.
0296:             *
0297:             * @return the name of the user currently connected within this Session
0298:             */
0299:            String getUsername() {
0300:                return user.getName();
0301:            }
0302:
0303:            /**
0304:             * Retrieves the User object representing the user currently controlling
0305:             * this Session.
0306:             *
0307:             * @return this Session's User object
0308:             */
0309:            public User getUser() {
0310:                return user;
0311:            }
0312:
0313:            /**
0314:             * Sets this Session's User object to the one specified by the
0315:             * user argument.
0316:             *
0317:             * @param  user the new User object for this session
0318:             */
0319:            void setUser(User user) {
0320:                this .user = user;
0321:            }
0322:
0323:            int getMaxRows() {
0324:                return currentMaxRows;
0325:            }
0326:
0327:            int getSQLMaxRows() {
0328:                return sessionMaxRows;
0329:            }
0330:
0331:            /**
0332:             * The SQL command SET MAXROWS n will override the Statement.setMaxRows(n)
0333:             * until SET MAXROWS 0 is issued.
0334:             *
0335:             * NB this is dedicated to the SET MAXROWS sql statement and should not
0336:             * otherwise be called. (fredt@users)
0337:             */
0338:            void setSQLMaxRows(int rows) {
0339:                currentMaxRows = sessionMaxRows = rows;
0340:            }
0341:
0342:            /**
0343:             * Checks whether this Session's current User has the privileges of
0344:             * the ADMIN role.
0345:             *
0346:             * @throws HsqlException if this Session's User does not have the
0347:             *      privileges of the ADMIN role.
0348:             */
0349:            void checkAdmin() throws HsqlException {
0350:                user.checkAdmin();
0351:            }
0352:
0353:            /**
0354:             * Checks whether this Session's current User has the set of rights
0355:             * specified by the right argument, in relation to the database
0356:             * object identifier specified by the object argument.
0357:             *
0358:             * @param  object the database object to check
0359:             * @param  right the rights to check for
0360:             * @throws  HsqlException if the Session User does not have such rights
0361:             */
0362:            void check(HsqlName object, int right) throws HsqlException {
0363:                user.check(object, right);
0364:            }
0365:
0366:            /**
0367:             * Checks the rights on a function
0368:             *
0369:             * @param  object the function
0370:             * @throws  HsqlException if the Session User does not have such rights
0371:             */
0372:            void check(String object) throws HsqlException {
0373:                user.check(object);
0374:            }
0375:
0376:            /**
0377:             * This is used for reading - writing to existing tables.
0378:             * @throws  HsqlException
0379:             */
0380:            void checkReadWrite() throws HsqlException {
0381:
0382:                if (isReadOnly) {
0383:                    throw Trace.error(Trace.DATABASE_IS_READONLY);
0384:                }
0385:            }
0386:
0387:            /**
0388:             * This is used for creating new database objects such as tables.
0389:             * @throws  HsqlException
0390:             */
0391:            void checkDDLWrite() throws HsqlException {
0392:
0393:                if (database.isFilesReadOnly() && !user.isSys()) {
0394:                    throw Trace.error(Trace.DATABASE_IS_READONLY);
0395:                }
0396:
0397:                checkReadWrite();
0398:            }
0399:
0400:            /**
0401:             *  Adds a single-row deletion step to the transaction UNDO buffer.
0402:             *
0403:             * @param  table the table from which the row was deleted
0404:             * @param  row the deleted row
0405:             * @throws  HsqlException
0406:             */
0407:            boolean addDeleteAction(Table table, Row row) throws HsqlException {
0408:
0409:                if (!isAutoCommit || isNestedTransaction) {
0410:                    Transaction t = new Transaction(true, table, row,
0411:                            actionTimestamp);
0412:
0413:                    rowActionList.add(t);
0414:                    database.txManager.addTransaction(this , t);
0415:
0416:                    return true;
0417:                } else {
0418:                    table.removeRowFromStore(row);
0419:                }
0420:
0421:                return false;
0422:            }
0423:
0424:            /**
0425:             *  Adds a single-row insertion step to the transaction UNDO buffer.
0426:             *
0427:             * @param  table the table into which the row was inserted
0428:             * @param  row the inserted row
0429:             * @throws  HsqlException
0430:             */
0431:            boolean addInsertAction(Table table, Row row) throws HsqlException {
0432:
0433:                if (!isAutoCommit || isNestedTransaction) {
0434:                    Transaction t = new Transaction(false, table, row,
0435:                            actionTimestamp);
0436:
0437:                    rowActionList.add(t);
0438:                    database.txManager.addTransaction(this , t);
0439:
0440:                    return true;
0441:                } else {
0442:                    table.commitRowToStore(row);
0443:                }
0444:
0445:                return false;
0446:            }
0447:
0448:            /**
0449:             *  Setter for the autocommit attribute.
0450:             *
0451:             * @param  autocommit the new value
0452:             * @throws  HsqlException
0453:             */
0454:            public void setAutoCommit(boolean autocommit) {
0455:
0456:                if (isClosed) {
0457:                    return;
0458:                }
0459:
0460:                synchronized (database) {
0461:                    if (autocommit != isAutoCommit) {
0462:                        commit();
0463:
0464:                        isAutoCommit = autocommit;
0465:
0466:                        try {
0467:                            database.logger.writeToLog(this ,
0468:                                    getAutoCommitStatement());
0469:                        } catch (HsqlException e) {
0470:                        }
0471:                    }
0472:                }
0473:            }
0474:
0475:            public void startPhasedTransaction() throws HsqlException {
0476:            }
0477:
0478:            public void prepareCommit() throws HsqlException {
0479:            }
0480:
0481:            /**
0482:             * Commits any uncommited transaction this Session may have open
0483:             *
0484:             * @throws  HsqlException
0485:             */
0486:            public void commit() {
0487:
0488:                if (isClosed) {
0489:                    return;
0490:                }
0491:
0492:                synchronized (database) {
0493:                    if (!rowActionList.isEmpty()) {
0494:                        try {
0495:                            database.logger.writeCommitStatement(this );
0496:                        } catch (HsqlException e) {
0497:                        }
0498:                    }
0499:
0500:                    database.txManager.commit(this );
0501:                    clearIndexRoots();
0502:                }
0503:            }
0504:
0505:            /**
0506:             * Rolls back any uncommited transaction this Session may have open.
0507:             *
0508:             * @throws  HsqlException
0509:             */
0510:            public void rollback() {
0511:
0512:                if (isClosed) {
0513:                    return;
0514:                }
0515:
0516:                synchronized (database) {
0517:                    if (rowActionList.size() != 0) {
0518:                        try {
0519:                            database.logger.writeToLog(this , Token.T_ROLLBACK);
0520:                        } catch (HsqlException e) {
0521:                        }
0522:                    }
0523:
0524:                    database.txManager.rollback(this );
0525:                    clearIndexRoots();
0526:                }
0527:            }
0528:
0529:            /**
0530:             * No-op in this implementation
0531:             */
0532:            public void resetSession() throws HsqlException {
0533:                throw new HsqlException("", "", 0);
0534:            }
0535:
0536:            /**
0537:             *  Implements a transaction SAVEPOINT. A new SAVEPOINT with the
0538:             *  name of an existing one replaces the old SAVEPOINT.
0539:             *
0540:             * @param  name of the savepoint
0541:             * @throws  HsqlException if there is no current transaction
0542:             */
0543:            void savepoint(String name) throws HsqlException {
0544:
0545:                savepoints.remove(name);
0546:                savepoints.add(name, ValuePool.getInt(rowActionList.size()));
0547:
0548:                try {
0549:                    database.logger.writeToLog(this , Token.T_SAVEPOINT + " "
0550:                            + name);
0551:                } catch (HsqlException e) {
0552:                }
0553:            }
0554:
0555:            /**
0556:             *  Implements a partial transaction ROLLBACK.
0557:             *
0558:             * @param  name Name of savepoint that was marked before by savepoint()
0559:             *      call
0560:             * @throws  HsqlException
0561:             */
0562:            void rollbackToSavepoint(String name) throws HsqlException {
0563:
0564:                if (isClosed) {
0565:                    return;
0566:                }
0567:
0568:                try {
0569:                    database.logger
0570:                            .writeToLog(this , Token.T_ROLLBACK + " "
0571:                                    + Token.T_TO + " " + Token.T_SAVEPOINT
0572:                                    + " " + name);
0573:                } catch (HsqlException e) {
0574:                }
0575:
0576:                database.txManager.rollbackSavepoint(this , name);
0577:            }
0578:
0579:            /**
0580:             * Implements release of named SAVEPOINT.
0581:             *
0582:             * @param  name Name of savepoint that was marked before by savepoint()
0583:             *      call
0584:             * @throws  HsqlException if name does not correspond to a savepoint
0585:             */
0586:            void releaseSavepoint(String name) throws HsqlException {
0587:
0588:                // remove this and all later savepoints
0589:                int index = savepoints.getIndex(name);
0590:
0591:                Trace.check(index >= 0, Trace.SAVEPOINT_NOT_FOUND, name);
0592:
0593:                while (savepoints.size() > index) {
0594:                    savepoints.remove(savepoints.size() - 1);
0595:                }
0596:            }
0597:
0598:            /**
0599:             * Starts a nested transaction.
0600:             *
0601:             * @throws  HsqlException
0602:             */
0603:            void beginNestedTransaction() throws HsqlException {
0604:
0605:                if (isNestedTransaction) {
0606:                    Trace.doAssert(false, "beginNestedTransaction");
0607:                }
0608:
0609:                nestedOldTransIndex = rowActionList.size();
0610:                isNestedTransaction = true;
0611:
0612:                if (isAutoCommit) {
0613:                    try {
0614:                        database.logger
0615:                                .writeToLog(this , "SET AUTOCOMMIT FALSE");
0616:                    } catch (HsqlException e) {
0617:                    }
0618:                }
0619:            }
0620:
0621:            /**
0622:             * @todo -- fredt 20050604 - if this method is called after an out of memory
0623:             * error during update, the next block might throw out of memory too and as
0624:             * a result inNestedTransaction remains true and no further update
0625:             * is possible. The session must be closed at that point by the user
0626:             * application.
0627:             */
0628:
0629:            /**
0630:             * Ends a nested transaction.
0631:             *
0632:             * @param  rollback true to roll back or false to commit the nested transaction
0633:             * @throws  HsqlException
0634:             */
0635:            void endNestedTransaction(boolean rollback) throws HsqlException {
0636:
0637:                if (!isNestedTransaction) {
0638:                    Trace.doAssert(false, "endNestedTransaction");
0639:                }
0640:
0641:                if (rollback) {
0642:                    database.txManager.rollbackTransactions(this ,
0643:                            nestedOldTransIndex, true);
0644:                }
0645:
0646:                // reset after the rollback
0647:                isNestedTransaction = false;
0648:
0649:                if (isAutoCommit) {
0650:                    database.txManager.commit(this );
0651:
0652:                    try {
0653:                        database.logger.writeToLog(this , "SET AUTOCOMMIT TRUE");
0654:                    } catch (HsqlException e) {
0655:                    }
0656:                }
0657:            }
0658:
0659:            /**
0660:             * Setter for readonly attribute.
0661:             *
0662:             * @param  readonly the new value
0663:             */
0664:            public void setReadOnly(boolean readonly) throws HsqlException {
0665:
0666:                if (!readonly && database.databaseReadOnly) {
0667:                    throw Trace.error(Trace.DATABASE_IS_READONLY);
0668:                }
0669:
0670:                isReadOnly = readonly;
0671:            }
0672:
0673:            /**
0674:             *  Getter for readonly attribute.
0675:             *
0676:             * @return the current value
0677:             */
0678:            public boolean isReadOnly() {
0679:                return isReadOnly;
0680:            }
0681:
0682:            /**
0683:             *  Getter for nestedTransaction attribute.
0684:             *
0685:             * @return the current value
0686:             */
0687:            boolean isNestedTransaction() {
0688:                return isNestedTransaction;
0689:            }
0690:
0691:            /**
0692:             *  Getter for autoCommit attribute.
0693:             *
0694:             * @return the current value
0695:             */
0696:            public boolean isAutoCommit() {
0697:                return isAutoCommit;
0698:            }
0699:
0700:            /**
0701:             *  A switch to set scripting on the basis of type of statement executed.
0702:             *  A method in DatabaseCommandInterpreter.java sets this value to false
0703:             *  before other  methods are called to act on an SQL statement, which may
0704:             *  set this to true. Afterwards the method reponsible for logging uses
0705:             *  getScripting() to determine if logging is required for the executed
0706:             *  statement. (fredt@users)
0707:             *
0708:             * @param  script The new scripting value
0709:             */
0710:            void setScripting(boolean script) {
0711:                this .script = script;
0712:            }
0713:
0714:            /**
0715:             * Getter for scripting attribute.
0716:             *
0717:             * @return  scripting for the last statement.
0718:             */
0719:            boolean getScripting() {
0720:                return script;
0721:            }
0722:
0723:            public String getAutoCommitStatement() {
0724:                return isAutoCommit ? "SET AUTOCOMMIT TRUE"
0725:                        : "SET AUTOCOMMIT FALSE";
0726:            }
0727:
0728:            /**
0729:             * Retrieves an internal Connection object equivalent to the one
0730:             * that created this Session.
0731:             *
0732:             * @return  internal connection.
0733:             */
0734:            jdbcConnection getInternalConnection() throws HsqlException {
0735:
0736:                if (intConnection == null) {
0737:                    intConnection = new jdbcConnection(this );
0738:                }
0739:
0740:                return intConnection;
0741:            }
0742:
0743:            // boucherb@users 20020810 metadata 1.7.2
0744:            //----------------------------------------------------------------
0745:            private final long connectTime = System.currentTimeMillis();
0746:
0747:            // more effecient for MetaData concerns than checkAdmin
0748:
0749:            /**
0750:             * Getter for admin attribute.
0751:             *
0752:             * @ return the current value
0753:             */
0754:            boolean isAdmin() {
0755:                return user.isAdmin();
0756:            }
0757:
0758:            /**
0759:             * Getter for connectTime attribute.
0760:             *
0761:             * @return the value
0762:             */
0763:            long getConnectTime() {
0764:                return connectTime;
0765:            }
0766:
0767:            /**
0768:             * Getter for transactionSise attribute.
0769:             *
0770:             * @return the current value
0771:             */
0772:            int getTransactionSize() {
0773:                return rowActionList.size();
0774:            }
0775:
0776:            /**
0777:             * Retrieves whether the database object identifier by the dbobject
0778:             * argument is accessible by the current Session User.
0779:             *
0780:             * @return true if so, else false
0781:             */
0782:            boolean isAccessible(String dbobject) throws HsqlException {
0783:                return user.isAccessible(dbobject);
0784:            }
0785:
0786:            boolean isAccessible(HsqlName dbobject) throws HsqlException {
0787:                return user.isAccessible(dbobject);
0788:            }
0789:
0790:            // boucherb@users 20030417 - patch 1.7.2 - compiled statement support
0791:            //-------------------------------------------------------------------
0792:            DatabaseCommandInterpreter dbCommandInterpreter;
0793:            CompiledStatementExecutor compiledStatementExecutor;
0794:            CompiledStatementManager compiledStatementManager;
0795:
0796:            CompiledStatement sqlCompileStatement(String sql)
0797:                    throws HsqlException {
0798:
0799:                parser.reset(sql);
0800:
0801:                CompiledStatement cs;
0802:                int brackets = 0;
0803:                String token = tokenizer.getString();
0804:                int cmd = Token.get(token);
0805:
0806:                switch (cmd) {
0807:
0808:                case Token.OPENBRACKET: {
0809:                    brackets = parser.parseOpenBracketsSelect() + 1;
0810:                }
0811:                case Token.SELECT: {
0812:                    cs = parser.compileSelectStatement(brackets);
0813:
0814:                    break;
0815:                }
0816:                case Token.INSERT: {
0817:                    cs = parser.compileInsertStatement();
0818:
0819:                    break;
0820:                }
0821:                case Token.UPDATE: {
0822:                    cs = parser.compileUpdateStatement();
0823:
0824:                    break;
0825:                }
0826:                case Token.DELETE: {
0827:                    cs = parser.compileDeleteStatement();
0828:
0829:                    break;
0830:                }
0831:                case Token.CALL: {
0832:                    cs = parser.compileCallStatement();
0833:
0834:                    break;
0835:                }
0836:                default: {
0837:
0838:                    // DDL statements
0839:                    cs = new CompiledStatement(currentSchema);
0840:
0841:                    break;
0842:                }
0843:                }
0844:
0845:                // In addition to requiring that the compilation was successful,
0846:                // we also require that the submitted sql represents a _single_
0847:                // valid DML or DDL statement. We do not check the DDL yet.
0848:                // fredt - now accepts semicolon and whitespace at the end of statement
0849:                // fredt - investigate if it should or not for prepared statements
0850:                if (cs.type != CompiledStatement.DDL) {
0851:                    while (tokenizer.getPosition() < tokenizer.getLength()) {
0852:                        token = tokenizer.getString();
0853:
0854:                        if (token.length() != 0
0855:                                && !token.equals(Token.T_SEMICOLON)) {
0856:                            throw Trace.error(Trace.UNEXPECTED_TOKEN, token);
0857:                        }
0858:                    }
0859:                }
0860:
0861:                // - need to be able to key cs against its sql in statement pool
0862:                // - also need to be able to revalidate its sql occasionally
0863:                cs.sql = sql;
0864:
0865:                return cs;
0866:            }
0867:
0868:            /**
0869:             * Executes the command encapsulated by the cmd argument.
0870:             *
0871:             * @param cmd the command to execute
0872:             * @return the result of executing the command
0873:             */
0874:            public Result execute(Result cmd) {
0875:
0876:                try {
0877:                    if (isClosed) {
0878:                        Trace.check(false, Trace.ACCESS_IS_DENIED, Trace
0879:                                .getMessage(Trace.Session_execute));
0880:                    }
0881:                } catch (Throwable t) {
0882:                    return new Result(t, null);
0883:                }
0884:
0885:                synchronized (database) {
0886:                    int type = cmd.mode;
0887:
0888:                    if (sessionMaxRows == 0) {
0889:                        currentMaxRows = cmd.updateCount;
0890:                    }
0891:
0892:                    // we simply get the next system change number - no matter what type of query
0893:                    actionTimestamp = database.txManager.nextActionTimestamp();
0894:
0895:                    JavaSystem.gc();
0896:
0897:                    switch (type) {
0898:
0899:                    case ResultConstants.SQLEXECUTE: {
0900:                        Result resultout = sqlExecute(cmd);
0901:
0902:                        resultout = performPostExecute(resultout);
0903:
0904:                        return resultout;
0905:                    }
0906:                    case ResultConstants.BATCHEXECUTE: {
0907:                        Result resultout = sqlExecuteBatch(cmd);
0908:
0909:                        resultout = performPostExecute(resultout);
0910:
0911:                        return resultout;
0912:                    }
0913:                    case ResultConstants.SQLEXECDIRECT: {
0914:                        Result resultout = sqlExecuteDirectNoPreChecks(cmd
0915:                                .getMainString());
0916:
0917:                        resultout = performPostExecute(resultout);
0918:
0919:                        return resultout;
0920:                    }
0921:                    case ResultConstants.BATCHEXECDIRECT: {
0922:                        Result resultout = sqlExecuteBatchDirect(cmd);
0923:
0924:                        resultout = performPostExecute(resultout);
0925:
0926:                        return resultout;
0927:                    }
0928:                    case ResultConstants.SQLPREPARE: {
0929:                        CompiledStatement cs;
0930:
0931:                        try {
0932:                            cs = compiledStatementManager.compile(this , cmd
0933:                                    .getMainString());
0934:                        } catch (Throwable t) {
0935:                            return new Result(t, cmd.getMainString());
0936:                        }
0937:
0938:                        Result rmd = cs.describeResult();
0939:                        Result pmd = cs.describeParameters();
0940:
0941:                        return Result.newPrepareResponse(cs.id, rmd, pmd);
0942:                    }
0943:                    case ResultConstants.SQLFREESTMT: {
0944:                        compiledStatementManager.freeStatement(cmd
0945:                                .getStatementID(), sessionId, false);
0946:
0947:                        return emptyUpdateCount;
0948:                    }
0949:                    case ResultConstants.GETSESSIONATTR: {
0950:                        return getAttributes();
0951:                    }
0952:                    case ResultConstants.SETSESSIONATTR: {
0953:                        return setAttributes(cmd);
0954:                    }
0955:                    case ResultConstants.SQLENDTRAN: {
0956:                        switch (cmd.getEndTranType()) {
0957:
0958:                        case ResultConstants.COMMIT:
0959:                            commit();
0960:                            break;
0961:
0962:                        case ResultConstants.ROLLBACK:
0963:                            rollback();
0964:                            break;
0965:
0966:                        case ResultConstants.SAVEPOINT_NAME_RELEASE:
0967:                            try {
0968:                                String name = cmd.getMainString();
0969:
0970:                                releaseSavepoint(name);
0971:                            } catch (Throwable t) {
0972:                                return new Result(t, null);
0973:                            }
0974:                            break;
0975:
0976:                        case ResultConstants.SAVEPOINT_NAME_ROLLBACK:
0977:                            try {
0978:                                rollbackToSavepoint(cmd.getMainString());
0979:                            } catch (Throwable t) {
0980:                                return new Result(t, null);
0981:                            }
0982:                            break;
0983:
0984:                        // not yet
0985:                        // case ResultConstants.COMMIT_AND_CHAIN :
0986:                        // case ResultConstants.ROLLBACK_AND_CHAIN :
0987:                        }
0988:
0989:                        return emptyUpdateCount;
0990:                    }
0991:                    case ResultConstants.SQLSETCONNECTATTR: {
0992:                        switch (cmd.getConnectionAttrType()) {
0993:
0994:                        case ResultConstants.SQL_ATTR_SAVEPOINT_NAME:
0995:                            try {
0996:                                savepoint(cmd.getMainString());
0997:                            } catch (Throwable t) {
0998:                                return new Result(t, null);
0999:                            }
1000:
1001:                            // case ResultConstants.SQL_ATTR_AUTO_IPD
1002:                            //   - always true
1003:                            // default: throw - case never happens
1004:                        }
1005:
1006:                        return emptyUpdateCount;
1007:                    }
1008:                    case ResultConstants.SQLDISCONNECT: {
1009:                        close();
1010:
1011:                        return emptyUpdateCount;
1012:                    }
1013:                    default: {
1014:                        return new Result(Trace.runtimeError(
1015:                                Trace.UNSUPPORTED_INTERNAL_OPERATION,
1016:                                "Session.execute()"), null);
1017:                    }
1018:                    }
1019:                }
1020:            }
1021:
1022:            private Result performPostExecute(Result r) {
1023:
1024:                try {
1025:                    if (database != null) {
1026:                        database.schemaManager.logSequences(this ,
1027:                                database.logger);
1028:
1029:                        if (isAutoCommit) {
1030:                            clearIndexRoots();
1031:                            database.logger.synchLog();
1032:                        }
1033:                    }
1034:
1035:                    return r;
1036:                } catch (Exception e) {
1037:                    return new Result(e, null);
1038:                } finally {
1039:                    if (database != null && database.logger.needsCheckpoint()) {
1040:                        try {
1041:                            database.logger.checkpoint(false);
1042:                        } catch (HsqlException e) {
1043:                            database.logger.appLog.logContext(
1044:                                    SimpleLog.LOG_ERROR,
1045:                                    "checkpoint did not complete");
1046:                        }
1047:                    }
1048:                }
1049:            }
1050:
1051:            public Result sqlExecuteDirectNoPreChecks(String sql) {
1052:
1053:                synchronized (database) {
1054:                    return dbCommandInterpreter.execute(sql);
1055:                }
1056:            }
1057:
1058:            Result sqlExecuteCompiledNoPreChecks(CompiledStatement cs,
1059:                    Object[] pvals) {
1060:                return compiledStatementExecutor.execute(cs, pvals);
1061:            }
1062:
1063:            private Result sqlExecuteBatch(Result cmd) {
1064:
1065:                int csid;
1066:                Record record;
1067:                Result out;
1068:                CompiledStatement cs;
1069:                Expression[] parameters;
1070:                int[] updateCounts;
1071:                int count;
1072:
1073:                csid = cmd.getStatementID();
1074:                cs = database.compiledStatementManager.getStatement(this , csid);
1075:
1076:                if (cs == null) {
1077:
1078:                    // invalid sql has been removed already
1079:                    return new Result(Trace.runtimeError(
1080:                            Trace.INVALID_PREPARED_STATEMENT, null), null);
1081:                }
1082:
1083:                parameters = cs.parameters;
1084:                count = 0;
1085:                updateCounts = new int[cmd.getSize()];
1086:                record = cmd.rRoot;
1087:
1088:                while (record != null) {
1089:                    Result in;
1090:                    Object[] pvals = record.data;
1091:
1092:                    in = sqlExecuteCompiledNoPreChecks(cs, pvals);
1093:
1094:                    // On the client side, iterate over the vals and throw
1095:                    // a BatchUpdateException if a batch status value of
1096:                    // esultConstants.EXECUTE_FAILED is encountered in the result
1097:                    if (in.mode == ResultConstants.UPDATECOUNT) {
1098:                        updateCounts[count++] = in.updateCount;
1099:                    } else if (in.isData()) {
1100:
1101:                        // FIXME:  we don't have what it takes yet
1102:                        // to differentiate between things like
1103:                        // stored procedure calls to methods with
1104:                        // void return type and select statements with
1105:                        // a single row/column containg null
1106:                        updateCounts[count++] = ResultConstants.SUCCESS_NO_INFO;
1107:                    } else {
1108:                        updateCounts = ArrayUtil.arraySlice(updateCounts, 0,
1109:                                count);
1110:
1111:                        break;
1112:                    }
1113:
1114:                    record = record.next;
1115:                }
1116:
1117:                out = new Result(ResultConstants.SQLEXECUTE, updateCounts, 0);
1118:
1119:                return out;
1120:            }
1121:
1122:            private Result sqlExecuteBatchDirect(Result cmd) {
1123:
1124:                Record record;
1125:                Result out;
1126:                int[] updateCounts;
1127:                int count;
1128:
1129:                count = 0;
1130:                updateCounts = new int[cmd.getSize()];
1131:                record = cmd.rRoot;
1132:
1133:                while (record != null) {
1134:                    Result in;
1135:                    String sql = (String) record.data[0];
1136:
1137:                    try {
1138:                        in = dbCommandInterpreter.execute(sql);
1139:                    } catch (Throwable t) {
1140:                        in = new Result(ResultConstants.ERROR);
1141:
1142:                        // if (t instanceof OutOfMemoryError) {
1143:                        // System.gc();
1144:                        // }
1145:                        // "in" alread equals "err"
1146:                        // maybe test for OOME and do a gc() ?
1147:                        // t.printStackTrace();
1148:                    }
1149:
1150:                    // On the client side, iterate over the colType vals and throw
1151:                    // a BatchUpdateException if a batch status value of
1152:                    // ResultConstants.EXECUTE_FAILED is encountered
1153:                    if (in.mode == ResultConstants.UPDATECOUNT) {
1154:                        updateCounts[count++] = in.updateCount;
1155:                    } else if (in.isData()) {
1156:
1157:                        // FIXME:  we don't have what it takes yet
1158:                        // to differentiate between things like
1159:                        // stored procedure calls to methods with
1160:                        // void return type and select statements with
1161:                        // a single row/column containg null
1162:                        updateCounts[count++] = ResultConstants.SUCCESS_NO_INFO;
1163:                    } else {
1164:                        updateCounts = ArrayUtil.arraySlice(updateCounts, 0,
1165:                                count);
1166:
1167:                        break;
1168:                    }
1169:
1170:                    record = record.next;
1171:                }
1172:
1173:                out = new Result(ResultConstants.SQLEXECUTE, updateCounts, 0);
1174:
1175:                return out;
1176:            }
1177:
1178:            /**
1179:             * Retrieves the result of executing the prepared statement whose csid
1180:             * and parameter values/types are encapsulated by the cmd argument.
1181:             *
1182:             * @return the result of executing the statement
1183:             */
1184:            private Result sqlExecute(Result cmd) {
1185:
1186:                int csid = cmd.getStatementID();
1187:                CompiledStatement cs = compiledStatementManager.getStatement(
1188:                        this , csid);
1189:
1190:                if (cs == null) {
1191:
1192:                    // invalid sql has been removed already
1193:                    return new Result(Trace.runtimeError(
1194:                            Trace.INVALID_PREPARED_STATEMENT, null), null);
1195:                }
1196:
1197:                Object[] pvals = cmd.getParameterData();
1198:
1199:                return sqlExecute(cs, pvals);
1200:            }
1201:
1202:            private Result sqlExecute(CompiledStatement cs, Object[] pvals) {
1203:                return sqlExecuteCompiledNoPreChecks(cs, pvals);
1204:            }
1205:
1206:            // session DATETIME functions
1207:            long currentDateTimeSCN;
1208:            long currentMillis;
1209:            Date currentDate;
1210:            Time currentTime;
1211:            Timestamp currentTimestamp;
1212:
1213:            /**
1214:             * Returns the current date, unchanged for the duration of the current
1215:             * execution unit (statement).<p>
1216:             *
1217:             * SQL standards require that CURRENT_DATE, CURRENT_TIME and
1218:             * CURRENT_TIMESTAMP are all evaluated at the same point of
1219:             * time in the duration of each SQL statement, no matter how long the
1220:             * SQL statement takes to complete.<p>
1221:             *
1222:             * When this method or a corresponding method for CURRENT_TIME or
1223:             * CURRENT_TIMESTAMP is first called in the scope of a system change
1224:             * number, currentMillis is set to the current system time. All further
1225:             * CURRENT_XXXX calls in this scope will use this millisecond value.
1226:             * (fredt@users)
1227:             */
1228:            Date getCurrentDate() {
1229:
1230:                if (currentDateTimeSCN != actionTimestamp) {
1231:                    currentDateTimeSCN = actionTimestamp;
1232:                    currentMillis = System.currentTimeMillis();
1233:                    currentDate = HsqlDateTime.getCurrentDate(currentMillis);
1234:                    currentTime = null;
1235:                    currentTimestamp = null;
1236:                } else if (currentDate == null) {
1237:                    currentDate = HsqlDateTime.getCurrentDate(currentMillis);
1238:                }
1239:
1240:                return currentDate;
1241:            }
1242:
1243:            /**
1244:             * Returns the current time, unchanged for the duration of the current
1245:             * execution unit (statement)
1246:             */
1247:            Time getCurrentTime() {
1248:
1249:                if (currentDateTimeSCN != actionTimestamp) {
1250:                    currentDateTimeSCN = actionTimestamp;
1251:                    currentMillis = System.currentTimeMillis();
1252:                    currentDate = null;
1253:                    currentTime = new Time(HsqlDateTime
1254:                            .getNormalisedTime(currentMillis));
1255:                    currentTimestamp = null;
1256:                } else if (currentTime == null) {
1257:                    currentTime = new Time(HsqlDateTime
1258:                            .getNormalisedTime(currentMillis));
1259:                }
1260:
1261:                return currentTime;
1262:            }
1263:
1264:            /**
1265:             * Returns the current timestamp, unchanged for the duration of the current
1266:             * execution unit (statement)
1267:             */
1268:            Timestamp getCurrentTimestamp() {
1269:
1270:                if (currentDateTimeSCN != actionTimestamp) {
1271:                    currentDateTimeSCN = actionTimestamp;
1272:                    currentMillis = System.currentTimeMillis();
1273:                    currentDate = null;
1274:                    currentTime = null;
1275:                    currentTimestamp = HsqlDateTime.getTimestamp(currentMillis);
1276:                } else if (currentTimestamp == null) {
1277:                    currentTimestamp = HsqlDateTime.getTimestamp(currentMillis);
1278:                }
1279:
1280:                return currentTimestamp;
1281:            }
1282:
1283:            Result getAttributes() {
1284:
1285:                Result r = Result.newSessionAttributesResult();
1286:                Object[] row = new Object[] { database.getURI(), getUsername(),
1287:                        ValuePool.getInt(sessionId),
1288:                        ValuePool.getInt(isolationMode),
1289:                        ValuePool.getBoolean(isAutoCommit),
1290:                        ValuePool.getBoolean(database.databaseReadOnly),
1291:                        ValuePool.getBoolean(isReadOnly) };
1292:
1293:                r.add(row);
1294:
1295:                return r;
1296:            }
1297:
1298:            Result setAttributes(Result r) {
1299:
1300:                Object[] row = r.rRoot.data;
1301:
1302:                for (int i = 0; i < row.length; i++) {
1303:                    Object value = row[i];
1304:
1305:                    if (value == null) {
1306:                        continue;
1307:                    }
1308:
1309:                    try {
1310:                        switch (i) {
1311:
1312:                        case SessionInterface.INFO_AUTOCOMMIT: {
1313:                            this 
1314:                                    .setAutoCommit(((Boolean) value)
1315:                                            .booleanValue());
1316:
1317:                            break;
1318:                        }
1319:                        case SessionInterface.INFO_CONNECTION_READONLY:
1320:                            this .setReadOnly(((Boolean) value).booleanValue());
1321:                            break;
1322:                        }
1323:                    } catch (HsqlException e) {
1324:                        return new Result(e, null);
1325:                    }
1326:                }
1327:
1328:                return emptyUpdateCount;
1329:            }
1330:
1331:            // DatabaseMetaData.getURL should work as specified for
1332:            // internal connections too.
1333:            public String getInternalConnectionURL() {
1334:                return DatabaseURL.S_URL_PREFIX + database.getURI();
1335:            }
1336:
1337:            boolean isProcessingScript() {
1338:                return isProcessingScript;
1339:            }
1340:
1341:            boolean isProcessingLog() {
1342:                return isProcessingLog;
1343:            }
1344:
1345:            boolean isSchemaDefintion() {
1346:                return oldSchema != null;
1347:            }
1348:
1349:            void startSchemaDefinition(String schema) throws HsqlException {
1350:
1351:                if (isProcessingScript) {
1352:                    setSchema(schema);
1353:
1354:                    return;
1355:                }
1356:
1357:                oldSchema = currentSchema;
1358:
1359:                setSchema(schema);
1360:            }
1361:
1362:            void endSchemaDefinition() throws HsqlException {
1363:
1364:                if (oldSchema == null) {
1365:                    return;
1366:                }
1367:
1368:                currentSchema = oldSchema;
1369:                oldSchema = null;
1370:
1371:                database.logger.writeToLog(this , "SET SCHEMA "
1372:                        + currentSchema.statementName);
1373:            }
1374:
1375:            // schema object methods
1376:            public void setSchema(String schema) throws HsqlException {
1377:                currentSchema = database.schemaManager
1378:                        .getSchemaHsqlName(schema);
1379:            }
1380:
1381:            /**
1382:             * If schemaName is null, return the current schema name, else return
1383:             * the HsqlName object for the schema. If schemaName does not exist,
1384:             * throw.
1385:             */
1386:            HsqlName getSchemaHsqlName(String name) throws HsqlException {
1387:                return name == null ? currentSchema : database.schemaManager
1388:                        .getSchemaHsqlName(name);
1389:            }
1390:
1391:            /**
1392:             * Same as above, but return string
1393:             */
1394:            public String getSchemaName(String name) throws HsqlException {
1395:                return name == null ? currentSchema.name
1396:                        : database.schemaManager.getSchemaName(name);
1397:            }
1398:
1399:            /**
1400:             * If schemaName is null, return the current schema name, else return
1401:             * the HsqlName object for the schema. If schemaName does not exist, or
1402:             * schema readonly, throw.
1403:             */
1404:            HsqlName getSchemaHsqlNameForWrite(String name)
1405:                    throws HsqlException {
1406:
1407:                HsqlName schema = getSchemaHsqlName(name);
1408:
1409:                if (database.schemaManager.isSystemSchema(schema)) {
1410:                    throw Trace.error(Trace.INVALID_SCHEMA_NAME_NO_SUBCLASS);
1411:                }
1412:
1413:                return schema;
1414:            }
1415:
1416:            /**
1417:             * Same as above, but return string
1418:             */
1419:            public String getSchemaNameForWrite(String name)
1420:                    throws HsqlException {
1421:
1422:                HsqlName schema = getSchemaHsqlNameForWrite(name);
1423:
1424:                return schema.name;
1425:            }
1426:
1427:            /**
1428:             * get the root for a temp table index
1429:             */
1430:            Node getIndexRoot(HsqlName index, boolean preserve) {
1431:
1432:                if (preserve) {
1433:                    if (indexArrayKeepMap == null) {
1434:                        return null;
1435:                    }
1436:
1437:                    return (Node) indexArrayKeepMap.get(index.hashCode());
1438:                } else {
1439:                    if (indexArrayMap == null) {
1440:                        return null;
1441:                    }
1442:
1443:                    return (Node) indexArrayMap.get(index.hashCode());
1444:                }
1445:            }
1446:
1447:            /**
1448:             * set the root for a temp table index
1449:             */
1450:            void setIndexRoot(HsqlName index, boolean preserve, Node root) {
1451:
1452:                if (preserve) {
1453:                    if (indexArrayKeepMap == null) {
1454:                        if (root == null) {
1455:                            return;
1456:                        }
1457:
1458:                        indexArrayKeepMap = new IntKeyHashMap();
1459:                    }
1460:
1461:                    indexArrayKeepMap.put(index.hashCode(), root);
1462:                } else {
1463:                    if (indexArrayMap == null) {
1464:                        if (root == null) {
1465:                            return;
1466:                        }
1467:
1468:                        indexArrayMap = new IntKeyHashMap();
1469:                    }
1470:
1471:                    indexArrayMap.put(index.hashCode(), root);
1472:                }
1473:            }
1474:
1475:            void dropIndex(HsqlName index, boolean preserve) {
1476:
1477:                if (preserve) {
1478:                    if (indexArrayKeepMap != null) {
1479:                        indexArrayKeepMap.remove(index.hashCode());
1480:                    }
1481:                } else {
1482:                    if (indexArrayMap != null) {
1483:                        indexArrayMap.remove(index.hashCode());
1484:                    }
1485:                }
1486:            }
1487:
1488:            /**
1489:             * clear default temp table contents for this session
1490:             */
1491:            void clearIndexRoots() {
1492:
1493:                if (indexArrayMap != null) {
1494:                    indexArrayMap.clear();
1495:                }
1496:            }
1497:
1498:            /**
1499:             * clear ON COMMIT PRESERVE temp table contents for this session
1500:             */
1501:            void clearIndexRootsKeep() {
1502:
1503:                if (indexArrayKeepMap != null) {
1504:                    indexArrayKeepMap.clear();
1505:                }
1506:            }
1507:
1508:            // warnings
1509:            HsqlArrayList sqlWarnings;
1510:
1511:            public void addWarning(HsqlException warning) {
1512:
1513:                if (sqlWarnings == null) {
1514:                    sqlWarnings = new HsqlArrayList(true);
1515:                }
1516:
1517:                sqlWarnings.add(warning);
1518:            }
1519:
1520:            public HsqlException[] getAndClearWarnings() {
1521:
1522:                if (sqlWarnings == null) {
1523:                    return new HsqlException[0];
1524:                }
1525:
1526:                HsqlException[] array = new HsqlException[sqlWarnings.size()];
1527:
1528:                sqlWarnings.toArray(array);
1529:                sqlWarnings.clear();
1530:
1531:                return array;
1532:            }
1533:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.