You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ba...@apache.org on 2005/04/28 21:05:45 UTC
svn commit: r165178 [3/26] - in /incubator/derby/code/trunk: ./ java/client/
java/client/org/ java/client/org/apache/ java/client/org/apache/derby/
java/client/org/apache/derby/client/ java/client/org/apache/derby/client/am/
java/client/org/apache/derby/client/net/
java/client/org/apache/derby/client/resources/
java/client/org/apache/derby/jdbc/ tools/ant/properties/
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,482 @@
+/*
+
+ Derby - Class org.apache.derby.client.am.Clob
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+public class Clob extends Lob implements java.sql.Clob
+{
+ //---------------------navigational members-----------------------------------
+
+ //-----------------------------state------------------------------------------
+ protected String string_ = null;
+
+ // Only used for input purposes. For output, each getXXXStream call
+ // must generate an independent stream.
+ protected java.io.InputStream asciiStream_ = null;
+ protected java.io.InputStream unicodeStream_ = null;
+ protected java.io.Reader characterStream_ = null;
+
+ // used for input
+ // Therefore, we always convert a String to UTF-8 before we flow it for input
+ protected byte[] utf8String_;
+
+ // the length of the clob returned by the LENGTH function.
+ protected long lengthInBytes_ = 0;
+
+ private PreparedStatement internalLengthStmt_ = null;
+
+ protected String encoding_ = "UNICODE";
+
+ //---------------------constructors/finalizer---------------------------------
+ public Clob(Agent agent, String string)
+ {
+ this (agent);
+ string_ = string;
+ sqlLength_ = string_.length();
+ lengthObtained_ = true;
+ dataType_ |= STRING;
+ }
+
+ // CTOR for output, when a btc isn't available; the encoding is
+ public Clob (Agent agent,
+ byte[] unconvertedBytes,
+ String charsetName,
+ int dataOffset) throws SqlException
+ {
+ this (agent);
+ try {
+ // check for null encoding is needed because the net layer
+ // will no longer throw an exception if the server didn't specify
+ // a mixed or double byte ccsid (ccsid = 0). this check for null in the
+ // cursor is only required for types which can have mixed or double
+ // byte ccsids.
+ if (charsetName == null) {
+ throw new SqlException (agent.logWriter_,
+ "Required character converter not available for data type.");
+ }
+
+ string_ = new String(unconvertedBytes,
+ dataOffset,
+ unconvertedBytes.length - dataOffset,
+ charsetName);
+ sqlLength_ = string_.length();
+ lengthObtained_ = true;
+ dataType_ |= STRING;
+ }
+ catch (java.io.UnsupportedEncodingException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+ }
+
+ // CTOR for ascii/unicode stream input
+ //"US-ASCII", "UTF-8", or "UnicodeBigUnmarked"
+ public Clob (Agent agent,
+ java.io.InputStream inputStream,
+ String encoding,
+ int length) throws SqlException
+ {
+ this (agent);
+
+ sqlLength_ = length;
+ lengthObtained_ = true;
+
+ if (encoding.equals ("US-ASCII")) {
+ asciiStream_ = inputStream;
+ dataType_ |= ASCII_STREAM;
+ }
+ else if (encoding.equals ("UTF-8")){ // "UTF-8"
+ unicodeStream_ = inputStream;
+ dataType_ |= UNICODE_STREAM;
+ }
+ else if (encoding.equals ("UnicodeBigUnmarked")){ // "UnicodeBigUnmarked"
+ try {
+ characterStream_ =
+ new java.io.InputStreamReader(inputStream, "UnicodeBigUnmarked");
+ }
+ catch(java.io.UnsupportedEncodingException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+ dataType_ |= CHARACTER_STREAM;
+ sqlLength_ = length / 2;
+ }
+ }
+
+ // CTOR for character stream input
+ // THE ENCODING IS ASSUMED TO BE "UTF-16BE"
+ public Clob(Agent agent, java.io.Reader reader, int length)
+ {
+ this (agent);
+ sqlLength_ = length;
+ lengthObtained_ = true;
+ characterStream_ = reader;
+ dataType_ |= CHARACTER_STREAM;
+ }
+
+ private Clob(Agent agent)
+ {
+ super (agent);
+ }
+
+ protected void finalize () throws java.lang.Throwable
+ {
+ super.finalize();
+ if (internalLengthStmt_ != null)
+ internalLengthStmt_.closeX();
+ }
+
+ // ---------------------------jdbc 2------------------------------------------
+ // Create another method lengthX for internal calls
+ public long length() throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled())
+ agent_.logWriter_.traceEntry(this, "length");
+
+ if (lengthObtained_)
+ return sqlLength_;
+
+ lengthInBytes_ = super.sqlLength ();
+
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "length", sqlLength_);
+ return sqlLength_;
+ }
+ }
+
+ public String getSubString (long pos, int length) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ String retVal = null;
+
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getSubString", (int) pos, length);
+
+ // We can also do a check for pos > length()
+ // Defer it till FP7 so that proper testing can be performed on this
+ if ((pos <= 0) || (length < 0))
+ throw new SqlException(agent_.logWriter_, "Invalid position " + pos +" or length " + length);
+
+ retVal = getSubStringX (pos, length);
+
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getSubString", retVal);
+ return retVal;
+ }
+ }
+
+ private String getSubStringX (long pos, int length) throws SqlException
+ {
+ checkForClosedConnection ();
+ long actualLength = Math.min (this.length() - pos + 1, (long) length);
+ return string_.substring((int)pos - 1, (int)(pos - 1 + actualLength));
+ }
+
+ public java.io.Reader getCharacterStream () throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCharacterStream");
+
+ java.io.Reader retVal = getCharacterStreamX();
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getCharacterStream", retVal);
+ return retVal;
+ }
+ }
+
+ private java.io.Reader getCharacterStreamX () throws SqlException
+ {
+ checkForClosedConnection ();
+
+ if (isCharacterStream ()) // this Lob is used for input
+ return characterStream_;
+
+ return new java.io.StringReader (string_);
+ }
+
+ public java.io.InputStream getAsciiStream () throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getAsciiStream");
+
+ java.io.InputStream retVal = getAsciiStreamX();
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getAsciiStream", retVal);
+ return retVal;
+ }
+ }
+
+ private java.io.InputStream getAsciiStreamX () throws SqlException
+ {
+ checkForClosedConnection ();
+
+ if (isAsciiStream ()) // this Lob is used for input
+ return asciiStream_;
+
+ return new AsciiStream (string_, new java.io.StringReader (string_));
+ }
+
+ public long position (String searchstr, long start) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled())
+ agent_.logWriter_.traceEntry(this,
+ "position(String, long)",
+ searchstr,
+ start);
+ if (searchstr == null)
+ throw new SqlException(agent_.logWriter_, "Search string cannot be null.");
+
+ long pos = positionX (searchstr, start);
+ if (agent_.loggingEnabled())
+ agent_.logWriter_.traceExit(this, "position(String, long)", pos);
+ return pos;
+ }
+ }
+
+ private long positionX (String searchstr, long start) throws SqlException
+ {
+ checkForClosedConnection ();
+
+
+ if (start <= 0)
+ throw new SqlException (agent_.logWriter_, "Clob.position(): start must be >= 1.");
+
+ int index = string_.indexOf(searchstr, (int) start - 1);
+ if (index != -1)
+ index++; // api index starts at 1
+ return (long) index;
+ }
+
+ public long position (java.sql.Clob searchstr, long start) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled())
+ agent_.logWriter_.traceEntry(this,
+ "position(Clob, long)",
+ searchstr,
+ start);
+ if (searchstr == null)
+ throw new SqlException(agent_.logWriter_, "Search string cannot be null.");
+ long pos = positionX (searchstr, start);
+ if (agent_.loggingEnabled())
+ agent_.logWriter_.traceExit(this, "position(Clob, long)", pos);
+ return pos;
+ }
+ }
+
+ private long positionX (java.sql.Clob searchstr, long start) throws SqlException
+ {
+ checkForClosedConnection ();
+
+ if (start <= 0)
+ throw new SqlException (agent_.logWriter_, "Clob.position(): start must be >= 1.");
+
+ // if the searchstr is longer than the source, no match
+ int index;
+ try {
+ if (searchstr.length() > length())
+ return -1;
+
+ index = string_.indexOf(searchstr.getSubString (1L, (int) searchstr.length()), (int) start -1);
+ } catch (java.sql.SQLException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+ if (index != -1) index++; // api index starts at 1
+ return (long) index;
+ }
+
+ //---------------------------- jdbc 3.0 -----------------------------------
+
+ public int setString (long pos, String str) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setString", (int) pos, str);
+ int length = setStringX (pos,str, 0,str.length());
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "setString", length);
+ return length;
+ }
+ }
+
+ public int setString (long pos, String str, int offset, int len) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setString", (int) pos, str, offset, len);
+ int length = setStringX (pos, str, offset, len);
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "setString", length);
+ return length;
+ }
+ }
+
+ public int setStringX (long pos, String str, int offset, int len) throws SqlException
+ {
+ if ( (int) pos <= 0 || pos - 1 > sqlLength_)
+ throw new SqlException(agent_.logWriter_, "Invalid position " + pos
+ + " , offset " + offset + " or length " + len);
+ if ( (offset < 0) || offset > str.length() || len < 0 )
+ throw new SqlException(agent_.logWriter_, "Invalid position " + pos
+ + " , offset " + offset + " or length " + len);
+ if (len == 0) return 0;
+
+ int length = 0;
+ length = Math.min((str.length() - offset ),len);
+ String newString = string_.substring(0,(int)pos-1);
+ string_ = newString.concat(str.substring(offset,offset+length));
+ asciiStream_ = new java.io.StringBufferInputStream(string_);
+ unicodeStream_ = new java.io.StringBufferInputStream(string_);
+ characterStream_ = new java.io.StringReader(string_);
+ sqlLength_ = string_.length();
+ return length;
+ }
+
+ public java.io.OutputStream setAsciiStream (long pos) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setAsciiStream", (int) pos);
+ ClobOutputStream outStream = new ClobOutputStream (this,pos);
+
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "setAsciiStream", outStream);
+ return outStream;
+ }
+ }
+
+ public java.io.Writer setCharacterStream (long pos) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setCharacterStream", (int) pos);
+ ClobWriter writer = new ClobWriter (this,pos);
+
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "setCharacterStream", writer);
+ return writer;
+ }
+ }
+
+ public void truncate (long len) throws SqlException
+ {
+ synchronized (agent_.connection_) {
+ if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, " truncate", (int) len);
+ if (len < 0 || len > this.length())
+ throw new SqlException(agent_.logWriter_, "Invalid length " + len);
+ if (len == this.length())
+ return;
+ String newstr = string_.substring(0,(int)len);
+ string_ = newstr;
+ asciiStream_ = new java.io.StringBufferInputStream(string_);
+ unicodeStream_ = new java.io.StringBufferInputStream(string_);
+ characterStream_ = new java.io.StringReader(string_);
+ sqlLength_ = string_.length();
+ }
+ }
+
+ //----------------------------helper methods----------------------------------
+
+ public boolean isString ()
+ {
+ return ((dataType_ & STRING) == STRING);
+ }
+
+ public boolean isAsciiStream ()
+ {
+ return ((dataType_ & ASCII_STREAM) == ASCII_STREAM);
+ }
+
+ public boolean isCharacterStream ()
+ {
+ return ((dataType_ & CHARACTER_STREAM) == CHARACTER_STREAM);
+ }
+
+ public boolean isUnicodeStream ()
+ {
+ return ((dataType_ & UNICODE_STREAM) == UNICODE_STREAM);
+ }
+
+ public java.io.InputStream getUnicodeStream ()
+ {
+ return unicodeStream_;
+ }
+
+ public String getString ()
+ {
+ return string_;
+ }
+
+ public byte[] getUtf8String ()
+ {
+ return utf8String_;
+ }
+
+ // Return the length of the equivalent UTF-8 string
+ // precondition: string_ is not null and dataType_ includes STRING
+ public int getUTF8Length () throws SqlException
+ {
+ if (utf8String_ != null) return utf8String_.length;
+
+ try {
+ utf8String_ = string_.getBytes("UTF-8");
+ return utf8String_.length;
+ }
+ catch (java.io.UnsupportedEncodingException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+ }
+
+ // auxiliary method for position (Clob, long)
+ protected Clob createClobWrapper (java.sql.Clob clob) throws SqlException
+ {
+ long length;
+ java.io.Reader rdr;
+
+ try {
+ length = clob.length();
+ }
+ catch (java.sql.SQLException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+
+ if (length > java.lang.Integer.MAX_VALUE)
+ throw new SqlException (agent_.logWriter_, "searchstr Clob object is too large");
+
+ try {
+ rdr = clob.getCharacterStream ();
+ }
+ catch (java.sql.SQLException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+
+ return new Clob (this.agent_, rdr, (int)length);
+ }
+
+ public void convertFromAsciiToCharacterStream () throws SqlException
+ {
+ try {
+ characterStream_ =
+ new java.io.InputStreamReader(asciiStream_, "US-ASCII");
+ dataType_ = CHARACTER_STREAM;
+ }
+ catch (java.io.UnsupportedEncodingException e) {
+ throw new SqlException (agent_.logWriter_, e.getMessage());
+ }
+ }
+
+ // this method is primarily for mixed clob length calculations.
+ // it was introduced to prevent recursion in the actual char length calculation
+ public long getByteLength () throws SqlException
+ {
+ if (lengthObtained_ == true)
+ return lengthInBytes_;
+
+ length();
+ return lengthInBytes_;
+ }
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Clob.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobOutputStream.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobOutputStream.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobOutputStream.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,72 @@
+/*
+
+ Derby - Class org.apache.derby.client.am.ClobOutputStream
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+
+public class ClobOutputStream extends java.io.OutputStream
+{
+ private Clob clob_;
+ private long offset_;
+
+ public ClobOutputStream (Clob clob, long offset) throws SqlException
+ {
+ clob_ = clob;
+ offset_ = offset;
+ if (offset_ > clob_.sqlLength_)
+ throw new IndexOutOfBoundsException();
+ }
+
+ public void write (int b) throws java.io.IOException
+ {
+ clob_.string_ = clob_.string_.substring(0, (int)offset_ - 1);
+ clob_.string_ = clob_.string_.concat("" + b + "");
+ clob_.asciiStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_.unicodeStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_. characterStream_ = new java.io.StringReader(clob_.string_);
+ clob_.sqlLength_ = clob_.string_.length();
+ }
+
+
+ public void write (byte b[], int off, int len) throws java.io.IOException
+ {
+ if (b == null) {
+ throw new NullPointerException();
+ }
+ else if ((off < 0) || (off > b.length) || (len < 0) ||
+ ((off + len) > b.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ }
+ else if (len == 0) {
+ return;
+ }
+
+ byte[] newByte = new byte[len];
+ System.arraycopy(b,off,newByte,0,len);
+ String str = new String (newByte);
+ clob_.string_ = clob_.string_.substring(0, (int)offset_ - 1);
+ clob_.string_ = clob_.string_.concat(str);
+ clob_.asciiStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_.unicodeStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_. characterStream_ = new java.io.StringReader(clob_.string_);
+ clob_.sqlLength_ = clob_.string_.length();
+ }
+}
+
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobOutputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobWriter.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobWriter.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobWriter.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobWriter.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,101 @@
+/*
+
+ Derby - Class org.apache.derby.client.am.ClobWriter
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+
+public class ClobWriter extends java.io.Writer
+{
+ private Clob clob_;
+ private long offset_;
+
+ public ClobWriter()
+ {}
+
+ public ClobWriter(Clob clob, long offset) throws SqlException
+ {
+ clob_ = clob;
+ offset_ = offset;
+
+ if (offset_ - 1 > clob_.sqlLength_)
+ throw new SqlException( clob_.agent_.logWriter_, "Invalid position: " + offset);
+ }
+
+ public void write (int c)
+ {
+ StringBuffer sb = new StringBuffer(clob_.string_.substring(0,(int)offset_-1));
+ sb.append(c);
+ clob_.string_ = sb.toString();
+ clob_.asciiStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_.unicodeStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_. characterStream_ = new java.io.StringReader(clob_.string_);
+ clob_.sqlLength_ = clob_.string_.length();
+ offset_ = clob_.sqlLength_ + 1;
+ }
+
+ public void write(char cbuf[], int off, int len)
+ {
+ if ((off < 0) || (off > cbuf.length) || (len < 0) ||
+ ((off + len) > cbuf.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ }
+ else if (len == 0) {
+ return;
+ }
+ StringBuffer sb = new StringBuffer(clob_.string_.substring(0,(int)offset_-1));
+ sb.append(cbuf,off,len);
+ clob_.string_ = sb.toString();
+ clob_.asciiStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_.unicodeStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_. characterStream_ = new java.io.StringReader(clob_.string_);
+ clob_.sqlLength_ = clob_.string_.length();
+ offset_ = clob_.sqlLength_ + 1;
+ }
+
+
+ public void write (String str)
+ {
+ StringBuffer sb = new StringBuffer(clob_.string_.substring(0,(int)offset_-1));
+ sb.append(str);
+ clob_.string_ = sb.toString();
+ clob_.asciiStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_.unicodeStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_. characterStream_ = new java.io.StringReader(clob_.string_);
+ clob_.sqlLength_ = clob_.string_.length();
+ offset_ = clob_.sqlLength_ + 1;
+ }
+
+
+ public void write(String str, int off, int len)
+ {
+ StringBuffer sb = new StringBuffer(clob_.string_.substring(0,(int)offset_-1));
+ sb.append(str.substring(off, off + len));
+ clob_.string_ = sb.toString();
+ clob_.asciiStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_.unicodeStream_ = new java.io.StringBufferInputStream(clob_.string_);
+ clob_. characterStream_ = new java.io.StringReader(clob_.string_);
+ clob_.sqlLength_ = clob_.string_.length();
+ offset_ = clob_.sqlLength_ + 1;
+ }
+
+ public void flush() {}
+ public void close() throws java.io.IOException {}
+}
+
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ClobWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,939 @@
+/*
+
+ Derby - Class org.apache.derby.client.am.ColumnMetaData
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+// Under JDBC 2, we must new up our parameter meta data as column meta data instances
+// Once we move to JDK 1.4 pre-req, create a ResultSetMetaData class and make this class abstract
+public class ColumnMetaData implements java.sql.ResultSetMetaData
+{
+
+ public int columns_;
+
+ public boolean[] nullable_;
+
+ // Although this is describe information, it is tagged transient for now becuase it is not currently used.
+ transient public int[] singleMixedByteOrDouble_; // 1 means single, 2 means double, 3 means mixed-byte, 0 not applicable
+
+ // All of the following state data comes from the SQLDA reply.
+
+ //Data from SQLDHGRP
+ public short sqldHold_;
+ public short sqldReturn_;
+ public short sqldScroll_;
+ public short sqldSensitive_;
+ public short sqldFcode_;
+ public short sqldKeytype_;
+ public String sqldRdbnam_; // catalog name, not used by driver, placeholder only
+ public String sqldSchema_; // schema name, not used by driver, placeholder only
+
+ //data comes from SQLDAGRP
+ public int[] sqlPrecision_; // adjusted sqllen;
+ public int[] sqlScale_;
+ public long[] sqlLength_; // This is maximum length for varchar fields
+ // These are the derby sql types, for use only by ResultSetMetaData, other code should use jdbcTypes_.
+ // sqlTypes_ is currently not set for input column meta data.
+ public int[] sqlType_;
+ public int[] sqlCcsid_;
+
+ // With the exception of sqlNames_ and sqlxParmmode_, the following members are only allocated when needed
+
+ //Data from SQLDOPTGRP
+ public String[] sqlName_; // column name, pre-allocated
+ public String[] sqlLabel_; // column label
+ public short[] sqlUnnamed_;
+ public String[] sqlComment_;
+
+ //Data from SQLDXGRP
+ public short[] sqlxKeymem_;
+ public short[] sqlxGenerated_;
+ public short[] sqlxParmmode_; // pre-allocated
+ public String[] sqlxCorname_;
+ public String[] sqlxName_;
+ public String[] sqlxBasename_; // table name
+ public int[] sqlxUpdatable_;
+ public String[] sqlxSchema_; // schema name
+ public String[] sqlxRdbnam_; // catalog name
+
+ //-----------------------------transient state--------------------------------
+
+ // For performance only, not part of logical model.
+ public transient int[][] protocolTypesCache_ = null;
+ public transient java.util.Hashtable protocolTypeToOverrideLidMapping_ = null;
+ public transient java.util.ArrayList mddOverrideArray_ = null;
+
+ public transient int[] types_;
+ public transient int[] clientParamtertype_;
+
+ public transient LogWriter logWriter_;
+
+ // only set on execute replies, this is not describe information.
+ // only used for result set meta data.
+
+ public transient int resultSetConcurrency_;
+
+ transient private java.util.Hashtable columnNameToIndexCache_ = null;
+
+ transient private boolean statementClosed_ = false;
+ void markClosed() {
+ statementClosed_ = true;
+ nullDataForGC();
+ }
+
+ void checkForClosedStatement() throws SqlException
+ {
+ // agent_.checkForDeferredExceptions();
+ if (statementClosed_) throw new SqlException (logWriter_, "Statement closed");
+ }
+
+
+ //---------------------navigational members-----------------------------------
+
+ //---------------------constructors/finalizer---------------------------------
+
+ // Called by NETColumnMetaData constructor before #columns is parsed out yet.
+ public ColumnMetaData (LogWriter logWriter)
+ {
+ logWriter_ = logWriter;
+ }
+
+ // For creating column meta data when describe input is not available.
+ // The upper bound that is passed in is determined by counting the number of parameter markers.
+ // Called by PreparedStatement.flowPrepareStatement() and flowDescribeInputOutput()
+ // only when describe input is not available.
+ public ColumnMetaData (LogWriter logWriter, int upperBound)
+ {
+ logWriter_ = logWriter;
+ initializeCache (upperBound);
+ }
+
+
+ public void initializeCache (int upperBound)
+ {
+ columns_ = upperBound;
+ nullable_ = new boolean[upperBound];
+ types_ = new int[upperBound];
+ clientParamtertype_ = new int[upperBound];
+ singleMixedByteOrDouble_ = new int[upperBound]; // 1 means single, 2 means double, 3 means mixed-byte, 0 not applicable
+
+ sqlPrecision_ = new int[upperBound];
+ sqlScale_ = new int[upperBound];
+ sqlLength_ = new long[upperBound];
+ sqlType_ = new int[upperBound];
+ sqlCcsid_ = new int[upperBound];
+
+ sqlName_ = new String[upperBound];
+ sqlxParmmode_ = new short[upperBound];
+ }
+
+ protected void finalize () throws java.lang.Throwable
+ {
+ super.finalize();
+ }
+
+ //--------------------Abstract material layer call-down methods-----------------
+
+ //------------------material layer event callback methods-----------------------
+
+ // ---------------------------jdbc 1------------------------------------------
+
+ public int getColumnCount () throws SqlException
+ {
+ checkForClosedStatement();
+ return columns_;
+ }
+
+ public boolean isAutoIncrement (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ return false;
+ }
+
+ public boolean isCaseSensitive (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ //return true if the SQLTYPE is CHAR, VARCHAR, LOGVARCHAR or CLOB
+ int type = types_[column-1];
+ return
+ type == Types.CHAR ||
+ type == Types.VARCHAR ||
+ type == Types.LONGVARCHAR ||
+ type == Types.CLOB;
+ }
+
+ // all searchable except distinct
+ public boolean isSearchable (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ return true;
+ }
+
+ public boolean isCurrency (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ return false;
+ }
+
+ public int isNullable (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ if (nullable_[column-1])
+ return java.sql.ResultSetMetaData.columnNullable;
+ else
+ return java.sql.ResultSetMetaData.columnNoNulls;
+ }
+
+ public boolean isSigned (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ //return true only if the SQLType is SMALLINT, INT, BIGINT, FLOAT, REAL, DOUBLE, NUMERIC OR DECIMAL
+ int type = types_[column-1];
+ return
+ type == Types.SMALLINT ||
+ type == Types.INTEGER ||
+ type == Types.BIGINT ||
+ type == java.sql.Types.FLOAT ||
+ type == Types.REAL ||
+ type == Types.DOUBLE ||
+ type == java.sql.Types.NUMERIC ||
+ type == Types.DECIMAL;
+ }
+
+ public int getColumnDisplaySize (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ int jdbcType = types_[column-1];
+ switch (jdbcType){
+ case Types.INTEGER:
+ return 11;
+ case Types.SMALLINT:
+ return 6;
+ case Types.BIGINT:
+ return 20;
+ case Types.REAL:
+ return 13;
+ case Types.DOUBLE:
+ case java.sql.Types.FLOAT:
+ return 22;
+ case Types.DECIMAL:
+ case java.sql.Types.NUMERIC:
+ return getPrecision(column) + 2; // add 1 for sign and 1 for decimal
+ case Types.CHAR:
+ case Types.VARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.CLOB:
+ return (int) sqlLength_[column-1];
+ case Types.DATE:
+ return 10;
+ case Types.TIME:
+ return 8;
+ case Types.TIMESTAMP:
+ return 26;
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ case Types.BLOB:
+ return (int) (2*sqlLength_[column-1]); // eg. "FF" represents just one byte
+ default:
+ throw new SqlException (logWriter_, "not supported");
+ }
+ }
+
+ public String getColumnLabel (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ // return labels if label is turned on, otherwise, return column name
+ if (sqlLabel_ != null && sqlLabel_[column-1] != null) return sqlLabel_[column-1];
+ if (sqlName_ == null || sqlName_[column-1] == null)
+ assignColumnName (column);
+ return sqlName_[column-1];
+ }
+
+ public String getColumnName (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ // The Javadoc and Jdbc book explicitly state that the empty string ("") is returned if "not applicable"
+ // for the following methods:
+ // getSchemaName()
+ // getTableName()
+ // getCatalogName()
+ // Since the empty string is a valid string and is not really a proper table name, schema name, or catalog name,
+ // we're not sure why the empty string was chosen over null, except possibly to be friendly to lazy jdbc apps
+ // that may not be checking for nulls, thereby minimizing potential NPE's.
+ // By induction, it would make sense to return the empty string when column name is not available/applicable.
+ //
+ // The JDBC specification contains blanket statements about SQL compliance levels,
+ // so elaboration within the JDBC specification is often bypassed.
+ // Personally, I would prefer to return Java null for all the not-applicable cases,
+ // but it appears that we have precedent for the empty ("") string.
+ //
+ // We assume a straightforward induction from jdbc spec that the column name be "" (empty)
+ // in preference to null or NULL for the not applicable case.
+ //
+ if (sqlName_ == null || sqlName_[column-1] == null)
+ assignColumnName (column);
+ return sqlName_[column-1];
+ }
+
+ public String getSchemaName (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ if (sqlxSchema_ == null || sqlxSchema_[column-1] == null) return ""; // Per jdbc spec
+ return sqlxSchema_[column-1];
+ }
+
+ public int getPrecision (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ int jdbcType = types_[column-1];
+
+ switch (jdbcType) {
+ case java.sql.Types.NUMERIC:
+ case Types.DECIMAL:
+ return sqlPrecision_[column-1];
+ case Types.SMALLINT:
+ return 5;
+ case Types.INTEGER:
+ return 10;
+ case Types.BIGINT:
+ return 19;
+ case java.sql.Types.FLOAT:
+ return 15;
+ case Types.REAL:
+ return 7; // This is the number of signed digits for IEEE float with mantissa 24, ie. 2^24
+ case Types.DOUBLE:
+ return 15; // This is the number of signed digits for IEEE float with mantissa 24, ie. 2^24
+ case Types.CHAR:
+ case Types.VARCHAR:
+ case Types.LONGVARCHAR:
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ case Types.CLOB:
+ case Types.BLOB:
+ return (int) sqlLength_[column-1];
+ case Types.DATE:
+ return 10;
+ case Types.TIME:
+ return 8;
+ case Types.TIMESTAMP:
+ return 26;
+ default:
+ throw new SqlException (logWriter_, "Unregistered column type");
+ }
+ }
+
+ public int getScale (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+
+ // We get the scale from the SQLDA as returned by DERBY, but DERBY does not return the ANSI-defined
+ // value of scale 6 for TIMESTAMP.
+ //
+ // The JDBC drivers should hardcode this info as a short/near term solution.
+ //
+ if (types_[column-1] == Types.TIMESTAMP) return 6;
+
+ return sqlScale_[column-1];
+ }
+
+ public String getTableName (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ if (sqlxBasename_ == null || sqlxBasename_[column-1] == null) return ""; // Per jdbc spec
+ return sqlxBasename_[column-1];
+ }
+
+ /**
+ * What's a column's table's catalog name?
+ *
+ * @param column the first column is 1, the second is 2, ...
+ * @return column name or "" if not applicable.
+ * @exception SQLException thrown on failure
+ */
+ public String getCatalogName (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ return "";
+ }
+
+ public int getColumnType (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+
+ return types_[column-1];
+ }
+
+ public String getColumnTypeName (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+
+ int jdbcType = types_[column-1];
+ // So these all come back zero for downlevel servers in PROTOCOL.
+ // John is going to write some code to construct the sqlType_ array
+ // based on the protocol types from the query descriptor.
+ int sqlType = sqlType_[column-1];
+
+ switch (sqlType) {
+ case Types.DERBY_SQLTYPE_DATE:
+ case Types.DERBY_SQLTYPE_NDATE:
+ return "DATE";
+ case Types.DERBY_SQLTYPE_TIME:
+ case Types.DERBY_SQLTYPE_NTIME:
+ return "TIME";
+ case Types.DERBY_SQLTYPE_TIMESTAMP:
+ case Types.DERBY_SQLTYPE_NTIMESTAMP:
+ return "TIMESTAMP";
+ case Types.DERBY_SQLTYPE_BLOB:
+ case Types.DERBY_SQLTYPE_NBLOB:
+ return "BLOB";
+ case Types.DERBY_SQLTYPE_CLOB:
+ case Types.DERBY_SQLTYPE_NCLOB:
+ return "CLOB";
+ case Types.DERBY_SQLTYPE_VARCHAR:
+ case Types.DERBY_SQLTYPE_NVARCHAR:
+ if (jdbcType == Types.VARBINARY)
+ return "VARCHAR FOR BIT DATA";
+ else
+ return "VARCHAR";
+ case Types.DERBY_SQLTYPE_CHAR:
+ case Types.DERBY_SQLTYPE_NCHAR:
+ if(jdbcType == Types.BINARY)
+ return "CHAR FOR BIT DATA";
+ else
+ return "CHAR";
+ case Types.DERBY_SQLTYPE_LONG:
+ case Types.DERBY_SQLTYPE_NLONG:
+ if(jdbcType == Types.LONGVARBINARY)
+ return "LONG VARCHAR FOR BIT DATA";
+ else
+ return "LONG VARCHAR";
+ case Types.DERBY_SQLTYPE_CSTR:
+ case Types.DERBY_SQLTYPE_NCSTR:
+ return "SBCS";
+ case Types.DERBY_SQLTYPE_FLOAT:
+ case Types.DERBY_SQLTYPE_NFLOAT:
+ if(jdbcType == Types.DOUBLE)
+ return "DOUBLE";
+ if(jdbcType == Types.REAL)
+ return "REAL";
+ case Types.DERBY_SQLTYPE_DECIMAL:
+ case Types.DERBY_SQLTYPE_NDECIMAL:
+ return "DECIMAL";
+ case Types.DERBY_SQLTYPE_BIGINT:
+ case Types.DERBY_SQLTYPE_NBIGINT:
+ return "BIGINT";
+ case Types.DERBY_SQLTYPE_INTEGER:
+ case Types.DERBY_SQLTYPE_NINTEGER:
+ return "INTEGER";
+ case Types.DERBY_SQLTYPE_SMALL:
+ case Types.DERBY_SQLTYPE_NSMALL:
+ return "SMALLINT";
+ case Types.DERBY_SQLTYPE_NUMERIC:
+ case Types.DERBY_SQLTYPE_NNUMERIC:
+ return "NUMERIC";
+ default:
+ throw new SqlException (logWriter_, "Not supported");
+ }
+ }
+
+ public boolean isReadOnly (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ if (sqlxUpdatable_ == null)
+ return (resultSetConcurrency_ == java.sql.ResultSet.CONCUR_READ_ONLY); // If no extended describe, return resultSet's concurrecnty
+ return sqlxUpdatable_[column-1] == 0; // PROTOCOL 0 means not updatable, 1 means updatable
+ }
+
+ public boolean isWritable (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ if (sqlxUpdatable_ == null)
+ return (resultSetConcurrency_ == java.sql.ResultSet.CONCUR_UPDATABLE); // If no extended describe, return resultSet's concurrency
+ return sqlxUpdatable_[column-1] == 1; // PROTOCOL 0 means not updatable, 1 means updatable
+ }
+
+ public boolean isDefinitelyWritable (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+ if (sqlxUpdatable_ == null) return false;
+ return sqlxUpdatable_[column-1] == 1; // PROTOCOL 0 means not updatable, 1 means updatable
+ }
+
+ //--------------------------jdbc 2.0-----------------------------------
+
+ public String getColumnClassName (int column) throws SqlException
+ {
+ checkForClosedStatement();
+ checkForValidColumnIndex (column);
+
+ int jdbcType = types_[column-1];
+ switch (jdbcType) {
+ case java.sql.Types.BIT:
+ return "java.lang.Boolean";
+ case java.sql.Types.TINYINT:
+ return "java.lang.Integer";
+ case Types.SMALLINT:
+ return "java.lang.Integer";
+ case Types.INTEGER:
+ return "java.lang.Integer";
+ case Types.BIGINT:
+ return "java.lang.Long";
+ case java.sql.Types.FLOAT:
+ return "java.lang.Double";
+ case Types.REAL:
+ return "java.lang.Float";
+ case Types.DOUBLE:
+ return "java.lang.Double";
+ case java.sql.Types.NUMERIC:
+ case Types.DECIMAL:
+ return "java.math.BigDecimal";
+ case Types.CHAR:
+ case Types.VARCHAR:
+ case Types.LONGVARCHAR:
+ return "java.lang.String";
+ case Types.DATE:
+ return "java.sql.Date";
+ case Types.TIME:
+ return "java.sql.Time";
+ case Types.TIMESTAMP:
+ return "java.sql.Timestamp";
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ return "byte[]";
+ case java.sql.Types.STRUCT:
+ return "java.sql.Struct";
+ case java.sql.Types.ARRAY:
+ return "java.sql.Array";
+ case Types.BLOB:
+ return "java.sql.Blob";
+ case Types.CLOB:
+ return "java.sql.Clob";
+ case java.sql.Types.REF:
+ return "java.sql.Ref";
+ default:
+ throw new SqlException (logWriter_, "Not supported");
+ }
+ }
+
+ //----------------------------helper methods----------------------------------
+
+
+ void checkForValidColumnIndex (int column) throws SqlException
+ {
+ if (column < 1 || column > columns_)
+ throw new SqlException (logWriter_, "Invalid argument: column index " +
+ column + " is out of range.");
+ }
+
+ // If the input parameter has been set, return true, else return false.
+ private boolean isParameterModeGuessedAsAnInput (int parameterIndex)
+ {
+ if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeIn ||
+ sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeInOut) {
+ return true;
+ }
+ return false;
+ }
+
+ // Does OUT parm registration rely on extended describe?
+ // If the output parameter has been registered, return true, else return false.
+ public boolean isParameterModeGuessedAsOutput (int parameterIndex)
+ {
+ return sqlxParmmode_[parameterIndex - 1] >= java.sql.ParameterMetaData.parameterModeInOut;
+ }
+
+ // Only called when column meta data is not described. Called by setXXX methods.
+ public void guessInputParameterMetaData (int parameterIndex,
+ int jdbcType) throws SqlException
+ {
+ guessInputParameterMetaData (parameterIndex, jdbcType, 0);
+ }
+
+ private void setParmModeForInputParameter (int parameterIndex)
+ {
+ if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeOut)
+ sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeInOut;
+ else if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeUnknown)
+ sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeIn;
+ }
+
+ // Only called when column meta data is not described. Called by setXXX methods.
+ // Scale is only applied for Decimal or Numeric JDBC type.
+ public void guessInputParameterMetaData (int parameterIndex,
+ int jdbcType,
+ int scale) throws SqlException
+ {
+ setParmModeForInputParameter (parameterIndex);
+ int driverType = getInternalTypeForGuessedOrRegisteredJdbcType (jdbcType);
+ // if output parameter has been registered already
+ if (isParameterModeGuessedAsOutput (parameterIndex)) {
+ if (!isCompatibleDriverTypes (types_[parameterIndex-1], driverType)) {
+ throw new SqlException (logWriter_, "The jdbcType " + jdbcType + " does not match between the setter method and " +
+ "the registerOutParameter method.");
+ }
+ else return; // don't bother guessing if the parameter was already registered
+ }
+ guessParameterMetaDataBasedOnSupportedDriverType (parameterIndex, jdbcType==java.sql.Types.BIGINT, driverType, scale);
+ }
+
+ private void setParmModeForOutputParameter (int parameterIndex)
+ {
+ if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeIn)
+ sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeInOut;
+ else if (sqlxParmmode_[parameterIndex - 1] == java.sql.ParameterMetaData.parameterModeUnknown)
+ sqlxParmmode_[parameterIndex - 1] = java.sql.ParameterMetaData.parameterModeOut;
+ }
+
+ // Only called when column meta data is not described, called by registerOutParameter methods.
+ public void guessOutputParameterMetaData (int parameterIndex,
+ int jdbcType,
+ int scale) throws SqlException
+ {
+ setParmModeForOutputParameter (parameterIndex);
+ int driverType = getInternalTypeForGuessedOrRegisteredJdbcType (jdbcType);
+ if (isParameterModeGuessedAsAnInput (parameterIndex)) { // if input parameter has been set already
+ // Verify that "set" and "registered" types are compatible.
+ if (!isCompatibleDriverTypes (driverType, types_[parameterIndex -1])) {
+ throw new SqlException (logWriter_, "The jdbcType does not match between the setter method and " +
+ "the registerOutParameter method.");
+ }
+ // the registered type will take precedence over any previously guessed input "set" type
+ }
+ guessParameterMetaDataBasedOnSupportedDriverType (parameterIndex, jdbcType==java.sql.Types.BIGINT, driverType, scale);
+ }
+
+ private boolean isCompatibleDriverTypes (int registeredType, int guessedInputType)
+ {
+ switch (registeredType) {
+ case Types.CHAR:
+ case Types.VARCHAR:
+ case Types.LONGVARCHAR:
+ return guessedInputType == Types.CHAR || guessedInputType == Types.VARCHAR || guessedInputType == Types.LONGVARCHAR;
+ case Types.BINARY:
+ case Types.VARBINARY:
+ case Types.LONGVARBINARY:
+ return guessedInputType == Types.BINARY || guessedInputType == Types.VARBINARY || guessedInputType == Types.LONGVARBINARY;
+ default:
+ return registeredType == guessedInputType;
+ }
+ }
+
+ // Only used when describe information is not available.
+ private int getInternalTypeForGuessedOrRegisteredJdbcType (int guessedOrRegisteredJdbcType) throws SqlException
+ {
+ switch (guessedOrRegisteredJdbcType) {
+ case java.sql.Types.BIT:
+ case java.sql.Types.TINYINT:
+ case java.sql.Types.SMALLINT:
+ return Types.SMALLINT;
+ case java.sql.Types.INTEGER:
+ return Types.INTEGER;
+ case java.sql.Types.BIGINT:
+ return Types.BIGINT;
+ case java.sql.Types.REAL:
+ return Types.REAL;
+ case java.sql.Types.DOUBLE:
+ case java.sql.Types.FLOAT:
+ return Types.DOUBLE;
+ case java.sql.Types.DECIMAL:
+ case java.sql.Types.NUMERIC:
+ return Types.DECIMAL;
+ case java.sql.Types.DATE:
+ return Types.DATE;
+ case java.sql.Types.TIME:
+ return Types.TIME;
+ case java.sql.Types.TIMESTAMP:
+ return Types.TIMESTAMP;
+ case java.sql.Types.CHAR:
+ return Types.CHAR;
+ case java.sql.Types.VARCHAR:
+ return Types.VARCHAR;
+ case java.sql.Types.LONGVARCHAR:
+ return Types.LONGVARCHAR;
+ case java.sql.Types.BINARY:
+ return Types.BINARY;
+ case java.sql.Types.VARBINARY:
+ return Types.VARBINARY;
+ case java.sql.Types.LONGVARBINARY:
+ return Types.LONGVARBINARY;
+ case java.sql.Types.BLOB:
+ return Types.BLOB;
+ case java.sql.Types.CLOB:
+ return Types.CLOB;
+ case java.sql.Types.NULL:
+ case java.sql.Types.OTHER:
+ throw new SqlException (logWriter_, "Jdbc type " + guessedOrRegisteredJdbcType + " not yet supported.");
+ default:
+ throw new SqlException (logWriter_, "Unrecognized jdbc type " + guessedOrRegisteredJdbcType);
+ }
+ }
+
+ private void guessParameterMetaDataBasedOnSupportedDriverType (int parameterIndex,
+ boolean isBigInt,
+ int driverType,
+ int scale) throws SqlException
+ {
+ switch (driverType) {
+ case Types.SMALLINT:
+ guessParameterMetaData (parameterIndex, driverType, 2, 0, 0);
+ break;
+ case Types.INTEGER:
+ guessParameterMetaData (parameterIndex, driverType, 4, 0, 0);
+ break;
+ case Types.BIGINT:
+ guessParameterMetaData (parameterIndex, driverType, 8, 0, 0);
+ break;
+ case Types.REAL:
+ guessParameterMetaData (parameterIndex, driverType, 4, 0, 0);
+ break;
+ case Types.DOUBLE:
+ guessParameterMetaData (parameterIndex, driverType, 8, 0, 0);
+ break;
+ case Types.DECIMAL:
+ if (isBigInt)
+ guessParameterMetaData (parameterIndex, driverType, 0, 19, 0);
+ else
+ guessParameterMetaData (parameterIndex, driverType, 0, 31, scale);
+ break;
+ case Types.DATE:
+ guessParameterMetaData (parameterIndex, driverType, 10, 0, 0);
+ break;
+ case Types.TIME:
+ guessParameterMetaData (parameterIndex, driverType, 8, 0, 0);
+ break;
+ case Types.TIMESTAMP:
+ guessParameterMetaData (parameterIndex, driverType, 26, 0, 0);
+ break;
+ case Types.CHAR:
+ case Types.VARCHAR:
+ guessParameterMetaData (parameterIndex, driverType, 32672, 0, 0);
+ break;
+ case Types.LONGVARCHAR:
+ guessParameterMetaData (parameterIndex, driverType, 32700, 0, 0);
+ break;
+ case Types.BINARY:
+ case Types.VARBINARY:
+ guessParameterMetaData (parameterIndex, driverType, 4000, 0, 0);
+ break;
+ case Types.LONGVARBINARY:
+ guessParameterMetaData (parameterIndex, driverType, 32700, 0, 0);
+ break;
+ case Types.BLOB:
+ // 32768 will cause 8004 for a null placeholder length (could hard code in NET layer)
+ guessParameterMetaData (parameterIndex, driverType, 32768, 0, 0);
+ break;
+ case Types.CLOB:
+ // 32768 will cause 8004 for a null placeholder length (could hard code in NET layer)
+ guessParameterMetaData (parameterIndex, driverType, 32768, 0, 0);
+ break;
+ default:
+ throw new SqlException (logWriter_, "Unrecognized driver type " + driverType);
+ }
+ }
+
+ // Only called when column meta data is not described
+ private void guessParameterMetaData (int parameterIndex,
+ int type,
+ int length,
+ int precision,
+ int scale)
+ {
+ // Always guess that the column is nullable
+ nullable_[parameterIndex-1] = true;
+ types_[parameterIndex-1] = type;
+ sqlLength_[parameterIndex-1] = length;
+ sqlPrecision_[parameterIndex-1] = precision;
+ sqlScale_[parameterIndex-1] = scale;
+ sqlType_[parameterIndex-1] = mapDriverToSqlType(type, true);
+ }
+
+ int mapDriverToSqlType(int type, boolean nullable)
+ {
+ int sqlType = 0;
+ switch (type)
+ {
+ case java.sql.Types.SMALLINT:
+ sqlType = Types.DERBY_SQLTYPE_NSMALL;
+ break;
+ case java.sql.Types.INTEGER:
+ sqlType = Types.DERBY_SQLTYPE_NINTEGER;
+ break;
+ case java.sql.Types.BIGINT:
+ sqlType = Types.DERBY_SQLTYPE_NBIGINT;
+ break;
+ case java.sql.Types.REAL:
+ case java.sql.Types.DOUBLE:
+ case java.sql.Types.FLOAT:
+ sqlType = Types.DERBY_SQLTYPE_NFLOAT;
+ break;
+ case java.sql.Types.DATE:
+ sqlType = Types.DERBY_SQLTYPE_NDATE;
+ break;
+ case java.sql.Types.TIME:
+ sqlType = Types.DERBY_SQLTYPE_NTIME;
+ break;
+ case java.sql.Types.TIMESTAMP:
+ sqlType = Types.DERBY_SQLTYPE_NTIMESTAMP;
+ break;
+ case java.sql.Types.CHAR:
+ case java.sql.Types.VARCHAR:
+ sqlType = Types.DERBY_SQLTYPE_NVARCHAR;
+ break;
+ case java.sql.Types.LONGVARCHAR:
+ sqlType = Types.DERBY_SQLTYPE_NLONG;
+ break;
+ case java.sql.Types.BINARY:
+ case java.sql.Types.VARBINARY:
+ sqlType = Types.DERBY_SQLTYPE_NVARCHAR;
+ break;
+ case java.sql.Types.LONGVARBINARY:
+ sqlType = Types.DERBY_SQLTYPE_NLONG;
+ break;
+ case java.sql.Types.NUMERIC:
+ case java.sql.Types.DECIMAL:
+ sqlType = Types.DERBY_SQLTYPE_NDECIMAL;
+ break;
+ case java.sql.Types.BLOB:
+ sqlType = Types.DERBY_SQLTYPE_NBLOB;
+ break;
+ case java.sql.Types.CLOB:
+ sqlType = Types.DERBY_SQLTYPE_NCLOB;
+ break;
+ default:
+ break; // bug check
+ }
+ if (!nullable)
+ sqlType--;
+ return sqlType;
+ }
+
+
+ public void setLogWriter (LogWriter logWriter)
+ {
+ logWriter_ = logWriter;
+ }
+
+ private void nullDataForGC()
+ {
+ columns_ = 0;
+ nullable_ = null;
+ types_ = null;
+ singleMixedByteOrDouble_ = null;
+ sqldRdbnam_ = null;
+ sqldSchema_ = null;
+ sqlPrecision_ = null;
+ sqlScale_ = null;
+ sqlLength_ = null;
+ sqlType_ = null;
+ sqlCcsid_ = null;
+ sqlName_ = null;
+ sqlLabel_ = null;
+ sqlUnnamed_ = null;
+ sqlComment_ = null;
+ sqlxKeymem_ = null;
+ sqlxGenerated_ = null;
+ sqlxParmmode_ = null;
+ sqlxCorname_ = null;
+ sqlxName_ = null;
+ sqlxBasename_ = null;
+ sqlxUpdatable_ = null;
+ sqlxSchema_ = null;
+ sqlxRdbnam_ = null;
+ clientParamtertype_ = null;
+ types_ = null;
+ }
+
+ public boolean hasLobColumns ()
+ {
+ for (int i=0; i<columns_; i++) {
+ switch (org.apache.derby.client.am.Utils.getNonNullableSqlType (sqlType_[i])) {
+ case org.apache.derby.client.am.Types.DERBY_SQLTYPE_BLOB:
+ case org.apache.derby.client.am.Types.DERBY_SQLTYPE_CLOB:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+ }
+
+ // Cache the hashtable in ColumnMetaData.
+ int findColumnX (String columnName) throws SqlException
+ {
+ // Create cache if it doesn't exist
+ if (columnNameToIndexCache_ == null) {
+ columnNameToIndexCache_ = new java.util.Hashtable ();
+ }
+ else { // Check cache for mapping
+ Integer index = (Integer) columnNameToIndexCache_.get (columnName);
+ if (index != null)
+ return index.intValue ();
+ }
+
+ // Ok, we'll have to search the metadata
+ for (int col = 0; col < this.columns_; col++) {
+ if (this.sqlName_ != null && // sqlName comes from an optional group
+ this.sqlName_[col] != null &&
+ this.sqlName_[col].equalsIgnoreCase (columnName)) {
+ // Found it, add it to the cache
+ columnNameToIndexCache_.put (columnName, new Integer (col+1));
+ return col+1;
+ }
+ }
+ throw new SqlException (logWriter_, "Invalid argument: unknown column name " + columnName);
+ }
+
+ // assign ordinal position as the column name if null.
+ void assignColumnName (int column)
+ {
+ if (columnNameToIndexCache_ == null)
+ columnNameToIndexCache_ = new java.util.Hashtable ();
+ String columnName = (new Integer(column)).toString();
+ columnNameToIndexCache_.put (columnName, new Integer (column));
+ sqlName_[column-1] = columnName;
+ }
+
+ public boolean columnIsNotInUnicode (int index)
+ {
+ return (sqlCcsid_[index] != 1208);
+ }
+
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ColumnMetaData.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,246 @@
+/*
+
+ Derby - Class org.apache.derby.client.am.Configuration
+
+ Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+import org.apache.derby.iapi.services.info.ProductVersionHolder;
+import org.apache.derby.iapi.services.info.ProductGenusNames;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class Configuration
+{
+
+
+ public static int traceFileSuffixIndex__ = 0;
+
+ public static int traceLevel__ = org.apache.derby.client.ClientBaseDataSource.TRACE_ALL;
+
+ public static String traceFile__ = null;
+
+ public static String traceDirectory__ = null;
+
+ public static boolean traceFileAppend__ = false;
+ public static String jreLevel = "1.3.0"; // default level if unable to read
+ public static int jreLevelMajor = 1;
+ public static int jreLevelMinor = 3;
+
+ private Configuration () {}
+
+ public static boolean traceSuspended__;
+
+ public static boolean[] enableConnectivityToTargetServer__;
+ public static boolean jvmSupportsMicrosClock__ = false;
+
+ // -------------------------- versioning -------------------------------------
+
+ public static ProductVersionHolder dncProductVersionHolder__;
+
+ public static ProductVersionHolder getProductVersionHolder()
+ {
+ return dncProductVersionHolder__;
+ }
+
+
+ // for DatabaseMetaData.getDriverName()
+ public final static String dncDriverName = "Apache Derby Network Client JDBC Driver" ;
+
+
+ // Hard-wired for JDBC
+ //
+ // Currently ASCII hex value of "SYSLVL01".
+ public final static byte[] dncPackageConsistencyToken =
+ {0x53, 0x59, 0x53, 0x4c, 0x56, 0x4c, 0x30, 0x31};
+
+ // We will not set packagge VERSION in the initial release.
+ // If we have to change the package version in the future then we can.
+ public static String dncPackageVersion = null;
+
+ // for Driver.jdbcCompliant()
+ public final static boolean jdbcCompliant = true;
+
+ // for Driver.getCompatibileJREVersions()
+ public final static String[] dncCompatibleJREVersions = new String[] {"1.3", "1.4"};
+
+ //---------------------- database URL protocols ------------------------------
+
+ // For DatabaseMetaData.getURL()
+ public final static String jdbcDerbyNETProtocol = "jdbc:derby://";
+
+ // -------------------------- metrics ----------------------
+ // Not currently used by production builds.
+ // We can't really use this stuff with tracing enabled, the results are not accurate.
+
+ // -------------------------- compiled in properties -------------------------
+
+ public final static boolean enableNetConnectionPooling = true;
+
+ final static boolean rangeCheckCrossConverters = true;
+
+ // Define different levels of bug checking, for now turn all bits on.
+ final static int bugCheckLevel = 0xff;
+
+ // --------------------------- connection defaults ---------------------------
+
+ // This is the DERBY default and maps to DERBY's "Cursor Stability".
+ public final static int defaultIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED;
+
+ // ---------------------------- statement defaults----------------------------
+
+ public static final int defaultFetchSize = 64;
+
+ // Prepare attribute constants
+ public static final String cursorAttribute_SensitiveStatic = "SENSITIVE STATIC SCROLL ";
+ public static final String cursorAttribute_SensitiveStaticRowset = cursorAttribute_SensitiveStatic;
+ public static final String cursorAttribute_SensitiveDynamic = "SENSITIVE DYNAMIC SCROLL ";
+ public static final String cursorAttribute_SensitiveDynamicRowset = "SENSITIVE DYNAMIC SCROLL WITH ROWSET POSITIONING ";
+ public static final String cursorAttribute_Insensitive = "INSENSITIVE SCROLL ";
+ public static final String cursorAttribute_InsensitiveRowset = cursorAttribute_Insensitive;
+
+ // uncomment the following when we want to use multi-row fetch to support sensitive static and
+ // insensitve cursors whenever the server has support for it.
+ //public static final String cursorAttribute_SensitiveStaticRowset = "SENSITIVE STATIC SCROLL WITH ROWSET POSITIONING ";
+ //public static final String cursorAttribute_InsensitiveRowset = "INSENSITIVE SCROLL WITH ROWSET POSITIONING ";
+
+ public static final String cursorAttribute_ForUpdate = "FOR UPDATE ";
+ public static final String cursorAttribute_ForReadOnly = "FOR READ ONLY ";
+
+ public static final String cursorAttribute_WithHold = "WITH HOLD ";
+
+ // -----------------------Load resource bundles for the driver asap-----------
+
+ private static final String packageNameForDNC = "org.apache.derby.client";
+ private static final String classNameForResources = "org.apache.derby.client.resources.Resources";
+
+ public static SqlException exceptionsOnLoadResources = null; // used by ClientDriver to accumulate load exceptions
+ public static java.util.ResourceBundle dncResources__;
+
+ static {
+ try {
+ loadProductVersionHolder();
+ loadResources ();
+ }
+ catch (SqlException e) {
+ exceptionsOnLoadResources = e;
+ }
+ try {
+ jreLevel = System.getProperty( "java.version" );
+ }
+ catch (SecurityException e) {} // ignore it, assume 1.3.0
+ java.util.StringTokenizer st = new java.util.StringTokenizer( jreLevel, "." );
+ int jreState = 0;
+ while( st.hasMoreTokens() )
+ {
+ int i;
+ try
+ {
+ i = java.lang.Integer.parseInt(st.nextToken()); // get int value
+ }
+ catch( NumberFormatException e ) { i=0;}
+ switch( jreState++ )
+ {
+ case 0:
+ jreLevelMajor = i; // state 0, this is the major version
+ break;
+ case 1:
+ jreLevelMinor = i; // state 1, this is the minor version
+ break;
+ default:
+ break; // state >1, ignore
+ }
+ }
+ }
+
+ private static void loadResources () throws SqlException
+ {
+ try {
+ dncResources__ = (java.util.ResourceBundle) java.security.AccessController.doPrivileged (
+ new org.apache.derby.client.am.GetResourceBundleAction (classNameForResources));
+ }
+ catch (java.security.PrivilegedActionException e) {
+ throw new SqlException (null,
+ "[derby] " +
+ "PrivilegedActionException:" +
+ e.getException());
+ }
+ catch (java.util.MissingResourceException e) {
+ // A null log writer is passed, because jdbc 1 sql exceptions are automatically traced
+ throw new SqlException (null,
+ "[derby] " +
+ "Missing resource bundle:" +
+ " a resource bundle could not be found" +
+ " in the " + packageNameForDNC + " package for " + Configuration.dncDriverName);
+ }
+ }
+
+ public static void checkForExceptionsFromLoadConfiguration (LogWriter dncLogWriter) throws SqlException
+ {
+ if (dncResources__ == null) {
+ throw new SqlException (dncLogWriter,
+ "Missing resource bundle: a resource bundle could not be found" +
+ " in the " + Configuration.packageNameForDNC + " package for " + Configuration.dncDriverName);
+ }
+ }
+
+ /**
+ * load product version information and accumulate exceptions
+ */
+ private static void loadProductVersionHolder() throws SqlException
+ {
+ try {
+ dncProductVersionHolder__ = buildProductVersionHolder();
+ }
+ catch (java.security.PrivilegedActionException e) {
+ throw new SqlException (null,
+ "[derby] " +
+ "PrivilegedActionException:" +
+ e.getException());
+ }
+ catch (java.io.IOException ioe) {
+ throw new SqlException (null,
+ "[derby] " +
+ "IOException:" +
+ ioe);
+ }
+ }
+
+
+ // Create ProductVersionHolder in security block for Java 2 security.
+ private static ProductVersionHolder buildProductVersionHolder() throws
+ java.security.PrivilegedActionException, IOException
+ {
+ ProductVersionHolder myPVH= null;
+ myPVH = (ProductVersionHolder)
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction() {
+
+ public Object run() throws IOException
+ {
+ InputStream versionStream = getClass().getResourceAsStream(ProductGenusNames.DNC_INFO);
+
+ return ProductVersionHolder.getProductVersionHolderFromMyEnv(versionStream);
+ }
+ });
+
+ return myPVH;
+ }
+
+}
Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Configuration.java
------------------------------------------------------------------------------
svn:eol-style = native