001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v2.c3p0.stmt;
024:
025: import java.sql.Connection;
026: import java.lang.reflect.Method;
027: import java.util.Arrays;
028: import com.mchange.v1.util.ArrayUtils;
029: import com.mchange.v2.lang.ObjectUtils;
030:
031: abstract class StatementCacheKey {
032: static final int SIMPLE = 0;
033: static final int MEMORY_COALESCED = 1;
034: static final int VALUE_IDENTITY = 2;
035:
036: //NOTE: subclasses rely upon their _find logic being protected by StatementCacheKey.class' lock!
037: public synchronized static StatementCacheKey find(Connection pcon,
038: Method stmtProducingMethod, Object[] args) {
039: switch (VALUE_IDENTITY) {
040: case SIMPLE:
041: return SimpleStatementCacheKey._find(pcon,
042: stmtProducingMethod, args);
043: case MEMORY_COALESCED:
044: return MemoryCoalescedStatementCacheKey._find(pcon,
045: stmtProducingMethod, args);
046: case VALUE_IDENTITY:
047: return ValueIdentityStatementCacheKey._find(pcon,
048: stmtProducingMethod, args);
049: default:
050: throw new InternalError(
051: "StatementCacheKey.find() is misconfigured.");
052: }
053: }
054:
055: //MT: instances are treated as immutable once they
056: // have been initialized and handed to
057: // a client. (Factories may reinitialize
058: // instances that never get released to
059: // clients -- those factories must prevent
060: // concurrent access to these recycled,
061: // nascent keys.)
062: Connection physicalConnection;
063: String stmtText;
064: boolean is_callable;
065: int result_set_type;
066: int result_set_concurrency;
067:
068: int[] columnIndexes; //jdbc3, null means default
069: String[] columnNames; //jdbc3, null means default
070:
071: Integer autogeneratedKeys; //jdbc3, null means driver default, which the spec does not sepcify
072: Integer resultSetHoldability; //jdbc3, null means driver default, which the spec does not sepcify
073:
074: StatementCacheKey() {
075: }
076:
077: StatementCacheKey(Connection physicalConnection, String stmtText,
078: boolean is_callable, int result_set_type,
079: int result_set_concurrency, int[] columnIndexes,
080: String[] columnNames, Integer autogeneratedKeys,
081: Integer resultSetHoldability) {
082: init(physicalConnection, stmtText, is_callable,
083: result_set_type, result_set_concurrency, columnIndexes,
084: columnNames, autogeneratedKeys, resultSetHoldability);
085: }
086:
087: void init(Connection physicalConnection, String stmtText,
088: boolean is_callable, int result_set_type,
089: int result_set_concurrency, int[] columnIndexes, //jdbc3
090: String[] columnNames, //jdbc3
091: Integer autogeneratedKeys, //jdbc3
092: Integer resultSetHoldability) //jdbc3
093: {
094: this .physicalConnection = physicalConnection;
095: this .stmtText = stmtText;
096: this .is_callable = is_callable;
097: this .result_set_type = result_set_type;
098: this .result_set_concurrency = result_set_concurrency;
099: this .columnIndexes = columnIndexes;
100: this .columnNames = columnNames;
101: this .autogeneratedKeys = autogeneratedKeys;
102: this .resultSetHoldability = resultSetHoldability;
103: }
104:
105: static boolean equals(StatementCacheKey _this , Object o) {
106: //TODO: assert( _this != null )
107:
108: if (_this == o)
109: return true;
110: if (o instanceof StatementCacheKey) {
111: StatementCacheKey sck = (StatementCacheKey) o;
112:
113: // System.err.println( sck.physicalConnection + " " +
114: // _this.physicalConnection + " equals? " +
115: // sck.physicalConnection.equals( _this.physicalConnection ) );
116:
117: return sck.physicalConnection
118: .equals(_this .physicalConnection)
119: && sck.stmtText.equals(_this .stmtText)
120: && sck.is_callable == _this .is_callable
121: && sck.result_set_type == _this .result_set_type
122: && sck.result_set_concurrency == _this .result_set_concurrency
123: && Arrays.equals(sck.columnIndexes,
124: _this .columnIndexes)
125: && Arrays
126: .equals(sck.columnNames, _this .columnNames)
127: && ObjectUtils.eqOrBothNull(sck.autogeneratedKeys,
128: _this .autogeneratedKeys)
129: && ObjectUtils.eqOrBothNull(
130: sck.resultSetHoldability,
131: _this .resultSetHoldability);
132: } else
133: return false;
134: }
135:
136: static int hashCode(StatementCacheKey _this ) {
137: return _this .physicalConnection.hashCode()
138: ^ _this .stmtText.hashCode()
139: ^ (_this .is_callable ? 1 : 0) ^ _this .result_set_type
140: ^ _this .result_set_concurrency
141: ^ ArrayUtils.hashOrZeroArray(_this .columnIndexes)
142: ^ ArrayUtils.hashOrZeroArray(_this .columnNames)
143: ^ ObjectUtils.hashOrZero(_this .autogeneratedKeys) ^ //this is okay -- genuine constants are non-zer0
144: ObjectUtils.hashOrZero(_this .resultSetHoldability); //this is okay -- genuine constants are non-zer0
145: }
146:
147: public String toString() {
148: StringBuffer out = new StringBuffer(128);
149: out.append("[" + this .getClass().getName() + ": ");
150: out.append("physicalConnection->" + physicalConnection);
151: out.append(", stmtText->" + stmtText);
152: out.append(", is_callable->" + is_callable);
153: out.append(", result_set_type->" + result_set_type);
154: out.append(", result_set_concurrency->"
155: + result_set_concurrency);
156: out.append(", columnIndexes->"
157: + ArrayUtils.toString(columnIndexes));
158: out
159: .append(", columnNames->"
160: + ArrayUtils.toString(columnNames));
161: out.append(", autogeneratedKeys->" + autogeneratedKeys);
162: out.append(", resultSetHoldability->" + resultSetHoldability);
163: out.append(']');
164: return out.toString();
165: }
166: }
|