store in bytea
Hi
Im using php to upload Binary data into bytea field.
The problem is that when I query what I uploaded I discover that it hold
only 13 characters and not the whole binary file
I tried manual insert more the 13 characters successfully.
I tried to do addslashes($data);
but still :(
$slashed_data = addslashes($data);
$sql = "insert into files (image_id, bin_data, filename, filesize, filetype)
values ('$image_id', '$slashed_data', '$new_name', '$filesize',
'$filetype');";
I tried strlen($slashed_data); before the insert to be sure that that the
binary is bigger then 13 characters and yes, its 4KB ( the tested file );
Any ideas ?
--------------------------
Canaan Surfing Ltd.
Internet Service Providers
Ben-Nes Michael - Manager
Tel: 972-4-6991122
http://sites.canaan.co.il
--------------------------
Hi
Im using php to upload Binary data into bytea field.
The problem is that when I query what I uploaded I discover that it hold
only 13 characters and not the whole binary fileI tried manual insert more the 13 characters successfully.
I tried to do addslashes($data);but still :(
$slashed_data = addslashes($data);
$sql = "insert into files (image_id, bin_data, filename, filesize,
filetype)
values ('$image_id', '$slashed_data', '$new_name', '$filesize',
'$filetype');";I tried strlen($slashed_data); before the insert to be sure that that the
binary is bigger then 13 characters and yes, its 4KB ( the tested file );
I recently posted a PHP function which escapes data for insertion
into a bytea column (for anyone who followed this from the last post,
I found that I needed to add one more escaped character):
function sqlesc($ct)
{
$buf = "";
for ($i = 0; $i < strlen($ct); $i++)
{
if (ord($ct[$i]) == 0)
$buf .= "\\\\000";
else if (ord($ct[$i]) == 10)
$buf .= "\\\\012";
else if (ord($ct[$i]) == 39)
$buf .= "\\\\047";
else if (ord($ct[$i]) == 92)
$buf .= "\\\\134";
else
$buf .= $ct[$i];
}
return $buf;
}
Here's an example of how to use it:
$fp = fopen("/dev/urandom","r");
$iv = fread($fp, 8);
fclose($fp);
$payload = "hello world";
$ct = mcrypt_encrypt (MCRYPT_TRIPLEDES, "mykey", $payload,
MCRYPT_MODE_CBC, $iv);
$esc_ct = sqlesc($ct);
$sql = "insert into foobar(f1,f2) values('$esc_ct',1)";
$rs = pg_exec($conn, $sql);
As far as storage is concerned, all escaped characters get converted back
into their single byte equivilent for storage, so using bytea is the most
efficient way to store binary in the database.
However on retrieval, PostgreSQL will escape all "nonprintable" characters
(based on the C "isprint()" function), which is quite a few. Your PHP app
will have to unescape all of the nonprintable characters. I haven't written
a PHP function for that yet, but it shouldn't be too hard.
I have started hacking the php pgsql extension to add pg_bytea_encode
and pg_bytea_decode functions (so far the pg_bytea_encode is working).
When I'm done I'll submit a patch to the PHP folks, and hopefully they will
accept it.
Hope this helps,
-- Joe
It sure is :)
On the theoretical issue, can I use TEXT field to store binary ?
If so, what will be the case with addslashes ? will it work ?
----- Original Message -----
From: "Joe Conway" <joseph.conway@home.com>
To: "Ben-Nes Michael" <miki@canaan.co.il>; <pgsql-general@postgresql.org>
Sent: Thursday, August 23, 2001 10:18 PM
Subject: Re: [GENERAL] store in bytea
Hi
Im using php to upload Binary data into bytea field.
The problem is that when I query what I uploaded I discover that it hold
only 13 characters and not the whole binary fileI tried manual insert more the 13 characters successfully.
I tried to do addslashes($data);but still :(
$slashed_data = addslashes($data);
$sql = "insert into files (image_id, bin_data, filename, filesize,filetype)
values ('$image_id', '$slashed_data', '$new_name', '$filesize',
'$filetype');";I tried strlen($slashed_data); before the insert to be sure that that
the
binary is bigger then 13 characters and yes, its 4KB ( the tested
file );
I recently posted a PHP function which escapes data for insertion
into a bytea column (for anyone who followed this from the last post,
I found that I needed to add one more escaped character):function sqlesc($ct)
{
$buf = "";
for ($i = 0; $i < strlen($ct); $i++)
{
if (ord($ct[$i]) == 0)
$buf .= "\\\\000";
else if (ord($ct[$i]) == 10)
$buf .= "\\\\012";
else if (ord($ct[$i]) == 39)
$buf .= "\\\\047";
else if (ord($ct[$i]) == 92)
$buf .= "\\\\134";
else
$buf .= $ct[$i];
}
return $buf;
}Here's an example of how to use it:
$fp = fopen("/dev/urandom","r");
$iv = fread($fp, 8);
fclose($fp);$payload = "hello world";
$ct = mcrypt_encrypt (MCRYPT_TRIPLEDES, "mykey", $payload,
MCRYPT_MODE_CBC, $iv);
$esc_ct = sqlesc($ct);$sql = "insert into foobar(f1,f2) values('$esc_ct',1)";
$rs = pg_exec($conn, $sql);
As far as storage is concerned, all escaped characters get converted back
into their single byte equivilent for storage, so using bytea is the most
efficient way to store binary in the database.However on retrieval, PostgreSQL will escape all "nonprintable" characters
(based on the C "isprint()" function), which is quite a few. Your PHP app
will have to unescape all of the nonprintable characters. I haven't
written
a PHP function for that yet, but it shouldn't be too hard.
I have started hacking the php pgsql extension to add pg_bytea_encode
and pg_bytea_decode functions (so far the pg_bytea_encode is working).
When I'm done I'll submit a patch to the PHP folks, and hopefully they
will
Show quoted text
accept it.
Hope this helps,
-- Joe
"Ben-Nes Michael" <miki@canaan.co.il> writes:
On the theoretical issue, can I use TEXT field to store binary ?
TEXT will not handle null (zero) bytes. If you are using a multibyte
character set, it will likely also do the wrong thing with byte
sequences that are illegal or incomplete multibyte characters.
Use BYTEA if you want to store arbitrary byte sequences --- that's what
it's for.
regards, tom lane
But Ill have to add double slashes and even more importent I will have to
unescape every binary data going out of the server, which mean in one of my
aplication all the Images.
Wont this action be much more heavey then the way I used untill now with
MySQL (blob) ?
addslash on insert and ordinary select for output.
Does any one here save his website images on DB and retrive them out on his
web page ?
Show quoted text
"Ben-Nes Michael" <miki@canaan.co.il> writes:
On the theoretical issue, can I use TEXT field to store binary ?
TEXT will not handle null (zero) bytes. If you are using a multibyte
character set, it will likely also do the wrong thing with byte
sequences that are illegal or incomplete multibyte characters.Use BYTEA if you want to store arbitrary byte sequences --- that's what
it's for.regards, tom lane
What are you using to develop? If perl, DBD::Pg will escape/unescape bytea
data after 0.98 version. (Unescaping is automatic, to escape, you need to
do bind(.., SQL_BINARY)).
-alex
On Fri, 24 Aug 2001, Ben-Nes Michael wrote:
Show quoted text
But Ill have to add double slashes and even more importent I will have to
unescape every binary data going out of the server, which mean in one of my
aplication all the Images.Wont this action be much more heavey then the way I used untill now with
MySQL (blob) ?
addslash on insert and ordinary select for output.Does any one here save his website images on DB and retrive them out on his
web page ?"Ben-Nes Michael" <miki@canaan.co.il> writes:
On the theoretical issue, can I use TEXT field to store binary ?
TEXT will not handle null (zero) bytes. If you are using a multibyte
character set, it will likely also do the wrong thing with byte
sequences that are illegal or incomplete multibyte characters.Use BYTEA if you want to store arbitrary byte sequences --- that's what
it's for.regards, tom lane
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
But Ill have to add double slashes and even more importent I will have to
unescape every binary data going out of the server, which mean in one of
my
aplication all the Images.
Wont this action be much more heavey then the way I used untill now with
MySQL (blob) ?
addslash on insert and ordinary select for output.
Not sure about performance (would be nice if you tried this and reported
back results of MySQL vs PostgreSQL), but last night I found a built-in PHP
function that looks like it would work to convert the escaped binary back to
binary -- see http://www.php.net/manual/en/function.stripcslashes.php
-- Joe
Im using PHP4.6
What are you using to develop? If perl, DBD::Pg will escape/unescape bytea
data after 0.98 version. (Unescaping is automatic, to escape, you need to
do bind(.., SQL_BINARY)).-alex
On Fri, 24 Aug 2001, Ben-Nes Michael wrote:
But Ill have to add double slashes and even more importent I will have
to
unescape every binary data going out of the server, which mean in one of
my
aplication all the Images.
Wont this action be much more heavey then the way I used untill now with
MySQL (blob) ?
addslash on insert and ordinary select for output.Does any one here save his website images on DB and retrive them out on
his
web page ?
"Ben-Nes Michael" <miki@canaan.co.il> writes:
On the theoretical issue, can I use TEXT field to store binary ?
TEXT will not handle null (zero) bytes. If you are using a multibyte
character set, it will likely also do the wrong thing with byte
sequences that are illegal or incomplete multibyte characters.Use BYTEA if you want to store arbitrary byte sequences --- that's
what
it's for.
regards, tom lane
--------------------------
Canaan Surfing Ltd.
Internet Service Providers
Ben-Nes Michael - Manager
Tel: 972-4-6991122
http://sites.canaan.co.il
--------------------------
At 09:28 AM 8/24/01 -0400, Tom Lane wrote:
"Ben-Nes Michael" <miki@canaan.co.il> writes:
On the theoretical issue, can I use TEXT field to store binary ?
TEXT will not handle null (zero) bytes. If you are using a multibyte
character set, it will likely also do the wrong thing with byte
sequences that are illegal or incomplete multibyte characters.Use BYTEA if you want to store arbitrary byte sequences --- that's what
it's for.
I wanted to use bytea wasn't sure how though. So I used base64 and text.
Yeah that is ugly but it works.
With bytea I didn't understand how to quote and unquote stuff. And how
stuff is stored. At that time the docs were sparse on it. I didn't know
what characters I'd need to unquote and quote and how, yeah null was one
but the others?
Sure people can use the source to figure out how to use bytea. But what if
the source is different from the intended behaviour and the source is fixed
later.
Don't want to be hit by a gotcha after writing lots of code y'know.
So base64 and text it was. It was either that or store in the filesystem
(that's what I did with 6.5 - sorry but I have no confidence in postgresql
BLOBs).
Cheerio,
Link.