KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > persist > Log


1 /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the Hypersonic SQL Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (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  *
30  * This software consists of voluntary contributions made by many individuals
31  * on behalf of the Hypersonic SQL Group.
32  *
33  *
34  * For work added by the HSQL Development Group:
35  *
36  * Copyright (c) 2001-2005, The HSQL Development Group
37  * All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions are met:
41  *
42  * Redistributions of source code must retain the above copyright notice, this
43  * list of conditions and the following disclaimer.
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.
48  *
49  * Neither the name of the HSQL Development Group nor the names of its
50  * contributors may be used to endorse or promote products derived from this
51  * software without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
54  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
57  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */

65
66
67 package org.hsqldb.persist;
68
69 import java.io.File JavaDoc;
70 import java.io.IOException JavaDoc;
71
72 import org.hsqldb.Database;
73 import org.hsqldb.HsqlException;
74 import org.hsqldb.NumberSequence;
75 import org.hsqldb.Session;
76 import org.hsqldb.Table;
77 import org.hsqldb.Trace;
78 import org.hsqldb.lib.FileAccess;
79 import org.hsqldb.lib.HashMap;
80 import org.hsqldb.lib.Iterator;
81 import org.hsqldb.lib.SimpleLog;
82 import org.hsqldb.lib.ZipUnzipFile;
83 import org.hsqldb.scriptio.ScriptReaderBase;
84 import org.hsqldb.scriptio.ScriptWriterBase;
85
86 // fredt@users 20020215 - patch 1.7.0 by fredt
87
// to move operations on the database.properties files to new
88
// class HsqlDatabaseProperties
89
// fredt@users 20020220 - patch 488200 by xclayl@users - throw exception
90
// throw addded to all methods relying on file io
91
// fredt@users 20020221 - patch 513005 by sqlbob@users (RMP)
92
// fredt@users 20020405 - patch 1.7.0 by fredt - no change in db location
93
// because important information about the database is now stored in the
94
// *.properties file, all database files should be in the same folder as the
95
// *.properties file
96
// tony_lai@users 20020820 - export hsqldb.log_size to .properties file
97
// tony_lai@users 20020820 - changes to shutdown compact to save memory
98
// fredt@users 20020910 - patch 1.7.1 by Nitin Chauhan - code improvements
99
// fredt@users 20021208 - ongoing revamp
100
// fredt@users 20021212 - do not rewrite the *.backup file if the *.data
101
// file has not been updated in the current session.
102
// boucherb@users 20030510 - patch 1.7.2 consolidated all periodic database
103
// tasks in one timed task queue
104
// fredt@users - 20050102 patch 1.8.0 - refactoring and clearer separation of concerns
105

106 /**
107  * This class is responsible for managing the database files. An HSQLDB database
108  * consists of a .properties file, a .script file (contains an SQL script),
109  * a .data file (contains data of cached tables) a .backup file
110  * and a .log file.<p>
111  * When using TEXT tables, a data source for each table is also present.<p>
112  *
113  * Notes on OpenOffice.org integration.
114  *
115  * A Storage API is used when HSQLDB is integrated into OpenOffice.org. All
116  * file operations on the 4 main files are performed by OOo, which integrates
117  * the contents of these files into its database file. The script format is
118  * always TEXT in this case.
119  *
120  * Extensively rewritten and extended in successive versions of HSQLDB.
121  *
122  * @author Thomas Mueller (Hypersonic SQL Group)
123  * @author fredt@users.
124  * @version 1.8.0
125  * @since Hypersonic SQL
126  */

127 public class Log {
128
129     private HsqlDatabaseProperties properties;
130     private String JavaDoc fileName;
131     private Database database;
132     private FileAccess fa;
133     private ScriptWriterBase dbLogWriter;
134     private String JavaDoc scriptFileName;
135     private String JavaDoc logFileName;
136     private boolean filesReadOnly;
137     private long maxLogSize;
138     private int writeDelay;
139     private int scriptFormat;
140     private DataFileCache cache;
141
142     Log(Database db) throws HsqlException {
143
144         database = db;
145         fa = db.getFileAccess();
146         fileName = db.getPath();
147         properties = db.getProperties();
148     }
149
150     void initParams() {
151
152         // Allows the user to set log size in the properties file.
153
int logMegas = properties.getIntegerProperty(
154             HsqlDatabaseProperties.hsqldb_log_size, 0);
155
156         maxLogSize = logMegas * 1024 * 1024;
157         scriptFormat = properties.getIntegerProperty(
158             HsqlDatabaseProperties.hsqldb_script_format,
159             ScriptWriterBase.SCRIPT_TEXT_170);
160         writeDelay = properties.getDefaultWriteDelay();
161         filesReadOnly = database.isFilesReadOnly();
162         scriptFileName = fileName + ".script";
163         logFileName = fileName + ".log";
164     }
165
166     /**
167      * When opening a database, the hsqldb.compatible_version property is
168      * used to determine if this version of the engine is equal to or greater
169      * than the earliest version of the engine capable of opening that
170      * database.<p>
171      *
172      * @throws HsqlException
173      */

174     void open() throws HsqlException {
175
176         initParams();
177
178         int state = properties.getDBModified();
179
180         switch (state) {
181
182             case HsqlDatabaseProperties.FILES_MODIFIED :
183                 deleteNewAndOldFiles();
184                 restoreBackup();
185                 processScript();
186                 processDataFile();
187                 processLog();
188                 close(false);
189
190                 if (cache != null) {
191                     cache.open(filesReadOnly);
192                 }
193
194                 reopenAllTextCaches();
195                 break;
196
197             case HsqlDatabaseProperties.FILES_NEW :
198                 try {
199                     deleteBackup();
200                     backupData();
201                     renameNewBackup();
202                     renameNewScript();
203                     deleteLog();
204                     properties.setDBModified(
205                         HsqlDatabaseProperties.FILES_NOT_MODIFIED);
206                 } catch (IOException JavaDoc e) {
207                     database.logger.appLog.logContext(e, null);
208                 }
209
210             // continue as non-modified files
211
case HsqlDatabaseProperties.FILES_NOT_MODIFIED :
212
213                 /**
214                  * if startup is after a SHUTDOWN SCRIPT and there are CACHED
215                  * or TEXT tables, perform a checkpoint so that the .script
216                  * file no longer contains CACHED or TEXT table rows.
217                  */

218                 processScript();
219
220                 if (isAnyCacheModified()) {
221                     properties.setDBModified(
222                         HsqlDatabaseProperties.FILES_MODIFIED);
223                     close(false);
224
225                     if (cache != null) {
226                         cache.open(filesReadOnly);
227                     }
228
229                     reopenAllTextCaches();
230                 }
231                 break;
232         }
233
234         openLog();
235
236         if (!filesReadOnly) {
237             properties.setDBModified(HsqlDatabaseProperties.FILES_MODIFIED);
238         }
239     }
240
241     /**
242      * Close all the database files. If script argument is true, no .data
243      * or .backup file will remain and the .script file will contain all the
244      * data of the cached tables as well as memory tables.
245      *
246      * This is not used for filesReadOnly databases which use shutdown.
247      */

248     void close(boolean script) throws HsqlException {
249
250         closeLog();
251         deleteNewAndOldFiles();
252         writeScript(script);
253         closeAllTextCaches(script);
254
255         if (cache != null) {
256             cache.close(true);
257         }
258
259         properties.setProperty(HsqlDatabaseProperties.db_version,
260                                HsqlDatabaseProperties.THIS_VERSION);
261         properties.setProperty(
262             HsqlDatabaseProperties.hsqldb_compatible_version,
263             HsqlDatabaseProperties.FIRST_COMPATIBLE_VERSION);
264
265         // set this one last to save the props
266
properties.setDBModified(HsqlDatabaseProperties.FILES_NEW);
267         deleteLog();
268
269         if (script) {
270             deleteBackup();
271             deleteData();
272         } else {
273             try {
274                 backupData();
275                 renameNewBackup();
276             } catch (IOException JavaDoc e) {}
277         }
278
279         renameNewScript();
280         properties.setDBModified(HsqlDatabaseProperties.FILES_NOT_MODIFIED);
281     }
282
283     /**
284      * Fast counterpart to close(). Does not perform a checkpoint or a backup
285      * of the .data file.
286      */

287     void shutdown() throws HsqlException {
288
289         synchLog();
290
291         if (cache != null) {
292             cache.close(false);
293         }
294
295         closeAllTextCaches(false);
296         closeLog();
297     }
298
299     /**
300      * Deletes the leftovers from any previous unfinished operations.
301      */

302     void deleteNewAndOldFiles() {
303
304         fa.removeElement(fileName + ".data" + ".old");
305         fa.removeElement(fileName + ".data" + ".new");
306         fa.removeElement(fileName + ".backup" + ".new");
307         fa.removeElement(scriptFileName + ".new");
308     }
309
310     void deleteBackup() {
311         fa.removeElement(fileName + ".backup");
312     }
313
314     void deleteData() {
315         fa.removeElement(fileName + ".data");
316     }
317
318     void backupData() throws IOException JavaDoc {
319
320         if (fa.isStreamElement(fileName + ".data")) {
321             ZipUnzipFile.compressFile(fileName + ".data",
322                                       fileName + ".backup.new",
323                                       database.getFileAccess());
324         }
325     }
326
327     void renameNewBackup() {
328
329         if (fa.isStreamElement(fileName + ".backup.new")) {
330             fa.renameElement(fileName + ".backup.new", fileName + ".backup");
331         }
332     }
333
334     void renameNewScript() {
335
336         if (fa.isStreamElement(scriptFileName + ".new")) {
337             fa.renameElement(scriptFileName + ".new", scriptFileName);
338         }
339     }
340
341     void deleteNewScript() {
342         fa.removeElement(scriptFileName + ".new");
343     }
344
345     void deleteNewBackup() {
346         fa.removeElement(scriptFileName + ".backup.new");
347     }
348
349     void deleteLog() {
350         fa.removeElement(logFileName);
351     }
352
353     /**
354      * Checks all the caches and returns true if the modified flag is set for any
355      */

356     boolean isAnyCacheModified() {
357
358         if (cache != null && cache.isFileModified()) {
359             return true;
360         }
361
362         return isAnyTextCacheModified();
363     }
364
365     /**
366      * Performs checkpoint including pre and post operations. Returns to the
367      * same state as before the checkpoint.
368      */

369     void checkpoint(boolean defrag) throws HsqlException {
370
371         if (filesReadOnly) {
372             return;
373         }
374
375         database.logger.appLog.logContext(SimpleLog.LOG_NORMAL, "start");
376         deleteNewAndOldFiles();
377
378         if (cache != null) {
379             if (forceDefrag()) {
380                 defrag = true;
381             }
382
383             if (defrag) {
384                 try {
385                     cache.defrag();
386                 } catch (Exception JavaDoc e) {}
387             } else {
388                 cache.close(true);
389
390                 try {
391                     cache.backupFile();
392                 } catch (IOException JavaDoc e1) {
393                     deleteNewBackup();
394                     cache.open(false);
395
396                     return;
397                 }
398
399                 cache.open(false);
400             }
401         }
402
403         writeScript(false);
404         properties.setDBModified(HsqlDatabaseProperties.FILES_NEW);
405         closeLog();
406         deleteLog();
407         renameNewScript();
408         renameNewBackup();
409         properties.setDBModified(HsqlDatabaseProperties.FILES_MODIFIED);
410
411         if (dbLogWriter == null) {
412             return;
413         }
414
415         openLog();
416
417         Session[] sessions = database.sessionManager.getAllSessions();
418
419         try {
420             for (int i = 0; i < sessions.length; i++) {
421                 Session session = sessions[i];
422
423                 if (session.isAutoCommit() == false) {
424                     dbLogWriter.writeLogStatement(
425                         session, session.getAutoCommitStatement());
426                 }
427             }
428         } catch (IOException JavaDoc e) {
429             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
430         }
431
432         database.logger.appLog.logContext(SimpleLog.LOG_NORMAL, "end");
433     }
434
435     /**
436      * Returns true if lost space is above the threshold
437      */

438     boolean forceDefrag() {
439
440         long megas = properties.getIntegerProperty(
441             HsqlDatabaseProperties.hsqldb_defrag_limit, 200);
442         long defraglimit = megas * 1024 * 1024;
443         long lostSize = cache.freeBlocks.getLostBlocksSize();
444
445         return lostSize > defraglimit;
446     }
447
448     /**
449      *
450      */

451     boolean hasCache() {
452         return cache != null;
453     }
454
455     /**
456      * Responsible for creating the cache instance.
457      */

458     DataFileCache getCache() throws HsqlException {
459
460 /*
461         if (database.isFilesInJar()) {
462             return null;
463         }
464 */

465         if (cache == null) {
466             cache = new DataFileCache(database, fileName);
467
468             cache.open(filesReadOnly);
469         }
470
471         return cache;
472     }
473
474     int getLogSize() {
475         return (int) (maxLogSize / (1024 * 11024));
476     }
477
478     void setLogSize(int megas) {
479
480         properties.setProperty(HsqlDatabaseProperties.hsqldb_log_size,
481                                String.valueOf(megas));
482
483         maxLogSize = megas * 1024 * 1024;
484     }
485
486     int getScriptType() {
487         return scriptFormat;
488     }
489
490     /**
491      * Changing the script format results in a checkpoint, with the .script
492      * file written in the new format.
493      */

494     void setScriptType(int type) throws HsqlException {
495
496         if (database.isStoredFileAccess()) {
497             return;
498         }
499
500         boolean needsCheckpoint = scriptFormat != type;
501
502         scriptFormat = type;
503
504         properties.setProperty(HsqlDatabaseProperties.hsqldb_script_format,
505                                String.valueOf(scriptFormat));
506
507         if (needsCheckpoint) {
508             database.logger.needsCheckpoint = true;
509         }
510     }
511
512     /**
513      * Write delay specifies the frequency of FileDescriptor.sync() calls.
514      */

515     int getWriteDelay() {
516         return writeDelay;
517     }
518
519     void setWriteDelay(int delay) {
520
521         writeDelay = delay;
522
523         if (dbLogWriter != null) {
524             synchLog();
525             dbLogWriter.setWriteDelay(delay);
526         }
527     }
528
529     /**
530      * Various writeXXX() methods are used for logging statements.
531      */

532     void writeStatement(Session session, String JavaDoc s) throws HsqlException {
533
534         if (s == null || s.length() == 0) {
535             return;
536         }
537
538         try {
539             dbLogWriter.writeLogStatement(session, s);
540         } catch (IOException JavaDoc e) {
541             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
542         }
543
544         if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
545             database.logger.needsCheckpoint = true;
546         }
547     }
548
549     void writeInsertStatement(Session session, Table t,
550                               Object JavaDoc[] row) throws HsqlException {
551
552         try {
553             dbLogWriter.writeInsertStatement(session, t, row);
554         } catch (IOException JavaDoc e) {
555             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
556         }
557
558         if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
559             database.logger.needsCheckpoint = true;
560         }
561     }
562
563     void writeDeleteStatement(Session session, Table t,
564                               Object JavaDoc[] row) throws HsqlException {
565
566         try {
567             dbLogWriter.writeDeleteStatement(session, t, row);
568         } catch (IOException JavaDoc e) {
569             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
570         }
571
572         if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
573             database.logger.needsCheckpoint = true;
574         }
575     }
576
577     void writeSequenceStatement(Session session,
578                                 NumberSequence s) throws HsqlException {
579
580         try {
581             dbLogWriter.writeSequenceStatement(session, s);
582         } catch (IOException JavaDoc e) {
583             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
584         }
585
586         if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
587             database.logger.needsCheckpoint = true;
588         }
589     }
590
591     void writeCommitStatement(Session session) throws HsqlException {
592
593         try {
594             dbLogWriter.writeCommitStatement(session);
595         } catch (IOException JavaDoc e) {
596             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
597         }
598
599         if (maxLogSize > 0 && dbLogWriter.size() > maxLogSize) {
600             database.logger.needsCheckpoint = true;
601         }
602     }
603
604     void synchLog() {
605
606         if (dbLogWriter != null) {
607             dbLogWriter.sync();
608         }
609     }
610
611     /**
612      * Wrappers for openning-starting / stoping-closing the log file and
613      * writer.
614      */

615     private void openLog() throws HsqlException {
616
617         if (filesReadOnly) {
618             return;
619         }
620
621         try {
622             dbLogWriter = ScriptWriterBase.newScriptWriter(database,
623                     logFileName, false, false,
624                     ScriptWriterBase.SCRIPT_TEXT_170);
625
626             dbLogWriter.setWriteDelay(writeDelay);
627             dbLogWriter.start();
628         } catch (Exception JavaDoc e) {
629             throw Trace.error(Trace.FILE_IO_ERROR, logFileName);
630         }
631     }
632
633     private synchronized void closeLog() throws HsqlException {
634
635         if (dbLogWriter != null) {
636             dbLogWriter.close();
637         }
638     }
639
640     /**
641      * Write the .script file as .script.new.
642      */

643     private void writeScript(boolean full) throws HsqlException {
644
645         deleteNewScript();
646
647         //fredt - to do - flag for chache set index
648
ScriptWriterBase scw = ScriptWriterBase.newScriptWriter(database,
649             scriptFileName + ".new", full, true, scriptFormat);
650
651         scw.writeAll();
652         scw.close();
653     }
654
655     /**
656      * Performs all the commands in the .script file.
657      */

658     private void processScript() throws HsqlException {
659
660         ScriptReaderBase scr = null;
661
662         try {
663             if (database.isFilesInJar()
664                     || fa.isStreamElement(scriptFileName)) {
665                 scr = ScriptReaderBase.newScriptReader(database,
666                                                        scriptFileName,
667                                                        scriptFormat);
668
669                 scr.readAll(database.sessionManager.getSysSession(null,
670                         true));
671                 scr.close();
672             }
673         } catch (Throwable JavaDoc e) {
674             if (scr != null) {
675                 scr.close();
676
677                 if (cache != null) {
678                     cache.close(false);
679                 }
680
681                 closeAllTextCaches(false);
682             }
683
684             database.logger.appLog.logContext(e, null);
685
686             if (e instanceof HsqlException) {
687                 throw (HsqlException) e;
688             } else if (e instanceof IOException JavaDoc) {
689                 throw Trace.error(Trace.FILE_IO_ERROR, e.toString());
690             } else if (e instanceof OutOfMemoryError JavaDoc) {
691                 throw Trace.error(Trace.OUT_OF_MEMORY);
692             } else {
693                 throw Trace.error(Trace.GENERAL_ERROR, e.toString());
694             }
695         }
696     }
697
698     /**
699      * Defrag large data files when the sum of .log and .data files is large.
700      */

701     private void processDataFile() throws HsqlException {
702
703         if (cache == null || filesReadOnly || database.isStoredFileAccess()
704                 ||!fa.isStreamElement(logFileName)) {
705             return;
706         }
707
708         File JavaDoc file = new File JavaDoc(logFileName);
709         long logLength = file.length();
710         long dataLength = cache.getFileFreePos();
711
712         if (logLength + dataLength > cache.maxDataFileSize) {
713             database.logger.needsCheckpoint = true;
714         }
715     }
716
717     /**
718      * Performs all the commands in the .log file.
719      */

720     private void processLog() throws HsqlException {
721
722         if (!database.isFilesInJar() && fa.isStreamElement(logFileName)) {
723             ScriptRunner.runScript(database, logFileName,
724                                    ScriptWriterBase.SCRIPT_TEXT_170);
725         }
726     }
727
728     /**
729      * Restores a compressed backup or the .data file.
730      */

731     private void restoreBackup() throws HsqlException {
732
733         // in case data file cannot be deleted, reset it
734
DataFileCache.deleteOrResetFreePos(database, fileName + ".data");
735
736         try {
737             ZipUnzipFile.decompressFile(fileName + ".backup",
738                                         fileName + ".data",
739                                         database.getFileAccess());
740         } catch (Exception JavaDoc e) {
741             throw Trace.error(Trace.FILE_IO_ERROR, Trace.Message_Pair,
742                               new Object JavaDoc[] {
743                 fileName + ".backup", e.toString()
744             });
745         }
746     }
747
748 // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) - text tables
749
private HashMap textCacheList = new HashMap();
750
751     DataFileCache openTextCache(Table table, String JavaDoc source,
752                                 boolean readOnlyData,
753                                 boolean reversed) throws HsqlException {
754
755         closeTextCache(table);
756
757         if (!properties.isPropertyTrue("textdb.allow_full_path")) {
758             if (source.indexOf("..") != -1) {
759                 throw (Trace.error(Trace.ACCESS_IS_DENIED, source));
760             }
761
762             String JavaDoc path = new File JavaDoc(
763                 new File JavaDoc(
764                     database.getPath()
765                     + ".properties").getAbsolutePath()).getParent();
766
767             if (path != null) {
768                 source = path + File.separator + source;
769             }
770         }
771
772         TextCache c;
773         int type;
774
775         if (reversed) {
776             c = new TextCache(table, source);
777         } else {
778             c = new TextCache(table, source);
779         }
780
781         c.open(readOnlyData || filesReadOnly);
782         textCacheList.put(table.getName(), c);
783
784         return c;
785     }
786
787     void closeTextCache(Table table) throws HsqlException {
788
789         TextCache c = (TextCache) textCacheList.remove(table.getName());
790
791         if (c != null) {
792             c.close(true);
793         }
794     }
795
796     private void closeAllTextCaches(boolean compact) throws HsqlException {
797
798         Iterator it = textCacheList.values().iterator();
799
800         while (it.hasNext()) {
801             if (compact) {
802                 ((TextCache) it.next()).purge();
803             } else {
804                 ((TextCache) it.next()).close(true);
805             }
806         }
807     }
808
809     private void reopenAllTextCaches() throws HsqlException {
810
811         Iterator it = textCacheList.values().iterator();
812
813         while (it.hasNext()) {
814             ((TextCache) it.next()).reopen();
815         }
816     }
817
818     private boolean isAnyTextCacheModified() {
819
820         Iterator it = textCacheList.values().iterator();
821
822         while (it.hasNext()) {
823             if (((TextCache) it.next()).isFileModified()) {
824                 return true;
825             }
826         }
827
828         return false;
829     }
830 }
831
Popular Tags