001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.lucene.store.jdbc.index;
018:
019: import java.io.IOException;
020: import java.sql.Blob;
021: import java.sql.PreparedStatement;
022: import java.sql.ResultSet;
023:
024: import org.apache.lucene.store.IndexInput;
025: import org.apache.lucene.store.jdbc.JdbcDirectory;
026: import org.apache.lucene.store.jdbc.JdbcFileEntrySettings;
027: import org.apache.lucene.store.jdbc.JdbcStoreException;
028: import org.apache.lucene.store.jdbc.support.JdbcTemplate;
029:
030: /**
031: * An <code>IndexInput</code> implementation that will read all the relevant data from the
032: * database when created, and will cache it untill it is closed.
033: * <p/>
034: * Used for small file entries in the database like the segments file.
035: *
036: * @author kimchy
037: */
038: public class FetchOnOpenJdbcIndexInput extends IndexInput implements
039: JdbcIndexConfigurable {
040:
041: //There is no synchronizaiton since Lucene RAMDirecoty performs no synchronizations.
042: // Need to get to the bottom of it.
043:
044: private int length;
045:
046: private int position = 0;
047:
048: private byte[] data;
049:
050: public void configure(final String name,
051: final JdbcDirectory jdbcDirectory,
052: JdbcFileEntrySettings settings) throws IOException {
053: jdbcDirectory.getJdbcTemplate().executeSelect(
054: jdbcDirectory.getTable().sqlSelectSizeValueByName(),
055: new JdbcTemplate.ExecuteSelectCallback() {
056: public void fillPrepareStatement(
057: PreparedStatement ps) throws Exception {
058: ps.setFetchSize(1);
059: ps.setString(1, name);
060: }
061:
062: public Object execute(ResultSet rs)
063: throws Exception {
064: if (!rs.next()) {
065: throw new JdbcStoreException(
066: "No entry for [" + name
067: + "] table "
068: + jdbcDirectory.getTable());
069: }
070: length = rs.getInt(3);
071:
072: Blob blob = rs.getBlob(2);
073: data = blob.getBytes(1, length);
074: if (data.length != length) {
075: throw new IOException("read past EOF");
076: }
077: return null;
078: }
079: });
080: }
081:
082: public byte readByte() throws IOException {
083: return data[position++];
084: }
085:
086: public void readBytes(byte[] b, int offset, int len)
087: throws IOException {
088: System.arraycopy(data, position, b, offset, len);
089: position += len;
090: }
091:
092: public void close() throws IOException {
093:
094: }
095:
096: public long getFilePointer() {
097: return position;
098: }
099:
100: public void seek(long pos) throws IOException {
101: position = (int) pos;
102: }
103:
104: public long length() {
105: return this.length;
106: }
107: }
|