001: package com.quadcap.sql.file;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.Externalizable;
042: import java.io.IOException;
043: import java.io.ObjectInput;
044: import java.io.ObjectOutput;
045:
046: import java.util.Vector;
047:
048: import java.sql.SQLException;
049:
050: import com.quadcap.sql.io.Extern;
051: import com.quadcap.sql.io.Externable;
052:
053: import com.quadcap.sql.lock.Transaction;
054:
055: import com.quadcap.util.Debug;
056:
057: /**
058: * An entry in the log. For 'STEP' items, which represent actions
059: * in the database, the first byte is the 'redo state', which is
060: * initially zero (DONE) and is overwritten to one (UNDONE) if the
061: * step is 'undone' as part of a rollback.
062: *
063: * @author Stan Bailes
064: */
065: public class LogEntry implements LogOp, Externable {
066: // codes
067: public static final int BEGIN_TRANSACTION = 1;
068: public static final int BEGIN_STATEMENT = 2;
069: public static final int COMMIT = 3;
070: public static final int ROLLBACK = 4;
071: public static final int CHECKPOINT = 5;
072: public static final int BLOCK_WRITE = 6;
073: public static final int CLOSE = 7;
074: public static final int FLUSH = 8;
075: public static final int STEP = 9;
076: public static final int SYNC = 10;
077: public static final int MAX_CODES = 11;
078:
079: // redo states
080: public static final int DONE = 0;
081: public static final int UNDONE = 1;
082:
083: int redoState = DONE;
084: int code;
085: long transId = -1;
086: int stmtId = -1;
087: int prev = -1;
088:
089: // my position in the log file, only valid for log entries
090: // which have been read from the file.
091: transient int position;
092:
093: public LogEntry() {
094: }
095:
096: public LogEntry(int code) {
097: this .code = code;
098: }
099:
100: public LogEntry(long transId, int code) {
101: this .transId = transId;
102: this .code = code;
103: }
104:
105: public LogEntry(long transId, int stmtId, int code) {
106: this .transId = transId;
107: this .stmtId = stmtId;
108: this .code = code;
109: }
110:
111: public final int getCode() {
112: return code;
113: }
114:
115: /**
116: * Bind this LogEntry to a transaction
117: */
118: public final void setTransactionId(long transId) {
119: this .transId = transId;
120: }
121:
122: /**
123: * Return the transaction ID for this entry
124: */
125: public final long getTransactionId() {
126: return transId;
127: }
128:
129: /**
130: * Bind this LogEntry to a statement
131: */
132: public final void setStatementId(int stmtId) {
133: this .stmtId = stmtId;
134: }
135:
136: /**
137: * Return the statement ID for this entry
138: */
139: public final int getStatementId() {
140: return stmtId;
141: }
142:
143: public final int getPosition() {
144: return position;
145: }
146:
147: final void setPosition(int position) {
148: this .position = position;
149: }
150:
151: final void setPrev(int prev) {
152: this .prev = prev;
153: }
154:
155: final int getPrev() {
156: return prev;
157: }
158:
159: public final int getRedoState() {
160: return redoState;
161: }
162:
163: public final void setRedoState(int redo) {
164: redoState = redo;
165: }
166:
167: public void readExternal(ObjectInput in) throws IOException,
168: ClassNotFoundException {
169: redoState = in.read();
170: code = in.read();
171: transId = in.readLong();
172: stmtId = in.readInt();
173: prev = in.readInt();
174: }
175:
176: public void writeExternal(ObjectOutput out) throws IOException {
177: out.write(redoState);
178: out.write(code);
179: out.writeLong(transId);
180: out.writeInt(stmtId);
181: out.writeInt(prev);
182: }
183:
184: //#ifdef DEBUG
185: public String toString() {
186: StringBuffer sb = new StringBuffer();
187: sb.append("[T");
188: sb.append(Long.toString(transId));
189: if (stmtId >= 0) {
190: sb.append(",");
191: sb.append(String.valueOf(stmtId));
192: }
193: sb.append("] (pos=" + position + " prev=" + prev + ") ");
194: switch (code) {
195: case BEGIN_TRANSACTION:
196: sb.append("BEGIN TRANSACTION");
197: break;
198: case BEGIN_STATEMENT:
199: sb.append("BEGIN_STATEMENT");
200: break;
201: case COMMIT:
202: sb.append("COMMIT");
203: break;
204: case ROLLBACK:
205: sb.append("ROLLBACK");
206: break;
207: case CHECKPOINT:
208: sb.append("CHECKPOINT");
209: break;
210: case BLOCK_WRITE:
211: sb.append("BLOCK_WRITE");
212: break;
213: case FLUSH:
214: sb.append("FLUSH");
215: break;
216: case CLOSE:
217: sb.append("CLOSE");
218: break;
219: case SYNC:
220: sb.append("SYNC");
221: break;
222: case STEP:
223: String s = this .getClass().getName();
224: int idx = s.lastIndexOf('.');
225: if (idx > 0)
226: s = s.substring(idx + 1);
227: s = s + ((redoState == DONE) ? "" : " [UNDONE]");
228: sb.append("STEP " + s);
229: break;
230: default:
231: sb.append(Integer.toString(code));
232: break;
233: }
234: return sb.toString();
235: }
236:
237: //#endif
238:
239: static Extern extern = null;
240:
241: public Extern getExtern() {
242: return extern;
243: }
244:
245: public void setExtern(Extern extern) {
246: LogEntry.extern = extern;
247: }
248:
249: public void handle(Log log) throws Exception {
250: log.reallyAddEntry(this );
251: }
252:
253: /**
254: * Do the actual work necessary to perform this logged operation.
255: * In this base class, there's nothing to do.
256: */
257: public void redo(Transaction t, Datafile db) throws IOException,
258: DatafileException {
259: }
260:
261: /**
262: * Do the actual work necessary to undo this logged operation.
263: * In this base class, there's nothing to do.
264: */
265: public void undo(Transaction t, Datafile db) throws IOException,
266: DatafileException {
267: }
268:
269: public void discard(Datafile db) throws IOException {
270: }
271: }
|