1 | /* |
2 | |
3 | Derby - Class org.apache.derby.impl.store.raw.log.FlushedScanHandle |
4 | |
5 | Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.impl.store.raw.log; |
22 | |
23 | import org.apache.derby.iapi.reference.SQLState; |
24 | |
25 | import org.apache.derby.impl.store.raw.log.LogCounter; |
26 | import org.apache.derby.impl.store.raw.log.LogRecord; |
27 | import org.apache.derby.impl.store.raw.log.StreamLogScan; |
28 | import org.apache.derby.iapi.services.io.ArrayInputStream; |
29 | import org.apache.derby.iapi.services.sanity.SanityManager; |
30 | import org.apache.derby.iapi.error.StandardException; |
31 | import org.apache.derby.iapi.store.raw.Loggable; |
32 | import org.apache.derby.iapi.store.raw.ScanHandle; |
33 | import org.apache.derby.iapi.store.raw.ScannedTransactionHandle; |
34 | import org.apache.derby.iapi.store.raw.log.LogFactory; |
35 | import org.apache.derby.iapi.store.raw.log.LogInstant; |
36 | import org.apache.derby.iapi.store.raw.xact.TransactionId; |
37 | import org.apache.derby.iapi.store.access.DatabaseInstant; |
38 | import java.io.IOException; |
39 | import java.io.InputStream; |
40 | import java.util.Enumeration; |
41 | |
42 | public class FlushedScanHandle implements ScanHandle |
43 | { |
44 | LogFactory lf; |
45 | StreamLogScan fs; |
46 | |
47 | LogRecord lr = null; |
48 | boolean readOptionalData = false; |
49 | int groupsIWant; |
50 | |
51 | ArrayInputStream rawInput = new ArrayInputStream(new byte[4096]); |
52 | |
53 | FlushedScanHandle(LogToFile lf, DatabaseInstant start, int groupsIWant) |
54 | throws StandardException |
55 | { |
56 | this.lf = lf; |
57 | fs = new FlushedScan(lf,((LogCounter)start).getValueAsLong()); |
58 | this.groupsIWant = groupsIWant; |
59 | } |
60 | |
61 | public boolean next() throws StandardException |
62 | { |
63 | readOptionalData = false; |
64 | lr = null; |
65 | |
66 | // filter the log stream so that only log records that belong to these |
67 | // interesting groups will be returned |
68 | |
69 | try |
70 | { |
71 | lr = fs.getNextRecord(rawInput,null, groupsIWant); |
72 | if (lr==null) return false; //End of flushed log |
73 | if (SanityManager.DEBUG) |
74 | { |
75 | if ((groupsIWant & lr.group()) == 0) |
76 | SanityManager.THROWASSERT(groupsIWant + "/" + lr.group()); |
77 | } |
78 | |
79 | return true; |
80 | } |
81 | catch (IOException ioe) |
82 | { |
83 | ioe.printStackTrace(); |
84 | fs.close(); |
85 | fs = null; |
86 | throw lf.markCorrupt( |
87 | StandardException.newException(SQLState.LOG_IO_ERROR, ioe)); |
88 | } |
89 | } |
90 | |
91 | /** |
92 | Get the group for the current log record. |
93 | @exception StandardException Oops |
94 | */ |
95 | public int getGroup() throws StandardException |
96 | { |
97 | return lr.group(); |
98 | } |
99 | |
100 | /** |
101 | Get the Loggable associated with the currentLogRecord |
102 | @exception StandardException Oops |
103 | */ |
104 | public Loggable getLoggable() throws StandardException |
105 | { |
106 | try { |
107 | return lr.getLoggable(); |
108 | } |
109 | |
110 | catch (IOException ioe) |
111 | { |
112 | ioe.printStackTrace(); |
113 | fs.close(); |
114 | fs = null; |
115 | throw lf.markCorrupt( |
116 | StandardException.newException(SQLState.LOG_IO_ERROR, ioe)); |
117 | } |
118 | |
119 | catch (ClassNotFoundException cnfe) |
120 | { |
121 | fs.close(); |
122 | fs = null; |
123 | throw lf.markCorrupt( |
124 | StandardException.newException(SQLState.LOG_CORRUPTED, cnfe)); |
125 | } |
126 | } |
127 | |
128 | //This may be called only once per log record. |
129 | public InputStream getOptionalData() |
130 | throws StandardException |
131 | { |
132 | if (SanityManager.DEBUG) SanityManager.ASSERT(!readOptionalData); |
133 | if (lr == null) return null; |
134 | try |
135 | { |
136 | int dataLength = rawInput.readInt(); |
137 | readOptionalData = true; |
138 | rawInput.setLimit(rawInput.getPosition(), dataLength); |
139 | return rawInput; |
140 | } |
141 | |
142 | catch (IOException ioe) |
143 | { |
144 | fs.close(); |
145 | fs = null; |
146 | throw lf.markCorrupt( |
147 | StandardException.newException(SQLState.LOG_IO_ERROR, ioe)); |
148 | } |
149 | } |
150 | |
151 | public DatabaseInstant getInstant() |
152 | throws StandardException |
153 | { |
154 | return fs.getLogInstant(); |
155 | } |
156 | |
157 | public Object getTransactionId() |
158 | throws StandardException |
159 | { |
160 | try |
161 | { |
162 | return lr.getTransactionId(); |
163 | } |
164 | catch (IOException ioe) |
165 | { |
166 | ioe.printStackTrace(); |
167 | fs.close(); |
168 | fs = null; |
169 | throw lf.markCorrupt( |
170 | StandardException.newException(SQLState.LOG_IO_ERROR, ioe)); |
171 | } |
172 | catch (ClassNotFoundException cnfe) |
173 | { |
174 | fs.close(); |
175 | fs = null; |
176 | throw lf.markCorrupt( |
177 | StandardException.newException(SQLState.LOG_CORRUPTED, cnfe)); |
178 | } |
179 | } |
180 | |
181 | public void close() |
182 | { |
183 | if (fs != null) fs.close(); |
184 | fs = null; |
185 | } |
186 | } |