00001
00025
package org.objectweb.cjdbc.driver;
00026
00027
import java.io.IOException;
00028
import java.net.Socket;
00029
import java.sql.ResultSet;
00030
import java.sql.SQLException;
00031
import java.sql.SQLWarning;
00032
import java.sql.Savepoint;
00033
import java.util.ArrayList;
00034
import java.util.Hashtable;
00035
import java.util.Properties;
00036
00037
import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException;
00038
import org.objectweb.cjdbc.common.sql.AbstractRequest;
00039
import org.objectweb.cjdbc.common.sql.AbstractWriteRequest;
00040
import org.objectweb.cjdbc.common.sql.NotImplementedException;
00041
import org.objectweb.cjdbc.common.sql.SelectRequest;
00042
import org.objectweb.cjdbc.common.sql.StoredProcedure;
00043
import org.objectweb.cjdbc.common.sql.filters.AbstractBlobFilter;
00044
import org.objectweb.cjdbc.common.sql.filters.HexaBlobFilter;
00045
import org.objectweb.cjdbc.common.stream.CJDBCInputStream;
00046
import org.objectweb.cjdbc.common.stream.CJDBCOutputStream;
00047
import org.objectweb.cjdbc.common.util.Constants;
00048
import org.objectweb.cjdbc.driver.protocol.CommandCompleted;
00049
import org.objectweb.cjdbc.driver.protocol.Commands;
00050
00067 public class Connection implements java.sql.
Connection
00068 {
00069
00070
00072 protected boolean autoCommit =
true;
00073
00075 protected boolean isClosed =
false;
00076
00078 protected boolean readOnly =
false;
00079
00081 protected int isolationLevel = java.sql.Connection.TRANSACTION_READ_COMMITTED;
00082
00084 protected long transactionId = 0;
00085
00087 protected boolean needSqlSkeleton =
false;
00088
00090 protected SQLWarning
firstWarning = null;
00091
00093 protected DatabaseMetaData metaData = null;
00094
00096 protected Driver driver = null;
00097
00099 protected String
url = null;
00100
00102 protected String
vdbUser = null;
00103 protected String
vdbPassword = null;
00104
00106 protected Socket
socket;
00107
00109 protected CJDBCInputStream
socketInput;
00110
00112 protected CJDBCOutputStream
socketOutput;
00113
00114 private int reconnectRetries = 0;
00115
00116
00117 private static final int MAX_RECONNECT_ATTEMPTS = 2;
00118
00119 private AbstractBlobFilter
blobFilter;
00120
00121
00122 protected boolean escapeBackslash =
true;
00123 protected boolean escapeSingleQuote =
true;
00124
00125
00126 protected boolean driverProcessed =
true;
00128 public static String
startParamTag =
"<?";
00130 public static String
endParamTag =
"|?>";
00131
00132
00133 protected String
preparedStatementBooleanTrue =
"'1'";
00134 protected String
preparedStatementBooleanFalse =
"'0'";
00135
00136 protected String
escapeChar =
"\'";
00137
00138 protected static final String
LINE_SEPARATOR = System
00139 .getProperty(
"line.separator");
00140
00141 private boolean closeSocketOnGC =
true;
00142
00143
00144
00145
00146
00147
00151 public Connection()
00152 {
00153 }
00154
00169 public Connection(
Driver driver, Socket socket, CJDBCInputStream in,
00170 CJDBCOutputStream out, String url, String userName, String password,
00171
boolean sqlSkeletonNeeded, AbstractBlobFilter filter)
00172 {
00173
this.driver = driver;
00174
this.socket = socket;
00175
this.socketInput = in;
00176
this.socketOutput = out;
00177
this.url = url;
00178
this.vdbUser = userName;
00179
this.vdbPassword = password;
00180
this.needSqlSkeleton = sqlSkeletonNeeded;
00181
this.blobFilter = filter;
00182 }
00183
00187 protected void finalize() throws Throwable
00188 {
00189
if (
this.closeSocketOnGC)
00190 {
00191 Throwable t = null;
00192
try
00193 {
00194
rollback();
00195 }
00196
catch (Exception e)
00197 {
00198 t = e;
00199 }
00200
try
00201 {
00202
close();
00203 }
00204
catch (Exception e)
00205 {
00206 t = e;
00207 }
00208
00209
if (t != null)
00210 {
00211
throw t;
00212 }
00213
00214 }
00215 super.finalize();
00216 }
00217
00223 public String
getURL()
00224 {
00225
return url;
00226 }
00227
00233 public String
getUserName()
00234 {
00235
return vdbUser;
00236 }
00237
00243 public String
getPassword()
00244 {
00245
return vdbUser;
00246 }
00247
00254 public String
getConnectedController()
00255 {
00256
if (
socket == null)
00257
return null;
00258
else
00259
return socket.getInetAddress().getHostName() +
":" +
socket.getPort();
00260 }
00261
00262
00263
00264
00265
00266
00273 public void clearWarnings() throws SQLException
00274 {
00275
firstWarning = null;
00276 }
00277
00285 public void close() throws SQLException
00286 {
00287
00288
00289
synchronized (
this)
00290 {
00291
if (
isClosed)
00292
return;
00293
else
00294
isClosed =
true;
00295 }
00296
00297
try
00298 {
00299
autoCommit =
true;
00300
readOnly =
false;
00301
socketOutput.writeInt(
Commands.Reset);
00302
socketOutput.flush();
00303 }
00304
catch (Exception e)
00305 {
00306
throw new SQLException(
"Error while closing the connection: " + e);
00307 }
00308
00309
synchronized (
driver.
pendingConnectionClosing)
00310 {
00311
if (!
driver.
connectionClosingThreadisAlive)
00312 {
00313
ConnectionClosingThread t =
new ConnectionClosingThread(
driver);
00314 t.start();
00315 }
00316
00317
driver.
pendingConnectionClosing.add(
this);
00318 }
00319 }
00320
00332 public void commit() throws SQLException
00333 {
00334
if (
autoCommit)
00335
throw new SQLException(
"Trying to commit a connection in autocommit mode");
00336
00337
if (
driver == null)
00338
throw new SQLException(
"No driver to send the commit request");
00339
try
00340 {
00341
socketOutput.writeInt(
Commands.Commit);
00342
socketOutput.flush();
00343
00344 Object r =
socketInput.readObject();
00345
if (r instanceof Long)
00346
transactionId = ((Long) r).longValue();
00347
else
00348
throw new SQLException(
00349
"Error occured while trying to start transaction after commit on C-JDBC Controller ("
00350 + r +
")");
00351 }
00352
catch (Exception e)
00353 {
00354
throw new SQLException(
"Error occured while commit of transaction '"
00355 +
transactionId +
"' was processed by C-JDBC Controller (" + e +
")");
00356 }
00357 }
00358
00369 public java.sql.Statement
createStatement() throws SQLException
00370 {
00371
return new Statement(
this);
00372 }
00373
00384 public java.sql.Statement
createStatement(
int resultSetType,
00385
int resultSetConcurrency)
throws SQLException
00386 {
00387
Statement s =
new Statement(
this);
00388 s.
setResultSetType(resultSetType);
00389 s.
setResultSetConcurrency(resultSetConcurrency);
00390
return s;
00391 }
00392
00400 public boolean getAutoCommit() throws SQLException
00401 {
00402
return this.autoCommit;
00403 }
00404
00414 public java.sql.DatabaseMetaData
getMetaData() throws SQLException
00415 {
00416
if (
metaData == null)
00417 {
00418
metaData =
new DatabaseMetaData(
this);
00419 }
00420
return metaData;
00421 }
00422
00430 public String
getCatalog() throws SQLException
00431 {
00432
if (
driver == null)
00433
throw new SQLException(
"No driver to get the catalog.");
00434
try
00435 {
00436
socketOutput.writeInt(
Commands.DatabaseMetaDataGetCatalog);
00437
socketOutput.flush();
00438
00439 Object rs =
socketInput.readObject();
00440
if (rs instanceof String)
00441 {
00442
return (String) rs;
00443 }
00444
else if (rs instanceof SQLException)
00445
throw (SQLException) rs;
00446
else
00447
throw new SQLException(
"Connection.getCatalog: Unexpected response ("
00448 + rs +
")");
00449 }
00450
catch (Exception e)
00451 {
00452
throw new SQLException(
00453
"Connection.getCatalog: Error occured while request was processed by C-JDBC Controller ("
00454 + e +
")");
00455 }
00456 }
00457
00464 public ResultSet
getCatalogs() throws SQLException
00465 {
00466
00467
if (
driver == null)
00468
throw new SQLException(
"No driver to get the catalogs.");
00469
try
00470 {
00471
socketOutput.writeInt(
Commands.DatabaseMetaDataGetCatalogs);
00472
socketOutput.flush();
00473
00474 Object rs =
socketInput.readObject();
00475
if (rs instanceof ResultSet)
00476
return (ResultSet) rs;
00477
else if (rs instanceof SQLException)
00478
throw (SQLException) rs;
00479
else
00480
throw new SQLException(
"Connection.getCatalogs: Unexpected response ("
00481 + rs +
")");
00482 }
00483
catch (Exception e)
00484 {
00485
throw new SQLException(
00486
"Connection.getCatalogs: Error occured while request was processed by C-JDBC Controller ("
00487 + e +
")");
00488 }
00489 }
00490
00491 protected java.sql.ResultSet
getProcedures(String catalog,
00492 String schemaPattern, String procedureNamePattern)
throws SQLException
00493 {
00494
if (
driver == null)
00495
throw new SQLException(
"No driver to get the tables.");
00496
try
00497 {
00498
socketOutput.writeInt(
Commands.DatabaseMetaDataGetProcedures);
00499
socketOutput.writeUTF(catalog);
00500
socketOutput.writeUTF(schemaPattern);
00501
socketOutput.writeUTF(procedureNamePattern);
00502
socketOutput.flush();
00503
00504 Object rs =
socketInput.readObject();
00505
if (rs instanceof ResultSet)
00506
return (ResultSet) rs;
00507
else if (rs instanceof SQLException)
00508
throw (SQLException) rs;
00509
else
00510
throw new SQLException(
00511
"Connection.getProcedures: Unexpected response (" + rs +
")");
00512 }
00513
catch (Exception e)
00514 {
00515
throw new SQLException(
00516
"Connection.getProcedures: Error occured while request was processed by C-JDBC Controller ("
00517 + e +
")");
00518 }
00519 }
00520
00521 protected java.sql.ResultSet
getProcedureColumns(String catalog,
00522 String schemaPattern, String procedureNamePattern,
00523 String columnNamePattern)
throws SQLException
00524 {
00525
if (
driver == null)
00526
throw new SQLException(
"No driver to get the tables.");
00527
try
00528 {
00529
socketOutput.writeInt(
Commands.DatabaseMetaDataGetProcedureColumns);
00530
socketOutput.writeUTF(catalog);
00531
socketOutput.writeUTF(schemaPattern);
00532
socketOutput.writeUTF(procedureNamePattern);
00533
socketOutput.writeUTF(columnNamePattern);
00534
socketOutput.flush();
00535
00536 Object rs =
socketInput.readObject();
00537
if (rs instanceof ResultSet)
00538
return (ResultSet) rs;
00539
else if (rs instanceof SQLException)
00540
throw (SQLException) rs;
00541
else
00542
throw new SQLException(
00543
"Connection.getProcedureColumns: Unexpected response (" + rs +
")");
00544 }
00545
catch (Exception e)
00546 {
00547
throw new SQLException(
00548
"Connection.getProcedureColumns: Error occured while request was processed by C-JDBC Controller ("
00549 + e +
")");
00550 }
00551 }
00552
00559 public int getTransactionIsolation() throws SQLException
00560 {
00561
return isolationLevel;
00562 }
00563
00570 public java.util.Map
getTypeMap() throws SQLException
00571 {
00572
throw new NotImplementedException(
"getTypeMap()");
00573 }
00574
00582 public SQLWarning
getWarnings() throws SQLException
00583 {
00584
return firstWarning;
00585 }
00586
00595 public boolean isClosed() throws SQLException
00596 {
00597
return isClosed;
00598 }
00599
00608 public boolean isReadOnly() throws SQLException
00609 {
00610
return readOnly;
00611 }
00612
00622 public String
nativeSQL(String query)
throws SQLException
00623 {
00624
return query;
00625 }
00626
00635 public java.sql.CallableStatement
prepareCall(String sql)
throws SQLException
00636 {
00637
return prepareCall(sql, java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
00638 java.sql.ResultSet.CONCUR_READ_ONLY);
00639 }
00640
00650 public java.sql.CallableStatement
prepareCall(String sql,
int resultSetType,
00651
int resultSetConcurrency)
throws SQLException
00652 {
00653
CallableStatement c =
new CallableStatement(
this, sql);
00654 c.
setResultSetType(resultSetType);
00655 c.
setResultSetConcurrency(resultSetConcurrency);
00656
return c;
00657 }
00658
00670 public java.
sql.PreparedStatement
prepareStatement(String sql)
00671
throws SQLException
00672 {
00673
return new PreparedStatement(
this, sql);
00674 }
00675
00687 public java.sql.PreparedStatement
prepareStatement(String sql,
00688
int resultSetType,
int resultSetConcurrency)
throws SQLException
00689 {
00690
PreparedStatement s =
new PreparedStatement(
this, sql);
00691 s.
setResultSetType(resultSetType);
00692 s.
setResultSetConcurrency(resultSetConcurrency);
00693
return s;
00694 }
00695
00705 public void rollback() throws SQLException
00706 {
00707
if (
autoCommit)
00708
throw new SQLException(
00709
"Trying to rollback a connection in autocommit mode");
00710
00711
if (
driver == null)
00712
throw new SQLException(
"No driver to send the rollback request");
00713
00714
try
00715 {
00716
socketOutput.writeInt(
Commands.Rollback);
00717
socketOutput.flush();
00718
00719 Object r =
socketInput.readObject();
00720
if (r instanceof Long)
00721
transactionId = ((Long) r).longValue();
00722
else
00723
throw new SQLException(
00724
"Error occured while trying to start transaction after rollback on C-JDBC Controller ("
00725 + r +
")");
00726 }
00727
catch (Exception e)
00728 {
00729
throw new SQLException(
"Error occured while rollback of transaction '"
00730 +
transactionId +
"' was processed by C-JDBC Controller (" + e +
")");
00731 }
00732 }
00733
00752 public void setAutoCommit(
boolean autoCommit)
throws SQLException
00753 {
00754
if (
this.autoCommit ==
autoCommit)
00755
return;
00756
00757
this.autoCommit =
autoCommit;
00758
if (
driver == null)
00759
throw new SQLException(
"No driver to get a transaction id");
00760
00761
if (
autoCommit)
00762 {
00763
transactionId = 0;
00764
try
00765 {
00766
socketOutput.writeInt(
Commands.SetAutoCommit);
00767
socketOutput.flush();
00768 Object r =
socketInput.readObject();
00769
if (r instanceof Boolean || ((Boolean) r).booleanValue())
00770
return;
00771
else
00772
throw new SQLException(
00773
"Error occured while trying to change autocommit value on C-JDBC Controller ("
00774 + r +
")");
00775 }
00776
catch (Exception e)
00777 {
00778
throw new SQLException(
00779
"Error occured while trying to change autocommit value on C-JDBC Controller ("
00780 + e +
")");
00781 }
00782 }
00783
else
00784 {
00785
00786
try
00787 {
00788
socketOutput.writeInt(
Commands.Begin);
00789
socketOutput.flush();
00790 Object r =
socketInput.readObject();
00791
if (r instanceof Long)
00792
transactionId = ((Long) r).longValue();
00793
else
00794
throw new SQLException(
00795
"Error occured while trying to start transaction on C-JDBC Controller ("
00796 + r +
")");
00797
this.autoCommit =
false;
00798 }
00799
catch (Exception e)
00800 {
00801
throw new SQLException(
00802
"Error occured while trying to start transaction on C-JDBC Controller ("
00803 + e +
")");
00804 }
00805 }
00806 }
00807
00814 public void setCatalog(String catalog)
throws SQLException
00815 {
00816
if (catalog == null)
00817
throw new SQLException(
"Invalid Catalog");
00818 Hashtable properties =
driver.
parseURL(
url);
00819 properties.put(
Driver.DATABASE_PROPERTY, catalog);
00820
url =
driver.
getUrlFromProperties(properties);
00821
00822
if (
driver == null)
00823
throw new SQLException(
"No driver to set the catalog.");
00824
try
00825 {
00826
socketOutput.writeInt(
Commands.ConnectionSetCatalog);
00827
socketOutput.writeUTF(catalog);
00828
socketOutput.flush();
00829
00830 Object rs =
socketInput.readObject();
00831
if (rs instanceof Boolean)
00832 {
00833
if (((Boolean) rs).booleanValue() ==
false)
00834
throw new SQLException(
"Invalid Catalog");
00835 }
00836
else
00837
throw new SQLException(
"Connection.setCatalog: Unexpected response ("
00838 + rs +
")");
00839 }
00840
catch (Exception e)
00841 {
00842
throw new SQLException(
00843
"Connection.setCatalog: Error occured while request was processed by C-JDBC Controller ("
00844 + e +
")");
00845 }
00846 }
00847
00859 public void setReadOnly(
boolean readOnly)
throws SQLException
00860 {
00861
if (
autoCommit ==
false)
00862
throw new SQLException(
00863
"setReadOnly cannot be called while in the middle of a transaction.");
00864
00865
this.readOnly =
readOnly;
00866 }
00867
00880 public void setTransactionIsolation(
int level)
throws SQLException
00881 {
00882
isolationLevel = level;
00883 }
00884
00891 public void setTypeMap(java.util.Map map) throws SQLException
00892 {
00893
throw new NotImplementedException(
"setTypeMap()");
00894 }
00895
00896
00897
00898
00899
00905 protected void setConnectionParametersOnRequest(
AbstractRequest request)
00906 {
00907 request.
setIsAutoCommit(
autoCommit);
00908 request.
setIsReadOnly(
readOnly);
00909 request.
setDriverProcessed(
driverProcessed);
00910 }
00911
00919 protected java.sql.ResultSet
execReadRequest(
SelectRequest request)
00920
throws SQLException
00921 {
00922
if (
driver == null)
00923
throw new SQLException(
"No driver to send the request '"
00924 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH) +
"'");
00925
try
00926 {
00927
setConnectionParametersOnRequest(request);
00928
socketOutput.writeInt(
Commands.ExecReadRequest);
00929
readRequestOnStream(request);
00930
socketOutput.flush();
00931
00932 Object in =
socketInput.readObject();
00933
if (in instanceof
NoMoreBackendException)
00934 {
00935
try
00936 {
00937
00938
if (
driver.
getControllerConfig().size() == 1)
00939
throw (SQLException) in;
00940
else
00941 {
00942
00943
00944
reconnect();
00945
return execReadRequest(request);
00946 }
00947 }
00948
catch (SQLException e1)
00949 {
00950
00951 in = e1;
00952 }
00953 }
00954
if (in instanceof IOException)
00955 {
00956
reconnect();
00957
return execReadRequest(request);
00958 }
00959
else if (in instanceof SQLException)
00960 {
00961
throw (SQLException) in;
00962 }
00963
else if (in instanceof
Field[])
00964 {
00965 Field[] fields = (Field[]) in;
00966 ArrayList data = null;
00967
boolean hasMoreData;
00968 String cursorName = null;
00969
try
00970 {
00971 data = (ArrayList)
socketInput.readObject();
00972 hasMoreData =
socketInput.readBoolean();
00973
if (hasMoreData)
00974 cursorName =
socketInput.readUTF();
00975 }
00976
catch (IOException e)
00977 {
00978
reconnect();
00979
return execReadRequest(request);
00980 }
00981
catch (Exception e1)
00982 {
00983
throw new SQLException(
00984
"Connection.execReadRequest: Unexpected response (" + e1
00985 +
") for request "
00986 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
00987 }
00988
return new org.objectweb.cjdbc.driver.DriverResultSet(fields, data,
00989 hasMoreData, cursorName);
00990 }
00991
else
00992 {
00993
throw new SQLException(
00994
"Connection.execReadRequest: Unexpected response (" + in
00995 +
") for request "
00996 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
00997 }
00998
00999 }
01000
catch (RuntimeException e)
01001 {
01002 e.printStackTrace();
01003
throw new SQLException(
01004
"Connection.execReadRequest: Error occured while request '"
01005 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01006 +
"' was processed by C-JDBC Controller (" + e +
")");
01007 }
01008
catch (IOException e)
01009 {
01010
try
01011 {
01012
reconnect();
01013
return execReadRequest(request);
01014 }
01015
catch (SQLException e1)
01016 {
01017
throw new SQLException(
"Connection lost while executing request '"
01018 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01019 +
"' and automatic reconnect failed (" + e1 +
")");
01020 }
01021 }
01022
catch (ClassNotFoundException e)
01023 {
01024 e.printStackTrace();
01025
throw new SQLException(
01026
"Connection.execReadRequest: Unexpected response (" + e
01027 +
") for request "
01028 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01029 }
01030 }
01031
01032 private void reconnect() throws SQLException
01033 {
01034
01035
try
01036 {
01037
this.socket.close();
01038 }
01039
catch (IOException ignore)
01040 {
01041 }
01042
try
01043 {
01044
this.socketInput.close();
01045 }
01046
catch (IOException ignore)
01047 {
01048 }
01049
try
01050 {
01051
this.socketOutput.close();
01052 }
01053
catch (IOException ignore)
01054 {
01055 }
01056
synchronized (
driver.
pendingConnectionClosing)
01057 {
01058
if (
driver.
pendingConnectionClosing.remove(
this))
01059 System.out.println(
"Warning! Closed call before reconnect");
01060 }
01061
01062
01063
reconnectRetries++;
01064
if (
reconnectRetries >
MAX_RECONNECT_ATTEMPTS)
01065 {
01066
reconnectRetries = 0;
01067
throw new SQLException(
"Aborting after " +
MAX_RECONNECT_ATTEMPTS
01068 +
" attemps.");
01069 }
01070 Properties prop =
new Properties();
01071 prop.setProperty(
Driver.USER_PROPERTY,
vdbUser);
01072 prop.setProperty(
Driver.PASSWORD_PROPERTY,
vdbPassword);
01073
Connection c = (
Connection)
driver.
connect(
url, prop);
01074 c.
setCloseSocketOnGC(
false);
01075
this.socket = c.
socket;
01076
this.socketInput = c.
socketInput;
01077
this.socketOutput = c.
socketOutput;
01078
this.isClosed =
false;
01079
try
01080 {
01081
socketOutput.writeInt(
Commands.RestoreConnectionState);
01082
socketOutput.writeBoolean(
autoCommit);
01083
if (!
autoCommit)
01084
socketOutput.writeLong(
transactionId);
01085 }
01086
catch (IOException e)
01087 {
01088
throw new SQLException(
"Failed to reconnect to controller (" + e +
")");
01089 }
01090
reconnectRetries = 0;
01091 }
01092
01098 protected void setCloseSocketOnGC(
boolean closeSocketOnGC)
01099 {
01100
this.closeSocketOnGC = closeSocketOnGC;
01101 }
01102
01110 protected int execWriteRequest(
AbstractWriteRequest request)
01111
throws SQLException
01112 {
01113
if (
driver == null)
01114
throw new SQLException(
"No driver to send the request '"
01115 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH) +
"'");
01116
try
01117 {
01118
setConnectionParametersOnRequest(request);
01119
socketOutput.writeInt(
Commands.ExecWriteRequest);
01120
writeRequestOnStream(request,
false);
01121
socketOutput.flush();
01122
01123 Object r =
socketInput.readObject();
01124
if (r instanceof Integer)
01125
return ((Integer) r).intValue();
01126
else if (r instanceof SQLException)
01127
throw (SQLException) r;
01128
else
01129
throw new SQLException(
01130
"Connection.execWriteRequest: Unexpected response (" + r
01131 +
") for request "
01132 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01133 }
01134
catch (IOException e)
01135 {
01136
try
01137 {
01138
reconnect();
01139
return execWriteRequest(request);
01140 }
01141
catch (SQLException e1)
01142 {
01143
throw new SQLException(
"Connection lost while executing request'"
01144 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01145 +
"' and automatic reconnect failed (" + e1 +
")");
01146 }
01147 }
01148
catch (Exception e)
01149 {
01150
throw new SQLException(
"execWriteRequest: Error occured while request '"
01151 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01152 +
"' was processed by C-JDBC Controller (" + e +
")");
01153 }
01154 }
01155
01163 private void readRequestOnStream(
SelectRequest request)
throws IOException
01164 {
01165
01166
socketOutput.writeUTF(request.getSQL());
01167
socketOutput.writeBoolean(request.getEscapeProcessing());
01168
socketOutput.writeUTF(
LINE_SEPARATOR);
01169
socketOutput.writeInt(request.getTimeout());
01170
socketOutput.writeBoolean(request.isAutoCommit());
01171
socketOutput.writeBoolean(request.isDriverProcessed());
01172
socketOutput.writeInt(request.getMaxRows());
01173
socketOutput.writeInt(request.getFetchSize());
01174 String cursor = request.getCursorName();
01175
if (cursor != null)
01176 {
01177
socketOutput.writeBoolean(
true);
01178
socketOutput.writeUTF(cursor);
01179 }
01180
else
01181
socketOutput.writeBoolean(
false);
01182
01183
01184
if (
needSqlSkeleton || !request.isDriverProcessed())
01185 {
01186 String skeleton = request.getSqlSkeleton();
01187
if (skeleton != null)
01188 {
01189
socketOutput.writeBoolean(
true);
01190
socketOutput.writeUTF(skeleton);
01191 }
01192
else
01193
socketOutput.writeBoolean(
false);
01194 }
01195
01196 }
01197
01206 private void procedureOnStream(
StoredProcedure proc,
boolean isRead)
01207
throws IOException
01208 {
01209
01210
socketOutput.writeUTF(proc.getSQL());
01211
socketOutput.writeBoolean(proc.getEscapeProcessing());
01212
socketOutput.writeUTF(
LINE_SEPARATOR);
01213
socketOutput.writeInt(proc.getTimeout());
01214
socketOutput.writeBoolean(proc.isAutoCommit());
01215
socketOutput.writeBoolean(proc.isDriverProcessed());
01216
if (isRead)
01217 {
01218
socketOutput.writeInt(proc.getMaxRows());
01219
socketOutput.writeInt(proc.getFetchSize());
01220 }
01221
01222
01223
if (
needSqlSkeleton || !proc.isDriverProcessed())
01224 {
01225 String skeleton = proc.getSqlSkeleton();
01226
if (skeleton != null)
01227 {
01228
socketOutput.writeBoolean(
true);
01229
socketOutput.writeUTF(skeleton);
01230 }
01231
else
01232
socketOutput.writeBoolean(
false);
01233 }
01234
01235 }
01236
01246 private void writeRequestOnStream(
AbstractWriteRequest request,
01247
boolean withKeys)
throws IOException
01248 {
01249
01250
boolean isCreate = request.isCreate();
01251
boolean isDelete = request.isDelete();
01252
boolean isDrop = request.isDrop();
01253
boolean isInsert = request.isInsert();
01254
boolean isUpdate = request.isUpdate();
01255
boolean isAlter = request.isAlter();
01256
int requestType = -1;
01257
if (isCreate)
01258 requestType =
Commands.CreateRequest;
01259
else if (isDelete)
01260 requestType =
Commands.DeleteRequest;
01261
else if (isDrop)
01262 requestType =
Commands.DropRequest;
01263
else if (isInsert)
01264 requestType =
Commands.InsertRequest;
01265
else if (isUpdate)
01266 requestType =
Commands.UpdateRequest;
01267
else if (isAlter)
01268 requestType =
Commands.AlterRequest;
01269
01270
socketOutput.writeInt(requestType);
01271
socketOutput.writeUTF(request.getSQL());
01272
socketOutput.writeBoolean(request.getEscapeProcessing());
01273
socketOutput.writeUTF(
LINE_SEPARATOR);
01274
socketOutput.writeInt(request.getTimeout());
01275
socketOutput.writeBoolean(request.isAutoCommit());
01276
socketOutput.writeBoolean(request.isDriverProcessed());
01277
if (withKeys)
01278 {
01279
socketOutput.writeInt(request.getMaxRows());
01280
socketOutput.writeInt(request.getFetchSize());
01281 }
01282
01283
01284
01285
if (
needSqlSkeleton || !request.isDriverProcessed())
01286 {
01287 String skeleton = request.getSqlSkeleton();
01288
if (skeleton != null)
01289 {
01290
socketOutput.writeBoolean(
true);
01291
socketOutput.writeUTF(skeleton);
01292 }
01293
else
01294
socketOutput.writeBoolean(
false);
01295 }
01296
01297 }
01298
01306 protected ResultSet
execWriteRequestWithKeys(
AbstractWriteRequest request)
01307
throws SQLException
01308 {
01309
if (
driver == null)
01310
throw new SQLException(
"No driver to send the request '"
01311 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH) +
"'");
01312
try
01313 {
01314
setConnectionParametersOnRequest(request);
01315
socketOutput.writeInt(
Commands.ExecWriteRequestWithKeys);
01316
writeRequestOnStream(request,
true);
01317
socketOutput.flush();
01318
01319 Object in =
socketInput.readObject();
01320
if (in instanceof SQLException)
01321
throw (SQLException) in;
01322
else if (in instanceof
Field[])
01323 {
01324 Field[] fields = (Field[]) in;
01325 ArrayList data = null;
01326
boolean hasMoreData;
01327 String cursorName = null;
01328
try
01329 {
01330 data = (ArrayList)
socketInput.readObject();
01331 hasMoreData =
socketInput.readBoolean();
01332
if (hasMoreData)
01333 cursorName =
socketInput.readUTF();
01334 }
01335
catch (Exception e1)
01336 {
01337
throw new SQLException(
01338
"Connection.execWriteRequestWithKeys: Unexpected response (" + e1
01339 +
") for request "
01340 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01341 }
01342
return new org.objectweb.cjdbc.driver.DriverResultSet(fields, data,
01343 hasMoreData, cursorName);
01344 }
01345
else
01346
throw new SQLException(
01347
"Connection.execWriteRequestWithKeys: Unexpected response (" + in
01348 +
") for request "
01349 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01350 }
01351
catch (Exception e)
01352 {
01353
throw new SQLException(
01354
"execWriteRequestWithKeys: Error occured while request '"
01355 + request.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01356 +
"' was processed by C-JDBC Controller (" + e +
")");
01357 }
01358 }
01359
01367 public ResultSet
execReadStoredProcedure(
StoredProcedure proc)
01368
throws SQLException
01369 {
01370
if (
driver == null)
01371
throw new SQLException(
"No driver to send the request '"
01372 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH) +
"'");
01373
try
01374 {
01375
setConnectionParametersOnRequest(proc);
01376
socketOutput.writeInt(
Commands.ExecReadStoredProcedure);
01377
procedureOnStream(proc,
true);
01378
socketOutput.flush();
01379
01380 Object in =
socketInput.readObject();
01381
if (in instanceof SQLException)
01382
throw (SQLException) in;
01383
else if (in instanceof
Field[])
01384 {
01385 Field[] fields = (Field[]) in;
01386 ArrayList data = null;
01387
boolean hasMoreData;
01388 String cursorName = null;
01389
try
01390 {
01391 data = (ArrayList)
socketInput.readObject();
01392 hasMoreData =
socketInput.readBoolean();
01393
if (hasMoreData)
01394 cursorName =
socketInput.readUTF();
01395 }
01396
catch (Exception e1)
01397 {
01398
throw new SQLException(
01399
"Connection.execReadStoredProcedure: Unexpected response (" + e1
01400 +
") for request "
01401 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01402 }
01403
return new org.objectweb.cjdbc.driver.DriverResultSet(fields, data,
01404 hasMoreData, cursorName);
01405 }
01406
else
01407
throw new SQLException(
01408
"Connection.execReadStoredProcedure: Unexpected response (" + in
01409 +
") for request "
01410 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01411 }
01412
catch (RuntimeException e)
01413 {
01414
throw new SQLException(
01415
"Connection.execReadStoredProcedure: Error occured while request '"
01416 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01417 +
"' was processed by C-JDBC Controller (" + e +
")");
01418 }
01419
catch (IOException e)
01420 {
01421
try
01422 {
01423
reconnect();
01424
return execReadStoredProcedure(proc);
01425 }
01426
catch (SQLException e1)
01427 {
01428
throw new SQLException(
"Connection lost while executing request'"
01429 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01430 +
"' and automatic reconnect failed (" + e1 +
")");
01431 }
01432 }
01433
catch (ClassNotFoundException e)
01434 {
01435
throw new SQLException(
01436
"Connection.execReadStoredProcedure: Unexpected response (" + e
01437 +
") for request "
01438 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01439 }
01440 }
01441
01449 protected int execWriteStoredProcedure(
StoredProcedure proc)
01450
throws SQLException
01451 {
01452
if (
driver == null)
01453
throw new SQLException(
"No driver to send the request '"
01454 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH) +
"'");
01455
try
01456 {
01457
setConnectionParametersOnRequest(proc);
01458
socketOutput.writeInt(
Commands.ExecWriteStoredProcedure);
01459
procedureOnStream(proc,
false);
01460
socketOutput.flush();
01461
01462 Object r =
socketInput.readObject();
01463
if (r instanceof Integer)
01464
return ((Integer) r).intValue();
01465
else if (r instanceof SQLException)
01466
throw (SQLException) r;
01467
else
01468
throw new SQLException(
01469
"Connection.execWriteStoredProcedure: Unexpected response (" + r
01470 +
") for request "
01471 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH));
01472 }
01473
catch (Exception e)
01474 {
01475
throw new SQLException(
01476
"execWriteStoredProcedure: Error occured while request '"
01477 + proc.getSQLShortForm(
Constants.SQL_SHORT_FORM_LENGTH)
01478 +
"' was processed by C-JDBC Controller (" + e +
")");
01479 }
01480 }
01481
01482 protected ResultSet
getColumns(String catalog, String schemaPattern,
01483 String tableNamePattern, String columnNamePattern)
throws SQLException
01484 {
01485
if (
driver == null)
01486
throw new SQLException(
"No driver to get the tables.");
01487
try
01488 {
01489
socketOutput.writeInt(
Commands.DatabaseMetaDataGetColumns);
01490
socketOutput.writeUTF(catalog);
01491
socketOutput.writeUTF(schemaPattern);
01492
socketOutput.writeUTF(tableNamePattern);
01493
socketOutput.writeUTF(columnNamePattern);
01494
socketOutput.flush();
01495
01496 Object rs =
socketInput.readObject();
01497
if (rs instanceof ResultSet)
01498
return (ResultSet) rs;
01499
else if (rs instanceof SQLException)
01500
throw (SQLException) rs;
01501
else
01502
throw new SQLException(
"Connection.getColumns: Unexpected response ("
01503 + rs +
")");
01504 }
01505
catch (Exception e)
01506 {
01507
throw new SQLException(
01508
"Connection.getColumns: Error occured while request was processed by C-JDBC Controller ("
01509 + e +
")");
01510 }
01511 }
01512
01516 protected ResultSet
getPrimaryKeys(String catalog, String schemaPattern,
01517 String tableNamePattern)
throws SQLException
01518 {
01519
if (
driver == null)
01520
throw new SQLException(
"No driver to get the tables.");
01521
try
01522 {
01523
socketOutput.writeInt(
Commands.DatabaseMetaDataGetPrimaryKeys);
01524
socketOutput.writeUTF(catalog);
01525
socketOutput.writeUTF(schemaPattern);
01526
socketOutput.writeUTF(tableNamePattern);
01527
socketOutput.flush();
01528
01529 Object rs =
socketInput.readObject();
01530
if (rs instanceof ResultSet)
01531
return (ResultSet) rs;
01532
else if (rs instanceof SQLException)
01533
throw (SQLException) rs;
01534
else
01535
throw new SQLException(
01536
"Connection.getPrimaryKeys: Unexpected response (" + rs +
")");
01537 }
01538
catch (Exception e)
01539 {
01540
throw new SQLException(
01541
"Connection.getPrimaryKeys: Error occured while request was processed by C-JDBC Controller ("
01542 + e +
")");
01543 }
01544 }
01545
01550 protected ResultSet
getTables(String catalog, String schemaPattern,
01551 String tableNamePattern, String[] types)
throws SQLException
01552 {
01553
if (
driver == null)
01554
throw new SQLException(
"No driver to get the tables.");
01555
try
01556 {
01557
socketOutput.writeInt(
Commands.DatabaseMetaDataGetTables);
01558
socketOutput.writeUTF(catalog);
01559
socketOutput.writeUTF(schemaPattern);
01560
socketOutput.writeUTF(tableNamePattern);
01561
socketOutput.writeObject(types);
01562
socketOutput.flush();
01563
01564 Object rs =
socketInput.readObject();
01565
if (rs instanceof ResultSet)
01566
return (ResultSet) rs;
01567
else if (rs instanceof SQLException)
01568
throw (SQLException) rs;
01569
else
01570
throw new SQLException(
"Connection.getTables: Unexpected response ("
01571 + rs +
")");
01572 }
01573
catch (Exception e)
01574 {
01575
throw new SQLException(
01576
"Connection.getTables: Error occured while request was processed by C-JDBC Controller ("
01577 + e +
")");
01578 }
01579 }
01580
01587 public String
getControllerVersionNumber() throws SQLException
01588 {
01589
try
01590 {
01591
socketOutput.writeInt(
Commands.GetControllerVersionNumber);
01592
socketOutput.flush();
01593
01594 Object s =
socketInput.readObject();
01595
if (s instanceof String)
01596
return (String) s;
01597
else
01598
throw new SQLException(
01599
"Connection.getControllerVersionNumber: Unexpected response (" + s
01600 +
")");
01601 }
01602
catch (Exception e)
01603 {
01604
throw new SQLException(
01605
"Connection.getControllerVersionNumber: Error occured while request was processed by C-JDBC Controller ("
01606 + e +
")");
01607 }
01608 }
01609
01610
01611
01626 public void setHoldability(
int holdability)
throws SQLException
01627 {
01628
throw new NotImplementedException(
"setHoldability");
01629 }
01630
01643 public int getHoldability() throws SQLException
01644 {
01645
throw new NotImplementedException(
"getHoldability");
01646 }
01647
01659 public Savepoint setSavepoint() throws SQLException
01660 {
01661
throw new NotImplementedException(
"setSavepoint");
01662 }
01663
01676 public Savepoint setSavepoint(String name)
throws SQLException
01677 {
01678
throw new NotImplementedException(
"setSavepoint");
01679 }
01680
01696 public void rollback(
Savepoint savepoint)
throws SQLException
01697 {
01698
throw new NotImplementedException(
"rollback");
01699 }
01700
01712 public void releaseSavepoint(
Savepoint savepoint)
throws SQLException
01713 {
01714
throw new NotImplementedException(
"releaseSavepoint");
01715 }
01716
01745 public java.sql.Statement
createStatement(
int resultSetType,
01746
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
01747 {
01748
throw new NotImplementedException(
"createStatement");
01749 }
01750
01782 public java.sql.PreparedStatement
prepareStatement(String sql,
01783
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability)
01784
throws SQLException
01785 {
01786
throw new NotImplementedException(
"prepareStatement");
01787 }
01788
01818 public java.sql.CallableStatement
prepareCall(String sql,
int resultSetType,
01819
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
01820 {
01821
throw new NotImplementedException(
"prepareCall");
01822 }
01823
01858 public java.sql.PreparedStatement
prepareStatement(String sql,
01859
int autoGeneratedKeys)
throws SQLException
01860 {
01861
PreparedStatement ps =
new PreparedStatement(
this, sql);
01862 ps.
setGeneratedKeysFlag(autoGeneratedKeys);
01863
return ps;
01864 }
01865
01900 public java.
sql.PreparedStatement
prepareStatement(String sql,
01901
int columnIndexes[])
throws SQLException
01902 {
01903
throw new NotImplementedException(
"prepareStatement");
01904 }
01905
01940 public java.sql.PreparedStatement
prepareStatement(String sql,
01941 String columnNames[])
throws SQLException
01942 {
01943
throw new NotImplementedException(
"prepareStatement");
01944 }
01945
01951 public AbstractBlobFilter
getBlobFilter()
01952 {
01953
if (
blobFilter == null)
01954
blobFilter =
new HexaBlobFilter();
01955
return blobFilter;
01956 }
01957
01966 public ResultSet
getTableTypes() throws SQLException
01967 {
01968
if (
driver == null)
01969
throw new SQLException(
"No driver to get the table types.");
01970
try
01971 {
01972
socketOutput.writeInt(
Commands.DatabaseMetaDataGetTableTypes);
01973
socketOutput.flush();
01974
01975 Object rs =
socketInput.readObject();
01976
if (rs instanceof ResultSet)
01977
return (ResultSet) rs;
01978
else if (rs instanceof SQLException)
01979
throw (SQLException) rs;
01980
else
01981
throw new SQLException(
01982
"Connection.getTableTypes: Unexpected response (" + rs +
")");
01983 }
01984
catch (Exception e)
01985 {
01986
throw new SQLException(
01987
"Connection.getTableTypes: Error occured while request was processed by C-JDBC Controller ("
01988 + e +
")");
01989 }
01990 }
01991
02008 public ResultSet
getTablePrivileges(String catalog, String schemaPattern,
02009 String tableNamePattern)
throws SQLException
02010 {
02011
if (
driver == null)
02012
throw new SQLException(
"No driver to get the table privileges.");
02013
try
02014 {
02015
socketOutput.writeInt(
Commands.DatabaseMetaDataGetTablePrivileges);
02016
socketOutput.writeUTF(catalog);
02017
socketOutput.writeUTF(schemaPattern);
02018
socketOutput.writeUTF(tableNamePattern);
02019
socketOutput.flush();
02020
02021 Object rs =
socketInput.readObject();
02022
if (rs instanceof ResultSet)
02023
return (ResultSet) rs;
02024
else if (rs instanceof SQLException)
02025
throw (SQLException) rs;
02026
else
02027
throw new SQLException(
02028
"Connection.getTablePrivileges: Unexpected response (" + rs +
")");
02029 }
02030
catch (Exception e)
02031 {
02032
throw new SQLException(
02033
"Connection.getTablePrivileges: Error occured while request was processed by C-JDBC Controller ("
02034 + e +
")");
02035 }
02036 }
02037
02041 public ResultSet
getSchemas() throws SQLException
02042 {
02043
if (
driver == null)
02044
throw new SQLException(
"No driver to get the schemas.");
02045
try
02046 {
02047
socketOutput.writeInt(
Commands.DatabaseMetaDataGetSchemas);
02048
socketOutput.flush();
02049
02050 Object rs =
socketInput.readObject();
02051
if (rs instanceof ResultSet)
02052
return (ResultSet) rs;
02053
else if (rs instanceof SQLException)
02054
throw (SQLException) rs;
02055
else
02056
throw new SQLException(
"Connection.getSchemas: Unexpected response ("
02057 + rs +
")");
02058 }
02059
catch (Exception e)
02060 {
02061
throw new SQLException(
02062
"Connection.getSchemas: Error occured while request was processed by C-JDBC Controller ("
02063 + e +
")");
02064 }
02065 }
02066
02070 public String
getDatabaseProductName() throws SQLException
02071 {
02072
try
02073 {
02074
socketOutput.writeInt(
Commands.GetDatabaseProductName);
02075
socketOutput.flush();
02076
02077 Object s =
socketInput.readObject();
02078
if (s instanceof String)
02079
return (String) s;
02080
else
02081
throw new SQLException(
02082
"Connection.GetDatabaseProductName: Unexpected response (" + s
02083 +
")");
02084 }
02085
catch (Exception e)
02086 {
02087
throw new SQLException(
02088
"Connection.getDatabaseProductName: Error occured while request was processed by C-JDBC Controller ("
02089 + e +
")");
02090 }
02091 }
02092
02101 public void fetchNextData(String cursorName,
int fetchSize,
02102
DriverResultSet drsToUpdate)
throws SQLException
02103 {
02104
try
02105 {
02106
socketOutput.writeInt(
Commands.FetchNextResultSetRows);
02107
socketOutput.writeUTF(cursorName);
02108
socketOutput.writeInt(fetchSize);
02109
socketOutput.flush();
02110
02111 Object data =
socketInput.readObject();
02112
if (data instanceof ArrayList)
02113 {
02114
boolean hasMoreData =
socketInput.readBoolean();
02115 drsToUpdate.setData((ArrayList) data);
02116 drsToUpdate.setHasMoreData(hasMoreData);
02117 }
02118
else if (data instanceof SQLException)
02119
throw (SQLException) data;
02120
else
02121
throw new SQLException(
02122
"Connection.fetchNextData: Unexpected response (" + data +
")");
02123 }
02124
catch (Exception e)
02125 {
02126
throw new SQLException(
02127
"Connection.fetchNextData: Error occured while request was processed by C-JDBC Controller ("
02128 + e +
")");
02129 }
02130 }
02131
02138 public void closeRemoteResultSet(String cursorName)
throws SQLException
02139 {
02140
try
02141 {
02142
socketOutput.writeInt(
Commands.CloseRemoteResultSet);
02143
socketOutput.writeUTF(cursorName);
02144
socketOutput.flush();
02145
02146 Object data =
socketInput.readObject();
02147
if (data instanceof
CommandCompleted)
02148
return;
02149
else if (data instanceof SQLException)
02150
throw (SQLException) data;
02151
else
02152
throw new SQLException(
02153
"Connection.closeRemoteResultSet: Unexpected response (" + data
02154 +
")");
02155 }
02156
catch (Exception e)
02157 {
02158
throw new SQLException(
02159
"Connection.closeRemoteResultSet: Error occured while request was processed by C-JDBC Controller ("
02160 + e +
")");
02161 }
02162 }
02163
02169 public String
getPreparedStatementBooleanFalse()
02170 {
02171
return preparedStatementBooleanFalse;
02172 }
02173
02179 public void setPreparedStatementBooleanFalse(String booleanFalse)
02180 {
02181
this.preparedStatementBooleanFalse = booleanFalse;
02182 }
02183
02189 public String
getPreparedStatementBooleanTrue()
02190 {
02191
return preparedStatementBooleanTrue;
02192 }
02193
02199 public void setPreparedStatementBooleanTrue(String booleanTrue)
02200 {
02201
this.preparedStatementBooleanTrue = booleanTrue;
02202 }
02203
02209 public boolean isEscapeBackslash()
02210 {
02211
return escapeBackslash;
02212 }
02213
02219 public void setEscapeBackslash(
boolean escapeBackslash)
02220 {
02221
this.escapeBackslash = escapeBackslash;
02222 }
02223
02229 public boolean isEscapeSingleQuote()
02230 {
02231
return escapeSingleQuote;
02232 }
02233
02239 public void setEscapeSingleQuote(
boolean escapeSingleQuote)
02240 {
02241
this.escapeSingleQuote = escapeSingleQuote;
02242 }
02243
02250 public void setDriverProcessed(
boolean processedByDriver)
02251 {
02252
this.driverProcessed = processedByDriver;
02253 }
02254
02260 public boolean isDriverProcessed()
02261 {
02262
return driverProcessed;
02263 }
02264
02270 public void setEscapeChar(String escapeChar)
02271 {
02272
this.escapeChar = escapeChar;
02273 }
02274
02278 public String
getEscapeChar()
02279 {
02280
return escapeChar;
02281 }
02282 }