1 30 31 32 package org.hsqldb.scriptio; 33 34 import java.io.BufferedOutputStream ; 35 import java.io.IOException ; 36 import java.io.OutputStream ; 37 38 import org.hsqldb.HsqlNameManager.HsqlName; 39 import org.hsqldb.Database; 40 import org.hsqldb.DatabaseManager; 41 import org.hsqldb.DatabaseScript; 42 import org.hsqldb.HsqlException; 43 import org.hsqldb.NumberSequence; 44 import org.hsqldb.Result; 45 import org.hsqldb.Session; 46 import org.hsqldb.Table; 47 import org.hsqldb.Token; 48 import org.hsqldb.Trace; 49 import org.hsqldb.index.RowIterator; 50 import org.hsqldb.lib.FileAccess; 51 import org.hsqldb.lib.FileUtil; 52 import org.hsqldb.lib.HsqlTimer; 53 import org.hsqldb.lib.Iterator; 54 55 59 85 public abstract class ScriptWriterBase implements Runnable { 86 87 Database database; 88 String outFile; 89 OutputStream fileStreamOut; 90 FileAccess.FileSync outDescriptor; 91 int tableRowCount; 92 HsqlName schemaToLog; 93 94 98 boolean isDump; 99 boolean includeCachedData; 100 long byteCount; 101 volatile boolean needsSync; 102 volatile boolean forceSync; 103 volatile boolean busyWriting; 104 private int syncCount; 105 static final int INSERT = 0; 106 static final int INSERT_WITH_SCHEMA = 1; 107 108 109 Session currentSession; 110 public static final String [] LIST_SCRIPT_FORMATS = new String [] { 111 Token.T_TEXT, Token.T_BINARY, null, Token.T_COMPRESSED 112 }; 113 public static final int SCRIPT_TEXT_170 = 0; 114 public static final int SCRIPT_BINARY_172 = 1; 115 public static final int SCRIPT_ZIPPED_BINARY_172 = 3; 116 117 public static ScriptWriterBase newScriptWriter(Database db, String file, 118 boolean includeCachedData, boolean newFile, 119 int scriptType) throws HsqlException { 120 121 if (scriptType == SCRIPT_TEXT_170) { 122 return new ScriptWriterText(db, file, includeCachedData, newFile, 123 false); 124 } else if (scriptType == SCRIPT_BINARY_172) { 125 return new ScriptWriterBinary(db, file, includeCachedData, 126 newFile); 127 } else { 128 return new ScriptWriterZipped(db, file, includeCachedData, 129 newFile); 130 } 131 } 132 133 ScriptWriterBase() {} 134 135 ScriptWriterBase(Database db, String file, boolean includeCachedData, 136 boolean isNewFile, boolean isDump) throws HsqlException { 137 138 this.isDump = isDump; 139 140 initBuffers(); 141 142 boolean exists = false; 143 144 if (isDump) { 145 exists = FileUtil.exists(file); 146 } else { 147 exists = db.getFileAccess().isStreamElement(file); 148 } 149 150 if (exists && isNewFile) { 151 throw Trace.error(Trace.FILE_IO_ERROR, file); 152 } 153 154 this.database = db; 155 this.includeCachedData = includeCachedData; 156 outFile = file; 157 currentSession = database.sessionManager.getSysSession(); 158 159 schemaToLog = currentSession.loggedSchema = 161 currentSession.currentSchema; 162 163 openFile(); 164 } 165 166 public void reopen() throws HsqlException { 167 openFile(); 168 } 169 170 protected abstract void initBuffers(); 171 172 175 public synchronized void sync() { 176 177 if (needsSync && fileStreamOut != null) { 178 if (busyWriting) { 179 forceSync = true; 180 181 return; 182 } 183 184 try { 185 fileStreamOut.flush(); 186 outDescriptor.sync(); 187 188 syncCount++; 189 } catch (IOException e) { 190 Trace.printSystemOut("flush() or sync() error: " 191 + e.toString()); 192 } 193 194 needsSync = false; 195 forceSync = false; 196 } 197 } 198 199 public void close() throws HsqlException { 200 201 stop(); 202 203 try { 204 if (fileStreamOut != null) { 205 fileStreamOut.flush(); 206 fileStreamOut.close(); 207 208 fileStreamOut = null; 209 } 210 } catch (IOException e) { 211 throw Trace.error(Trace.FILE_IO_ERROR); 212 } 213 214 byteCount = 0; 215 } 216 217 public long size() { 218 return byteCount; 219 } 220 221 public void writeAll() throws HsqlException { 222 223 try { 224 writeDDL(); 225 writeExistingData(); 226 finishStream(); 227 } catch (IOException e) { 228 throw Trace.error(Trace.FILE_IO_ERROR); 229 } 230 } 231 232 236 protected void openFile() throws HsqlException { 237 238 try { 239 FileAccess fa = isDump ? FileUtil.getDefaultInstance() 240 : database.getFileAccess(); 241 OutputStream fos = fa.openOutputStreamElement(outFile); 242 243 outDescriptor = fa.getFileSync(fos); 244 fileStreamOut = new BufferedOutputStream (fos, 2 << 12); 245 } catch (IOException e) { 246 throw Trace.error(Trace.FILE_IO_ERROR, Trace.Message_Pair, 247 new Object [] { 248 e.toString(), outFile 249 }); 250 } 251 } 252 253 257 protected void finishStream() throws IOException {} 258 259 protected void writeDDL() throws IOException , HsqlException { 260 261 Result ddlPart = DatabaseScript.getScript(database, 262 !includeCachedData); 263 264 writeSingleColumnResult(ddlPart); 265 } 266 267 protected void writeExistingData() throws HsqlException, IOException { 268 269 currentSession.loggedSchema = null; 271 272 Iterator schemas = database.schemaManager.userSchemaNameIterator(); 273 274 while (schemas.hasNext()) { 275 String schema = (String ) schemas.next(); 276 Iterator tables = database.schemaManager.tablesIterator(schema); 277 278 while (tables.hasNext()) { 279 Table t = (Table) tables.next(); 280 281 boolean script = false; 286 287 switch (t.getTableType()) { 288 289 case Table.MEMORY_TABLE : 290 script = true; 291 break; 292 293 case Table.CACHED_TABLE : 294 script = includeCachedData; 295 break; 296 297 case Table.TEXT_TABLE : 298 script = includeCachedData &&!t.isReadOnly(); 299 break; 300 } 301 302 try { 303 if (script) { 304 schemaToLog = t.getName().schema; 305 306 writeTableInit(t); 307 308 RowIterator it = t.rowIterator(currentSession); 309 310 while (it.hasNext()) { 311 writeRow(currentSession, t, it.next().getData()); 312 } 313 314 writeTableTerm(t); 315 } 316 } catch (Exception e) { 317 throw Trace.error(Trace.ASSERT_FAILED, e.toString()); 318 } 319 } 320 } 321 322 writeDataTerm(); 323 } 324 325 protected void writeTableInit(Table t) 326 throws HsqlException, IOException {} 327 328 protected void writeTableTerm(Table t) throws HsqlException, IOException { 329 330 if (t.isDataReadOnly() &&!t.isTemp() &&!t.isText()) { 331 StringBuffer a = new StringBuffer ("SET TABLE "); 332 333 a.append(t.getName().statementName); 334 a.append(" READONLY TRUE"); 335 writeLogStatement(currentSession, a.toString()); 336 } 337 } 338 339 protected void writeSingleColumnResult(Result r) 340 throws HsqlException, IOException { 341 342 Iterator it = r.iterator(); 343 344 while (it.hasNext()) { 345 Object [] data = (Object []) it.next(); 346 347 writeLogStatement(currentSession, (String ) data[0]); 348 } 349 } 350 351 abstract void writeRow(Session session, Table table, 352 Object [] data) throws HsqlException, IOException ; 353 354 protected abstract void writeDataTerm() throws IOException ; 355 356 protected abstract void addSessionId(Session session) throws IOException ; 357 358 public abstract void writeLogStatement(Session session, 359 String s) 360 throws IOException , HsqlException; 361 362 public abstract void writeInsertStatement(Session session, Table table, 363 Object [] data) throws HsqlException, IOException ; 364 365 public abstract void writeDeleteStatement(Session session, Table table, 366 Object [] data) throws HsqlException, IOException ; 367 368 public abstract void writeSequenceStatement(Session session, 369 NumberSequence seq) throws HsqlException, IOException ; 370 371 public abstract void writeCommitStatement(Session session) 372 throws HsqlException, IOException ; 373 374 private Object timerTask; 376 377 protected volatile int writeDelay = 60000; 379 380 public void run() { 381 382 try { 383 if (writeDelay != 0) { 384 sync(); 385 } 386 387 } catch (Exception e) { 389 390 if (Trace.TRACE) { 393 Trace.printSystemOut(e.toString()); 394 } 395 } 396 } 397 398 public void setWriteDelay(int delay) { 399 400 writeDelay = delay; 401 402 int period = writeDelay == 0 ? 1000 403 : writeDelay; 404 405 HsqlTimer.setPeriod(timerTask, period); 406 } 407 408 public void start() { 409 410 int period = writeDelay == 0 ? 1000 411 : writeDelay; 412 413 timerTask = DatabaseManager.getTimer().schedulePeriodicallyAfter(0, 414 period, this, false); 415 } 416 417 public void stop() { 418 419 if (timerTask != null) { 420 HsqlTimer.cancel(timerTask); 421 422 timerTask = null; 423 } 424 } 425 426 public int getWriteDelay() { 427 return writeDelay; 428 } 429 } 430 | Popular Tags |