001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: oracle_jdbc_driver_OracleDriver.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.cmf.dam.contentstores.rawstoredrivers;
009:
010: import com.uwyn.rife.cmf.dam.ContentDataUser;
011: import com.uwyn.rife.cmf.dam.contentstores.exceptions.UseContentDataErrorException;
012: import com.uwyn.rife.cmf.dam.exceptions.ContentManagerException;
013: import com.uwyn.rife.config.RifeConfig;
014: import com.uwyn.rife.database.Datasource;
015: import com.uwyn.rife.database.DbPreparedStatement;
016: import com.uwyn.rife.database.DbPreparedStatementHandler;
017: import com.uwyn.rife.database.DbResultSet;
018: import com.uwyn.rife.database.DbResultSetHandler;
019: import com.uwyn.rife.database.exceptions.DatabaseException;
020: import com.uwyn.rife.database.queries.Insert;
021: import com.uwyn.rife.database.queries.Select;
022: import java.io.BufferedInputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.io.OutputStream;
026: import java.sql.SQLException;
027: import oracle.sql.BLOB;
028:
029: public class oracle_jdbc_driver_OracleDriver extends generic {
030: private final static int BUFFER_SIZE = 65535; // 64kB
031: private final static int MAX_BLOB_SIZE = 1024 * 1024 * 1024 * 2; // 2GB
032:
033: public oracle_jdbc_driver_OracleDriver(Datasource datasource) {
034: super (datasource);
035:
036: mStoreContentChunk = new Insert(getDatasource()).into(
037: RifeConfig.Cmf.getTableContentStoreRawChunk())
038: .fieldParameter("contentId").fieldParameter("ordinal")
039: .fieldCustom("chunk", "empty_blob()");
040: }
041:
042: protected String getContentSizeColumnName() {
043: return "contentsize";
044: }
045:
046: public <ResultType> ResultType useContentData(final int id,
047: ContentDataUser user) throws ContentManagerException {
048: if (id < 0)
049: throw new IllegalArgumentException("id must be positive");
050: if (null == user)
051: throw new IllegalArgumentException("user can't be null");
052:
053: try {
054: InputStream data = RawContentStreamOracle.getInstance(this ,
055: mRetrieveContentChunks, id);
056: try {
057: return (ResultType) user.useContentData(data);
058: } finally {
059: if (data != null) {
060: try {
061: data.close();
062: } catch (IOException e) {
063: throw new UseContentDataErrorException(id, e);
064: }
065: }
066: }
067: } catch (DatabaseException e) {
068: throw new UseContentDataErrorException(id, e);
069: }
070: }
071:
072: protected int storeChunks(Insert storeContentChunk, final int id,
073: final InputStream data) throws IOException {
074: class Scope {
075: int size = 0;
076: int length = 0;
077: int ordinal = 0;
078: byte[] buffer = null;
079: int blobsize = 0;
080: }
081: final Scope s = new Scope();
082:
083: if (data != null) {
084: s.buffer = new byte[BUFFER_SIZE];
085: while (s.length != -1
086: && (s.length = data.read(s.buffer)) != -1) {
087: if (executeUpdate(storeContentChunk,
088: new DbPreparedStatementHandler() {
089: public void setParameters(
090: DbPreparedStatement statement) {
091: statement.setInt("contentId", id)
092: .setInt("ordinal", s.ordinal);
093: }
094: }) <= 0) {
095: return -1;
096: }
097:
098: s.blobsize = 0;
099:
100: executeQuery(new Select(getDatasource()).from(
101: storeContentChunk.getInto()).field("chunk")
102: .where("contentId", "=", id).whereAnd(
103: "ordinal = " + s.ordinal
104: + " FOR UPDATE"),
105: new DbResultSetHandler() {
106: public Object concludeResults(
107: DbResultSet resultset)
108: throws SQLException {
109: if (!resultset.next()) {
110: return null;
111: }
112:
113: BLOB blob = (BLOB) resultset.getBlob(1);
114: OutputStream os = blob
115: .getBinaryOutputStream();
116: try {
117: try {
118: do {
119: os.write(s.buffer, 0,
120: s.length);
121: s.size += s.length;
122: s.blobsize += s.length;
123: } while (s.blobsize < MAX_BLOB_SIZE
124: && (s.length = data
125: .read(s.buffer)) != -1);
126: } finally {
127: os.close();
128: }
129: } catch (IOException e) {
130: throw new DatabaseException(e);
131: }
132:
133: return null;
134: }
135: });
136:
137: s.ordinal++;
138: }
139: }
140:
141: return s.size;
142: }
143:
144: protected void serveChunks(DbResultSet resultset, OutputStream os,
145: int size) throws SQLException, IOException {
146: do {
147: BLOB blob = (BLOB) resultset.getBlob("chunk");
148: if (null == blob) {
149: return;
150: }
151:
152: InputStream is = blob.getBinaryStream();
153: try {
154: byte[] buffer = new byte[blob.getBufferSize()];
155: BufferedInputStream buffered_image_is = new BufferedInputStream(
156: is, buffer.length);
157: int input_size = 0;
158: while ((input_size = buffered_image_is.read(buffer)) != -1) {
159: os.write(buffer, 0, input_size);
160: }
161: } finally {
162: is.close();
163: }
164: } while (resultset.next());
165: }
166: }
|