001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.log.FlushedScanHandle
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.store.raw.log;
023:
024: import org.apache.derby.iapi.reference.SQLState;
025:
026: import org.apache.derby.impl.store.raw.log.LogCounter;
027: import org.apache.derby.impl.store.raw.log.LogRecord;
028: import org.apache.derby.impl.store.raw.log.StreamLogScan;
029: import org.apache.derby.iapi.services.io.ArrayInputStream;
030: import org.apache.derby.iapi.services.sanity.SanityManager;
031: import org.apache.derby.iapi.error.StandardException;
032: import org.apache.derby.iapi.store.raw.Loggable;
033: import org.apache.derby.iapi.store.raw.ScanHandle;
034: import org.apache.derby.iapi.store.raw.ScannedTransactionHandle;
035: import org.apache.derby.iapi.store.raw.log.LogFactory;
036: import org.apache.derby.iapi.store.raw.log.LogInstant;
037: import org.apache.derby.iapi.store.raw.xact.TransactionId;
038: import org.apache.derby.iapi.store.access.DatabaseInstant;
039: import java.io.IOException;
040: import java.io.InputStream;
041: import java.util.Enumeration;
042:
043: public class FlushedScanHandle implements ScanHandle {
044: LogFactory lf;
045: StreamLogScan fs;
046:
047: LogRecord lr = null;
048: boolean readOptionalData = false;
049: int groupsIWant;
050:
051: ArrayInputStream rawInput = new ArrayInputStream(new byte[4096]);
052:
053: FlushedScanHandle(LogToFile lf, DatabaseInstant start,
054: int groupsIWant) throws StandardException {
055: this .lf = lf;
056: fs = new FlushedScan(lf, ((LogCounter) start).getValueAsLong());
057: this .groupsIWant = groupsIWant;
058: }
059:
060: public boolean next() throws StandardException {
061: readOptionalData = false;
062: lr = null;
063:
064: // filter the log stream so that only log records that belong to these
065: // interesting groups will be returned
066:
067: try {
068: lr = fs.getNextRecord(rawInput, null, groupsIWant);
069: if (lr == null)
070: return false; //End of flushed log
071: if (SanityManager.DEBUG) {
072: if ((groupsIWant & lr.group()) == 0)
073: SanityManager.THROWASSERT(groupsIWant + "/"
074: + lr.group());
075: }
076:
077: return true;
078: } catch (IOException ioe) {
079: ioe.printStackTrace();
080: fs.close();
081: fs = null;
082: throw lf.markCorrupt(StandardException.newException(
083: SQLState.LOG_IO_ERROR, ioe));
084: }
085: }
086:
087: /**
088: Get the group for the current log record.
089: @exception StandardException Oops
090: */
091: public int getGroup() throws StandardException {
092: return lr.group();
093: }
094:
095: /**
096: Get the Loggable associated with the currentLogRecord
097: @exception StandardException Oops
098: */
099: public Loggable getLoggable() throws StandardException {
100: try {
101: return lr.getLoggable();
102: }
103:
104: catch (IOException ioe) {
105: ioe.printStackTrace();
106: fs.close();
107: fs = null;
108: throw lf.markCorrupt(StandardException.newException(
109: SQLState.LOG_IO_ERROR, ioe));
110: }
111:
112: catch (ClassNotFoundException cnfe) {
113: fs.close();
114: fs = null;
115: throw lf.markCorrupt(StandardException.newException(
116: SQLState.LOG_CORRUPTED, cnfe));
117: }
118: }
119:
120: //This may be called only once per log record.
121: public InputStream getOptionalData() throws StandardException {
122: if (SanityManager.DEBUG)
123: SanityManager.ASSERT(!readOptionalData);
124: if (lr == null)
125: return null;
126: try {
127: int dataLength = rawInput.readInt();
128: readOptionalData = true;
129: rawInput.setLimit(rawInput.getPosition(), dataLength);
130: return rawInput;
131: }
132:
133: catch (IOException ioe) {
134: fs.close();
135: fs = null;
136: throw lf.markCorrupt(StandardException.newException(
137: SQLState.LOG_IO_ERROR, ioe));
138: }
139: }
140:
141: public DatabaseInstant getInstant() throws StandardException {
142: return fs.getLogInstant();
143: }
144:
145: public Object getTransactionId() throws StandardException {
146: try {
147: return lr.getTransactionId();
148: } catch (IOException ioe) {
149: ioe.printStackTrace();
150: fs.close();
151: fs = null;
152: throw lf.markCorrupt(StandardException.newException(
153: SQLState.LOG_IO_ERROR, ioe));
154: } catch (ClassNotFoundException cnfe) {
155: fs.close();
156: fs = null;
157: throw lf.markCorrupt(StandardException.newException(
158: SQLState.LOG_CORRUPTED, cnfe));
159: }
160: }
161:
162: public void close() {
163: if (fs != null)
164: fs.close();
165: fs = null;
166: }
167: }
|