DatabaseCore : add the function lo_write , lo_replace and lo_read to create large

objects from string
This commit is contained in:
sparkyx 2025-09-08 17:19:09 +02:00
parent 01a968e4fc
commit 40839add43
2 changed files with 164 additions and 2 deletions

View file

@ -759,6 +759,80 @@ class DatabaseCore
}
return false;
}
/**
* @brief large_object writee: create a Large object if oid is not given
* with data content in a binaray
* @param $binary_data (raw data) binary
* @returns $oid of the LO, false if it fails
*/
function lo_write($binary_data)
{
//var $a : 0 where in a transaction, 1 we are not in a transaction
$a=0;
if ( $this->status() !== PGSQL_TRANSACTION_INTRANS ) {
$a=1;
$this->start();
}
$oid= pg_lo_create($this->db);
if ( ($handle=pg_lo_open($this->db,$oid,"w")) == false ) { return false ;}
pg_lo_write($handle, $binary_data);
pg_lo_close($handle);
if ( $a==1) { $this->commit(); }
return $oid;
}
/**
* @brief read a Large object with data content in a binary
* @param $oid (int8) oid of the large object
* @returns $binary_data (raw data) binary
*/
function lo_read($oid)
{
//var $a : 0 where in a transaction, 1 we are not in a transaction
$a=0;
if ( $this->status() !== PGSQL_TRANSACTION_INTRANS ) {
$a=1;
$this->start();
}
$handle=pg_lo_open($this->db,$oid,"r");
if ( $handle == false ) { return false ;}
// set position end of the LO
pg_lo_seek($handle, 0, PGSQL_SEEK_END);
// get the size
$size= pg_lo_tell($handle);
// set position to start
pg_lo_seek($handle, 0, PGSQL_SEEK_SET);
// read the comùplete LOB
$binary_data = pg_lo_read($handle,$size );
pg_lo_close($handle);
if ( $a==1) { $this->commit(); }
return $binary_data;
}
/**
* @brief replace a Large object with data content in a binary
* @param $oid (int8) oid of the large object
* @param $binary_data (raw data) binary
* @returns $oid of the LO, false if it fails
*/
function lo_replace($binary_data, $oid) {
$a = 0;
if ($this->status() !== PGSQL_TRANSACTION_INTRANS) {
$a = 1;
$this->start();
}
$handle = pg_lo_open($this->db, $oid, "w");
if ( $handle == false ) { return false ;}
pg_lo_truncate($handle, 0);
pg_lo_write($handle, $binary_data);
pg_lo_close($handle);
if ($a == 1) {
$this->commit();
}
return $oid;
}
/**
* \brief wrapper for the function pg_num_rows
@ -823,7 +897,7 @@ class DatabaseCore
/**
* \brief wrapper for the function pg_lo_unlink
* \param $p_oid is the of oid
* \return return the result of the operation
* \return return the result of the operation : false == fails
*/
function lo_unlink($p_oid)

View file

@ -123,6 +123,94 @@ class DatabaseCoreTest extends TestCase
$this->assertStringContainsString("Documentation", $p_content,"$filename invalid content");
}
/**
* @brief read / write large object
* @testDox read and write - unlink large object
*
*/
public function testWrite_Read_large_object()
{
$md5="965765540c1531370e5856ff81696107";
$file=__DIR__."/file/developpement-widget.pdf";
// step 1 : we create the large object
$binary_data= file_get_contents($file);
$this->assertEquals($md5,md5($binary_data)," error when reading $file ");
$oid = $this->object->lo_write($binary_data);
$this->assertTrue ($oid != false , "writing in DB fails");
// step 2 = read object
$retrieve = $this->object->lo_read($oid);
$this->assertEquals($md5,md5($retrieve)," error when retrieving file from db");
$target=$file."retrieve.pdf";
if ( file_exists($target) ) { unlink($target);}
file_put_contents($target, $retrieve);
$this->assertTrue(file_exists($target));
if ( file_exists($target) ) { unlink($target);}
$this->assertTrue( $this->object->lo_unlink($oid)," cannot unlink it");
}
/**
* @brief import export large objects
* @testDox import and export large object
*
*/
public function testImport_export_large_object()
{
$md5="965765540c1531370e5856ff81696107";
$file=__DIR__."/file/developpement-widget.pdf";
$this->object->start();
$oid = $this->object->lo_import($file);
$this->object->commit();
$this->assertTrue( $oid != false , "import of the file fails");
$target=$file."-tmp";
if ( file_exists($target) ) { unlink($target);}
$this->object->start();
$this->object->lo_export($oid , $file."-tmp");
$this->object->commit();
$this->assertTrue(file_exists($file."-tmp")," file not exported");
if ( file_exists($target) ) { unlink($target);}
$this->assertTrue( $this->object->lo_unlink($oid)," cannot unlink it");
}
public function testReplace() {
$string=<<<EOF
Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
EOF;
$md5=md5($string);
$this->object->start();
$oid=$this->object->lo_write($string);
$this->object->commit();
$this->object->start();
$stringDB = $this->object->lo_read($oid);
$this->object->commit();
$this->assertEquals(md5($string),md5($stringDB)," error string from DB corrupted");
$string = "second";
$this->object->start();
$this->object->lo_replace($string,$oid);
$this->object->commit();
$this->object->start();
$stringDB = $this->object->lo_read($oid);
var_dump($stringDB);
$this->object->commit();
$this->assertEquals(md5($string),md5($stringDB)," after lo_replace(), string from DB corrupted");
}
}