oracleocilob.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 954 行 · 第 1/2 页
JAVA
954 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Rodrigo Westrupp */package com.caucho.quercus.lib.db;import com.caucho.quercus.annotation.NotNull;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.annotation.Name;import com.caucho.quercus.env.Env;import com.caucho.quercus.env.LongValue;import com.caucho.quercus.env.StringValue;import com.caucho.util.L10N;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.vfs.WriteStream;import java.io.InputStream;import java.io.OutputStream;import java.io.Reader;import java.io.Writer;import java.lang.reflect.Method;import java.sql.Blob;import java.sql.Clob;import java.sql.Connection;import java.util.logging.Level;import java.util.logging.Logger;/** * Quercus Oracle OCI-Lob object oriented API. */public class OracleOciLob { private static final Logger log = Logger.getLogger(OracleOciLob.class.getName()); private static final L10N L = new L10N(OracleOciLob.class); // The large object private Object _lob; // Cache the connection. See writeTemporary() private Oracle _conn; // Current position (seek) private long _currentPointer; // OCI Lob type: OCI_D_FILE, OCI_D_LOB or OCI_D_ROWID private int _type; // This could be refactored in two classes: OracleOciBlob and OracleOciClob private OutputStream _outputStream; private Writer _writer; // Cache classes and methods for oracle.sql.BLOB and oracle.sql.CLOB private static Class classOracleBLOB; private static Class classOracleCLOB; private static Method createTemporaryBLOB; private static Method createTemporaryCLOB; private static int BLOB_DURATION_CALL; private static int BLOB_DURATION_SESSION; private static int CLOB_DURATION_CALL; private static int CLOB_DURATION_SESSION; static { try { classOracleBLOB = Class.forName("oracle.sql.BLOB"); classOracleCLOB = Class.forName("oracle.sql.CLOB"); createTemporaryBLOB = classOracleBLOB.getDeclaredMethod("createTemporary", new Class[] {Connection.class, Boolean.TYPE, Integer.TYPE}); createTemporaryCLOB = classOracleCLOB.getDeclaredMethod("createTemporary", new Class[] {Connection.class, Boolean.TYPE, Integer.TYPE}); BLOB_DURATION_CALL = classOracleBLOB.getDeclaredField("DURATION_CALL").getInt(null); BLOB_DURATION_SESSION = classOracleBLOB.getDeclaredField("DURATION_SESSION").getInt(null); CLOB_DURATION_CALL = classOracleCLOB.getDeclaredField("DURATION_CALL").getInt(null); CLOB_DURATION_SESSION = classOracleCLOB.getDeclaredField("DURATION_SESSION").getInt(null); } catch (Exception e) { log.log(Level.FINER, L.l("Unable to load LOB classes or methods for oracle.sql.BLOB and oracle.sql.CLOB.")); } } /** * Constructor for OracleOciLob * * @param type one of the following types: * * OCI_D_FILE - a FILE descriptor * * OCI_D_LOB - a LOB descriptor * * OCI_D_ROWID - a ROWID descriptor */ OracleOciLob(Oracle conn, int type) { _conn = conn; _lob = null; _currentPointer = 0; _type = type; _outputStream = null; _writer = null; } /** * Appends data from the large object to another large object */ public boolean append(Env env, OracleOciLob lobFrom) { try { switch (_type) { case OracleModule.OCI_D_FILE: break; case OracleModule.OCI_D_LOB: if (_lob instanceof Blob) { Blob blob = (Blob) _lob; return appendInternalBlob(env, lobFrom); } else if (_lob instanceof Clob) { Clob clob = (Clob) _lob; return appendInternalClob(env, lobFrom); } break; case OracleModule.OCI_D_ROWID: break; } return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Closes LOB descriptor */ public boolean close(Env env) { try { _currentPointer = 0; if (_outputStream != null) { _outputStream.close(); _outputStream = null; } if (_writer != null) { _writer.close(); _writer = null; } return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Tests for end-of-file on a large object's descriptor */ public boolean eof(Env env) { try { long length = -1; switch (_type) { case OracleModule.OCI_D_FILE: break; case OracleModule.OCI_D_LOB: if (_lob instanceof Blob) { Blob blob = (Blob) _lob; length = blob.length(); } else if (_lob instanceof Clob) { Clob clob = (Clob) _lob; length = clob.length(); } break; case OracleModule.OCI_D_ROWID: break; } if (_currentPointer == length) { return true; } } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); } return false; } /** * Erases a specified portion of the internal LOB data * * @return the actual number of characters/bytes erased or * FALSE in case of error. */ @ReturnNullAsFalse public LongValue erase(Env env, @Optional("0") long offset, @Optional("-1") long length) { try { if (offset < 0) { offset = 0; } switch (_type) { case OracleModule.OCI_D_FILE: break; case OracleModule.OCI_D_LOB: if (_lob instanceof Blob) { Blob blob = (Blob) _lob; if (_outputStream != null) _outputStream.close(); _outputStream = blob.setBinaryStream(offset); long blobLength = blob.length(); if ((length < 0) || (offset + length > blobLength)) { length = blobLength - offset; } long remaining = length; byte zeroBuffer[] = new byte[128]; while (remaining >= 128) { _outputStream.write(zeroBuffer, 0, 128); remaining -= 128; } if (remaining > 0) { _outputStream.write(zeroBuffer, 0, (int) remaining); } _outputStream.close(); _outputStream = null; } else if (_lob instanceof Clob) { Clob clob = (Clob) _lob; if (_writer != null) _writer.close(); _writer = clob.setCharacterStream(offset); long clobLength = clob.length(); if ((length < 0) || (offset + length > clobLength)) { length = clobLength - offset; } long remaining = length; char spaceBuffer[] = new char[128]; while (remaining >= 128) { _writer.write(spaceBuffer, 0, 128); remaining -= 128; } if (remaining > 0) { _writer.write(spaceBuffer, 0, (int) remaining); } _writer.close(); _writer = null; } _currentPointer = offset + length; break; case OracleModule.OCI_D_ROWID: break; } if (length > 0) { return LongValue.create(length); } } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); } return null; } /** * Exports LOB's contents to a file */ public boolean export(Env env, Path file, @Optional("0") long start, @Optional("-1") long length) { try { WriteStream writeStream = file.openWrite(); if (_lob instanceof Blob) { Blob blob = (Blob) _lob; InputStream is = blob.getBinaryStream(); is.skip(start); writeStream.writeStream(is); is.close(); } else if (_lob instanceof Clob) { Clob clob = (Clob) _lob; Reader reader = clob.getCharacterStream(); reader.skip(start); writeStream.writeStream(reader); reader.close(); } else { writeStream.close(); return false; } writeStream.close(); return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Flushes/writes buffer of the LOB to the server */ public boolean flush(Env env, @Optional("-1") int flag) { try { if (_outputStream != null) { _outputStream.flush(); } if (_writer != null) { _writer.flush(); } if (flag == OracleModule.OCI_LOB_BUFFER_FREE) { close(env); } return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Frees resources associated with the LOB descriptor */ public boolean free(Env env) { try { _lob = null; return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Returns current state of buffering for the large object */ public boolean getBuffering(Env env) { // XXX: we assume buffering is always turned on. return true; } /** * Imports file data to the LOB */ @Name("import") public boolean q_import(Env env, Path file) { try { ReadStream readStream = file.openRead(); if (_lob instanceof Blob) { Blob blob = (Blob) _lob; blob.truncate(0); if (_outputStream != null) _outputStream.close(); _outputStream = blob.setBinaryStream(0); long nbytes; byte buffer[] = new byte[128]; while ((nbytes = readStream.read(buffer, 0, 128)) > 0) { _outputStream.write(buffer, 0, (int) nbytes); _currentPointer += nbytes; } _outputStream.close(); _outputStream = null; } else if (_lob instanceof Clob) { Clob clob = (Clob) _lob; clob.truncate(0); if (_writer != null) _writer.close(); _writer = clob.setCharacterStream(0); long nchars; char buffer[] = new char[128]; while ((nchars = readStream.read(buffer, 0, 128)) > 0) { _writer.write(buffer, 0, (int) nchars); _currentPointer += nchars; } _writer.close(); _writer = null; } else { readStream.close(); return false; } readStream.close(); return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Returns large object's contents */ @ReturnNullAsFalse public Object load(Env env) { try { switch (_type) { case OracleModule.OCI_D_FILE: break; case OracleModule.OCI_D_LOB: if (_lob instanceof Blob) { return readInternalBlob(env, -1);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?