Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
8d600a7d
Commit
8d600a7d
authored
Jul 24, 2002
by
Barry Lind
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Second phase of restructuring to add jdbc3 support.
parent
43515ba3
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1072 additions
and
1950 deletions
+1072
-1950
src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
...ces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
+834
-2
src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
...terfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
+1
-1
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java
...interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java
+2
-2
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java
...ces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java
+14
-0
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
+2
-2
src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
...terfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
+0
-843
src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
...ces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
+4
-4
src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
...ces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
+195
-3
src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
...terfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
+1
-1
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java
...interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java
+2
-2
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
...ces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
+15
-0
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
+2
-4
src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
...terfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
+0
-1086
No files found.
src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
View file @
8d600a7d
package
org.postgresql.jdbc1
;
import
java.io.*
;
import
java.math.BigDecimal
;
import
java.sql.*
;
import
org.postgresql.util.PSQLException
;
import
java.util.Vector
;
import
org.postgresql.largeobject.*
;
import
org.postgresql.util.*
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.
2 2002/07/24 22:08:39
barry Exp $
* This class defines methods of the jdbc1 specification. This class is
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
...
...
@@ -34,6 +39,56 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
private
static
final
short
BACKSLASH
=
2
;
private
static
final
short
ESC_TIMEDATE
=
3
;
// Some performance caches
private
StringBuffer
sbuf
=
new
StringBuffer
();
//Used by the preparedstatement style methods
protected
String
sql
;
protected
String
[]
templateStrings
;
protected
String
[]
inStrings
;
public
AbstractJdbc1Statement
(
AbstractJdbc1Connection
connection
)
{
this
.
connection
=
connection
;
}
public
AbstractJdbc1Statement
(
AbstractJdbc1Connection
connection
,
String
sql
)
throws
SQLException
{
this
.
sql
=
sql
;
this
.
connection
=
connection
;
parseSqlStmt
();
// this allows Callable stmt to override
}
protected
void
parseSqlStmt
()
throws
SQLException
{
Vector
v
=
new
Vector
();
boolean
inQuotes
=
false
;
int
lastParmEnd
=
0
,
i
;
for
(
i
=
0
;
i
<
sql
.
length
();
++
i
)
{
int
c
=
sql
.
charAt
(
i
);
if
(
c
==
'\''
)
inQuotes
=
!
inQuotes
;
if
(
c
==
'?'
&&
!
inQuotes
)
{
v
.
addElement
(
sql
.
substring
(
lastParmEnd
,
i
));
lastParmEnd
=
i
+
1
;
}
}
v
.
addElement
(
sql
.
substring
(
lastParmEnd
,
sql
.
length
()));
templateStrings
=
new
String
[
v
.
size
()];
inStrings
=
new
String
[
v
.
size
()
-
1
];
clearParameters
();
for
(
i
=
0
;
i
<
templateStrings
.
length
;
++
i
)
templateStrings
[
i
]
=
(
String
)
v
.
elementAt
(
i
);
}
/*
* Execute a SQL statement that retruns a single ResultSet
*
...
...
@@ -51,6 +106,18 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
return
result
;
}
/*
* A Prepared SQL query is executed and its ResultSet is returned
*
* @return a ResultSet that contains the data produced by the
* * query - never null
* @exception SQLException if a database access error occurs
*/
public
java
.
sql
.
ResultSet
executeQuery
()
throws
SQLException
{
return
executeQuery
(
compileQuery
());
}
/*
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition
* SQL statements that return nothing such as SQL DDL statements
...
...
@@ -68,6 +135,20 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
return
this
.
getUpdateCount
();
}
/*
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
* SQL statements that return nothing such as SQL DDL statements can
* be executed.
*
* @return either the row count for INSERT, UPDATE or DELETE; or
* * 0 for SQL statements that return nothing.
* @exception SQLException if a database access error occurs
*/
public
int
executeUpdate
()
throws
SQLException
{
return
executeUpdate
(
compileQuery
());
}
/*
* Execute a SQL statement that may return multiple results. We
* don't have to worry about this since we do not support multiple
...
...
@@ -101,6 +182,20 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
return
(
result
!=
null
&&
((
AbstractJdbc1ResultSet
)
result
).
reallyResultSet
());
}
/*
* Some prepared statements return multiple results; the execute method
* handles these complex statements as well as the simpler form of
* statements handled by executeQuery and executeUpdate
*
* @return true if the next result is a ResultSet; false if it is an
* * update count or there are no more results
* @exception SQLException if a database access error occurs
*/
public
boolean
execute
()
throws
SQLException
{
return
execute
(
compileQuery
());
}
/*
* setCursorName defines the SQL cursor name that will be used by
* subsequent execute methods. This name can then be used in SQL
...
...
@@ -466,6 +561,743 @@ public abstract class AbstractJdbc1Statement implements org.postgresql.PGStateme
return
((
AbstractJdbc1ResultSet
)
result
).
getLastOID
();
}
/*
* Set a parameter to SQL NULL
*
* <p><B>Note:</B> You must specify the parameters SQL type (although
* PostgreSQL ignores it)
*
* @param parameterIndex the first parameter is 1, etc...
* @param sqlType the SQL type code defined in java.sql.Types
* @exception SQLException if a database access error occurs
*/
public
void
setNull
(
int
parameterIndex
,
int
sqlType
)
throws
SQLException
{
set
(
parameterIndex
,
"null"
);
}
/*
* Set a parameter to a Java boolean value. The driver converts this
* to a SQL BIT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBoolean
(
int
parameterIndex
,
boolean
x
)
throws
SQLException
{
set
(
parameterIndex
,
x
?
"'t'"
:
"'f'"
);
}
/*
* Set a parameter to a Java byte value. The driver converts this to
* a SQL TINYINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setByte
(
int
parameterIndex
,
byte
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java short value. The driver converts this
* to a SQL SMALLINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setShort
(
int
parameterIndex
,
short
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java int value. The driver converts this to
* a SQL INTEGER value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setInt
(
int
parameterIndex
,
int
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java long value. The driver converts this to
* a SQL BIGINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setLong
(
int
parameterIndex
,
long
x
)
throws
SQLException
{
set
(
parameterIndex
,
Long
.
toString
(
x
));
}
/*
* Set a parameter to a Java float value. The driver converts this
* to a SQL FLOAT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setFloat
(
int
parameterIndex
,
float
x
)
throws
SQLException
{
set
(
parameterIndex
,
Float
.
toString
(
x
));
}
/*
* Set a parameter to a Java double value. The driver converts this
* to a SQL DOUBLE value when it sends it to the database
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setDouble
(
int
parameterIndex
,
double
x
)
throws
SQLException
{
set
(
parameterIndex
,
Double
.
toString
(
x
));
}
/*
* Set a parameter to a java.lang.BigDecimal value. The driver
* converts this to a SQL NUMERIC value when it sends it to the
* database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBigDecimal
(
int
parameterIndex
,
BigDecimal
x
)
throws
SQLException
{
if
(
x
==
null
)
setNull
(
parameterIndex
,
Types
.
OTHER
);
else
{
set
(
parameterIndex
,
x
.
toString
());
}
}
/*
* Set a parameter to a Java String value. The driver converts this
* to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
* size relative to the driver's limits on VARCHARs) when it sends it
* to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setString
(
int
parameterIndex
,
String
x
)
throws
SQLException
{
// if the passed string is null, then set this column to null
if
(
x
==
null
)
setNull
(
parameterIndex
,
Types
.
OTHER
);
else
{
// use the shared buffer object. Should never clash but this makes
// us thread safe!
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
int
i
;
sbuf
.
append
(
'\''
);
for
(
i
=
0
;
i
<
x
.
length
()
;
++
i
)
{
char
c
=
x
.
charAt
(
i
);
if
(
c
==
'\\'
||
c
==
'\''
)
sbuf
.
append
((
char
)
'\\'
);
sbuf
.
append
(
c
);
}
sbuf
.
append
(
'\''
);
set
(
parameterIndex
,
sbuf
.
toString
());
}
}
}
/*
* Set a parameter to a Java array of bytes. The driver converts this
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
* size relative to the driver's limits on VARBINARYs) when it sends
* it to the database.
*
* <p>Implementation note:
* <br>With org.postgresql, this creates a large object, and stores the
* objects oid in this column.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBytes
(
int
parameterIndex
,
byte
x
[])
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports the bytea datatype for byte arrays
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
setString
(
parameterIndex
,
PGbytea
.
toPGString
(
x
));
}
}
else
{
//Version 7.1 and earlier support done as LargeObjects
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
lob
.
write
(
x
);
lob
.
close
();
setInt
(
parameterIndex
,
oid
);
}
}
/*
* Set a parameter to a java.sql.Date value. The driver converts this
* to a SQL DATE value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setDate
(
int
parameterIndex
,
java
.
sql
.
Date
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
"'"
+
x
.
toString
()
+
"'"
);
}
}
/*
* Set a parameter to a java.sql.Time value. The driver converts
* this to a SQL TIME value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...));
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setTime
(
int
parameterIndex
,
Time
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
"'"
+
x
.
toString
()
+
"'"
);
}
}
/*
* Set a parameter to a java.sql.Timestamp value. The driver converts
* this to a SQL TIMESTAMP value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setTimestamp
(
int
parameterIndex
,
Timestamp
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
// Use the shared StringBuffer
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
sbuf
.
append
(
"'"
);
//format the timestamp
//we do our own formating so that we can get a format
//that works with both timestamp with time zone and
//timestamp without time zone datatypes.
//The format is '2002-01-01 23:59:59.123456-0130'
//we need to include the local time and timezone offset
//so that timestamp without time zone works correctly
int
l_year
=
x
.
getYear
()
+
1900
;
sbuf
.
append
(
l_year
);
sbuf
.
append
(
'-'
);
int
l_month
=
x
.
getMonth
()
+
1
;
if
(
l_month
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_month
);
sbuf
.
append
(
'-'
);
int
l_day
=
x
.
getDate
();
if
(
l_day
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_day
);
sbuf
.
append
(
' '
);
int
l_hours
=
x
.
getHours
();
if
(
l_hours
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_hours
);
sbuf
.
append
(
':'
);
int
l_minutes
=
x
.
getMinutes
();
if
(
l_minutes
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_minutes
);
sbuf
.
append
(
':'
);
int
l_seconds
=
x
.
getSeconds
();
if
(
l_seconds
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_seconds
);
// Make decimal from nanos.
char
[]
l_decimal
=
{
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
};
char
[]
l_nanos
=
Integer
.
toString
(
x
.
getNanos
()).
toCharArray
();
System
.
arraycopy
(
l_nanos
,
0
,
l_decimal
,
l_decimal
.
length
-
l_nanos
.
length
,
l_nanos
.
length
);
sbuf
.
append
(
'.'
);
if
(
connection
.
haveMinimumServerVersion
(
"7.2"
))
{
sbuf
.
append
(
l_decimal
,
0
,
6
);
}
else
{
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
sbuf
.
append
(
l_decimal
,
0
,
2
);
}
//add timezone offset
int
l_offset
=
-(
x
.
getTimezoneOffset
());
int
l_houros
=
l_offset
/
60
;
if
(
l_houros
>=
0
)
{
sbuf
.
append
(
'+'
);
}
else
{
sbuf
.
append
(
'-'
);
}
if
(
l_houros
>
-
10
&&
l_houros
<
10
)
sbuf
.
append
(
'0'
);
if
(
l_houros
>=
0
)
{
sbuf
.
append
(
l_houros
);
}
else
{
sbuf
.
append
(-
l_houros
);
}
int
l_minos
=
l_offset
-
(
l_houros
*
60
);
if
(
l_minos
!=
0
)
{
if
(
l_minos
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_minos
);
}
sbuf
.
append
(
"'"
);
set
(
parameterIndex
,
sbuf
.
toString
());
}
}
}
/*
* When a very large ASCII value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* ASCII to the database char format.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @param length the number of bytes in the stream
* @exception SQLException if a database access error occurs
*/
public
void
setAsciiStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
//As the spec/javadoc for this method indicate this is to be used for
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
try
{
InputStreamReader
l_inStream
=
new
InputStreamReader
(
x
,
"ASCII"
);
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
=
l_inStream
.
read
(
l_chars
,
0
,
length
);
setString
(
parameterIndex
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
catch
(
UnsupportedEncodingException
l_uee
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_uee
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
}
else
{
//Version 7.1 supported only LargeObjects by treating everything
//as binary data
setBinaryStream
(
parameterIndex
,
x
,
length
);
}
}
/*
* When a very large Unicode value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* UNICODE to the database char format.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setUnicodeStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
//As the spec/javadoc for this method indicate this is to be used for
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
try
{
InputStreamReader
l_inStream
=
new
InputStreamReader
(
x
,
"UTF-8"
);
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
=
l_inStream
.
read
(
l_chars
,
0
,
length
);
setString
(
parameterIndex
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
catch
(
UnsupportedEncodingException
l_uee
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_uee
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
}
else
{
//Version 7.1 supported only LargeObjects by treating everything
//as binary data
setBinaryStream
(
parameterIndex
,
x
,
length
);
}
}
/*
* When a very large binary value is input to a LONGVARBINARY parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBinaryStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports BinaryStream for for the PG bytea type
//As the spec/javadoc for this method indicate this is to be used for
//large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
//long binary datatype, but with toast the bytea datatype is capable of
//handling very large values. Thus the implementation ends up calling
//setBytes() since there is no current way to stream the value to the server
byte
[]
l_bytes
=
new
byte
[
length
];
int
l_bytesRead
;
try
{
l_bytesRead
=
x
.
read
(
l_bytes
,
0
,
length
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
if
(
l_bytesRead
==
length
)
{
setBytes
(
parameterIndex
,
l_bytes
);
}
else
{
//the stream contained less data than they said
byte
[]
l_bytes2
=
new
byte
[
l_bytesRead
];
System
.
arraycopy
(
l_bytes
,
0
,
l_bytes2
,
0
,
l_bytesRead
);
setBytes
(
parameterIndex
,
l_bytes2
);
}
}
else
{
//Version 7.1 only supported streams for LargeObjects
//but the jdbc spec indicates that streams should be
//available for LONGVARBINARY instead
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
x
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
length
)
{
los
.
write
(
c
);
c
=
x
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
parameterIndex
,
oid
);
}
}
/*
* In general, parameter values remain in force for repeated used of a
* Statement. Setting a parameter value automatically clears its
* previous value. However, in coms cases, it is useful to immediately
* release the resources used by the current parameter values; this
* can be done by calling clearParameters
*
* @exception SQLException if a database access error occurs
*/
public
void
clearParameters
()
throws
SQLException
{
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
i
++)
inStrings
[
i
]
=
null
;
}
/*
* Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values.
*
* <P>The given Java object will be converted to the targetSqlType before
* being sent to the database.
*
* <P>note that this method may be used to pass database-specific
* abstract data types. This is done by using a Driver-specific
* Java type and using a targetSqlType of java.sql.Types.OTHER
*
* @param parameterIndex the first parameter is 1...
* @param x the object containing the input parameter value
* @param targetSqlType The SQL type to be send to the database
* @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
* * types this is the number of digits after the decimal. For
* * all other types this value will be ignored.
* @exception SQLException if a database access error occurs
*/
public
void
setObject
(
int
parameterIndex
,
Object
x
,
int
targetSqlType
,
int
scale
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
return
;
}
switch
(
targetSqlType
)
{
case
Types
.
TINYINT
:
case
Types
.
SMALLINT
:
case
Types
.
INTEGER
:
case
Types
.
BIGINT
:
case
Types
.
REAL
:
case
Types
.
FLOAT
:
case
Types
.
DOUBLE
:
case
Types
.
DECIMAL
:
case
Types
.
NUMERIC
:
if
(
x
instanceof
Boolean
)
set
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
()
?
"1"
:
"0"
);
else
set
(
parameterIndex
,
x
.
toString
());
break
;
case
Types
.
CHAR
:
case
Types
.
VARCHAR
:
case
Types
.
LONGVARCHAR
:
setString
(
parameterIndex
,
x
.
toString
());
break
;
case
Types
.
DATE
:
setDate
(
parameterIndex
,
(
java
.
sql
.
Date
)
x
);
break
;
case
Types
.
TIME
:
setTime
(
parameterIndex
,
(
Time
)
x
);
break
;
case
Types
.
TIMESTAMP
:
setTimestamp
(
parameterIndex
,
(
Timestamp
)
x
);
break
;
case
Types
.
BIT
:
if
(
x
instanceof
Boolean
)
{
set
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
()
?
"TRUE"
:
"FALSE"
);
}
else
{
throw
new
PSQLException
(
"postgresql.prep.type"
);
}
break
;
case
Types
.
BINARY
:
case
Types
.
VARBINARY
:
setObject
(
parameterIndex
,
x
);
break
;
case
Types
.
OTHER
:
setString
(
parameterIndex
,
((
PGobject
)
x
).
getValue
());
break
;
default
:
throw
new
PSQLException
(
"postgresql.prep.type"
);
}
}
public
void
setObject
(
int
parameterIndex
,
Object
x
,
int
targetSqlType
)
throws
SQLException
{
setObject
(
parameterIndex
,
x
,
targetSqlType
,
0
);
}
/*
* This stores an Object into a parameter.
* <p>New for 6.4, if the object is not recognised, but it is
* Serializable, then the object is serialised using the
* org.postgresql.util.Serialize class.
*/
public
void
setObject
(
int
parameterIndex
,
Object
x
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
return
;
}
if
(
x
instanceof
String
)
setString
(
parameterIndex
,
(
String
)
x
);
else
if
(
x
instanceof
BigDecimal
)
setBigDecimal
(
parameterIndex
,
(
BigDecimal
)
x
);
else
if
(
x
instanceof
Short
)
setShort
(
parameterIndex
,
((
Short
)
x
).
shortValue
());
else
if
(
x
instanceof
Integer
)
setInt
(
parameterIndex
,
((
Integer
)
x
).
intValue
());
else
if
(
x
instanceof
Long
)
setLong
(
parameterIndex
,
((
Long
)
x
).
longValue
());
else
if
(
x
instanceof
Float
)
setFloat
(
parameterIndex
,
((
Float
)
x
).
floatValue
());
else
if
(
x
instanceof
Double
)
setDouble
(
parameterIndex
,
((
Double
)
x
).
doubleValue
());
else
if
(
x
instanceof
byte
[])
setBytes
(
parameterIndex
,
(
byte
[])
x
);
else
if
(
x
instanceof
java
.
sql
.
Date
)
setDate
(
parameterIndex
,
(
java
.
sql
.
Date
)
x
);
else
if
(
x
instanceof
Time
)
setTime
(
parameterIndex
,
(
Time
)
x
);
else
if
(
x
instanceof
Timestamp
)
setTimestamp
(
parameterIndex
,
(
Timestamp
)
x
);
else
if
(
x
instanceof
Boolean
)
setBoolean
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
());
else
if
(
x
instanceof
PGobject
)
setString
(
parameterIndex
,
((
PGobject
)
x
).
getValue
());
else
// Try to store java object in database
setSerialize
(
parameterIndex
,
connection
.
storeObject
(
x
),
x
.
getClass
().
getName
()
);
}
/*
* Returns the SQL statement with the current template values
* substituted.
* NB: This is identical to compileQuery() except instead of throwing
* SQLException if a parameter is null, it places ? instead.
*/
public
String
toString
()
{
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
sbuf
.
append
(
'?'
);
else
sbuf
.
append
(
templateStrings
[
i
]);
sbuf
.
append
(
inStrings
[
i
]);
}
sbuf
.
append
(
templateStrings
[
inStrings
.
length
]);
return
sbuf
.
toString
();
}
}
/*
* There are a lot of setXXX classes which all basically do
* the same thing. We need a method which actually does the
* set for us.
*
* @param paramIndex the index into the inString
* @param s a string to be stored
* @exception SQLException if something goes wrong
*/
protected
void
set
(
int
paramIndex
,
String
s
)
throws
SQLException
{
if
(
paramIndex
<
1
||
paramIndex
>
inStrings
.
length
)
throw
new
PSQLException
(
"postgresql.prep.range"
);
inStrings
[
paramIndex
-
1
]
=
s
;
}
/*
* Helper - this compiles the SQL query from the various parameters
* This is identical to toString() except it throws an exception if a
* parameter is unused.
*/
protected
synchronized
String
compileQuery
()
throws
SQLException
{
sbuf
.
setLength
(
0
);
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
throw
new
PSQLException
(
"postgresql.prep.param"
,
new
Integer
(
i
+
1
));
sbuf
.
append
(
templateStrings
[
i
]).
append
(
inStrings
[
i
]);
}
sbuf
.
append
(
templateStrings
[
inStrings
.
length
]);
return
sbuf
.
toString
();
}
/*
* Set a parameter to a tablerow-type oid reference.
*
* @param parameterIndex the first parameter is 1...
* @param x the oid of the object from org.postgresql.util.Serialize.store
* @param classname the classname of the java object x
* @exception SQLException if a database access error occurs
*/
private
void
setSerialize
(
int
parameterIndex
,
long
x
,
String
classname
)
throws
SQLException
{
// converts . to _, toLowerCase, and ensures length<32
String
tablename
=
Serialize
.
toPostgreSQL
(
classname
);
DriverManager
.
println
(
"setSerialize: setting "
+
x
+
"::"
+
tablename
);
// OID reference to tablerow-type must be cast like: <oid>::<tablename>
// Note that postgres support for tablerow data types is incomplete/broken.
// This cannot be just a plain OID because then there would be ambiguity
// between when you want the oid itself and when you want the object
// an oid references.
set
(
parameterIndex
,
Long
.
toString
(
x
)
+
"::"
+
tablename
);
}
}
src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
View file @
8d600a7d
...
...
@@ -39,7 +39,7 @@ import java.math.*;
* @see ResultSet
*/
public
class
CallableStatement
extends
PreparedStatement
implements
java
.
sql
.
CallableStatement
public
class
CallableStatement
extends
Jdbc1
PreparedStatement
implements
java
.
sql
.
CallableStatement
{
/*
* @exception SQLException on failure
...
...
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Connection.java
View file @
8d600a7d
...
...
@@ -6,7 +6,7 @@ import java.sql.*;
import
org.postgresql.Field
;
import
org.postgresql.util.PSQLException
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Connection.java,v 1.
2 2002/07/24 22:08:40
barry Exp $
* This class implements the java.sql.Connection interface for JDBC1.
* However most of the implementation is really done in
* org.postgresql.jdbc1.AbstractJdbc1Connection
...
...
@@ -21,7 +21,7 @@ public class Jdbc1Connection extends org.postgresql.jdbc1.AbstractJdbc1Connectio
public
java
.
sql
.
PreparedStatement
prepareStatement
(
String
sql
)
throws
SQLException
{
return
new
org
.
postgresql
.
jdbc1
.
PreparedStatement
(
this
,
sql
);
return
new
org
.
postgresql
.
jdbc1
.
Jdbc1
PreparedStatement
(
this
,
sql
);
}
//BJL TODO - merge callable statement logic from jdbc2 to jdbc1
...
...
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1PreparedStatement.java
0 → 100644
View file @
8d600a7d
package
org.postgresql.jdbc1
;
import
java.sql.*
;
public
class
Jdbc1PreparedStatement
extends
AbstractJdbc1Statement
implements
PreparedStatement
{
public
Jdbc1PreparedStatement
(
Jdbc1Connection
connection
,
String
sql
)
throws
SQLException
{
super
(
connection
,
sql
);
}
}
src/interfaces/jdbc/org/postgresql/jdbc1/Jdbc1Statement.java
View file @
8d600a7d
...
...
@@ -3,7 +3,7 @@ package org.postgresql.jdbc1;
import
java.sql.*
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/Jdbc1Statement.java,v 1.
2 2002/07/24 22:08:40
barry Exp $
* This class implements the java.sql.Statement interface for JDBC1.
* However most of the implementation is really done in
* org.postgresql.jdbc1.AbstractJdbc1Statement
...
...
@@ -13,7 +13,7 @@ public class Jdbc1Statement extends org.postgresql.jdbc1.AbstractJdbc1Statement
public
Jdbc1Statement
(
Jdbc1Connection
c
)
{
connection
=
c
;
super
(
c
)
;
}
}
src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
deleted
100644 → 0
View file @
43515ba3
package
org.postgresql.jdbc1
;
// IMPORTANT NOTE: This file implements the JDBC 1 version of the driver.
// If you make any modifications to this file, you must make sure that the
// changes are also made (if relevent) to the related JDBC 2 class in the
// org.postgresql.jdbc2 package.
import
java.io.*
;
import
java.math.*
;
import
java.sql.*
;
import
java.text.*
;
import
java.util.*
;
import
org.postgresql.largeobject.*
;
import
org.postgresql.util.*
;
/*
* A SQL Statement is pre-compiled and stored in a PreparedStatement object.
* This object can then be used to efficiently execute this statement multiple
* times.
*
* <p><B>Note:</B> The setXXX methods for setting IN parameter values must
* specify types that are compatible with the defined SQL type of the input
* parameter. For instance, if the IN parameter has SQL type Integer, then
* setInt should be used.
*
* <p>If arbitrary parameter type conversions are required, then the setObject
* method should be used with a target SQL type.
*
* @see ResultSet
* @see java.sql.PreparedStatement
*/
public
class
PreparedStatement
extends
Jdbc1Statement
implements
java
.
sql
.
PreparedStatement
{
String
sql
;
String
[]
templateStrings
;
String
[]
inStrings
;
Jdbc1Connection
connection
;
// Some performance caches
private
StringBuffer
sbuf
=
new
StringBuffer
();
/*
* Constructor for the PreparedStatement class.
* Split the SQL statement into segments - separated by the arguments.
* When we rebuild the thing with the arguments, we can substitute the
* args and join the whole thing together.
*
* @param conn the instanatiating connection
* @param sql the SQL statement with ? for IN markers
* @exception SQLException if something bad occurs
*/
public
PreparedStatement
(
Jdbc1Connection
connection
,
String
sql
)
throws
SQLException
{
super
(
connection
);
Vector
v
=
new
Vector
();
boolean
inQuotes
=
false
;
int
lastParmEnd
=
0
,
i
;
this
.
sql
=
sql
;
this
.
connection
=
connection
;
for
(
i
=
0
;
i
<
sql
.
length
();
++
i
)
{
int
c
=
sql
.
charAt
(
i
);
if
(
c
==
'\''
)
inQuotes
=
!
inQuotes
;
if
(
c
==
'?'
&&
!
inQuotes
)
{
v
.
addElement
(
sql
.
substring
(
lastParmEnd
,
i
));
lastParmEnd
=
i
+
1
;
}
}
v
.
addElement
(
sql
.
substring
(
lastParmEnd
,
sql
.
length
()));
templateStrings
=
new
String
[
v
.
size
()];
inStrings
=
new
String
[
v
.
size
()
-
1
];
clearParameters
();
for
(
i
=
0
;
i
<
templateStrings
.
length
;
++
i
)
templateStrings
[
i
]
=
(
String
)
v
.
elementAt
(
i
);
}
/*
* A Prepared SQL query is executed and its ResultSet is returned
*
* @return a ResultSet that contains the data produced by the
* * query - never null
* @exception SQLException if a database access error occurs
*/
public
java
.
sql
.
ResultSet
executeQuery
()
throws
SQLException
{
StringBuffer
s
=
new
StringBuffer
();
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
throw
new
PSQLException
(
"postgresql.prep.param"
,
new
Integer
(
i
+
1
));
s
.
append
(
templateStrings
[
i
]);
s
.
append
(
inStrings
[
i
]);
}
s
.
append
(
templateStrings
[
inStrings
.
length
]);
return
super
.
executeQuery
(
s
.
toString
());
// in Statement class
}
/*
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
* SQL statements that return nothing such as SQL DDL statements can
* be executed.
*
* @return either the row count for INSERT, UPDATE or DELETE; or
* * 0 for SQL statements that return nothing.
* @exception SQLException if a database access error occurs
*/
public
int
executeUpdate
()
throws
SQLException
{
StringBuffer
s
=
new
StringBuffer
();
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
throw
new
PSQLException
(
"postgresql.prep.param"
,
new
Integer
(
i
+
1
));
s
.
append
(
templateStrings
[
i
]);
s
.
append
(
inStrings
[
i
]);
}
s
.
append
(
templateStrings
[
inStrings
.
length
]);
return
super
.
executeUpdate
(
s
.
toString
());
// in Statement class
}
/*
* Set a parameter to SQL NULL
*
* <p><B>Note:</B> You must specify the parameters SQL type (although
* PostgreSQL ignores it)
*
* @param parameterIndex the first parameter is 1, etc...
* @param sqlType the SQL type code defined in java.sql.Types
* @exception SQLException if a database access error occurs
*/
public
void
setNull
(
int
parameterIndex
,
int
sqlType
)
throws
SQLException
{
set
(
parameterIndex
,
"null"
);
}
/*
* Set a parameter to a Java boolean value. The driver converts this
* to a SQL BIT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBoolean
(
int
parameterIndex
,
boolean
x
)
throws
SQLException
{
set
(
parameterIndex
,
x
?
"'t'"
:
"'f'"
);
}
/*
* Set a parameter to a Java byte value. The driver converts this to
* a SQL TINYINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setByte
(
int
parameterIndex
,
byte
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java short value. The driver converts this
* to a SQL SMALLINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setShort
(
int
parameterIndex
,
short
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java int value. The driver converts this to
* a SQL INTEGER value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setInt
(
int
parameterIndex
,
int
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java long value. The driver converts this to
* a SQL BIGINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setLong
(
int
parameterIndex
,
long
x
)
throws
SQLException
{
set
(
parameterIndex
,
Long
.
toString
(
x
));
}
/*
* Set a parameter to a Java float value. The driver converts this
* to a SQL FLOAT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setFloat
(
int
parameterIndex
,
float
x
)
throws
SQLException
{
set
(
parameterIndex
,
Float
.
toString
(
x
));
}
/*
* Set a parameter to a Java double value. The driver converts this
* to a SQL DOUBLE value when it sends it to the database
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setDouble
(
int
parameterIndex
,
double
x
)
throws
SQLException
{
set
(
parameterIndex
,
Double
.
toString
(
x
));
}
/*
* Set a parameter to a java.lang.BigDecimal value. The driver
* converts this to a SQL NUMERIC value when it sends it to the
* database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBigDecimal
(
int
parameterIndex
,
BigDecimal
x
)
throws
SQLException
{
if
(
x
==
null
)
setNull
(
parameterIndex
,
Types
.
OTHER
);
else
{
set
(
parameterIndex
,
x
.
toString
());
}
}
/*
* Set a parameter to a Java String value. The driver converts this
* to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
* size relative to the driver's limits on VARCHARs) when it sends it
* to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setString
(
int
parameterIndex
,
String
x
)
throws
SQLException
{
// if the passed string is null, then set this column to null
if
(
x
==
null
)
setNull
(
parameterIndex
,
Types
.
OTHER
);
else
{
StringBuffer
b
=
new
StringBuffer
();
int
i
;
b
.
append
(
'\''
);
for
(
i
=
0
;
i
<
x
.
length
()
;
++
i
)
{
char
c
=
x
.
charAt
(
i
);
if
(
c
==
'\\'
||
c
==
'\''
)
b
.
append
((
char
)
'\\'
);
b
.
append
(
c
);
}
b
.
append
(
'\''
);
set
(
parameterIndex
,
b
.
toString
());
}
}
/*
* Set a parameter to a Java array of bytes. The driver converts this
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
* size relative to the driver's limits on VARBINARYs) when it sends
* it to the database.
*
* <p>Implementation note:
* <br>With org.postgresql, this creates a large object, and stores the
* objects oid in this column.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBytes
(
int
parameterIndex
,
byte
x
[])
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports the bytea datatype for byte arrays
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
setString
(
parameterIndex
,
PGbytea
.
toPGString
(
x
));
}
}
else
{
//Version 7.1 and earlier support done as LargeObjects
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
lob
.
write
(
x
);
lob
.
close
();
setInt
(
parameterIndex
,
oid
);
}
}
/*
* Set a parameter to a java.sql.Date value. The driver converts this
* to a SQL DATE value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setDate
(
int
parameterIndex
,
java
.
sql
.
Date
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
"'"
+
x
.
toString
()
+
"'"
);
}
}
/*
* Set a parameter to a java.sql.Time value. The driver converts
* this to a SQL TIME value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...));
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setTime
(
int
parameterIndex
,
Time
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
"'"
+
x
.
toString
()
+
"'"
);
}
}
/*
* Set a parameter to a java.sql.Timestamp value. The driver converts
* this to a SQL TIMESTAMP value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setTimestamp
(
int
parameterIndex
,
Timestamp
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
// Use the shared StringBuffer
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
sbuf
.
append
(
"'"
);
//format the timestamp
//we do our own formating so that we can get a format
//that works with both timestamp with time zone and
//timestamp without time zone datatypes.
//The format is '2002-01-01 23:59:59.123456-0130'
//we need to include the local time and timezone offset
//so that timestamp without time zone works correctly
int
l_year
=
x
.
getYear
()
+
1900
;
sbuf
.
append
(
l_year
);
sbuf
.
append
(
'-'
);
int
l_month
=
x
.
getMonth
()
+
1
;
if
(
l_month
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_month
);
sbuf
.
append
(
'-'
);
int
l_day
=
x
.
getDate
();
if
(
l_day
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_day
);
sbuf
.
append
(
' '
);
int
l_hours
=
x
.
getHours
();
if
(
l_hours
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_hours
);
sbuf
.
append
(
':'
);
int
l_minutes
=
x
.
getMinutes
();
if
(
l_minutes
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_minutes
);
sbuf
.
append
(
':'
);
int
l_seconds
=
x
.
getSeconds
();
if
(
l_seconds
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_seconds
);
// Make decimal from nanos.
char
[]
l_decimal
=
{
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
};
char
[]
l_nanos
=
Integer
.
toString
(
x
.
getNanos
()).
toCharArray
();
System
.
arraycopy
(
l_nanos
,
0
,
l_decimal
,
l_decimal
.
length
-
l_nanos
.
length
,
l_nanos
.
length
);
sbuf
.
append
(
'.'
);
if
(
connection
.
haveMinimumServerVersion
(
"7.2"
))
{
sbuf
.
append
(
l_decimal
,
0
,
6
);
}
else
{
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
sbuf
.
append
(
l_decimal
,
0
,
2
);
}
//add timezone offset
int
l_offset
=
-(
x
.
getTimezoneOffset
());
int
l_houros
=
l_offset
/
60
;
if
(
l_houros
>=
0
)
{
sbuf
.
append
(
'+'
);
}
else
{
sbuf
.
append
(
'-'
);
}
if
(
l_houros
>
-
10
&&
l_houros
<
10
)
sbuf
.
append
(
'0'
);
if
(
l_houros
>=
0
)
{
sbuf
.
append
(
l_houros
);
}
else
{
sbuf
.
append
(-
l_houros
);
}
int
l_minos
=
l_offset
-
(
l_houros
*
60
);
if
(
l_minos
!=
0
)
{
if
(
l_minos
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_minos
);
}
sbuf
.
append
(
"'"
);
set
(
parameterIndex
,
sbuf
.
toString
());
}
}
}
/*
* When a very large ASCII value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* ASCII to the database char format.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @param length the number of bytes in the stream
* @exception SQLException if a database access error occurs
*/
public
void
setAsciiStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
//As the spec/javadoc for this method indicate this is to be used for
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
try
{
InputStreamReader
l_inStream
=
new
InputStreamReader
(
x
,
"ASCII"
);
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
=
l_inStream
.
read
(
l_chars
,
0
,
length
);
setString
(
parameterIndex
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
catch
(
UnsupportedEncodingException
l_uee
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_uee
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
}
else
{
//Version 7.1 supported only LargeObjects by treating everything
//as binary data
setBinaryStream
(
parameterIndex
,
x
,
length
);
}
}
/*
* When a very large Unicode value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* UNICODE to the database char format.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setUnicodeStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
//As the spec/javadoc for this method indicate this is to be used for
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
try
{
InputStreamReader
l_inStream
=
new
InputStreamReader
(
x
,
"UTF-8"
);
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
=
l_inStream
.
read
(
l_chars
,
0
,
length
);
setString
(
parameterIndex
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
catch
(
UnsupportedEncodingException
l_uee
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_uee
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
}
else
{
//Version 7.1 supported only LargeObjects by treating everything
//as binary data
setBinaryStream
(
parameterIndex
,
x
,
length
);
}
}
/*
* When a very large binary value is input to a LONGVARBINARY parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBinaryStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports BinaryStream for for the PG bytea type
//As the spec/javadoc for this method indicate this is to be used for
//large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
//long binary datatype, but with toast the bytea datatype is capable of
//handling very large values. Thus the implementation ends up calling
//setBytes() since there is no current way to stream the value to the server
byte
[]
l_bytes
=
new
byte
[
length
];
int
l_bytesRead
;
try
{
l_bytesRead
=
x
.
read
(
l_bytes
,
0
,
length
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
if
(
l_bytesRead
==
length
)
{
setBytes
(
parameterIndex
,
l_bytes
);
}
else
{
//the stream contained less data than they said
byte
[]
l_bytes2
=
new
byte
[
l_bytesRead
];
System
.
arraycopy
(
l_bytes
,
0
,
l_bytes2
,
0
,
l_bytesRead
);
setBytes
(
parameterIndex
,
l_bytes2
);
}
}
else
{
//Version 7.1 only supported streams for LargeObjects
//but the jdbc spec indicates that streams should be
//available for LONGVARBINARY instead
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
x
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
length
)
{
los
.
write
(
c
);
c
=
x
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
parameterIndex
,
oid
);
}
}
/*
* In general, parameter values remain in force for repeated used of a
* Statement. Setting a parameter value automatically clears its
* previous value. However, in coms cases, it is useful to immediately
* release the resources used by the current parameter values; this
* can be done by calling clearParameters
*
* @exception SQLException if a database access error occurs
*/
public
void
clearParameters
()
throws
SQLException
{
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
i
++)
inStrings
[
i
]
=
null
;
}
/*
* Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values.
*
* <P>The given Java object will be converted to the targetSqlType before
* being sent to the database.
*
* <P>note that this method may be used to pass database-specific
* abstract data types. This is done by using a Driver-specific
* Java type and using a targetSqlType of java.sql.Types.OTHER
*
* @param parameterIndex the first parameter is 1...
* @param x the object containing the input parameter value
* @param targetSqlType The SQL type to be send to the database
* @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
* * types this is the number of digits after the decimal. For
* * all other types this value will be ignored.
* @exception SQLException if a database access error occurs
*/
public
void
setObject
(
int
parameterIndex
,
Object
x
,
int
targetSqlType
,
int
scale
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
return
;
}
switch
(
targetSqlType
)
{
case
Types
.
TINYINT
:
case
Types
.
SMALLINT
:
case
Types
.
INTEGER
:
case
Types
.
BIGINT
:
case
Types
.
REAL
:
case
Types
.
FLOAT
:
case
Types
.
DOUBLE
:
case
Types
.
DECIMAL
:
case
Types
.
NUMERIC
:
if
(
x
instanceof
Boolean
)
set
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
()
?
"1"
:
"0"
);
else
set
(
parameterIndex
,
x
.
toString
());
break
;
case
Types
.
CHAR
:
case
Types
.
VARCHAR
:
case
Types
.
LONGVARCHAR
:
setString
(
parameterIndex
,
x
.
toString
());
break
;
case
Types
.
DATE
:
setDate
(
parameterIndex
,
(
java
.
sql
.
Date
)
x
);
break
;
case
Types
.
TIME
:
setTime
(
parameterIndex
,
(
Time
)
x
);
break
;
case
Types
.
TIMESTAMP
:
setTimestamp
(
parameterIndex
,
(
Timestamp
)
x
);
break
;
case
Types
.
BIT
:
if
(
x
instanceof
Boolean
)
{
set
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
()
?
"TRUE"
:
"FALSE"
);
}
else
{
throw
new
PSQLException
(
"postgresql.prep.type"
);
}
break
;
case
Types
.
BINARY
:
case
Types
.
VARBINARY
:
setObject
(
parameterIndex
,
x
);
break
;
case
Types
.
OTHER
:
setString
(
parameterIndex
,
((
PGobject
)
x
).
getValue
());
break
;
default
:
throw
new
PSQLException
(
"postgresql.prep.type"
);
}
}
public
void
setObject
(
int
parameterIndex
,
Object
x
,
int
targetSqlType
)
throws
SQLException
{
setObject
(
parameterIndex
,
x
,
targetSqlType
,
0
);
}
/*
* This stores an Object into a parameter.
* <p>New for 6.4, if the object is not recognised, but it is
* Serializable, then the object is serialised using the
* org.postgresql.util.Serialize class.
*/
public
void
setObject
(
int
parameterIndex
,
Object
x
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
return
;
}
if
(
x
instanceof
String
)
setString
(
parameterIndex
,
(
String
)
x
);
else
if
(
x
instanceof
BigDecimal
)
setBigDecimal
(
parameterIndex
,
(
BigDecimal
)
x
);
else
if
(
x
instanceof
Short
)
setShort
(
parameterIndex
,
((
Short
)
x
).
shortValue
());
else
if
(
x
instanceof
Integer
)
setInt
(
parameterIndex
,
((
Integer
)
x
).
intValue
());
else
if
(
x
instanceof
Long
)
setLong
(
parameterIndex
,
((
Long
)
x
).
longValue
());
else
if
(
x
instanceof
Float
)
setFloat
(
parameterIndex
,
((
Float
)
x
).
floatValue
());
else
if
(
x
instanceof
Double
)
setDouble
(
parameterIndex
,
((
Double
)
x
).
doubleValue
());
else
if
(
x
instanceof
byte
[])
setBytes
(
parameterIndex
,
(
byte
[])
x
);
else
if
(
x
instanceof
java
.
sql
.
Date
)
setDate
(
parameterIndex
,
(
java
.
sql
.
Date
)
x
);
else
if
(
x
instanceof
Time
)
setTime
(
parameterIndex
,
(
Time
)
x
);
else
if
(
x
instanceof
Timestamp
)
setTimestamp
(
parameterIndex
,
(
Timestamp
)
x
);
else
if
(
x
instanceof
Boolean
)
setBoolean
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
());
else
if
(
x
instanceof
PGobject
)
setString
(
parameterIndex
,
((
PGobject
)
x
).
getValue
());
else
setLong
(
parameterIndex
,
connection
.
storeObject
(
x
));
}
/*
* Some prepared statements return multiple results; the execute method
* handles these complex statements as well as the simpler form of
* statements handled by executeQuery and executeUpdate
*
* @return true if the next result is a ResultSet; false if it is an
* * update count or there are no more results
* @exception SQLException if a database access error occurs
*/
public
boolean
execute
()
throws
SQLException
{
StringBuffer
s
=
new
StringBuffer
();
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
throw
new
PSQLException
(
"postgresql.prep.param"
,
new
Integer
(
i
+
1
));
s
.
append
(
templateStrings
[
i
]);
s
.
append
(
inStrings
[
i
]);
}
s
.
append
(
templateStrings
[
inStrings
.
length
]);
return
super
.
execute
(
s
.
toString
());
// in Statement class
}
/*
* Returns the SQL statement with the current template values
* substituted.
*/
public
String
toString
()
{
StringBuffer
s
=
new
StringBuffer
();
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
s
.
append
(
'?'
);
else
s
.
append
(
templateStrings
[
i
]);
s
.
append
(
inStrings
[
i
]);
}
s
.
append
(
templateStrings
[
inStrings
.
length
]);
return
s
.
toString
();
}
// **************************************************************
// END OF PUBLIC INTERFACE
// **************************************************************
/*
* There are a lot of setXXX classes which all basically do
* the same thing. We need a method which actually does the
* set for us.
*
* @param paramIndex the index into the inString
* @param s a string to be stored
* @exception SQLException if something goes wrong
*/
private
void
set
(
int
paramIndex
,
String
s
)
throws
SQLException
{
if
(
paramIndex
<
1
||
paramIndex
>
inStrings
.
length
)
throw
new
PSQLException
(
"postgresql.prep.range"
);
inStrings
[
paramIndex
-
1
]
=
s
;
}
}
src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java
View file @
8d600a7d
...
...
@@ -13,14 +13,14 @@ import org.postgresql.largeobject.*;
import
org.postgresql.util.PGbytea
;
import
org.postgresql.util.PSQLException
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2ResultSet.java,v 1.
2 2002/07/24 22:08:42
barry Exp $
* This class defines methods of the jdbc2 specification. This class extends
* org.postgresql.jdbc1.AbstractJdbc1ResultSet which provides the jdbc1
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2ResultSet
*/
public
class
AbstractJdbc2ResultSet
extends
org
.
postgresql
.
jdbc1
.
AbstractJdbc1ResultSet
{
protected
Jdbc2
Statement
statement
;
protected
Statement
statement
;
protected
String
sqlQuery
=
null
;
...
...
@@ -373,7 +373,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
}
// This one needs some thought, as not all ResultSets come from a statement
public
java
.
sql
.
Statement
getStatement
()
throws
SQLException
public
Statement
getStatement
()
throws
SQLException
{
return
statement
;
}
...
...
@@ -740,7 +740,7 @@ public class AbstractJdbc2ResultSet extends org.postgresql.jdbc1.AbstractJdbc1Re
* It's used currently by getStatement() but may also with the new core
* package.
*/
public
void
setStatement
(
Jdbc2
Statement
statement
)
public
void
setStatement
(
Statement
statement
)
{
this
.
statement
=
statement
;
}
...
...
src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java
View file @
8d600a7d
package
org.postgresql.jdbc2
;
import
java.io.*
;
import
java.sql.*
;
import
java.util.Vector
;
import
org.postgresql.largeobject.*
;
import
org.postgresql.util.PSQLException
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/AbstractJdbc2Statement.java,v 1.
2 2002/07/24 22:08:42
barry Exp $
* This class defines methods of the jdbc2 specification. This class extends
* org.postgresql.jdbc1.AbstractJdbc1Statement which provides the jdbc1
* methods. The real Statement class (for jdbc2) is org.postgresql.jdbc2.Jdbc2Statement
...
...
@@ -17,6 +19,18 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
protected
int
resultsettype
;
// the resultset type to return
protected
int
concurrency
;
// is it updateable or not?
public
AbstractJdbc2Statement
(
AbstractJdbc2Connection
c
)
{
super
(
c
);
resultsettype
=
java
.
sql
.
ResultSet
.
TYPE_SCROLL_INSENSITIVE
;
concurrency
=
java
.
sql
.
ResultSet
.
CONCUR_READ_ONLY
;
}
public
AbstractJdbc2Statement
(
AbstractJdbc2Connection
connection
,
String
sql
)
throws
SQLException
{
super
(
connection
,
sql
);
}
/*
* Execute a SQL statement that may return multiple results. We
* don't have to worry about this since we do not support multiple
...
...
@@ -31,10 +45,9 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
public
boolean
execute
(
String
sql
)
throws
SQLException
{
boolean
l_return
=
super
.
execute
(
sql
);
//Now do the jdbc2 specific stuff
//required for ResultSet.getStatement() to work
((
AbstractJdbc2ResultSet
)
result
).
setStatement
((
Jdbc2
Statement
)
this
);
((
AbstractJdbc2ResultSet
)
result
).
setStatement
((
Statement
)
this
);
// Added this so that the Updateable resultset knows the query that gave this
((
AbstractJdbc2ResultSet
)
result
).
setSQLQuery
(
sql
);
...
...
@@ -139,4 +152,183 @@ public abstract class AbstractJdbc2Statement extends org.postgresql.jdbc1.Abstra
resultsettype
=
value
;
}
public
void
addBatch
()
throws
SQLException
{
addBatch
(
compileQuery
());
}
public
java
.
sql
.
ResultSetMetaData
getMetaData
()
throws
SQLException
{
java
.
sql
.
ResultSet
rs
=
getResultSet
();
if
(
rs
!=
null
)
return
rs
.
getMetaData
();
// Does anyone really know what this method does?
return
null
;
}
public
void
setArray
(
int
i
,
java
.
sql
.
Array
x
)
throws
SQLException
{
setString
(
i
,
x
.
toString
());
}
public
void
setBlob
(
int
i
,
Blob
x
)
throws
SQLException
{
InputStream
l_inStream
=
x
.
getBinaryStream
();
int
l_length
=
(
int
)
x
.
length
();
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
l_inStream
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
l_length
)
{
los
.
write
(
c
);
c
=
l_inStream
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
i
,
oid
);
}
public
void
setCharacterStream
(
int
i
,
java
.
io
.
Reader
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports CharacterStream for for the PG text types
//As the spec/javadoc for this method indicate this is to be used for
//large text values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all the text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
;
try
{
l_charsRead
=
x
.
read
(
l_chars
,
0
,
length
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
setString
(
i
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
else
{
//Version 7.1 only supported streams for LargeObjects
//but the jdbc spec indicates that streams should be
//available for LONGVARCHAR instead
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
x
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
length
)
{
los
.
write
(
c
);
c
=
x
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
i
,
oid
);
}
}
public
void
setClob
(
int
i
,
Clob
x
)
throws
SQLException
{
InputStream
l_inStream
=
x
.
getAsciiStream
();
int
l_length
=
(
int
)
x
.
length
();
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
l_inStream
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
l_length
)
{
los
.
write
(
c
);
c
=
l_inStream
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
i
,
oid
);
}
public
void
setNull
(
int
i
,
int
t
,
String
s
)
throws
SQLException
{
setNull
(
i
,
t
);
}
public
void
setRef
(
int
i
,
Ref
x
)
throws
SQLException
{
throw
org
.
postgresql
.
Driver
.
notImplemented
();
}
public
void
setDate
(
int
i
,
java
.
sql
.
Date
d
,
java
.
util
.
Calendar
cal
)
throws
SQLException
{
if
(
cal
==
null
)
setDate
(
i
,
d
);
else
{
cal
.
setTime
(
d
);
setDate
(
i
,
new
java
.
sql
.
Date
(
cal
.
getTime
().
getTime
()));
}
}
public
void
setTime
(
int
i
,
Time
t
,
java
.
util
.
Calendar
cal
)
throws
SQLException
{
if
(
cal
==
null
)
setTime
(
i
,
t
);
else
{
cal
.
setTime
(
t
);
setTime
(
i
,
new
java
.
sql
.
Time
(
cal
.
getTime
().
getTime
()));
}
}
public
void
setTimestamp
(
int
i
,
Timestamp
t
,
java
.
util
.
Calendar
cal
)
throws
SQLException
{
if
(
cal
==
null
)
setTimestamp
(
i
,
t
);
else
{
cal
.
setTime
(
t
);
setTimestamp
(
i
,
new
java
.
sql
.
Timestamp
(
cal
.
getTime
().
getTime
()));
}
}
}
src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
View file @
8d600a7d
...
...
@@ -40,7 +40,7 @@ import org.postgresql.util.*;
* @author Paul Bethe (implementer)
*/
public
class
CallableStatement
extends
org
.
postgresql
.
jdbc2
.
PreparedStatement
implements
java
.
sql
.
CallableStatement
public
class
CallableStatement
extends
org
.
postgresql
.
jdbc2
.
Jdbc2
PreparedStatement
implements
java
.
sql
.
CallableStatement
{
/*
* @exception SQLException on failure
...
...
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Connection.java
View file @
8d600a7d
...
...
@@ -5,7 +5,7 @@ import java.sql.*;
import
java.util.Vector
;
import
org.postgresql.Field
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Connection.java,v 1.
2 2002/07/24 22:08:42
barry Exp $
* This class implements the java.sql.Connection interface for JDBC2.
* However most of the implementation is really done in
* org.postgresql.jdbc2.AbstractJdbc2Connection or one of it's parents
...
...
@@ -24,7 +24,7 @@ public class Jdbc2Connection extends org.postgresql.jdbc2.AbstractJdbc2Connectio
public
java
.
sql
.
PreparedStatement
prepareStatement
(
String
sql
,
int
resultSetType
,
int
resultSetConcurrency
)
throws
SQLException
{
org
.
postgresql
.
jdbc2
.
PreparedStatement
s
=
new
org
.
postgresql
.
jdbc2
.
PreparedStatement
(
this
,
sql
);
Jdbc2PreparedStatement
s
=
new
Jdbc2
PreparedStatement
(
this
,
sql
);
s
.
setResultSetType
(
resultSetType
);
s
.
setResultSetConcurrency
(
resultSetConcurrency
);
return
s
;
...
...
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2PreparedStatement.java
0 → 100644
View file @
8d600a7d
package
org.postgresql.jdbc2
;
import
java.sql.*
;
public
class
Jdbc2PreparedStatement
extends
AbstractJdbc2Statement
implements
java
.
sql
.
PreparedStatement
{
public
Jdbc2PreparedStatement
(
Jdbc2Connection
connection
,
String
sql
)
throws
SQLException
{
super
(
connection
,
sql
);
}
}
src/interfaces/jdbc/org/postgresql/jdbc2/Jdbc2Statement.java
View file @
8d600a7d
...
...
@@ -3,7 +3,7 @@ package org.postgresql.jdbc2;
import
java.sql.*
;
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.
1 2002/07/23 03:59:55
barry Exp $
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/Attic/Jdbc2Statement.java,v 1.
2 2002/07/24 22:08:43
barry Exp $
* This class implements the java.sql.Statement interface for JDBC2.
* However most of the implementation is really done in
* org.postgresql.jdbc2.AbstractJdbc2Statement or one of it's parents
...
...
@@ -13,9 +13,7 @@ public class Jdbc2Statement extends org.postgresql.jdbc2.AbstractJdbc2Statement
public
Jdbc2Statement
(
Jdbc2Connection
c
)
{
connection
=
c
;
resultsettype
=
java
.
sql
.
ResultSet
.
TYPE_SCROLL_INSENSITIVE
;
concurrency
=
java
.
sql
.
ResultSet
.
CONCUR_READ_ONLY
;
super
(
c
);
}
}
src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
deleted
100644 → 0
View file @
43515ba3
package
org.postgresql.jdbc2
;
// IMPORTANT NOTE: This file implements the JDBC 2 version of the driver.
// If you make any modifications to this file, you must make sure that the
// changes are also made (if relevent) to the related JDBC 1 class in the
// org.postgresql.jdbc1 package.
import
java.io.*
;
import
java.math.*
;
import
java.sql.*
;
import
java.text.*
;
import
java.util.*
;
import
org.postgresql.largeobject.*
;
import
org.postgresql.util.*
;
/*
* A SQL Statement is pre-compiled and stored in a PreparedStatement object.
* This object can then be used to efficiently execute this statement multiple
* times.
*
* <p><B>Note:</B> The setXXX methods for setting IN parameter values must
* specify types that are compatible with the defined SQL type of the input
* parameter. For instance, if the IN parameter has SQL type Integer, then
* setInt should be used.
*
* <p>If arbitrary parameter type conversions are required, then the setObject
* method should be used with a target SQL type.
*
* @see ResultSet
* @see java.sql.PreparedStatement
*/
public
class
PreparedStatement
extends
Jdbc2Statement
implements
java
.
sql
.
PreparedStatement
{
String
sql
;
String
[]
templateStrings
;
String
[]
inStrings
;
Jdbc2Connection
connection
;
// Some performance caches
private
StringBuffer
sbuf
=
new
StringBuffer
();
/*
* Constructor for the PreparedStatement class.
* Split the SQL statement into segments - separated by the arguments.
* When we rebuild the thing with the arguments, we can substitute the
* args and join the whole thing together.
*
* @param conn the instanatiating connection
* @param sql the SQL statement with ? for IN markers
* @exception SQLException if something bad occurs
*/
public
PreparedStatement
(
Jdbc2Connection
connection
,
String
sql
)
throws
SQLException
{
super
(
connection
);
this
.
sql
=
sql
;
this
.
connection
=
connection
;
parseSqlStmt
();
// this allows Callable stmt to override
}
protected
void
parseSqlStmt
()
throws
SQLException
{
Vector
v
=
new
Vector
();
boolean
inQuotes
=
false
;
int
lastParmEnd
=
0
,
i
;
for
(
i
=
0
;
i
<
sql
.
length
();
++
i
)
{
int
c
=
sql
.
charAt
(
i
);
if
(
c
==
'\''
)
inQuotes
=
!
inQuotes
;
if
(
c
==
'?'
&&
!
inQuotes
)
{
v
.
addElement
(
sql
.
substring
(
lastParmEnd
,
i
));
lastParmEnd
=
i
+
1
;
}
}
v
.
addElement
(
sql
.
substring
(
lastParmEnd
,
sql
.
length
()));
templateStrings
=
new
String
[
v
.
size
()];
inStrings
=
new
String
[
v
.
size
()
-
1
];
clearParameters
();
for
(
i
=
0
;
i
<
templateStrings
.
length
;
++
i
)
templateStrings
[
i
]
=
(
String
)
v
.
elementAt
(
i
);
}
/*
* A Prepared SQL query is executed and its ResultSet is returned
*
* @return a ResultSet that contains the data produced by the
* * query - never null
* @exception SQLException if a database access error occurs
*/
public
java
.
sql
.
ResultSet
executeQuery
()
throws
SQLException
{
return
super
.
executeQuery
(
compileQuery
());
// in Statement class
}
/*
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
* SQL statements that return nothing such as SQL DDL statements can
* be executed.
*
* @return either the row count for INSERT, UPDATE or DELETE; or
* * 0 for SQL statements that return nothing.
* @exception SQLException if a database access error occurs
*/
public
int
executeUpdate
()
throws
SQLException
{
return
super
.
executeUpdate
(
compileQuery
());
// in Statement class
}
/*
* Helper - this compiles the SQL query from the various parameters
* This is identical to toString() except it throws an exception if a
* parameter is unused.
*/
protected
synchronized
String
compileQuery
()
throws
SQLException
{
sbuf
.
setLength
(
0
);
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
throw
new
PSQLException
(
"postgresql.prep.param"
,
new
Integer
(
i
+
1
));
sbuf
.
append
(
templateStrings
[
i
]).
append
(
inStrings
[
i
]);
}
sbuf
.
append
(
templateStrings
[
inStrings
.
length
]);
return
sbuf
.
toString
();
}
/*
* Set a parameter to SQL NULL
*
* <p><B>Note:</B> You must specify the parameters SQL type (although
* PostgreSQL ignores it)
*
* @param parameterIndex the first parameter is 1, etc...
* @param sqlType the SQL type code defined in java.sql.Types
* @exception SQLException if a database access error occurs
*/
public
void
setNull
(
int
parameterIndex
,
int
sqlType
)
throws
SQLException
{
set
(
parameterIndex
,
"null"
);
}
/*
* Set a parameter to a Java boolean value. The driver converts this
* to a SQL BIT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBoolean
(
int
parameterIndex
,
boolean
x
)
throws
SQLException
{
set
(
parameterIndex
,
x
?
"'t'"
:
"'f'"
);
}
/*
* Set a parameter to a Java byte value. The driver converts this to
* a SQL TINYINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setByte
(
int
parameterIndex
,
byte
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java short value. The driver converts this
* to a SQL SMALLINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setShort
(
int
parameterIndex
,
short
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java int value. The driver converts this to
* a SQL INTEGER value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setInt
(
int
parameterIndex
,
int
x
)
throws
SQLException
{
set
(
parameterIndex
,
Integer
.
toString
(
x
));
}
/*
* Set a parameter to a Java long value. The driver converts this to
* a SQL BIGINT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setLong
(
int
parameterIndex
,
long
x
)
throws
SQLException
{
set
(
parameterIndex
,
Long
.
toString
(
x
));
}
/*
* Set a parameter to a Java float value. The driver converts this
* to a SQL FLOAT value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setFloat
(
int
parameterIndex
,
float
x
)
throws
SQLException
{
set
(
parameterIndex
,
Float
.
toString
(
x
));
}
/*
* Set a parameter to a Java double value. The driver converts this
* to a SQL DOUBLE value when it sends it to the database
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setDouble
(
int
parameterIndex
,
double
x
)
throws
SQLException
{
set
(
parameterIndex
,
Double
.
toString
(
x
));
}
/*
* Set a parameter to a java.lang.BigDecimal value. The driver
* converts this to a SQL NUMERIC value when it sends it to the
* database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBigDecimal
(
int
parameterIndex
,
BigDecimal
x
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
x
.
toString
());
}
}
/*
* Set a parameter to a Java String value. The driver converts this
* to a SQL VARCHAR or LONGVARCHAR value (depending on the arguments
* size relative to the driver's limits on VARCHARs) when it sends it
* to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setString
(
int
parameterIndex
,
String
x
)
throws
SQLException
{
// if the passed string is null, then set this column to null
if
(
x
==
null
)
setNull
(
parameterIndex
,
Types
.
OTHER
);
else
{
// use the shared buffer object. Should never clash but this makes
// us thread safe!
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
int
i
;
sbuf
.
append
(
'\''
);
for
(
i
=
0
;
i
<
x
.
length
()
;
++
i
)
{
char
c
=
x
.
charAt
(
i
);
if
(
c
==
'\\'
||
c
==
'\''
)
sbuf
.
append
((
char
)
'\\'
);
sbuf
.
append
(
c
);
}
sbuf
.
append
(
'\''
);
set
(
parameterIndex
,
sbuf
.
toString
());
}
}
}
/*
* Set a parameter to a Java array of bytes. The driver converts this
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
* size relative to the driver's limits on VARBINARYs) when it sends
* it to the database.
*
* <p>Implementation note:
* <br>With org.postgresql, this creates a large object, and stores the
* objects oid in this column.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBytes
(
int
parameterIndex
,
byte
x
[])
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports the bytea datatype for byte arrays
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
setString
(
parameterIndex
,
PGbytea
.
toPGString
(
x
));
}
}
else
{
//Version 7.1 and earlier support done as LargeObjects
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
lob
.
write
(
x
);
lob
.
close
();
setInt
(
parameterIndex
,
oid
);
}
}
/*
* Set a parameter to a java.sql.Date value. The driver converts this
* to a SQL DATE value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setDate
(
int
parameterIndex
,
java
.
sql
.
Date
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
"'"
+
x
.
toString
()
+
"'"
);
}
}
/*
* Set a parameter to a java.sql.Time value. The driver converts
* this to a SQL TIME value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...));
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setTime
(
int
parameterIndex
,
Time
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
set
(
parameterIndex
,
"'"
+
x
.
toString
()
+
"'"
);
}
}
/*
* Set a parameter to a java.sql.Timestamp value. The driver converts
* this to a SQL TIMESTAMP value when it sends it to the database.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setTimestamp
(
int
parameterIndex
,
Timestamp
x
)
throws
SQLException
{
if
(
null
==
x
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
}
else
{
// Use the shared StringBuffer
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
sbuf
.
append
(
"'"
);
//format the timestamp
//we do our own formating so that we can get a format
//that works with both timestamp with time zone and
//timestamp without time zone datatypes.
//The format is '2002-01-01 23:59:59.123456-0130'
//we need to include the local time and timezone offset
//so that timestamp without time zone works correctly
int
l_year
=
x
.
getYear
()
+
1900
;
sbuf
.
append
(
l_year
);
sbuf
.
append
(
'-'
);
int
l_month
=
x
.
getMonth
()
+
1
;
if
(
l_month
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_month
);
sbuf
.
append
(
'-'
);
int
l_day
=
x
.
getDate
();
if
(
l_day
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_day
);
sbuf
.
append
(
' '
);
int
l_hours
=
x
.
getHours
();
if
(
l_hours
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_hours
);
sbuf
.
append
(
':'
);
int
l_minutes
=
x
.
getMinutes
();
if
(
l_minutes
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_minutes
);
sbuf
.
append
(
':'
);
int
l_seconds
=
x
.
getSeconds
();
if
(
l_seconds
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_seconds
);
// Make decimal from nanos.
char
[]
l_decimal
=
{
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
,
'0'
};
char
[]
l_nanos
=
Integer
.
toString
(
x
.
getNanos
()).
toCharArray
();
System
.
arraycopy
(
l_nanos
,
0
,
l_decimal
,
l_decimal
.
length
-
l_nanos
.
length
,
l_nanos
.
length
);
sbuf
.
append
(
'.'
);
if
(
connection
.
haveMinimumServerVersion
(
"7.2"
))
{
sbuf
.
append
(
l_decimal
,
0
,
6
);
}
else
{
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
sbuf
.
append
(
l_decimal
,
0
,
2
);
}
//add timezone offset
int
l_offset
=
-(
x
.
getTimezoneOffset
());
int
l_houros
=
l_offset
/
60
;
if
(
l_houros
>=
0
)
{
sbuf
.
append
(
'+'
);
}
else
{
sbuf
.
append
(
'-'
);
}
if
(
l_houros
>
-
10
&&
l_houros
<
10
)
sbuf
.
append
(
'0'
);
if
(
l_houros
>=
0
)
{
sbuf
.
append
(
l_houros
);
}
else
{
sbuf
.
append
(-
l_houros
);
}
int
l_minos
=
l_offset
-
(
l_houros
*
60
);
if
(
l_minos
!=
0
)
{
if
(
l_minos
<
10
)
sbuf
.
append
(
'0'
);
sbuf
.
append
(
l_minos
);
}
sbuf
.
append
(
"'"
);
set
(
parameterIndex
,
sbuf
.
toString
());
}
}
}
/*
* When a very large ASCII value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* ASCII to the database char format.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @param length the number of bytes in the stream
* @exception SQLException if a database access error occurs
*/
public
void
setAsciiStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
//As the spec/javadoc for this method indicate this is to be used for
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
try
{
InputStreamReader
l_inStream
=
new
InputStreamReader
(
x
,
"ASCII"
);
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
=
l_inStream
.
read
(
l_chars
,
0
,
length
);
setString
(
parameterIndex
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
catch
(
UnsupportedEncodingException
l_uee
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_uee
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
}
else
{
//Version 7.1 supported only LargeObjects by treating everything
//as binary data
setBinaryStream
(
parameterIndex
,
x
,
length
);
}
}
/*
* When a very large Unicode value is input to a LONGVARCHAR parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file. The JDBC driver will do any necessary conversion from
* UNICODE to the database char format.
*
* ** DEPRECIATED IN JDBC 2 **
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
* @deprecated
*/
public
void
setUnicodeStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports AsciiStream for all PG text types (char, varchar, text)
//As the spec/javadoc for this method indicate this is to be used for
//large String values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
try
{
InputStreamReader
l_inStream
=
new
InputStreamReader
(
x
,
"UTF-8"
);
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
=
l_inStream
.
read
(
l_chars
,
0
,
length
);
setString
(
parameterIndex
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
catch
(
UnsupportedEncodingException
l_uee
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_uee
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
}
else
{
//Version 7.1 supported only LargeObjects by treating everything
//as binary data
setBinaryStream
(
parameterIndex
,
x
,
length
);
}
}
/*
* When a very large binary value is input to a LONGVARBINARY parameter,
* it may be more practical to send it via a java.io.InputStream.
* JDBC will read the data from the stream as needed, until it reaches
* end-of-file.
*
* <P><B>Note:</B> This stream object can either be a standard Java
* stream object or your own subclass that implements the standard
* interface.
*
* @param parameterIndex the first parameter is 1...
* @param x the parameter value
* @exception SQLException if a database access error occurs
*/
public
void
setBinaryStream
(
int
parameterIndex
,
InputStream
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports BinaryStream for for the PG bytea type
//As the spec/javadoc for this method indicate this is to be used for
//large binary values (i.e. LONGVARBINARY) PG doesn't have a separate
//long binary datatype, but with toast the bytea datatype is capable of
//handling very large values. Thus the implementation ends up calling
//setBytes() since there is no current way to stream the value to the server
byte
[]
l_bytes
=
new
byte
[
length
];
int
l_bytesRead
;
try
{
l_bytesRead
=
x
.
read
(
l_bytes
,
0
,
length
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
if
(
l_bytesRead
==
length
)
{
setBytes
(
parameterIndex
,
l_bytes
);
}
else
{
//the stream contained less data than they said
byte
[]
l_bytes2
=
new
byte
[
l_bytesRead
];
System
.
arraycopy
(
l_bytes
,
0
,
l_bytes2
,
0
,
l_bytesRead
);
setBytes
(
parameterIndex
,
l_bytes2
);
}
}
else
{
//Version 7.1 only supported streams for LargeObjects
//but the jdbc spec indicates that streams should be
//available for LONGVARBINARY instead
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
x
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
length
)
{
los
.
write
(
c
);
c
=
x
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
parameterIndex
,
oid
);
}
}
/*
* In general, parameter values remain in force for repeated used of a
* Statement. Setting a parameter value automatically clears its
* previous value. However, in coms cases, it is useful to immediately
* release the resources used by the current parameter values; this
* can be done by calling clearParameters
*
* @exception SQLException if a database access error occurs
*/
public
void
clearParameters
()
throws
SQLException
{
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
i
++)
inStrings
[
i
]
=
null
;
}
/*
* Set the value of a parameter using an object; use the java.lang
* equivalent objects for integral values.
*
* <P>The given Java object will be converted to the targetSqlType before
* being sent to the database.
*
* <P>note that this method may be used to pass database-specific
* abstract data types. This is done by using a Driver-specific
* Java type and using a targetSqlType of java.sql.Types.OTHER
*
* @param parameterIndex the first parameter is 1...
* @param x the object containing the input parameter value
* @param targetSqlType The SQL type to be send to the database
* @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC
* types this is the number of digits after the decimal. For
* all other types this value will be ignored.
* @exception SQLException if a database access error occurs
*/
public
void
setObject
(
int
parameterIndex
,
Object
x
,
int
targetSqlType
,
int
scale
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
return
;
}
switch
(
targetSqlType
)
{
case
Types
.
TINYINT
:
case
Types
.
SMALLINT
:
case
Types
.
INTEGER
:
case
Types
.
BIGINT
:
case
Types
.
REAL
:
case
Types
.
FLOAT
:
case
Types
.
DOUBLE
:
case
Types
.
DECIMAL
:
case
Types
.
NUMERIC
:
if
(
x
instanceof
Boolean
)
set
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
()
?
"1"
:
"0"
);
else
set
(
parameterIndex
,
x
.
toString
());
break
;
case
Types
.
CHAR
:
case
Types
.
VARCHAR
:
case
Types
.
LONGVARCHAR
:
setString
(
parameterIndex
,
x
.
toString
());
break
;
case
Types
.
DATE
:
setDate
(
parameterIndex
,
(
java
.
sql
.
Date
)
x
);
break
;
case
Types
.
TIME
:
setTime
(
parameterIndex
,
(
Time
)
x
);
break
;
case
Types
.
TIMESTAMP
:
setTimestamp
(
parameterIndex
,
(
Timestamp
)
x
);
break
;
case
Types
.
BIT
:
if
(
x
instanceof
Boolean
)
{
set
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
()
?
"TRUE"
:
"FALSE"
);
}
else
{
throw
new
PSQLException
(
"postgresql.prep.type"
);
}
break
;
case
Types
.
BINARY
:
case
Types
.
VARBINARY
:
setObject
(
parameterIndex
,
x
);
break
;
case
Types
.
OTHER
:
setString
(
parameterIndex
,
((
PGobject
)
x
).
getValue
());
break
;
default
:
throw
new
PSQLException
(
"postgresql.prep.type"
);
}
}
public
void
setObject
(
int
parameterIndex
,
Object
x
,
int
targetSqlType
)
throws
SQLException
{
setObject
(
parameterIndex
,
x
,
targetSqlType
,
0
);
}
/*
* This stores an Object into a parameter.
* <p>New for 6.4, if the object is not recognised, but it is
* Serializable, then the object is serialised using the
* org.postgresql.util.Serialize class.
*/
public
void
setObject
(
int
parameterIndex
,
Object
x
)
throws
SQLException
{
if
(
x
==
null
)
{
setNull
(
parameterIndex
,
Types
.
OTHER
);
return
;
}
if
(
x
instanceof
String
)
setString
(
parameterIndex
,
(
String
)
x
);
else
if
(
x
instanceof
BigDecimal
)
setBigDecimal
(
parameterIndex
,
(
BigDecimal
)
x
);
else
if
(
x
instanceof
Short
)
setShort
(
parameterIndex
,
((
Short
)
x
).
shortValue
());
else
if
(
x
instanceof
Integer
)
setInt
(
parameterIndex
,
((
Integer
)
x
).
intValue
());
else
if
(
x
instanceof
Long
)
setLong
(
parameterIndex
,
((
Long
)
x
).
longValue
());
else
if
(
x
instanceof
Float
)
setFloat
(
parameterIndex
,
((
Float
)
x
).
floatValue
());
else
if
(
x
instanceof
Double
)
setDouble
(
parameterIndex
,
((
Double
)
x
).
doubleValue
());
else
if
(
x
instanceof
byte
[])
setBytes
(
parameterIndex
,
(
byte
[])
x
);
else
if
(
x
instanceof
java
.
sql
.
Date
)
setDate
(
parameterIndex
,
(
java
.
sql
.
Date
)
x
);
else
if
(
x
instanceof
Time
)
setTime
(
parameterIndex
,
(
Time
)
x
);
else
if
(
x
instanceof
Timestamp
)
setTimestamp
(
parameterIndex
,
(
Timestamp
)
x
);
else
if
(
x
instanceof
Boolean
)
setBoolean
(
parameterIndex
,
((
Boolean
)
x
).
booleanValue
());
else
if
(
x
instanceof
PGobject
)
setString
(
parameterIndex
,
((
PGobject
)
x
).
getValue
());
else
// Try to store java object in database
setSerialize
(
parameterIndex
,
connection
.
storeObject
(
x
),
x
.
getClass
().
getName
()
);
}
/*
* Some prepared statements return multiple results; the execute method
* handles these complex statements as well as the simpler form of
* statements handled by executeQuery and executeUpdate
*
* @return true if the next result is a ResultSet; false if it is an
* update count or there are no more results
* @exception SQLException if a database access error occurs
*/
public
boolean
execute
()
throws
SQLException
{
return
super
.
execute
(
compileQuery
());
// in Statement class
}
/*
* Returns the SQL statement with the current template values
* substituted.
* NB: This is identical to compileQuery() except instead of throwing
* SQLException if a parameter is null, it places ? instead.
*/
public
String
toString
()
{
synchronized
(
sbuf
)
{
sbuf
.
setLength
(
0
);
int
i
;
for
(
i
=
0
;
i
<
inStrings
.
length
;
++
i
)
{
if
(
inStrings
[
i
]
==
null
)
sbuf
.
append
(
'?'
);
else
sbuf
.
append
(
templateStrings
[
i
]);
sbuf
.
append
(
inStrings
[
i
]);
}
sbuf
.
append
(
templateStrings
[
inStrings
.
length
]);
return
sbuf
.
toString
();
}
}
// **************************************************************
// END OF PUBLIC INTERFACE
// **************************************************************
/*
* There are a lot of setXXX classes which all basically do
* the same thing. We need a method which actually does the
* set for us.
*
* @param paramIndex the index into the inString
* @param s a string to be stored
* @exception SQLException if something goes wrong
*/
protected
void
set
(
int
paramIndex
,
String
s
)
throws
SQLException
{
if
(
paramIndex
<
1
||
paramIndex
>
inStrings
.
length
)
throw
new
PSQLException
(
"postgresql.prep.range"
);
inStrings
[
paramIndex
-
1
]
=
s
;
}
/*
* Set a parameter to a tablerow-type oid reference.
*
* @param parameterIndex the first parameter is 1...
* @param x the oid of the object from org.postgresql.util.Serialize.store
* @param classname the classname of the java object x
* @exception SQLException if a database access error occurs
*/
private
void
setSerialize
(
int
parameterIndex
,
long
x
,
String
classname
)
throws
SQLException
{
// converts . to _, toLowerCase, and ensures length<32
String
tablename
=
Serialize
.
toPostgreSQL
(
classname
);
DriverManager
.
println
(
"setSerialize: setting "
+
x
+
"::"
+
tablename
);
// OID reference to tablerow-type must be cast like: <oid>::<tablename>
// Note that postgres support for tablerow data types is incomplete/broken.
// This cannot be just a plain OID because then there would be ambiguity
// between when you want the oid itself and when you want the object
// an oid references.
set
(
parameterIndex
,
Long
.
toString
(
x
)
+
"::"
+
tablename
);
}
// ** JDBC 2 Extensions **
/*
* This parses the query and adds it to the current batch
*/
public
void
addBatch
()
throws
SQLException
{
super
.
addBatch
(
compileQuery
());
}
/*
* Not sure what this one does, so I'm saying this returns the MetaData for
* the last ResultSet returned!
*/
public
java
.
sql
.
ResultSetMetaData
getMetaData
()
throws
SQLException
{
java
.
sql
.
ResultSet
rs
=
getResultSet
();
if
(
rs
!=
null
)
return
rs
.
getMetaData
();
// Does anyone really know what this method does?
return
null
;
}
public
void
setArray
(
int
i
,
java
.
sql
.
Array
x
)
throws
SQLException
{
setString
(
i
,
x
.
toString
());
}
/*
* Sets a Blob
*/
public
void
setBlob
(
int
i
,
Blob
x
)
throws
SQLException
{
InputStream
l_inStream
=
x
.
getBinaryStream
();
int
l_length
=
(
int
)
x
.
length
();
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
l_inStream
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
l_length
)
{
los
.
write
(
c
);
c
=
l_inStream
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
i
,
oid
);
}
/*
* This is similar to setBinaryStream except it uses a Reader instead of
* InputStream.
*/
public
void
setCharacterStream
(
int
i
,
java
.
io
.
Reader
x
,
int
length
)
throws
SQLException
{
if
(
connection
.
haveMinimumCompatibleVersion
(
"7.2"
))
{
//Version 7.2 supports CharacterStream for for the PG text types
//As the spec/javadoc for this method indicate this is to be used for
//large text values (i.e. LONGVARCHAR) PG doesn't have a separate
//long varchar datatype, but with toast all the text datatypes are capable of
//handling very large values. Thus the implementation ends up calling
//setString() since there is no current way to stream the value to the server
char
[]
l_chars
=
new
char
[
length
];
int
l_charsRead
;
try
{
l_charsRead
=
x
.
read
(
l_chars
,
0
,
length
);
}
catch
(
IOException
l_ioe
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
l_ioe
);
}
setString
(
i
,
new
String
(
l_chars
,
0
,
l_charsRead
));
}
else
{
//Version 7.1 only supported streams for LargeObjects
//but the jdbc spec indicates that streams should be
//available for LONGVARCHAR instead
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
x
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
length
)
{
los
.
write
(
c
);
c
=
x
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
i
,
oid
);
}
}
/*
* New in 7.1
*/
public
void
setClob
(
int
i
,
Clob
x
)
throws
SQLException
{
InputStream
l_inStream
=
x
.
getAsciiStream
();
int
l_length
=
(
int
)
x
.
length
();
LargeObjectManager
lom
=
connection
.
getLargeObjectAPI
();
int
oid
=
lom
.
create
();
LargeObject
lob
=
lom
.
open
(
oid
);
OutputStream
los
=
lob
.
getOutputStream
();
try
{
// could be buffered, but then the OutputStream returned by LargeObject
// is buffered internally anyhow, so there would be no performance
// boost gained, if anything it would be worse!
int
c
=
l_inStream
.
read
();
int
p
=
0
;
while
(
c
>
-
1
&&
p
<
l_length
)
{
los
.
write
(
c
);
c
=
l_inStream
.
read
();
p
++;
}
los
.
close
();
}
catch
(
IOException
se
)
{
throw
new
PSQLException
(
"postgresql.unusual"
,
se
);
}
// lob is closed by the stream so don't call lob.close()
setInt
(
i
,
oid
);
}
/*
* At least this works as in PostgreSQL null represents anything null ;-)
*
* New in 7,1
*/
public
void
setNull
(
int
i
,
int
t
,
String
s
)
throws
SQLException
{
setNull
(
i
,
t
);
}
public
void
setRef
(
int
i
,
Ref
x
)
throws
SQLException
{
throw
org
.
postgresql
.
Driver
.
notImplemented
();
}
/*
* New in 7,1
*/
public
void
setDate
(
int
i
,
java
.
sql
.
Date
d
,
java
.
util
.
Calendar
cal
)
throws
SQLException
{
if
(
cal
==
null
)
setDate
(
i
,
d
);
else
{
cal
.
setTime
(
d
);
setDate
(
i
,
new
java
.
sql
.
Date
(
cal
.
getTime
().
getTime
()));
}
}
/*
* New in 7,1
*/
public
void
setTime
(
int
i
,
Time
t
,
java
.
util
.
Calendar
cal
)
throws
SQLException
{
if
(
cal
==
null
)
setTime
(
i
,
t
);
else
{
cal
.
setTime
(
t
);
setTime
(
i
,
new
java
.
sql
.
Time
(
cal
.
getTime
().
getTime
()));
}
}
/*
* New in 7,1
*/
public
void
setTimestamp
(
int
i
,
Timestamp
t
,
java
.
util
.
Calendar
cal
)
throws
SQLException
{
if
(
cal
==
null
)
setTimestamp
(
i
,
t
);
else
{
cal
.
setTime
(
t
);
setTimestamp
(
i
,
new
java
.
sql
.
Timestamp
(
cal
.
getTime
().
getTime
()));
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment