001: /*-------------------------------------------------------------------------
002: *
003: * Copyright (c) 2004-2005, PostgreSQL Global Development Group
004: * Copyright (c) 2004, Open Cloud Limited.
005: *
006: * IDENTIFICATION
007: * $PostgreSQL: pgjdbc/org/postgresql/core/v3/ProtocolConnectionImpl.java,v 1.11 2006/12/01 08:53:45 jurka Exp $
008: *
009: *-------------------------------------------------------------------------
010: */
011: package org.postgresql.core.v3;
012:
013: import org.postgresql.PGNotification;
014: import org.postgresql.core.*;
015:
016: import java.sql.*;
017: import java.io.IOException;
018: import java.util.ArrayList;
019: import java.util.Properties;
020:
021: /**
022: * ProtocolConnection implementation for the V3 protocol.
023: *
024: * @author Oliver Jowett (oliver@opencloud.com)
025: */
026: class ProtocolConnectionImpl implements ProtocolConnection {
027: ProtocolConnectionImpl(PGStream pgStream, String user,
028: String database, Properties info, Logger logger) {
029: this .pgStream = pgStream;
030: this .user = user;
031: this .database = database;
032: this .logger = logger;
033: this .executor = new QueryExecutorImpl(this , pgStream, info,
034: logger);
035: // default value for server versions that don't report standard_conforming_strings
036: this .standardConformingStrings = false;
037: }
038:
039: public String getHost() {
040: return pgStream.getHost();
041: }
042:
043: public int getPort() {
044: return pgStream.getPort();
045: }
046:
047: public String getUser() {
048: return user;
049: }
050:
051: public String getDatabase() {
052: return database;
053: }
054:
055: public String getServerVersion() {
056: return serverVersion;
057: }
058:
059: public synchronized boolean getStandardConformingStrings() {
060: return standardConformingStrings;
061: }
062:
063: public synchronized int getTransactionState() {
064: return transactionState;
065: }
066:
067: public synchronized PGNotification[] getNotifications()
068: throws SQLException {
069: executor.processNotifies();
070: PGNotification[] array = (PGNotification[]) notifications
071: .toArray(new PGNotification[notifications.size()]);
072: notifications.clear();
073: return array;
074: }
075:
076: public synchronized SQLWarning getWarnings() {
077: SQLWarning chain = warnings;
078: warnings = null;
079: return chain;
080: }
081:
082: public QueryExecutor getQueryExecutor() {
083: return executor;
084: }
085:
086: public void sendQueryCancel() throws SQLException {
087: PGStream cancelStream = null;
088:
089: // Now we need to construct and send a cancel packet
090: try {
091: if (logger.logDebug())
092: logger.debug(" FE=> CancelRequest(pid=" + cancelPid
093: + ",ckey=" + cancelKey + ")");
094:
095: cancelStream = new PGStream(pgStream.getHost(), pgStream
096: .getPort());
097: cancelStream.SendInteger4(16);
098: cancelStream.SendInteger2(1234);
099: cancelStream.SendInteger2(5678);
100: cancelStream.SendInteger4(cancelPid);
101: cancelStream.SendInteger4(cancelKey);
102: cancelStream.flush();
103: cancelStream.ReceiveEOF();
104: cancelStream.close();
105: cancelStream = null;
106: } catch (IOException e) {
107: // Safe to ignore.
108: if (logger.logDebug())
109: logger
110: .debug("Ignoring exception on cancel request:",
111: e);
112: } finally {
113: if (cancelStream != null) {
114: try {
115: cancelStream.close();
116: } catch (IOException e) {
117: // Ignored.
118: }
119: }
120: }
121: }
122:
123: public void close() {
124: if (closed)
125: return;
126:
127: try {
128: if (logger.logDebug())
129: logger.debug(" FE=> Terminate");
130:
131: pgStream.SendChar('X');
132: pgStream.SendInteger4(4);
133: pgStream.flush();
134: pgStream.close();
135: } catch (IOException ioe) {
136: // Forget it.
137: if (logger.logDebug())
138: logger.debug("Discarding IOException on close:", ioe);
139: }
140:
141: closed = true;
142: }
143:
144: public Encoding getEncoding() {
145: return pgStream.getEncoding();
146: }
147:
148: public boolean isClosed() {
149: return closed;
150: }
151:
152: //
153: // Package-private accessors called during connection setup
154: //
155:
156: void setServerVersion(String serverVersion) {
157: this .serverVersion = serverVersion;
158: }
159:
160: void setBackendKeyData(int cancelPid, int cancelKey) {
161: this .cancelPid = cancelPid;
162: this .cancelKey = cancelKey;
163: }
164:
165: //
166: // Package-private accessors called by the query executor
167: //
168:
169: synchronized void addWarning(SQLWarning newWarning) {
170: if (warnings == null)
171: warnings = newWarning;
172: else
173: warnings.setNextWarning(newWarning);
174: }
175:
176: synchronized void addNotification(PGNotification notification) {
177: notifications.add(notification);
178: }
179:
180: synchronized void setTransactionState(int state) {
181: transactionState = state;
182: }
183:
184: synchronized void setStandardConformingStrings(boolean value) {
185: standardConformingStrings = value;
186: }
187:
188: public int getProtocolVersion() {
189: return 3;
190: }
191:
192: private String serverVersion;
193: private int cancelPid;
194: private int cancelKey;
195:
196: private boolean standardConformingStrings;
197: private int transactionState;
198: private SQLWarning warnings;
199:
200: private boolean closed = false;
201:
202: private final ArrayList notifications = new ArrayList();
203:
204: private final PGStream pgStream;
205: private final String user;
206: private final String database;
207: private final QueryExecutorImpl executor;
208: private final Logger logger;
209: }
|