001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.command.dml;
007:
008: import java.io.BufferedInputStream;
009: import java.io.BufferedOutputStream;
010: import java.io.IOException;
011: import java.io.InputStream;
012: import java.io.OutputStream;
013: import java.sql.SQLException;
014:
015: import org.h2.command.Prepared;
016: import org.h2.constant.ErrorCode;
017: import org.h2.constant.SysProperties;
018: import org.h2.engine.Constants;
019: import org.h2.engine.Database;
020: import org.h2.engine.Session;
021: import org.h2.message.Message;
022: import org.h2.security.SHA256;
023: import org.h2.store.DataHandler;
024: import org.h2.store.FileStore;
025: import org.h2.store.FileStoreInputStream;
026: import org.h2.store.FileStoreOutputStream;
027: import org.h2.tools.CompressTool;
028: import org.h2.util.FileUtils;
029: import org.h2.util.IOUtils;
030: import org.h2.util.SmallLRUCache;
031: import org.h2.value.Value;
032:
033: /**
034: * This class is the base for RunScriptCommand and ScriptCommand.
035: */
036: public abstract class ScriptBase extends Prepared implements
037: DataHandler {
038:
039: /**
040: * The output stream.
041: */
042: protected OutputStream out;
043:
044: /**
045: * The input stream.
046: */
047: protected InputStream in;
048:
049: /**
050: * The file name (if set).
051: */
052: protected String fileName;
053:
054: private String cipher;
055: private byte[] key;
056: private FileStore store;
057: private String compressionAlgorithm;
058:
059: public ScriptBase(Session session) {
060: super (session);
061: }
062:
063: public void setCipher(String c) {
064: cipher = c;
065: }
066:
067: protected boolean isEncrypted() {
068: return cipher != null;
069: }
070:
071: public void setPassword(char[] password) {
072: SHA256 sha = new SHA256();
073: key = sha.getKeyPasswordHash("script", password);
074: }
075:
076: public void setFileName(String fileName) {
077: if (fileName == null || fileName.trim().length() == 0) {
078: fileName = "script.sql";
079: }
080: this .fileName = SysProperties.scriptDirectory + fileName;
081: }
082:
083: public boolean isTransactional() {
084: return false;
085: }
086:
087: protected void deleteStore() throws SQLException {
088: if (fileName != null) {
089: FileUtils.delete(fileName);
090: }
091: }
092:
093: private void initStore() throws SQLException {
094: byte[] magic = Database.getMagic(true);
095: Database db = session.getDatabase();
096: // script files are always in text format
097: store = FileStore.open(db, fileName, "rw", magic, cipher, key);
098: store.setCheckedWriting(false);
099: store.init();
100: }
101:
102: protected void openOutput() throws SQLException {
103: if (fileName == null) {
104: return;
105: }
106: if (isEncrypted()) {
107: initStore();
108: out = new FileStoreOutputStream(store, this ,
109: compressionAlgorithm);
110: // always use a big buffer, otherwise end-of-block is written a lot
111: out = new BufferedOutputStream(out,
112: Constants.IO_BUFFER_SIZE_COMPRESS);
113: } else {
114: OutputStream o = FileUtils.openFileOutputStream(fileName,
115: false);
116: out = new BufferedOutputStream(o, Constants.IO_BUFFER_SIZE);
117: out = CompressTool.wrapOutputStream(out,
118: compressionAlgorithm, Constants.SCRIPT_SQL);
119: }
120: }
121:
122: protected void openInput() throws SQLException {
123: if (fileName == null) {
124: return;
125: }
126: if (isEncrypted()) {
127: initStore();
128: in = new FileStoreInputStream(store, this ,
129: compressionAlgorithm != null, false);
130: } else {
131: InputStream inStream;
132: try {
133: inStream = FileUtils.openFileInputStream(fileName);
134: } catch (IOException e) {
135: throw Message.convertIOException(e, fileName);
136: }
137: in = new BufferedInputStream(inStream,
138: Constants.IO_BUFFER_SIZE);
139: in = CompressTool.wrapInputStream(in, compressionAlgorithm,
140: Constants.SCRIPT_SQL);
141: if (in == null) {
142: throw Message.getSQLException(
143: ErrorCode.FILE_NOT_FOUND_1,
144: Constants.SCRIPT_SQL + " in " + fileName);
145: }
146: }
147: }
148:
149: protected void closeIO() {
150: IOUtils.closeSilently(out);
151: out = null;
152: IOUtils.closeSilently(in);
153: in = null;
154: if (store != null) {
155: store.closeSilently();
156: store = null;
157: }
158: }
159:
160: public boolean needRecompile() {
161: return false;
162: }
163:
164: public boolean getTextStorage() {
165: // script files are always in text format
166: return true;
167: }
168:
169: public String getDatabasePath() {
170: return null;
171: }
172:
173: public FileStore openFile(String name, String mode,
174: boolean mustExist) throws SQLException {
175: return null;
176: }
177:
178: public int getChecksum(byte[] data, int start, int end) {
179: return session.getDatabase().getChecksum(data, start, end);
180: }
181:
182: public void checkPowerOff() throws SQLException {
183: session.getDatabase().checkPowerOff();
184: }
185:
186: public void checkWritingAllowed() throws SQLException {
187: session.getDatabase().checkWritingAllowed();
188: }
189:
190: public void freeUpDiskSpace() throws SQLException {
191: session.getDatabase().checkWritingAllowed();
192: }
193:
194: public void handleInvalidChecksum() throws SQLException {
195: session.getDatabase().handleInvalidChecksum();
196: }
197:
198: public int compareTypeSave(Value a, Value b) throws SQLException {
199: throw Message.getInternalError();
200: }
201:
202: public int getMaxLengthInplaceLob() {
203: return session.getDatabase().getMaxLengthInplaceLob();
204: }
205:
206: public int allocateObjectId(boolean b, boolean c) {
207: return session.getDatabase().allocateObjectId(b, c);
208: }
209:
210: public String createTempFile() throws SQLException {
211: return session.getDatabase().createTempFile();
212: }
213:
214: public String getLobCompressionAlgorithm(int type) {
215: return session.getDatabase().getLobCompressionAlgorithm(type);
216: }
217:
218: public void setCompressionAlgorithm(String algorithm) {
219: this .compressionAlgorithm = algorithm;
220: }
221:
222: public Object getLobSyncObject() {
223: return this ;
224: }
225:
226: public boolean getLobFilesInDirectories() {
227: return session.getDatabase().getLobFilesInDirectories();
228: }
229:
230: public SmallLRUCache getLobFileListCache() {
231: return null;
232: }
233:
234: }
|