Thread: store in bytea

store in bytea

From
"Ben-Nes Michael"
Date:
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
--------------------------



Re: store in bytea

From
"Joe Conway"
Date:
> 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 );
>

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







Re: store in bytea

From
"Ben-Nes Michael"
Date:
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 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 );
> >
>
> 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
>
>
>
>
>
>
>


Re: store in bytea

From
Tom Lane
Date:
"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

Re: store in bytea

From
"Ben-Nes Michael"
Date:
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
>


Re: store in bytea

From
Alex Pilosov
Date:
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
> >
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
>
>


Re: store in bytea

From
"Joe Conway"
Date:
> 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


Re: store in bytea

From
"Ben-Nes Michael"
Date:
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
--------------------------



Re: store in bytea

From
Lincoln Yeoh
Date:
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.