001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc.sql.conv;
012:
013: import com.versant.core.jdbc.JdbcConverter;
014: import com.versant.core.jdbc.JdbcConverterFactory;
015: import com.versant.core.jdbc.JdbcTypeRegistry;
016: import com.versant.core.jdbc.metadata.JdbcColumn;
017:
018: import java.sql.PreparedStatement;
019: import java.sql.SQLException;
020: import java.sql.ResultSet;
021:
022: import javax.jdo.JDOFatalDataStoreException; //todo: appears only in throws-clause
023:
024: import org.polepos.teams.jdo.*;
025:
026: import com.versant.core.common.BindingSupportImpl;
027:
028: // import oracle.sql.BLOB;
029:
030: /**
031: * This converter converts byte[] stored in Oracle BLOB columns to
032: * and from SQL.
033: * @keep-all
034: */
035: public class OracleBlobConverter implements JdbcConverter {
036:
037: public OracleBlobConverter() {
038: VoaEdited.exception();
039: }
040:
041: public static class Factory extends NoArgJdbcConverterFactory {
042:
043: private OracleBlobConverter converter;
044:
045: /**
046: * Create a converter for col using args as parameters. Return null if
047: * no converter is required.
048: */
049: public JdbcConverter createJdbcConverter(JdbcColumn col,
050: Object args, JdbcTypeRegistry jdbcTypeRegistry) {
051: if (converter == null)
052: converter = new OracleBlobConverter();
053: return converter;
054: }
055:
056: }
057:
058: private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
059:
060: /**
061: * Is this converter for an Oracle style LOB column? Oracle LOBs require
062: * a hard coded a value into the insert/update statement instead of using
063: * a replaceable parameter and then select the value (if not null) and
064: * modify it.
065: */
066: public boolean isOracleStyleLOB() {
067: return true;
068: }
069:
070: /**
071: * This is only called if isOracleStyleLOB returns true. Get the String
072: * to be embedded in an SQL insert/update statement when the value for
073: * this column is not null (e.g. "empty_clob()");
074: */
075: public String getOracleStyleLOBNotNullString() {
076: return "empty_blob()";
077: }
078:
079: /**
080: * Get the value of col from rs at position index.
081: * @exception SQLException on SQL errors
082: * @exception JDOFatalDataStoreException if the ResultSet value is invalid
083: */
084: public Object get(ResultSet rs, int index, JdbcColumn col)
085: throws SQLException, JDOFatalDataStoreException {
086:
087: VoaEdited.exception();
088: return null;
089:
090: // BLOB blob = (BLOB)rs.getBlob(index);
091: // if (blob == null || blob.isEmptyLob()) return null;
092: // if (blob.length() == 0) return EMPTY_BYTE_ARRAY;
093: // return blob.getBytes(1, (int)blob.length());
094:
095: }
096:
097: /**
098: * Set parameter index on ps to value (for col).
099: * @exception SQLException on SQL errors
100: * @exception JDOFatalDataStoreException if value is invalid
101: */
102: public void set(PreparedStatement ps, int index, JdbcColumn col,
103: Object value) throws SQLException,
104: JDOFatalDataStoreException {
105: throw BindingSupportImpl.getInstance().fatalDatastore(
106: "set(ps..) called");
107: }
108:
109: /**
110: * Set parameter index on ps to value (for col). This special form is used
111: * when the value to be set is available as an int to avoid creating
112: * an wrapper instance.
113: * @exception SQLException on SQL errors
114: * @exception JDOFatalDataStoreException if value is invalid
115: */
116: public void set(PreparedStatement ps, int index, JdbcColumn col,
117: int value) throws SQLException, JDOFatalDataStoreException {
118: throw BindingSupportImpl.getInstance().fatalDatastore(
119: "set(..int) called");
120: }
121:
122: /**
123: * This method is called for converters that return true for
124: * isOracleStyleLOB. The value at index in rs will contain the LOB to
125: * be updated.
126: * @exception SQLException on SQL errors
127: * @exception JDOFatalDataStoreException if value is invalid
128: */
129: public void set(ResultSet rs, int index, JdbcColumn col,
130: Object value) throws SQLException,
131: JDOFatalDataStoreException {
132:
133: VoaEdited.exception();
134:
135: // BLOB blob = (BLOB)rs.getBlob(index);
136: // blob.putBytes(1, (byte[])value);
137:
138: // Calling trim leaks cursors - we make new CLOBs for every update to
139: // avoid this problem
140: // DO NOT DO - blob.trim( ((byte[])value).length );
141: }
142:
143: /**
144: * Get the type of our expected value objects (e.g. java.util.Locale
145: * for a converter for Locale's).
146: */
147: public Class getValueType() {
148: return byte[].class;
149: }
150:
151: }
|