KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > Log


1 /* Copyrights and Licenses
2  *
3  * This product includes Hypersonic SQL.
4  * Originally developed by Thomas Mueller and the Hypersonic SQL Group.
5  *
6  * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved.
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  * - Redistributions of source code must retain the above copyright notice, this list of conditions
10  * and the following disclaimer.
11  * - Redistributions in binary form must reproduce the above copyright notice, this list of
12  * conditions and the following disclaimer in the documentation and/or other materials
13  * provided with the distribution.
14  * - All advertising materials mentioning features or use of this software must display the
15  * following acknowledgment: "This product includes Hypersonic SQL."
16  * - Products derived from this software may not be called "Hypersonic SQL" nor may
17  * "Hypersonic SQL" appear in their names without prior written permission of the
18  * Hypersonic SQL Group.
19  * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
20  * product includes Hypersonic SQL."
21  * This software is provided "as is" and any expressed or implied warranties, including, but
22  * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
23  * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
24  * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
25  * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
26  * or business interruption). However caused any on any theory of liability, whether in contract,
27  * strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this
28  * software, even if advised of the possibility of such damage.
29  * This software consists of voluntary contributions made by many individuals on behalf of the
30  * Hypersonic SQL Group.
31  *
32  *
33  * For work added by the HSQL Development Group:
34  *
35  * Copyright (c) 2001-2002, The HSQL Development Group
36  * All rights reserved.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions are met:
40  *
41  * Redistributions of source code must retain the above copyright notice, this
42  * list of conditions and the following disclaimer, including earlier
43  * license statements (above) and comply with all above license conditions.
44  *
45  * Redistributions in binary form must reproduce the above copyright notice,
46  * this list of conditions and the following disclaimer in the documentation
47  * and/or other materials provided with the distribution, including earlier
48  * license statements (above) and comply with all above license conditions.
49  *
50  * Neither the name of the HSQL Development Group nor the names of its
51  * contributors may be used to endorse or promote products derived from this
52  * software without specific prior written permission.
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
58  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
59  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
60  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65  */

66
67
68 package org.hsqldb;
69
70 import org.hsqldb.lib.HsqlArrayList;
71 import org.hsqldb.lib.HsqlHashMap;
72 import org.hsqldb.lib.HsqlStringBuffer;
73 import java.io.IOException JavaDoc;
74 import java.io.BufferedWriter JavaDoc;
75  import java.io.ByteArrayInputStream JavaDoc;
76  import java.io.ByteArrayOutputStream JavaDoc;
77 import java.io.File JavaDoc;
78 import java.io.FileInputStream JavaDoc;
79 import java.io.FileOutputStream JavaDoc;
80 import java.io.FileReader JavaDoc;
81 import java.io.FileWriter JavaDoc;
82  import java.io.InputStreamReader JavaDoc;
83 import java.io.LineNumberReader JavaDoc;
84  import java.io.OutputStreamWriter JavaDoc;
85 import java.io.Writer JavaDoc;
86 import java.sql.SQLException JavaDoc;
87 import java.util.Enumeration JavaDoc;
88
89 //import java.util.zip.
90
import java.util.zip.Deflater JavaDoc;
91 import java.util.zip.DeflaterOutputStream JavaDoc;
92 import java.util.zip.Inflater JavaDoc;
93 import java.util.zip.InflaterInputStream JavaDoc;
94
95 // fredt@users 20020215 - patch 1.7.0 by fredt
96
// to move operations on the database.properties files to new
97
// class HsqlDatabaseProperties
98
// fredt@users 20020220 - patch 488200 by xclay@users - throw exception
99
// throw addded to all methods relying on file io
100
// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
101
// fredt@users 20020405 - patch 1.7.0 by fredt - no change in db location
102
// because important information about the database is now stored in the
103
// *.properties file, all database files should be in the same folder as the
104
// *.properties file
105
// tony_lai@users 20020820 - export hsqldb.log_size to .properties file
106
// tony_lai@users 20020820 - Modification to shutdown compact process to save memory usage
107

108 /**
109  * This class is responsible for most file handling. A HSQL database
110  * consists of a .properties file, a .script file (contains a SQL script),
111  * a .data file (contains data of cached tables) and a .backup file
112  * (contains the compressed .data file) <P>
113  *
114  * This is an example of the .properties file. The version and the modified
115  * properties are automatically created by the database and should not be
116  * changed manually: <pre>
117  * modified=no
118  * version=1.43
119  * </pre> The following lines are optional, this means they are not created
120  * automatically by the database, but they are interpreted if they exist in
121  * the .script file. They have to be created manually if required. If they
122  * don't exist the default is used. This are the defaults of the database
123  * 'test': <pre>
124  * readonly=false
125  * </pre>
126  *
127  * @version 1.7.0
128  */

129 class Log implements Runnable JavaDoc {
130
131     // block size for copying data
132
private static final int COPY_BLOCK_SIZE = 1 << 16;
133     private HsqlDatabaseProperties pProperties;
134     private String JavaDoc sName;
135     private Database dDatabase;
136     private Session sysSession;
137     private Writer JavaDoc wScript;
138     private String JavaDoc sFileScript;
139     private String JavaDoc sFileCache;
140     private String JavaDoc sFileBackup;
141     private boolean bRestoring;
142     private boolean bReadOnly;
143     private int iLogSize;
144     private int iLogCount;
145     private Thread JavaDoc tRunner;
146     private volatile boolean bNeedFlush;
147     private volatile boolean bWriteDelay;
148     private int mLastId;
149     private Cache cCache;
150
151 // boucherb@users - comment - FIXME
152
// boolean stopped;
153

154     /**
155      * Constructor declaration
156      *
157      * @param db
158      * @param system
159      * @param name
160      * @exception SQLException Description of the Exception
161      */

162     Log(Database db, Session system, String JavaDoc name) throws SQLException JavaDoc {
163
164         dDatabase = db;
165         sysSession = system;
166         sName = name;
167         pProperties = db.getProperties();
168         tRunner = new Thread JavaDoc(this);
169
170         // boucherb@users - FIXME:
171
// standard VM behaviour is to shut down only after all
172
// non-daemon threads exit. Therefor, tRunner shuld be
173
// daemon. Consider the case of:
174
/*
175          public void main(String[] args) {
176          ...
177          try {
178          // fails due to bad user/password...must then connect with valid combo
179          // again to *really* shutdown database, or explicitly call System.exit(...)
180          DriverManager.getConnection("jdbc:hsqldb:filespec,"user","password");
181          ...
182          } catch (...) {
183          }
184          ...
185          }
186          */

187
188         // the VM will not exit, since tRunner is still running and
189
// no shutdown is issued to close the database.
190
//
191
// - setDaemon(false) may require flush in finalization
192
// CB
193
// tRunner.setDaemon(false);
194
tRunner.start();
195     }
196
197     /**
198      * Method declaration
199      */

200     public void run() {
201
202         // boucherb@users - FIXME
203
// while (!stopped) {
204
while (tRunner != null) {
205             try {
206                 tRunner.sleep(1000);
207
208                 if (bNeedFlush) {
209                     wScript.flush();
210
211                     bNeedFlush = false;
212                 }
213
214                 // todo: try to do Cache.cleanUp() here, too
215
} catch (Exception JavaDoc e) {
216
217                 // ignore exceptions; may be InterruptedException or IOException
218
}
219         }
220     }
221
222     /**
223      * Method declaration
224      *
225      * @param delay
226      */

227     void setWriteDelay(boolean delay) {
228         bWriteDelay = delay;
229     }
230
231     /**
232      * When opening a database, the hsqldb.compatible_version property is
233      * used to determine if this version of the engine is equal to or greater
234      * than the earliest version of the engine capable of opening that
235      * database.<p>
236      *
237      * @return
238      * @throws SQLException
239      */

240     boolean open() throws SQLException JavaDoc {
241
242         if (Trace.TRACE) {
243             Trace.trace();
244         }
245
246         if (!pProperties.checkFileExists()) {
247             create();
248             open();
249
250             // this is a new database
251
return true;
252         }
253
254         // todo: some parts are not necessary for ready-only access
255
pProperties.load();
256
257         sFileScript = sName + ".script";
258         sFileCache = sName + ".data";
259         sFileBackup = sName + ".backup";
260
261         // tony_lai@users 20020820
262
// Allows the user to modify log size from the properties file.
263
iLogSize = pProperties.getIntegerProperty("hsqldb.log_size",
264                 iLogSize);
265
266         String JavaDoc version = pProperties.getProperty("hsqldb.compatible_version");
267
268 // fredt@users 20020428 - patch 1.7.0 by fredt
269
int check = version.substring(0, 5).compareTo(jdbcDriver.VERSION);
270
271         Trace.check(check <= 0, Trace.WRONG_DATABASE_FILE_VERSION);
272
273         // save the current version
274
pProperties.setProperty("hsqldb.version", jdbcDriver.VERSION);
275
276         if (pProperties.isPropertyTrue("readonly")) {
277             bReadOnly = true;
278
279             dDatabase.setReadOnly();
280
281             if (cCache != null) {
282                 cCache.open(true);
283             }
284
285             reopenAllTextCaches();
286             runScript();
287
288             return false;
289         }
290
291         boolean needbackup = false;
292         String JavaDoc state = pProperties.getProperty("modified");
293
294         if (state.equals("yes-new-files")) {
295             renameNewToCurrent(sFileScript);
296             renameNewToCurrent(sFileBackup);
297         } else if (state.equals("yes")) {
298             if (isAlreadyOpen()) {
299                 throw Trace.error(Trace.DATABASE_ALREADY_IN_USE);
300             }
301
302             // recovering after a crash (or forgot to close correctly)
303
restoreBackup();
304
305             needbackup = true;
306         }
307
308         pProperties.setProperty("modified", "yes");
309         pProperties.save();
310
311         if (cCache != null) {
312             cCache.open(false);
313         }
314
315         reopenAllTextCaches();
316         runScript();
317
318         if (needbackup) {
319             close(false);
320             pProperties.setProperty("modified", "yes");
321             pProperties.save();
322
323             if (cCache != null) {
324                 cCache.open(false);
325             }
326
327             reopenAllTextCaches();
328         }
329
330         openScript();
331
332         // this is an existing database
333
return false;
334     }
335
336     Cache getCache() throws SQLException JavaDoc {
337
338         if (cCache == null) {
339             cCache = new Cache(sFileCache, pProperties);
340
341             cCache.open(bReadOnly);
342         }
343
344         return (cCache);
345     }
346
347     /**
348      * Method declaration
349      */

350     void /* synchronized */ stop() {
351
352         //boucherb@users - FIXME:
353
/*
354          if (!stopped)
355          stopped = true;
356          tRunner.interrupt();
357          tRunner = null;
358          }
359          */

360         tRunner = null;
361     }
362
363     /**
364      * Method declaration
365      *
366      * @param compact
367      * @throws SQLException
368      */

369     void close(boolean compact) throws SQLException JavaDoc {
370
371         if (Trace.TRACE) {
372             Trace.trace();
373         }
374
375         if (bReadOnly) {
376             return;
377         }
378
379         // no more scripting
380
closeScript();
381
382         // create '.script.new' (for this the cache may be still required)
383
writeScript(compact);
384
385         // flush the cache (important: after writing the script)
386
if (cCache != null) {
387             cCache.flush();
388         }
389
390         closeAllTextCaches(compact);
391
392         // create '.backup.new' using the '.data'
393
backup();
394
395         // we have the new files
396
pProperties.setProperty("modified", "yes-new-files");
397         pProperties.save();
398
399         // old files can be removed and new files renamed
400
renameNewToCurrent(sFileScript);
401         renameNewToCurrent(sFileBackup);
402
403         // now its done completely
404
pProperties.setProperty("modified", "no");
405         pProperties.setProperty("version", jdbcDriver.VERSION);
406         pProperties.setProperty("hsqldb.compatible_version", "1.7.0");
407         pProperties.save();
408         pProperties.close();
409
410         if (compact) {
411
412             // stop the runner thread of this process (just for security)
413
stop();
414
415             // delete the .data so then a new file is created
416
(new File JavaDoc(sFileCache)).delete();
417             (new File JavaDoc(sFileBackup)).delete();
418
419             // tony_lai@users 20020820
420
// The database re-open and close has been moved to
421
// Database#close(int closemode) for saving memory usage.
422
}
423     }
424
425     /**
426      * Method declaration
427      *
428      * @throws SQLException
429      */

430     void checkpoint() throws SQLException JavaDoc {
431
432         close(false);
433         pProperties.setProperty("modified", "yes");
434         pProperties.save();
435
436         if (cCache != null) {
437             cCache.open(false);
438         }
439
440         reopenAllTextCaches();
441         openScript();
442     }
443
444     /**
445      * Method declaration
446      *
447      * @param mb
448      */

449     void setLogSize(int mb) {
450
451         iLogSize = mb;
452
453         pProperties.setProperty("hsqldb.log_size", iLogSize);
454     }
455
456     /**
457      * Method declaration
458      *
459      * @param c
460      * @param s
461      * @throws SQLException
462      */

463     void write(Session c, String JavaDoc s) throws SQLException JavaDoc {
464
465         if (bRestoring || s == null || s.length() == 0) {
466             return;
467         }
468
469         if (!bReadOnly) {
470             int id = 0;
471
472             if (c != null) {
473                 id = c.getId();
474             }
475
476             if (id != mLastId) {
477                 s = "/*C" + id + "*/" + s;
478                 mLastId = id;
479             }
480
481             try {
482                 writeLine(wScript, s);
483
484                 if (bWriteDelay) {
485                     bNeedFlush = true;
486                 } else {
487                     wScript.flush();
488                 }
489             } catch (IOException JavaDoc e) {
490                 throw Trace.error(Trace.FILE_IO_ERROR, sFileScript);
491             }
492
493             // fredt@users - todo - eliminate new File() calls
494
if (iLogSize > 0 && iLogCount++ > 100) {
495                 iLogCount = 0;
496
497                 if ((new File JavaDoc(sFileScript)).length()
498                         > iLogSize * 1024 * 1024) {
499                     checkpoint();
500                 }
501             }
502         }
503     }
504
505     /**
506      * Method declaration
507      *
508      * @throws SQLException
509      */

510     void shutdown() throws SQLException JavaDoc {
511
512         tRunner = null;
513
514         if (cCache != null) {
515             cCache.shutdown();
516
517             cCache = null;
518         }
519
520         shutdownAllTextCaches();
521         closeScript();
522         pProperties.close();
523     }
524
525     /**
526      * Method declaration
527      *
528      * @param db
529      * @param file
530      * @param full
531      * @param session
532      * @throws SQLException
533      */

534     static void scriptToFile(Database db, String JavaDoc file, boolean full,
535                              Session session) throws SQLException JavaDoc {
536
537         if ((new File JavaDoc(file)).exists()) {
538
539             // there must be no such file; overwriting not allowed for security
540
throw Trace.error(Trace.FILE_IO_ERROR, file);
541         }
542
543         try {
544             long time = System.currentTimeMillis();
545
546             // only ddl commands; needs not so much memory
547
Result r;
548
549             if (full) {
550
551                 // no drop, no insert, and no positions for cached tables
552
r = db.getScript(false, false, false, session);
553             } else {
554
555                 // no drop, no insert, but positions for cached tables
556
r = db.getScript(false, false, true, session);
557             }
558
559             Record n = r.rRoot;
560             FileWriter JavaDoc w = new FileWriter JavaDoc(file);
561
562             while (n != null) {
563                 writeLine(w, (String JavaDoc) n.data[0]);
564
565                 n = n.next;
566             }
567
568             // inserts are done separetely to save memory
569
HsqlArrayList tables = db.getTables();
570
571             for (int i = 0; i < tables.size(); i++) {
572                 Table t = (Table) tables.get(i);
573
574 // cached tables have the index roots set in the ddl script
575
if ((full ||!t.isCached()) &&!t.isTemp() &&!t.isView()
576                         && (!t.isText() ||!t.isDataReadOnly())) {
577                     Index primary = t.getPrimaryIndex();
578                     Node x = primary.first();
579
580                     while (x != null) {
581                         writeLine(w, t.getInsertStatement(x.getData()));
582
583                         x = primary.next(x);
584                     }
585                 }
586
587 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
588
if (t.isDataReadOnly() &&!t.isTemp() &&!t.isText()) {
589                     HsqlStringBuffer a = new HsqlStringBuffer("SET TABLE ");
590
591                     a.append(t.getName().statementName);
592                     a.append(" READONLY TRUE");
593                     writeLine(w, a.toString());
594                 }
595             }
596
597             w.close();
598
599             time = System.currentTimeMillis() - time;
600
601             if (Trace.TRACE) {
602                 Trace.trace(time);
603             }
604         } catch (IOException JavaDoc e) {
605             throw Trace.error(Trace.FILE_IO_ERROR, file + " " + e);
606         }
607     }
608
609
610
611      /**
612       * Called internally by replication to generate initial state to be sent to new replica
613       * Returns null if the generation fails, or throws an exception
614       */

615      static byte[] scriptToBuffer(Database db, boolean full,
616                   Session session) throws SQLException JavaDoc {
617
618      ByteArrayOutputStream JavaDoc bos=null;
619      OutputStreamWriter JavaDoc w=null;
620
621      try {
622          long time = System.currentTimeMillis();
623
624          // only ddl commands; needs not so much memory
625
Result r;
626
627          if (full) {
628
629          // no drop, no insert, and no positions for cached tables
630
r = db.getScript(false, false, false, session);
631          } else {
632
633          // no drop, no insert, but positions for cached tables
634
r = db.getScript(false, false, true, session);
635          }
636
637          Record n = r.rRoot;
638          // FileWriter w = new FileWriter(file);
639
bos=new ByteArrayOutputStream JavaDoc(0xff);
640          w=new OutputStreamWriter JavaDoc(bos);
641
642          while (n != null) {
643          writeLine(w, (String JavaDoc) n.data[0]);
644
645          n = n.next;
646          }
647
648          // inserts are done separetely to save memory
649
HsqlArrayList tables = db.getTables();
650
651          for (int i = 0; i < tables.size(); i++) {
652          Table t = (Table) tables.get(i);
653
654  // cached tables have the index roots set in the ddl script
655
if ((full ||!t.isCached()) &&!t.isTemp() &&!t.isView()
656              && (!t.isText() ||!t.isDataReadOnly())) {
657              Index primary = t.getPrimaryIndex();
658              Node x = primary.first();
659
660              while (x != null) {
661              writeLine(w, t.getInsertStatement(x.getData()));
662
663              x = primary.next(x);
664              }
665          }
666
667  // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
668
if (t.isDataReadOnly() &&!t.isTemp() &&!t.isText()) {
669              HsqlStringBuffer a = new HsqlStringBuffer("SET TABLE ");
670
671              a.append(t.getName().statementName);
672              a.append(" READONLY TRUE");
673              writeLine(w, a.toString());
674          }
675          }
676
677          w.close(); // flushes as well
678

679          time = System.currentTimeMillis() - time;
680
681          if (Trace.TRACE) {
682          Trace.trace(time);
683          }
684
685          return bos != null? bos.toByteArray() : null;
686
687      } catch (IOException JavaDoc e) {
688          throw Trace.error(Trace.FILE_IO_ERROR, e.toString());
689      }
690      }
691
692
693
694
695
696
697
698
699
700     /**
701      * Method declaration
702      *
703      * @param file
704      */

705     private void renameNewToCurrent(String JavaDoc file) {
706
707         // even if it crashes here, recovering is no problem
708
if ((new File JavaDoc(file + ".new")).exists()) {
709
710             // if we have a new file
711
// delete the old (maybe already deleted)
712
(new File JavaDoc(file)).delete();
713
714             // rename the new to the current
715
new File JavaDoc(file + ".new").renameTo(new File JavaDoc(file));
716         }
717     }
718
719     private void create() throws SQLException JavaDoc {
720
721         if (Trace.TRACE) {
722             Trace.trace(sName);
723         }
724
725         pProperties.setProperty("version", jdbcDriver.VERSION);
726         pProperties.save();
727     }
728
729     /**
730      * Method declaration
731      *
732      * @return
733      * @throws SQLException
734      */

735     private boolean isAlreadyOpen() throws SQLException JavaDoc {
736
737         // reading the last modified, wait 3 seconds, read again.
738
// if the same information was read the file was not changed
739
// and is probably, except the other process is blocked
740
if (Trace.TRACE) {
741             Trace.trace();
742         }
743
744         File JavaDoc f = new File JavaDoc(sName + ".lock");
745         long l1 = f.lastModified();
746
747         try {
748             Thread.sleep(3000);
749         } catch (Exception JavaDoc e) {}
750
751         long l2 = f.lastModified();
752
753         if (l1 != l2) {
754             return true;
755         }
756
757         return pProperties.isFileOpen();
758     }
759
760     /**
761      * Method declaration
762      *
763      * @throws SQLException
764      */

765     private void backup() throws SQLException JavaDoc {
766
767         if (Trace.TRACE) {
768             Trace.trace();
769
770             // if there is no cache file then backup is not necessary
771
}
772
773         if (!(new File JavaDoc(sFileCache)).exists()) {
774             return;
775         }
776
777         try {
778             long time = System.currentTimeMillis();
779
780             // create a '.new' file; rename later
781
DeflaterOutputStream JavaDoc f = new DeflaterOutputStream JavaDoc(
782                 new FileOutputStream JavaDoc(sFileBackup + ".new"),
783                 new Deflater JavaDoc(Deflater.BEST_SPEED), COPY_BLOCK_SIZE);
784             byte b[] = new byte[COPY_BLOCK_SIZE];
785             FileInputStream JavaDoc in = new FileInputStream JavaDoc(sFileCache);
786
787             while (true) {
788                 int l = in.read(b, 0, COPY_BLOCK_SIZE);
789
790                 if (l == -1) {
791                     break;
792                 }
793
794                 f.write(b, 0, l);
795             }
796
797             f.close();
798             in.close();
799
800             time = System.currentTimeMillis() - time;
801
802             if (Trace.TRACE) {
803                 Trace.trace(time);
804             }
805         } catch (Exception JavaDoc e) {
806             throw Trace.error(Trace.FILE_IO_ERROR, sFileBackup);
807         }
808     }
809
810     /**
811      * Method declaration
812      *
813      * @throws SQLException
814      */

815     private void restoreBackup() throws SQLException JavaDoc {
816
817         if (Trace.TRACE) {
818             Trace.trace("not closed last time!");
819         }
820
821         if (!(new File JavaDoc(sFileBackup)).exists()) {
822
823             // the backup don't exists because it was never made or is empty
824
// the cache file must be deleted in this case
825
(new File JavaDoc(sFileCache)).delete();
826
827             return;
828         }
829
830         try {
831             long time = System.currentTimeMillis();
832             InflaterInputStream JavaDoc f =
833                 new InflaterInputStream JavaDoc(new FileInputStream JavaDoc(sFileBackup),
834                                         new Inflater JavaDoc());
835             FileOutputStream JavaDoc cache = new FileOutputStream JavaDoc(sFileCache);
836             byte b[] = new byte[COPY_BLOCK_SIZE];
837
838             while (true) {
839                 int l = f.read(b, 0, COPY_BLOCK_SIZE);
840
841                 if (l == -1) {
842                     break;
843                 }
844
845                 cache.write(b, 0, l);
846             }
847
848             cache.close();
849             f.close();
850
851             time = System.currentTimeMillis() - time;
852
853             if (Trace.TRACE) {
854                 Trace.trace(time);
855             }
856         } catch (Exception JavaDoc e) {
857             throw Trace.error(Trace.FILE_IO_ERROR, sFileBackup);
858         }
859     }
860
861     /**
862      * Method declaration
863      *
864      * @throws SQLException
865      */

866     private void openScript() throws SQLException JavaDoc {
867
868         if (Trace.TRACE) {
869             Trace.trace();
870         }
871
872         try {
873
874             // todo: use a compressed stream
875
wScript = new BufferedWriter JavaDoc(new FileWriter JavaDoc(sFileScript, true),
876                                          4096);
877         } catch (Exception JavaDoc e) {
878             throw Trace.error(Trace.FILE_IO_ERROR, sFileScript);
879         }
880     }
881
882     /**
883      * Method declaration
884      *
885      * @throws SQLException
886      */

887     private void closeScript() throws SQLException JavaDoc {
888
889         if (Trace.TRACE) {
890             Trace.trace();
891         }
892
893         try {
894             if (wScript != null) {
895                 wScript.close();
896
897                 wScript = null;
898             }
899         } catch (Exception JavaDoc e) {
900             throw Trace.error(Trace.FILE_IO_ERROR, sFileScript);
901         }
902     }
903
904     /**
905      * Method declaration
906      *
907      * @throws SQLException
908      */

909     private void runScript() throws SQLException JavaDoc {
910
911         if (Trace.TRACE) {
912             Trace.trace();
913         }
914
915         if (!(new File JavaDoc(sFileScript)).exists()) {
916             return;
917         }
918
919         bRestoring = true;
920
921         dDatabase.setReferentialIntegrity(false);
922
923         HsqlArrayList session = new HsqlArrayList();
924
925         session.add(sysSession);
926
927         Session current = sysSession;
928
929         try {
930             long time = System.currentTimeMillis();
931             LineNumberReader JavaDoc r =
932                 new LineNumberReader JavaDoc(new FileReader JavaDoc(sFileScript));
933
934             while (true) {
935                 String JavaDoc s = readLine(r);
936
937                 if (s == null) {
938                     break;
939                 }
940
941                 if (s.startsWith("/*C")) {
942                     int id = Integer.parseInt(s.substring(3, s.indexOf('*',
943                                  4)));
944
945                     if (id >= session.size()) {
946                         session.setSize(id + 1);
947                     }
948
949                     current = (Session) session.get(id);
950
951                     if (current == null) {
952                         current = new Session(sysSession, id);
953
954                         session.set(id, current);
955                         dDatabase.registerSession(current);
956                     }
957
958                     s = s.substring(s.indexOf('/', 1) + 1);
959                 }
960
961                 if (s.length() != 0) {
962                     Result result = dDatabase.execute(s, current);
963
964                     if ((result != null) && (result.iMode == Result.ERROR)) {
965                         throw (Trace.getError(result.errorCode,
966                                               result.sError));
967                     }
968                 }
969
970                 if (s.equals("DISCONNECT")) {
971                     int id = current.getId();
972
973                     current = new Session(sysSession, id);
974
975                     session.set(id, current);
976                 }
977             }
978
979             r.close();
980
981             for (int i = 0; i < session.size(); i++) {
982                 current = (Session) session.get(i);
983
984                 if (current != null) {
985                     current.rollback();
986                 }
987             }
988
989             time = System.currentTimeMillis() - time;
990
991             if (Trace.TRACE) {
992                 Trace.trace(time);
993             }
994         } catch (IOException JavaDoc e) {
995             throw Trace.error(Trace.FILE_IO_ERROR, sFileScript + " " + e);
996         }
997
998         dDatabase.setReferentialIntegrity(true);
999
1000        bRestoring = false;
1001    }
1002
1003
1004
1005     void initializeDatabaseFromBuffer(byte[] buf) throws SQLException JavaDoc {
1006     ByteArrayInputStream JavaDoc bis;
1007     InputStreamReader JavaDoc in;
1008
1009     if (Trace.TRACE) {
1010         Trace.trace();
1011     }
1012
1013     if(buf == null)
1014         throw Trace.error(Trace.FILE_IO_ERROR, "Log.initializeDatabaseFromBuffer(): buffer is null");
1015
1016     bRestoring = true;
1017
1018     dDatabase.setReferentialIntegrity(false);
1019
1020     HsqlArrayList session = new HsqlArrayList();
1021
1022     session.add(sysSession);
1023
1024     Session current = sysSession;
1025     int size = 1;
1026
1027     try {
1028         long time = System.currentTimeMillis();
1029         LineNumberReader JavaDoc r = null;
1030
1031         bis=new ByteArrayInputStream JavaDoc(buf);
1032         in=new InputStreamReader JavaDoc(bis);
1033         r=new LineNumberReader JavaDoc(in);
1034
1035         while (true) {
1036         String JavaDoc s = readLine(r);
1037
1038                if (s == null) {
1039                    break;
1040                }
1041
1042                if (s.startsWith("/*C")) {
1043                    int id = Integer.parseInt(s.substring(3, s.indexOf('*',
1044                                 4)));
1045
1046                    if (id >= size) {
1047                        session.setSize(id + 1);
1048                    }
1049
1050                    current = (Session) session.get(id);
1051
1052                    if (current == null) {
1053                        current = new Session(sysSession, id);
1054
1055                        session.set(id, current);
1056                        dDatabase.registerSession(current);
1057                    }
1058
1059                    s = s.substring(s.indexOf('/', 1) + 1);
1060                }
1061
1062                if (s.length() != 0) {
1063                    Result result = dDatabase.execute(s, current);
1064
1065                    if ((result != null) && (result.iMode == Result.ERROR)) {
1066                        throw (Trace.getError(result.errorCode,
1067                                              result.sError));
1068                    }
1069                }
1070
1071                if (s.equals("DISCONNECT")) {
1072                    int id = current.getId();
1073
1074                    current = new Session(sysSession, id);
1075
1076                    session.set(id, current);
1077                }
1078            }
1079
1080            r.close();
1081
1082            for (int i = 0; i < size; i++) {
1083                current = (Session) session.get(i);
1084
1085                if (current != null) {
1086                    current.rollback();
1087                }
1088            }
1089
1090            time = System.currentTimeMillis() - time;
1091
1092            if (Trace.TRACE) {
1093                Trace.trace(time);
1094            }
1095        } catch (IOException JavaDoc e) {
1096            throw Trace.error(Trace.FILE_IO_ERROR, sFileScript + " " + e);
1097        }
1098
1099        dDatabase.setReferentialIntegrity(true);
1100
1101        bRestoring = false;
1102    }
1103
1104
1105
1106
1107
1108    /**
1109     * Method declaration
1110     *
1111     * @param full
1112     * @throws SQLException
1113     */

1114    private void writeScript(boolean full) throws SQLException JavaDoc {
1115
1116        if (Trace.TRACE) {
1117            Trace.trace();
1118
1119            // create script in '.new' file
1120
}
1121
1122        (new File JavaDoc(sFileScript + ".new")).delete();
1123
1124        // script; but only positions of cached tables, not full
1125
scriptToFile(dDatabase, sFileScript + ".new", full, sysSession);
1126    }
1127
1128    /**
1129     * Method declaration
1130     *
1131     * @param w
1132     * @param s
1133     * @throws IOException
1134     */

1135
1136// fredt@users 20011120 - patch 450455 by kibu@users - optimised
1137
private static final String JavaDoc lineSep = System.getProperty("line.separator",
1138                                              "\n");
1139
1140    private static void writeLine(Writer JavaDoc w, String JavaDoc s) throws IOException JavaDoc {
1141        w.write(StringConverter.unicodeToAscii(s).append(lineSep).toString());
1142    }
1143
1144    /**
1145     * Method declaration
1146     *
1147     * @param r
1148     * @return
1149     * @throws IOException
1150     */

1151    private static String JavaDoc readLine(LineNumberReader JavaDoc r) throws IOException JavaDoc {
1152
1153        String JavaDoc s = r.readLine();
1154
1155        return StringConverter.asciiToUnicode(s);
1156    }
1157
1158    /**
1159     * Method declaration
1160     *
1161     * @return
1162     */

1163    HsqlDatabaseProperties getProperties() {
1164        return pProperties;
1165    }
1166
1167// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - text tables
1168
private HsqlHashMap textCacheList = new HsqlHashMap();
1169
1170    Cache openTextCache(String JavaDoc table, String JavaDoc source, boolean readOnlyData,
1171                        boolean reversed) throws SQLException JavaDoc {
1172
1173        closeTextCache(table);
1174
1175        if (pProperties.getProperty("textdb.allow_full_path",
1176                                    "false").equals("false")) {
1177            if (source.indexOf("..") != -1) {
1178                throw (Trace.error(Trace.ACCESS_IS_DENIED, source));
1179            }
1180
1181            String JavaDoc path =
1182                new File JavaDoc(new File JavaDoc(sName).getAbsolutePath()).getParent();
1183
1184            if (path != null) {
1185                source = path + File.separator + source;
1186            }
1187        }
1188
1189        String JavaDoc prefix = "textdb." + table.toLowerCase() + ".";
1190        TextCache c;
1191
1192        if (reversed) {
1193            c = new ReverseTextCache(source, prefix, pProperties);
1194        } else {
1195            c = new TextCache(source, prefix, pProperties);
1196        }
1197
1198        c.open(readOnlyData || bReadOnly);
1199        textCacheList.put(table, c);
1200
1201        return (c);
1202    }
1203
1204    void closeTextCache(String JavaDoc table) throws SQLException JavaDoc {
1205
1206        TextCache c = (TextCache) textCacheList.remove(table);
1207
1208        if (c != null) {
1209            c.flush();
1210        }
1211    }
1212
1213    void closeAllTextCaches(boolean compact) throws SQLException JavaDoc {
1214
1215        for (Enumeration JavaDoc e =
1216                textCacheList.elements(); e.hasMoreElements(); ) {
1217            if (compact) {
1218                ((TextCache) e.nextElement()).purge();
1219            } else {
1220                ((TextCache) e.nextElement()).flush();
1221            }
1222        }
1223    }
1224
1225    void reopenAllTextCaches() throws SQLException JavaDoc {
1226
1227        for (Enumeration JavaDoc e =
1228                textCacheList.elements(); e.hasMoreElements(); ) {
1229            ((TextCache) e.nextElement()).reopen();
1230        }
1231    }
1232
1233    void shutdownAllTextCaches() throws SQLException JavaDoc {
1234
1235        for (Enumeration JavaDoc e =
1236                textCacheList.elements(); e.hasMoreElements(); ) {
1237            ((TextCache) e.nextElement()).shutdown();
1238        }
1239
1240        textCacheList = new HsqlHashMap();
1241    }
1242}
1243
Popular Tags