Postgres BYTEA and RETURNING problem

Just starting out? Need help? Post your questions and find answers here.
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Postgres BYTEA and RETURNING problem

Post by infratec »

Hi,

INSERT a file in a BYTEA field: no problem.
Use an INSERT with RETURNING in DatabaseQuery(): no problem.

If I use an INSERT with a BYTEA field (SetDatabaseBlob() in front) and RETURNING, I get a DatabaseError():
'There is no parameter $1'

Is this a limitation of Postgres or is it a bug in PB handling of DatabaseQuery() :?:

Code: Select all

#WithReturning = #True
#WithBYTEA = #True

EnableExplicit

UsePostgreSQLDatabase()


Procedure StoreDataFromFile(DB.i, Table$, Filename$)
 
  Protected Result.i, File.i, Size.i, *Buffer, SQL$
 
 
  File = ReadFile(#PB_Any, Filename$)
  If File
    Size = Lof(File)
    Debug "FileSize: " + Str(Size)
    *Buffer = AllocateMemory(Size)
    If *Buffer
      If ReadData(File, *Buffer, Size) = Size        
        
        SetDatabaseBlob(DB, 0, *Buffer, Size)
CompilerIf #WithReturning = #False
        SQL$ = "INSERT INTO " + Table$ + " (filename, filesize, filedata) VALUES (E'" + ReplaceString(Filename$, "\", "\\") + "'," + Str(Size) + ", $1)"
        Debug "(Update) " + SQL$
        If DatabaseUpdate(DB, SQL$)
CompilerElse
  CompilerIf #WithBYTEA = #False
        SQL$ = "INSERT INTO " + Table$ + " (filename, filesize) VALUES (E'" + ReplaceString(Filename$, "\", "\\") + "'," + Str(Size) + ") RETURNING id"
  CompilerElse
        SQL$ = "INSERT INTO " + Table$ + " (filename, filesize, filedata) VALUES (E'" + ReplaceString(Filename$, "\", "\\") + "'," + Str(Size) + ", $1) RETURNING id"
  CompilerEndIf
        Debug "(Query) " + SQL$
        If DatabaseQuery(DB, SQL$)
          If NextDatabaseRow(DB)
            Debug "Returnvalue: " + Str(GetDatabaseLong(DB, 0))
          EndIf
          FinishDatabaseQuery(DB)
CompilerEndIf
          Result = #True
        Else
          Debug DatabaseError()
        EndIf
      EndIf
      FreeMemory(*Buffer)
    EndIf
    CloseFile(File)
  EndIf
 
  ProcedureReturn Result
 
EndProcedure




Procedure RestoreDataToFile(DB.i, Table$, Filename$="")
 
  Protected Result.i, File.i, Size.q, *Buffer
 
 
  If DatabaseQuery(DB, "SELECT filename, filesize, filedata FROM " + Table$)
    If NextDatabaseRow(DB)
      If Filename$ = ""
        Filename$ = GetDatabaseString(DB, 0)
      EndIf
     
      Size = GetDatabaseLong(DB, 1) ;/ Get size of the blob
      *Buffer = AllocateMemory(Size)
      If *Buffer
       
        Debug "Columnsize: " + Str(DatabaseColumnSize(DB, 2))
       
        GetDatabaseBlob(DB, 2, *Buffer, Size)
        File = CreateFile(#PB_Any, Filename$)
        If File
          If WriteData(File, *Buffer, Size) = Size
            Result = #True
          EndIf
          CloseFile(File)
        EndIf
        FreeMemory(*Buffer)
      EndIf
    EndIf
    FinishDatabaseQuery(DB)
  EndIf
 
  ProcedureReturn Result
 
EndProcedure



Define DB.i, Table$, Filename$

DB = OpenDatabase(#PB_Any, "host=xxx.xxx.xxx.xxx port=5432", "yyy", "zzz")
If DB
 
  Table$ = "datatest"
 
  If DatabaseUpdate(DB, "CREATE TEMP TABLE " + Table$ + " (id SERIAL, filename TEXT, filesize INTEGER, filedata BYTEA)")
   
    Filename$ = OpenFileRequester("Choose a file", "", "*.*", 0)
    If Filename$
     
      If StoreDataFromFile(DB, Table$, Filename$)
        RestoreDataToFile(DB, Table$, Filename$ + "." + GetExtensionPart(Filename$))
      EndIf
     
    EndIf
   
  EndIf
  CloseDatabase(DB)
Else
  MessageRequester("Error", "Was not able to connect.")
EndIf
You can change the 2 flags at he beginning to see what happens.
Oh, you need top adjust the OpenDatabase() line.

Bernd
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Postgres BYTEA and RETURNING problem

Post by Fred »

What is the version of your Postgresql server ? The PB lib used was old and doesn't support HEX encoding for BYTEA (which is now default on 9.x servers). I have upgraded the client lib for the next version to 9.2.4.
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Postgres BYTEA and RETURNING problem

Post by infratec »

Hi Fred,

we still use a debian 6.0.7 with Postgresql 8.4.17.
So it should not be a problem of the lib.

Bernd
Last edited by infratec on Tue Jun 11, 2013 9:56 am, edited 1 time in total.
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Postgres BYTEA and RETURNING problem

Post by RichAlgeni »

Have you tried doing the same Insert using the PSQL shell? Make sure it works there first. If it does, it is a PureBasic issue.

I always make sure it works correctly in PSQL first, then code it into my program.
infratec
Always Here
Always Here
Posts: 7591
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Postgres BYTEA and RETURNING problem

Post by infratec »

@RichAlgeni
A test with psql is not possible in this case.
All ways (that I found) to insert a binary file in a table field are totally different to that what PB does.

@Fred
I just checked it with Wireshark:
If DatabaseUpdate() is used there is an additional Parameter field in the packet.
If DatabaseQuery() is used this field is missing and also the binary data is not transmitted,
only the plain INSERT command is in the packet.

As workaround I have to use now an additional SELECT to get the id of the last inserted record.

Bernd
sput
New User
New User
Posts: 2
Joined: Fri Jan 14, 2011 3:16 pm

Re: Postgres BYTEA and RETURNING problem

Post by sput »

same problem....

Can anyone give me a working code ? ... to save and load pictures

Postegre 9.3
Jagermeister
Enthusiast
Enthusiast
Posts: 137
Joined: Thu Nov 15, 2012 11:38 pm
Location: Los Angeles

Re: Postgres BYTEA and RETURNING problem

Post by Jagermeister »

Based off these attempts, I had an idea to convert say a JPEG to quads (like bin2data output) and INSERT as text. Being that the characters would be 0-9, A-F, I needn't worry about escape characters. How would I decode that from a query returned as string?

UPDATE: Nevermind. http://www.purebasic.fr/english/viewtop ... ecode+jpeg
Post Reply