|
|
sybperl-l Archive
Up Prev Next
From: jmcallister at dtint dot com
Subject: help with ct_send_data and image data
Date: Aug 16 2001 6:21PM
I'm getting the following OpenClient errors with Sybperl 2.13, Solaris 8
and ASE 12.0.0.3 that I haven't seen before.
OPEN CLIENT MESSAGE: "ct_send_data(): user api layer: external error:
1481944 bytes exceeds the amount of bytes specified for this send data
operation. Only 0 more bytes can be sent."
OPEN CLIENT MESSAGE: "ct_send(): protocol specific layer: internal Client
Library error: There is a tds state machine error. An illegal tds token
sequence was received."
OPEN CLIENT MESSAGE: "ct_results(): user api layer: external error: The
connection has been marked dead."
WARNING: Detected a size mismatch while writing text/image data read from
/james/jpegs/foo.jpg. <-- These errors come from my code.
WARNING: The file size is 1481944 bytes, but 0 bytes were written to the
database.
Here's the relevant code:
sub file2db {
my($dbh, $table, $id_col, $id, $image_col, $path) = @_;
my($size, $bytes_read, $total_read, $buffer) = (0, 0, 0, '');
my($ret, $query, $restype, @row);
# Open the file that holds the image data.
#
if (! open(IMAGE, $path)) {
complain("Unable to open file $path from which to read text/image
data ($!).");
return 0;
}
# Find out how big (in bytes) the file is.
#
$size = -s IMAGE;
if ($size <= 0) {
complain(
"Cannot read text/image data from $path.",
"The file is empty."
);
close(IMAGE);
return 0;
}
# In preparation for saving the image data, set the image column to
NULL.
#
$query = qq(
update $table
set $image_col = NULL
where $id_col = $id
);
$dbh->ct_sql($query);
# Make sure a row exists to take the blob.
#
if ($dbh->{ROW_COUNT} < 1) {
complain(
"Cannot write text/image data read from $path.",
"Apparently no row exists in table $table where $id_col = $id."
);
close(IMAGE);
return 0;
}
# Select the image column for the new row. This primes the pump
# for successive WRITETEXT calls.
#
$query = "select $image_col from $table where $id_col = $id";
$dbh->ct_execute($query);
while ($dbh->ct_results($restype) == CS_SUCCEED) {
next unless $dbh->ct_fetchable($restype);
while (@row = $dbh->ct_fetch) {
$dbh->ct_data_info(CS_GET, 1);
}
}
$dbh->ct_command(CS_SEND_DATA_CMD, '', CS_UNUSED, CS_COLUMN_DATA);
$dbh->ct_data_info(CS_SET, 1, {total_txtlen => $size});
# Read chunks of data from disk and send them to the SQL server.
# Keep track of the total number of bytes read.
#
while (($bytes_read = sysread(IMAGE, $buffer, $::gParams{in_buf_sz})) >
0) { ### <=== I've tried different values of buffer size including numbers
larger than the file size.
$ret = $dbh->ct_send_data($buffer, $bytes_read);
last if $ret == CS_FAIL;
$total_read += $bytes_read;
}
# Finish the TEXT/IMAGE update.
#
$dbh->ct_send;
while ($dbh->ct_results($restype) == CS_SUCCEED) {
next unless $dbh->ct_fetchable($restype);
while (@row = $dbh->ct_fetch) { ; }
}
# Make sure the total bytes read and sent matches the total file size.
#
complain(
"Detected a size mismatch while writing text/image data read from
$path.",
"The file size is $size bytes, but $total_read bytes were written
to the database."
) if $total_read != $size;
close(IMAGE);
$total_read;
}
file2db($dbh, 'mytable', 'name', '"foo"', 'filedata',
"/james/jpegs/foo.jpg");
This code worked well on earlier versions of perl, Sybperl, Solaris and
Sybase. Any clues, suggestions, etc. would be greatly appreciated.
Thanks in advance,
James McAllister
|