Source Code Cross Referenced for Log.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:        /* Copyrights and Licenses
0002:         *
0003:         * This product includes Hypersonic SQL.
0004:         * Originally developed by Thomas Mueller and the Hypersonic SQL Group. 
0005:         *
0006:         * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved. 
0007:         * Redistribution and use in source and binary forms, with or without modification, are permitted
0008:         * provided that the following conditions are met: 
0009:         *     -  Redistributions of source code must retain the above copyright notice, this list of conditions
0010:         *         and the following disclaimer. 
0011:         *     -  Redistributions in binary form must reproduce the above copyright notice, this list of
0012:         *         conditions and the following disclaimer in the documentation and/or other materials
0013:         *         provided with the distribution. 
0014:         *     -  All advertising materials mentioning features or use of this software must display the
0015:         *        following acknowledgment: "This product includes Hypersonic SQL." 
0016:         *     -  Products derived from this software may not be called "Hypersonic SQL" nor may
0017:         *        "Hypersonic SQL" appear in their names without prior written permission of the
0018:         *         Hypersonic SQL Group. 
0019:         *     -  Redistributions of any form whatsoever must retain the following acknowledgment: "This
0020:         *          product includes Hypersonic SQL." 
0021:         * This software is provided "as is" and any expressed or implied warranties, including, but
0022:         * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
0023:         * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
0024:         * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
0025:         * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
0026:         * or business interruption). However caused any on any theory of liability, whether in contract,
0027:         * strict liability, or tort (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:         * This software consists of voluntary contributions made by many individuals on behalf of the
0030:         * Hypersonic SQL Group.
0031:         *
0032:         *
0033:         * For work added by the HSQL Development Group:
0034:         *
0035:         * Copyright (c) 2001-2002, The HSQL Development Group
0036:         * All rights reserved.
0037:         *
0038:         * Redistribution and use in source and binary forms, with or without
0039:         * modification, are permitted provided that the following conditions are met:
0040:         *
0041:         * Redistributions of source code must retain the above copyright notice, this
0042:         * list of conditions and the following disclaimer, including earlier
0043:         * license statements (above) and comply with all above license conditions.
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, including earlier
0048:         * license statements (above) and comply with all above license conditions.
0049:         *
0050:         * Neither the name of the HSQL Development Group nor the names of its
0051:         * contributors may be used to endorse or promote products derived from this
0052:         * software without specific prior written permission.
0053:         *
0054:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0055:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0056:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0057:         * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 
0058:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
0059:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
0060:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0061:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0062:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0063:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0064:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0065:         */
0066:
0067:        package org.hsqldb;
0068:
0069:        import org.hsqldb.lib.HsqlArrayList;
0070:        import org.hsqldb.lib.HsqlHashMap;
0071:        import org.hsqldb.lib.HsqlStringBuffer;
0072:        import java.io.IOException;
0073:        import java.io.BufferedWriter;
0074:        import java.io.ByteArrayInputStream;
0075:        import java.io.ByteArrayOutputStream;
0076:        import java.io.File;
0077:        import java.io.FileInputStream;
0078:        import java.io.FileOutputStream;
0079:        import java.io.FileReader;
0080:        import java.io.FileWriter;
0081:        import java.io.InputStreamReader;
0082:        import java.io.LineNumberReader;
0083:        import java.io.OutputStreamWriter;
0084:        import java.io.Writer;
0085:        import java.sql.SQLException;
0086:        import java.util.Enumeration;
0087:
0088:        //import java.util.zip.
0089:        import java.util.zip.Deflater;
0090:        import java.util.zip.DeflaterOutputStream;
0091:        import java.util.zip.Inflater;
0092:        import java.util.zip.InflaterInputStream;
0093:
0094:        // fredt@users 20020215 - patch 1.7.0 by fredt
0095:        // to move operations on the database.properties files to new
0096:        // class HsqlDatabaseProperties
0097:        // fredt@users 20020220 - patch 488200 by xclay@users - throw exception
0098:        // throw addded to all methods relying on file io
0099:        // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
0100:        // fredt@users 20020405 - patch 1.7.0 by fredt - no change in db location
0101:        // because important information about the database is now stored in the
0102:        // *.properties file, all database files should be in the same folder as the
0103:        // *.properties file
0104:        // tony_lai@users 20020820 - export hsqldb.log_size to .properties file
0105:        // tony_lai@users 20020820 - Modification to shutdown compact process to save memory usage
0106:
0107:        /**
0108:         *  This class is responsible for most file handling. A HSQL database
0109:         *  consists of a .properties file, a .script file (contains a SQL script),
0110:         *  a .data file (contains data of cached tables) and a .backup file
0111:         *  (contains the compressed .data file) <P>
0112:         *
0113:         *  This is an example of the .properties file. The version and the modified
0114:         *  properties are automatically created by the database and should not be
0115:         *  changed manually: <pre>
0116:         * modified=no
0117:         * version=1.43
0118:         * </pre> The following lines are optional, this means they are not created
0119:         *  automatically by the database, but they are interpreted if they exist in
0120:         *  the .script file. They have to be created manually if required. If they
0121:         *  don't exist the default is used. This are the defaults of the database
0122:         *  'test': <pre>
0123:         * readonly=false
0124:         * </pre>
0125:         *
0126:         * @version 1.7.0
0127:         */
0128:        class Log implements  Runnable {
0129:
0130:            // block size for copying data
0131:            private static final int COPY_BLOCK_SIZE = 1 << 16;
0132:            private HsqlDatabaseProperties pProperties;
0133:            private String sName;
0134:            private Database dDatabase;
0135:            private Session sysSession;
0136:            private Writer wScript;
0137:            private String sFileScript;
0138:            private String sFileCache;
0139:            private String sFileBackup;
0140:            private boolean bRestoring;
0141:            private boolean bReadOnly;
0142:            private int iLogSize;
0143:            private int iLogCount;
0144:            private Thread tRunner;
0145:            private volatile boolean bNeedFlush;
0146:            private volatile boolean bWriteDelay;
0147:            private int mLastId;
0148:            private Cache cCache;
0149:
0150:            // boucherb@users - comment - FIXME
0151:            //  boolean                  stopped;
0152:
0153:            /**
0154:             *  Constructor declaration
0155:             *
0156:             * @param  db
0157:             * @param  system
0158:             * @param  name
0159:             * @exception  SQLException  Description of the Exception
0160:             */
0161:            Log(Database db, Session system, String name) throws SQLException {
0162:
0163:                dDatabase = db;
0164:                sysSession = system;
0165:                sName = name;
0166:                pProperties = db.getProperties();
0167:                tRunner = new Thread(this );
0168:
0169:                // boucherb@users - FIXME:
0170:                // standard VM behaviour is to shut down only after all
0171:                // non-daemon threads exit.  Therefor, tRunner shuld be
0172:                // daemon.  Consider the case of:
0173:                /*
0174:                 public void main(String[] args) {
0175:                 ...
0176:                 try {
0177:                 // fails due to bad user/password...must then connect with valid combo
0178:                 // again to *really* shutdown database, or explicitly call System.exit(...)
0179:                 DriverManager.getConnection("jdbc:hsqldb:filespec,"user","password");
0180:                 ...
0181:                 } catch (...) {
0182:                 }
0183:                 ...
0184:                 }
0185:                 */
0186:
0187:                // the VM will not exit, since tRunner is still running and
0188:                // no shutdown is issued to close the database.
0189:                //
0190:                //  - setDaemon(false) may require flush in finalization
0191:                // CB
0192:                // tRunner.setDaemon(false);
0193:                tRunner.start();
0194:            }
0195:
0196:            /**
0197:             *  Method declaration
0198:             */
0199:            public void run() {
0200:
0201:                // boucherb@users - FIXME
0202:                // while (!stopped) {
0203:                while (tRunner != null) {
0204:                    try {
0205:                        tRunner.sleep(1000);
0206:
0207:                        if (bNeedFlush) {
0208:                            wScript.flush();
0209:
0210:                            bNeedFlush = false;
0211:                        }
0212:
0213:                        // todo: try to do Cache.cleanUp() here, too
0214:                    } catch (Exception e) {
0215:
0216:                        // ignore exceptions; may be InterruptedException or IOException
0217:                    }
0218:                }
0219:            }
0220:
0221:            /**
0222:             *  Method declaration
0223:             *
0224:             * @param  delay
0225:             */
0226:            void setWriteDelay(boolean delay) {
0227:                bWriteDelay = delay;
0228:            }
0229:
0230:            /**
0231:             * When opening a database, the hsqldb.compatible_version property is
0232:             * used to determine if this version of the engine is equal to or greater
0233:             * than the earliest version of the engine capable of opening that
0234:             * database.<p>
0235:             *
0236:             * @return
0237:             * @throws  SQLException
0238:             */
0239:            boolean open() throws SQLException {
0240:
0241:                if (Trace.TRACE) {
0242:                    Trace.trace();
0243:                }
0244:
0245:                if (!pProperties.checkFileExists()) {
0246:                    create();
0247:                    open();
0248:
0249:                    // this is a new database
0250:                    return true;
0251:                }
0252:
0253:                // todo: some parts are not necessary for ready-only access
0254:                pProperties.load();
0255:
0256:                sFileScript = sName + ".script";
0257:                sFileCache = sName + ".data";
0258:                sFileBackup = sName + ".backup";
0259:
0260:                // tony_lai@users 20020820
0261:                // Allows the user to modify log size from the properties file.
0262:                iLogSize = pProperties.getIntegerProperty("hsqldb.log_size",
0263:                        iLogSize);
0264:
0265:                String version = pProperties
0266:                        .getProperty("hsqldb.compatible_version");
0267:
0268:                // fredt@users 20020428 - patch 1.7.0 by fredt
0269:                int check = version.substring(0, 5).compareTo(
0270:                        jdbcDriver.VERSION);
0271:
0272:                Trace.check(check <= 0, Trace.WRONG_DATABASE_FILE_VERSION);
0273:
0274:                // save the current version
0275:                pProperties.setProperty("hsqldb.version", jdbcDriver.VERSION);
0276:
0277:                if (pProperties.isPropertyTrue("readonly")) {
0278:                    bReadOnly = true;
0279:
0280:                    dDatabase.setReadOnly();
0281:
0282:                    if (cCache != null) {
0283:                        cCache.open(true);
0284:                    }
0285:
0286:                    reopenAllTextCaches();
0287:                    runScript();
0288:
0289:                    return false;
0290:                }
0291:
0292:                boolean needbackup = false;
0293:                String state = pProperties.getProperty("modified");
0294:
0295:                if (state.equals("yes-new-files")) {
0296:                    renameNewToCurrent(sFileScript);
0297:                    renameNewToCurrent(sFileBackup);
0298:                } else if (state.equals("yes")) {
0299:                    if (isAlreadyOpen()) {
0300:                        throw Trace.error(Trace.DATABASE_ALREADY_IN_USE);
0301:                    }
0302:
0303:                    // recovering after a crash (or forgot to close correctly)
0304:                    restoreBackup();
0305:
0306:                    needbackup = true;
0307:                }
0308:
0309:                pProperties.setProperty("modified", "yes");
0310:                pProperties.save();
0311:
0312:                if (cCache != null) {
0313:                    cCache.open(false);
0314:                }
0315:
0316:                reopenAllTextCaches();
0317:                runScript();
0318:
0319:                if (needbackup) {
0320:                    close(false);
0321:                    pProperties.setProperty("modified", "yes");
0322:                    pProperties.save();
0323:
0324:                    if (cCache != null) {
0325:                        cCache.open(false);
0326:                    }
0327:
0328:                    reopenAllTextCaches();
0329:                }
0330:
0331:                openScript();
0332:
0333:                // this is an existing database
0334:                return false;
0335:            }
0336:
0337:            Cache getCache() throws SQLException {
0338:
0339:                if (cCache == null) {
0340:                    cCache = new Cache(sFileCache, pProperties);
0341:
0342:                    cCache.open(bReadOnly);
0343:                }
0344:
0345:                return (cCache);
0346:            }
0347:
0348:            /**
0349:             *  Method declaration
0350:             */
0351:            void /* synchronized */stop() {
0352:
0353:                //boucherb@users - FIXME:
0354:                /*
0355:                 if (!stopped)
0356:                 stopped = true;
0357:                 tRunner.interrupt();
0358:                 tRunner = null;
0359:                 }
0360:                 */
0361:                tRunner = null;
0362:            }
0363:
0364:            /**
0365:             *  Method declaration
0366:             *
0367:             * @param  compact
0368:             * @throws  SQLException
0369:             */
0370:            void close(boolean compact) throws SQLException {
0371:
0372:                if (Trace.TRACE) {
0373:                    Trace.trace();
0374:                }
0375:
0376:                if (bReadOnly) {
0377:                    return;
0378:                }
0379:
0380:                // no more scripting
0381:                closeScript();
0382:
0383:                // create '.script.new' (for this the cache may be still required)
0384:                writeScript(compact);
0385:
0386:                // flush the cache (important: after writing the script)
0387:                if (cCache != null) {
0388:                    cCache.flush();
0389:                }
0390:
0391:                closeAllTextCaches(compact);
0392:
0393:                // create '.backup.new' using the '.data'
0394:                backup();
0395:
0396:                // we have the new files
0397:                pProperties.setProperty("modified", "yes-new-files");
0398:                pProperties.save();
0399:
0400:                // old files can be removed and new files renamed
0401:                renameNewToCurrent(sFileScript);
0402:                renameNewToCurrent(sFileBackup);
0403:
0404:                // now its done completely
0405:                pProperties.setProperty("modified", "no");
0406:                pProperties.setProperty("version", jdbcDriver.VERSION);
0407:                pProperties.setProperty("hsqldb.compatible_version", "1.7.0");
0408:                pProperties.save();
0409:                pProperties.close();
0410:
0411:                if (compact) {
0412:
0413:                    // stop the runner thread of this process (just for security)
0414:                    stop();
0415:
0416:                    // delete the .data so then a new file is created
0417:                    (new File(sFileCache)).delete();
0418:                    (new File(sFileBackup)).delete();
0419:
0420:                    // tony_lai@users 20020820
0421:                    // The database re-open and close has been moved to
0422:                    // Database#close(int closemode) for saving memory usage.
0423:                }
0424:            }
0425:
0426:            /**
0427:             *  Method declaration
0428:             *
0429:             * @throws  SQLException
0430:             */
0431:            void checkpoint() throws SQLException {
0432:
0433:                close(false);
0434:                pProperties.setProperty("modified", "yes");
0435:                pProperties.save();
0436:
0437:                if (cCache != null) {
0438:                    cCache.open(false);
0439:                }
0440:
0441:                reopenAllTextCaches();
0442:                openScript();
0443:            }
0444:
0445:            /**
0446:             *  Method declaration
0447:             *
0448:             * @param  mb
0449:             */
0450:            void setLogSize(int mb) {
0451:
0452:                iLogSize = mb;
0453:
0454:                pProperties.setProperty("hsqldb.log_size", iLogSize);
0455:            }
0456:
0457:            /**
0458:             *  Method declaration
0459:             *
0460:             * @param  c
0461:             * @param  s
0462:             * @throws  SQLException
0463:             */
0464:            void write(Session c, String s) throws SQLException {
0465:
0466:                if (bRestoring || s == null || s.length() == 0) {
0467:                    return;
0468:                }
0469:
0470:                if (!bReadOnly) {
0471:                    int id = 0;
0472:
0473:                    if (c != null) {
0474:                        id = c.getId();
0475:                    }
0476:
0477:                    if (id != mLastId) {
0478:                        s = "/*C" + id + "*/" + s;
0479:                        mLastId = id;
0480:                    }
0481:
0482:                    try {
0483:                        writeLine(wScript, s);
0484:
0485:                        if (bWriteDelay) {
0486:                            bNeedFlush = true;
0487:                        } else {
0488:                            wScript.flush();
0489:                        }
0490:                    } catch (IOException e) {
0491:                        throw Trace.error(Trace.FILE_IO_ERROR, sFileScript);
0492:                    }
0493:
0494:                    // fredt@users - todo - eliminate new File() calls
0495:                    if (iLogSize > 0 && iLogCount++ > 100) {
0496:                        iLogCount = 0;
0497:
0498:                        if ((new File(sFileScript)).length() > iLogSize * 1024 * 1024) {
0499:                            checkpoint();
0500:                        }
0501:                    }
0502:                }
0503:            }
0504:
0505:            /**
0506:             *  Method declaration
0507:             *
0508:             * @throws  SQLException
0509:             */
0510:            void shutdown() throws SQLException {
0511:
0512:                tRunner = null;
0513:
0514:                if (cCache != null) {
0515:                    cCache.shutdown();
0516:
0517:                    cCache = null;
0518:                }
0519:
0520:                shutdownAllTextCaches();
0521:                closeScript();
0522:                pProperties.close();
0523:            }
0524:
0525:            /**
0526:             *  Method declaration
0527:             *
0528:             * @param  db
0529:             * @param  file
0530:             * @param  full
0531:             * @param  session
0532:             * @throws  SQLException
0533:             */
0534:            static void scriptToFile(Database db, String file, boolean full,
0535:                    Session session) throws SQLException {
0536:
0537:                if ((new File(file)).exists()) {
0538:
0539:                    // there must be no such file; overwriting not allowed for security
0540:                    throw Trace.error(Trace.FILE_IO_ERROR, file);
0541:                }
0542:
0543:                try {
0544:                    long time = System.currentTimeMillis();
0545:
0546:                    // only ddl commands; needs not so much memory
0547:                    Result r;
0548:
0549:                    if (full) {
0550:
0551:                        // no drop, no insert, and no positions for cached tables
0552:                        r = db.getScript(false, false, false, session);
0553:                    } else {
0554:
0555:                        // no drop, no insert, but positions for cached tables
0556:                        r = db.getScript(false, false, true, session);
0557:                    }
0558:
0559:                    Record n = r.rRoot;
0560:                    FileWriter w = new FileWriter(file);
0561:
0562:                    while (n != null) {
0563:                        writeLine(w, (String) n.data[0]);
0564:
0565:                        n = n.next;
0566:                    }
0567:
0568:                    // inserts are done separetely to save memory
0569:                    HsqlArrayList tables = db.getTables();
0570:
0571:                    for (int i = 0; i < tables.size(); i++) {
0572:                        Table t = (Table) tables.get(i);
0573:
0574:                        // cached tables have the index roots set in the ddl script
0575:                        if ((full || !t.isCached()) && !t.isTemp()
0576:                                && !t.isView()
0577:                                && (!t.isText() || !t.isDataReadOnly())) {
0578:                            Index primary = t.getPrimaryIndex();
0579:                            Node x = primary.first();
0580:
0581:                            while (x != null) {
0582:                                writeLine(w, t.getInsertStatement(x.getData()));
0583:
0584:                                x = primary.next(x);
0585:                            }
0586:                        }
0587:
0588:                        // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
0589:                        if (t.isDataReadOnly() && !t.isTemp() && !t.isText()) {
0590:                            HsqlStringBuffer a = new HsqlStringBuffer(
0591:                                    "SET TABLE ");
0592:
0593:                            a.append(t.getName().statementName);
0594:                            a.append(" READONLY TRUE");
0595:                            writeLine(w, a.toString());
0596:                        }
0597:                    }
0598:
0599:                    w.close();
0600:
0601:                    time = System.currentTimeMillis() - time;
0602:
0603:                    if (Trace.TRACE) {
0604:                        Trace.trace(time);
0605:                    }
0606:                } catch (IOException e) {
0607:                    throw Trace.error(Trace.FILE_IO_ERROR, file + " " + e);
0608:                }
0609:            }
0610:
0611:            /**
0612:             * Called internally by replication to generate initial state to be sent to new replica
0613:             * Returns null if the generation fails, or throws an exception
0614:             */
0615:            static byte[] scriptToBuffer(Database db, boolean full,
0616:                    Session session) throws SQLException {
0617:
0618:                ByteArrayOutputStream bos = null;
0619:                OutputStreamWriter w = null;
0620:
0621:                try {
0622:                    long time = System.currentTimeMillis();
0623:
0624:                    // only ddl commands; needs not so much memory
0625:                    Result r;
0626:
0627:                    if (full) {
0628:
0629:                        // no drop, no insert, and no positions for cached tables
0630:                        r = db.getScript(false, false, false, session);
0631:                    } else {
0632:
0633:                        // no drop, no insert, but positions for cached tables
0634:                        r = db.getScript(false, false, true, session);
0635:                    }
0636:
0637:                    Record n = r.rRoot;
0638:                    // FileWriter w = new FileWriter(file);
0639:                    bos = new ByteArrayOutputStream(0xff);
0640:                    w = new OutputStreamWriter(bos);
0641:
0642:                    while (n != null) {
0643:                        writeLine(w, (String) n.data[0]);
0644:
0645:                        n = n.next;
0646:                    }
0647:
0648:                    // inserts are done separetely to save memory
0649:                    HsqlArrayList tables = db.getTables();
0650:
0651:                    for (int i = 0; i < tables.size(); i++) {
0652:                        Table t = (Table) tables.get(i);
0653:
0654:                        // cached tables have the index roots set in the ddl script
0655:                        if ((full || !t.isCached()) && !t.isTemp()
0656:                                && !t.isView()
0657:                                && (!t.isText() || !t.isDataReadOnly())) {
0658:                            Index primary = t.getPrimaryIndex();
0659:                            Node x = primary.first();
0660:
0661:                            while (x != null) {
0662:                                writeLine(w, t.getInsertStatement(x.getData()));
0663:
0664:                                x = primary.next(x);
0665:                            }
0666:                        }
0667:
0668:                        // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
0669:                        if (t.isDataReadOnly() && !t.isTemp() && !t.isText()) {
0670:                            HsqlStringBuffer a = new HsqlStringBuffer(
0671:                                    "SET TABLE ");
0672:
0673:                            a.append(t.getName().statementName);
0674:                            a.append(" READONLY TRUE");
0675:                            writeLine(w, a.toString());
0676:                        }
0677:                    }
0678:
0679:                    w.close(); // flushes as well
0680:
0681:                    time = System.currentTimeMillis() - time;
0682:
0683:                    if (Trace.TRACE) {
0684:                        Trace.trace(time);
0685:                    }
0686:
0687:                    return bos != null ? bos.toByteArray() : null;
0688:
0689:                } catch (IOException e) {
0690:                    throw Trace.error(Trace.FILE_IO_ERROR, e.toString());
0691:                }
0692:            }
0693:
0694:            /**
0695:             *  Method declaration
0696:             *
0697:             * @param  file
0698:             */
0699:            private void renameNewToCurrent(String file) {
0700:
0701:                // even if it crashes here, recovering is no problem
0702:                if ((new File(file + ".new")).exists()) {
0703:
0704:                    // if we have a new file
0705:                    // delete the old (maybe already deleted)
0706:                    (new File(file)).delete();
0707:
0708:                    // rename the new to the current
0709:                    new File(file + ".new").renameTo(new File(file));
0710:                }
0711:            }
0712:
0713:            private void create() throws SQLException {
0714:
0715:                if (Trace.TRACE) {
0716:                    Trace.trace(sName);
0717:                }
0718:
0719:                pProperties.setProperty("version", jdbcDriver.VERSION);
0720:                pProperties.save();
0721:            }
0722:
0723:            /**
0724:             *  Method declaration
0725:             *
0726:             * @return
0727:             * @throws  SQLException
0728:             */
0729:            private boolean isAlreadyOpen() throws SQLException {
0730:
0731:                // reading the last modified, wait 3 seconds, read again.
0732:                // if the same information was read the file was not changed
0733:                // and is probably, except the other process is blocked
0734:                if (Trace.TRACE) {
0735:                    Trace.trace();
0736:                }
0737:
0738:                File f = new File(sName + ".lock");
0739:                long l1 = f.lastModified();
0740:
0741:                try {
0742:                    Thread.sleep(3000);
0743:                } catch (Exception e) {
0744:                }
0745:
0746:                long l2 = f.lastModified();
0747:
0748:                if (l1 != l2) {
0749:                    return true;
0750:                }
0751:
0752:                return pProperties.isFileOpen();
0753:            }
0754:
0755:            /**
0756:             *  Method declaration
0757:             *
0758:             * @throws  SQLException
0759:             */
0760:            private void backup() throws SQLException {
0761:
0762:                if (Trace.TRACE) {
0763:                    Trace.trace();
0764:
0765:                    // if there is no cache file then backup is not necessary
0766:                }
0767:
0768:                if (!(new File(sFileCache)).exists()) {
0769:                    return;
0770:                }
0771:
0772:                try {
0773:                    long time = System.currentTimeMillis();
0774:
0775:                    // create a '.new' file; rename later
0776:                    DeflaterOutputStream f = new DeflaterOutputStream(
0777:                            new FileOutputStream(sFileBackup + ".new"),
0778:                            new Deflater(Deflater.BEST_SPEED), COPY_BLOCK_SIZE);
0779:                    byte b[] = new byte[COPY_BLOCK_SIZE];
0780:                    FileInputStream in = new FileInputStream(sFileCache);
0781:
0782:                    while (true) {
0783:                        int l = in.read(b, 0, COPY_BLOCK_SIZE);
0784:
0785:                        if (l == -1) {
0786:                            break;
0787:                        }
0788:
0789:                        f.write(b, 0, l);
0790:                    }
0791:
0792:                    f.close();
0793:                    in.close();
0794:
0795:                    time = System.currentTimeMillis() - time;
0796:
0797:                    if (Trace.TRACE) {
0798:                        Trace.trace(time);
0799:                    }
0800:                } catch (Exception e) {
0801:                    throw Trace.error(Trace.FILE_IO_ERROR, sFileBackup);
0802:                }
0803:            }
0804:
0805:            /**
0806:             *  Method declaration
0807:             *
0808:             * @throws  SQLException
0809:             */
0810:            private void restoreBackup() throws SQLException {
0811:
0812:                if (Trace.TRACE) {
0813:                    Trace.trace("not closed last time!");
0814:                }
0815:
0816:                if (!(new File(sFileBackup)).exists()) {
0817:
0818:                    // the backup don't exists because it was never made or is empty
0819:                    // the cache file must be deleted in this case
0820:                    (new File(sFileCache)).delete();
0821:
0822:                    return;
0823:                }
0824:
0825:                try {
0826:                    long time = System.currentTimeMillis();
0827:                    InflaterInputStream f = new InflaterInputStream(
0828:                            new FileInputStream(sFileBackup), new Inflater());
0829:                    FileOutputStream cache = new FileOutputStream(sFileCache);
0830:                    byte b[] = new byte[COPY_BLOCK_SIZE];
0831:
0832:                    while (true) {
0833:                        int l = f.read(b, 0, COPY_BLOCK_SIZE);
0834:
0835:                        if (l == -1) {
0836:                            break;
0837:                        }
0838:
0839:                        cache.write(b, 0, l);
0840:                    }
0841:
0842:                    cache.close();
0843:                    f.close();
0844:
0845:                    time = System.currentTimeMillis() - time;
0846:
0847:                    if (Trace.TRACE) {
0848:                        Trace.trace(time);
0849:                    }
0850:                } catch (Exception e) {
0851:                    throw Trace.error(Trace.FILE_IO_ERROR, sFileBackup);
0852:                }
0853:            }
0854:
0855:            /**
0856:             *  Method declaration
0857:             *
0858:             * @throws  SQLException
0859:             */
0860:            private void openScript() throws SQLException {
0861:
0862:                if (Trace.TRACE) {
0863:                    Trace.trace();
0864:                }
0865:
0866:                try {
0867:
0868:                    // todo: use a compressed stream
0869:                    wScript = new BufferedWriter(new FileWriter(sFileScript,
0870:                            true), 4096);
0871:                } catch (Exception e) {
0872:                    throw Trace.error(Trace.FILE_IO_ERROR, sFileScript);
0873:                }
0874:            }
0875:
0876:            /**
0877:             *  Method declaration
0878:             *
0879:             * @throws  SQLException
0880:             */
0881:            private void closeScript() throws SQLException {
0882:
0883:                if (Trace.TRACE) {
0884:                    Trace.trace();
0885:                }
0886:
0887:                try {
0888:                    if (wScript != null) {
0889:                        wScript.close();
0890:
0891:                        wScript = null;
0892:                    }
0893:                } catch (Exception e) {
0894:                    throw Trace.error(Trace.FILE_IO_ERROR, sFileScript);
0895:                }
0896:            }
0897:
0898:            /**
0899:             *  Method declaration
0900:             *
0901:             * @throws  SQLException
0902:             */
0903:            private void runScript() throws SQLException {
0904:
0905:                if (Trace.TRACE) {
0906:                    Trace.trace();
0907:                }
0908:
0909:                if (!(new File(sFileScript)).exists()) {
0910:                    return;
0911:                }
0912:
0913:                bRestoring = true;
0914:
0915:                dDatabase.setReferentialIntegrity(false);
0916:
0917:                HsqlArrayList session = new HsqlArrayList();
0918:
0919:                session.add(sysSession);
0920:
0921:                Session current = sysSession;
0922:
0923:                try {
0924:                    long time = System.currentTimeMillis();
0925:                    LineNumberReader r = new LineNumberReader(new FileReader(
0926:                            sFileScript));
0927:
0928:                    while (true) {
0929:                        String s = readLine(r);
0930:
0931:                        if (s == null) {
0932:                            break;
0933:                        }
0934:
0935:                        if (s.startsWith("/*C")) {
0936:                            int id = Integer.parseInt(s.substring(3, s.indexOf(
0937:                                    '*', 4)));
0938:
0939:                            if (id >= session.size()) {
0940:                                session.setSize(id + 1);
0941:                            }
0942:
0943:                            current = (Session) session.get(id);
0944:
0945:                            if (current == null) {
0946:                                current = new Session(sysSession, id);
0947:
0948:                                session.set(id, current);
0949:                                dDatabase.registerSession(current);
0950:                            }
0951:
0952:                            s = s.substring(s.indexOf('/', 1) + 1);
0953:                        }
0954:
0955:                        if (s.length() != 0) {
0956:                            Result result = dDatabase.execute(s, current);
0957:
0958:                            if ((result != null)
0959:                                    && (result.iMode == Result.ERROR)) {
0960:                                throw (Trace.getError(result.errorCode,
0961:                                        result.sError));
0962:                            }
0963:                        }
0964:
0965:                        if (s.equals("DISCONNECT")) {
0966:                            int id = current.getId();
0967:
0968:                            current = new Session(sysSession, id);
0969:
0970:                            session.set(id, current);
0971:                        }
0972:                    }
0973:
0974:                    r.close();
0975:
0976:                    for (int i = 0; i < session.size(); i++) {
0977:                        current = (Session) session.get(i);
0978:
0979:                        if (current != null) {
0980:                            current.rollback();
0981:                        }
0982:                    }
0983:
0984:                    time = System.currentTimeMillis() - time;
0985:
0986:                    if (Trace.TRACE) {
0987:                        Trace.trace(time);
0988:                    }
0989:                } catch (IOException e) {
0990:                    throw Trace.error(Trace.FILE_IO_ERROR, sFileScript + " "
0991:                            + e);
0992:                }
0993:
0994:                dDatabase.setReferentialIntegrity(true);
0995:
0996:                bRestoring = false;
0997:            }
0998:
0999:            void initializeDatabaseFromBuffer(byte[] buf) throws SQLException {
1000:                ByteArrayInputStream bis;
1001:                InputStreamReader in;
1002:
1003:                if (Trace.TRACE) {
1004:                    Trace.trace();
1005:                }
1006:
1007:                if (buf == null)
1008:                    throw Trace
1009:                            .error(Trace.FILE_IO_ERROR,
1010:                                    "Log.initializeDatabaseFromBuffer(): buffer is null");
1011:
1012:                bRestoring = true;
1013:
1014:                dDatabase.setReferentialIntegrity(false);
1015:
1016:                HsqlArrayList session = new HsqlArrayList();
1017:
1018:                session.add(sysSession);
1019:
1020:                Session current = sysSession;
1021:                int size = 1;
1022:
1023:                try {
1024:                    long time = System.currentTimeMillis();
1025:                    LineNumberReader r = null;
1026:
1027:                    bis = new ByteArrayInputStream(buf);
1028:                    in = new InputStreamReader(bis);
1029:                    r = new LineNumberReader(in);
1030:
1031:                    while (true) {
1032:                        String s = readLine(r);
1033:
1034:                        if (s == null) {
1035:                            break;
1036:                        }
1037:
1038:                        if (s.startsWith("/*C")) {
1039:                            int id = Integer.parseInt(s.substring(3, s.indexOf(
1040:                                    '*', 4)));
1041:
1042:                            if (id >= size) {
1043:                                session.setSize(id + 1);
1044:                            }
1045:
1046:                            current = (Session) session.get(id);
1047:
1048:                            if (current == null) {
1049:                                current = new Session(sysSession, id);
1050:
1051:                                session.set(id, current);
1052:                                dDatabase.registerSession(current);
1053:                            }
1054:
1055:                            s = s.substring(s.indexOf('/', 1) + 1);
1056:                        }
1057:
1058:                        if (s.length() != 0) {
1059:                            Result result = dDatabase.execute(s, current);
1060:
1061:                            if ((result != null)
1062:                                    && (result.iMode == Result.ERROR)) {
1063:                                throw (Trace.getError(result.errorCode,
1064:                                        result.sError));
1065:                            }
1066:                        }
1067:
1068:                        if (s.equals("DISCONNECT")) {
1069:                            int id = current.getId();
1070:
1071:                            current = new Session(sysSession, id);
1072:
1073:                            session.set(id, current);
1074:                        }
1075:                    }
1076:
1077:                    r.close();
1078:
1079:                    for (int i = 0; i < size; i++) {
1080:                        current = (Session) session.get(i);
1081:
1082:                        if (current != null) {
1083:                            current.rollback();
1084:                        }
1085:                    }
1086:
1087:                    time = System.currentTimeMillis() - time;
1088:
1089:                    if (Trace.TRACE) {
1090:                        Trace.trace(time);
1091:                    }
1092:                } catch (IOException e) {
1093:                    throw Trace.error(Trace.FILE_IO_ERROR, sFileScript + " "
1094:                            + e);
1095:                }
1096:
1097:                dDatabase.setReferentialIntegrity(true);
1098:
1099:                bRestoring = false;
1100:            }
1101:
1102:            /**
1103:             *  Method declaration
1104:             *
1105:             * @param  full
1106:             * @throws  SQLException
1107:             */
1108:            private void writeScript(boolean full) throws SQLException {
1109:
1110:                if (Trace.TRACE) {
1111:                    Trace.trace();
1112:
1113:                    // create script in '.new' file
1114:                }
1115:
1116:                (new File(sFileScript + ".new")).delete();
1117:
1118:                // script; but only positions of cached tables, not full
1119:                scriptToFile(dDatabase, sFileScript + ".new", full, sysSession);
1120:            }
1121:
1122:            /**
1123:             *  Method declaration
1124:             *
1125:             * @param  w
1126:             * @param  s
1127:             * @throws  IOException
1128:             */
1129:
1130:            // fredt@users 20011120 - patch 450455 by kibu@users - optimised
1131:            private static final String lineSep = System.getProperty(
1132:                    "line.separator", "\n");
1133:
1134:            private static void writeLine(Writer w, String s)
1135:                    throws IOException {
1136:                w.write(StringConverter.unicodeToAscii(s).append(lineSep)
1137:                        .toString());
1138:            }
1139:
1140:            /**
1141:             *  Method declaration
1142:             *
1143:             * @param  r
1144:             * @return
1145:             * @throws  IOException
1146:             */
1147:            private static String readLine(LineNumberReader r)
1148:                    throws IOException {
1149:
1150:                String s = r.readLine();
1151:
1152:                return StringConverter.asciiToUnicode(s);
1153:            }
1154:
1155:            /**
1156:             *  Method declaration
1157:             *
1158:             * @return
1159:             */
1160:            HsqlDatabaseProperties getProperties() {
1161:                return pProperties;
1162:            }
1163:
1164:            // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - text tables
1165:            private HsqlHashMap textCacheList = new HsqlHashMap();
1166:
1167:            Cache openTextCache(String table, String source,
1168:                    boolean readOnlyData, boolean reversed) throws SQLException {
1169:
1170:                closeTextCache(table);
1171:
1172:                if (pProperties.getProperty("textdb.allow_full_path", "false")
1173:                        .equals("false")) {
1174:                    if (source.indexOf("..") != -1) {
1175:                        throw (Trace.error(Trace.ACCESS_IS_DENIED, source));
1176:                    }
1177:
1178:                    String path = new File(new File(sName).getAbsolutePath())
1179:                            .getParent();
1180:
1181:                    if (path != null) {
1182:                        source = path + File.separator + source;
1183:                    }
1184:                }
1185:
1186:                String prefix = "textdb." + table.toLowerCase() + ".";
1187:                TextCache c;
1188:
1189:                if (reversed) {
1190:                    c = new ReverseTextCache(source, prefix, pProperties);
1191:                } else {
1192:                    c = new TextCache(source, prefix, pProperties);
1193:                }
1194:
1195:                c.open(readOnlyData || bReadOnly);
1196:                textCacheList.put(table, c);
1197:
1198:                return (c);
1199:            }
1200:
1201:            void closeTextCache(String table) throws SQLException {
1202:
1203:                TextCache c = (TextCache) textCacheList.remove(table);
1204:
1205:                if (c != null) {
1206:                    c.flush();
1207:                }
1208:            }
1209:
1210:            void closeAllTextCaches(boolean compact) throws SQLException {
1211:
1212:                for (Enumeration e = textCacheList.elements(); e
1213:                        .hasMoreElements();) {
1214:                    if (compact) {
1215:                        ((TextCache) e.nextElement()).purge();
1216:                    } else {
1217:                        ((TextCache) e.nextElement()).flush();
1218:                    }
1219:                }
1220:            }
1221:
1222:            void reopenAllTextCaches() throws SQLException {
1223:
1224:                for (Enumeration e = textCacheList.elements(); e
1225:                        .hasMoreElements();) {
1226:                    ((TextCache) e.nextElement()).reopen();
1227:                }
1228:            }
1229:
1230:            void shutdownAllTextCaches() throws SQLException {
1231:
1232:                for (Enumeration e = textCacheList.elements(); e
1233:                        .hasMoreElements();) {
1234:                    ((TextCache) e.nextElement()).shutdown();
1235:                }
1236:
1237:                textCacheList = new HsqlHashMap();
1238:            }
1239:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.