Preparing MVP2
The first thing we're going to do in this article 10 is to deal with the delete(), recall() and deleted() methods. These are operations that allow you to delete a record logically, recall it (recall()) and test whether it has been deleted logically or not (deleted()).
These operations involve the header of each record, the 4-byte structure that precedes each record: bit #0 (the rightmost bit) of byte#3 (the last byte of the header). As these are bitwise operations, we'll need to use the operators provided by PHP.
delete(), recall() deleted()
These 3 methods were not empty in our test code. So if I run a test code, we won't have any heart-breaking complaint from PHP. However, the methods won't do exactly what's expected of them or how I'd like them to: we won't learn anything from them for now. On the other hand, as the test code has not yet been created, it would be desirable to do so:
$DBName = 'quitus';
$folder = '/home/vaesoli/central-catalog';
echo "<h2>Testing delete(), recall(), deleted()</h2>";
$oDB = new IllicoDB3();
$t1 = microtime( true ); /* Start measuring perf. */
if ( $success = $oDB->open( $DBName,$folder ) )
{
if ( $users = $oDB->users ?? null )
{
$users->recno = 20;
$users->delete();
echo "<p>LINE: <b>" . __LINE__ . "</b> recno {$users->recno} is " . ( $users->deleted() ? 'deleted' : 'NOT deleted' ) . "</p>\n";
$users->delete();
echo "<p>LINE: <b>" . __LINE__ . "</b> recno {$users->recno} is " . ( $users->deleted() ? 'deleted' : 'NOT deleted' ) . "</p>\n";
$users->recall();
echo "<p>LINE: <b>" . __LINE__ . "</b> recno {$users->recno} is " . ( $users->deleted() ? 'deleted' : 'NOT deleted' ) . "</p>\n";
$users->delete();
echo "<p>LINE: <b>" . __LINE__ . "</b> recno {$users->recno} is " . ( $users->deleted() ? 'deleted' : 'NOT deleted' ) . "</p>\n";
$users->recall();
echo "<p>LINE: <b>" . __LINE__ . "</b> recno {$users->recno} is " . ( $users->deleted() ? 'deleted' : 'NOT deleted' ) . "</p>\n";
} /* if ( $users = $oDB->users ?? null ) */
} /* if ( $success = $oDB->open( $DBName,$folder ) ) */
Initially, record no. 20 was not deleted; we're going to delete it and see immediately whether it is or not. We carry out these operations several times, deleting it, resurrecting it, etc., and find that the test results are in line with our expectations.
ests of IllicoDB3
Testing delete(), recall(), deleted()
LINE: 1817 recno 20 is deleted
LINE: 1820 recno 20 is deleted
LINE: 1823 recno 20 is NOT deleted
LINE: 1826 recno 20 is deleted
LINE: 1829 recno 20 is NOT deleted
All OK.
What Else?
The backlog of IllicoDB3 contained a set of small methods here and there that were not fundamental but were nonetheless considered interesting. Among them was the record() method, which can retrieve an entire record. There were also features for logical deletion, the pack() function (which reconstructs a table by excluding records marked for deletion, as well as reconstructing the blobs to avoid wasting space and invalidating indexes). This was considered interesting work.
These three methods are implemented. So, let’s move on!!!
That’s done too. Allez ... hue!
I'm really into virtual methods and the method of exporting a table to an XML file. Let's first the 3 methods for the virtual methods implementation. We will develop this code BUT, as an exception we are not going to make use of them yet in a test code (I have some reasons for that).
addVirtualMethod(), removeVirtualMethod() and removeAllVirtualMethods()
领英推荐
/* ==================================================== */
/** {{*addVirtualMethod( $name,$callback )=
Adds the @var.name virtual method
{*params
$name (string) The name of the virtual method
$callback (function) Anonymous function
*}
{*warning
If the @var.name virtual method exists, it is updated.
*}
{*return
(void) No value returned
*}
*}}
*/
/* ==================================================== */
public function addVirtualMethod( $name,$callback )
{
$this->virtualMethods[ $name ] = $callback;
} /* End of IllicoDB3Table.addVirtualMethod() */
/* ==================================================== */
/* ==================================================== */
/** {{*removeVirtualMethod( $name )=
Deletes the @var.name virtual method
{*params
$name (string) The name of the virtual method
*}
{*return
(void) No value returned
*}
*}}
*/
/* ==================================================== */
public function removeVirtualMethod( $name )
{
if ( isset( $this->virtualMethods[ $name ] ) )
unset( $this->virtualMethods[ $name ] );
} /* End of IllicoDB3Table.removeVirtualMethod() */
/* ==================================================== */
/* ==================================================== */
/** {{*removeAllVirtualMethods()=
Deletes all virtual methods contained in the object
{*params
*}
{*return
(void) No value returned
*}
*}}
*/
/* ==================================================== */
public function removeAllVirtualMethods()
{
$this->virtualMethods = [];
} /* End of IllicoDB3Table.removeAllVirtualMethods() */
/* ==================================================== */
We will use these methods later.
__toXML()
Let's create the test code directly to get back into TDD habits:
$DBName = 'quitus';
$folder = '/home/vaesoli/central-catalog';
echo "<h2>Testing __toXML()</h2>";
$oDB = new IllicoDB3();
$t1 = microtime( true ); /* Start measuring perf. */
if ( $success = $oDB->open( $DBName,$folder ) )
{
if ( $users = $oDB->users ?? null )
{
$t1 = microtime( true ); /* Start measuring perf. */
if ( $users->__toXML() )
echo "<p>LINE: <b>" . __LINE__ . "</b> XML file created</p>\n";
else
echo "<p>LINE: <b>" . __LINE__ . "</b> XML file CANNOT be created</p>\n";
$t2 = microtime( true ); /* Stop measuring perf. */
echo "<p>LINE: <b>" . __LINE__ . "</b> -- Perf: ",number_format( $t2-$t1,6,',', '.' )," sec to export the data to an XML file</p>\n";
} /* if ( $users = $oDB->users ?? null ) */
} /* if ( $success = $oDB->open( $DBName,$folder ) ) */
As anticipated, it crashes:
Tests of IllicoDB3
Testing __toXML()
Fatal error: Uncaught Exception: trql\db\IllicoDB3\IllicoDB3Table::__call() at line 2304: '__toXML()' ... UNKNOWN method (ErrCode: EXCEPTION_UNKNOWN_METHOD = 1001000) in trql.illicodb3.class.php:2304 Stack trace: #0 test.illicodb3.php(1881): trql\db\IllicoDB3\IllicoDB3Table->__call() #1 {main} thrown in trql.illicodb3.class.php on line 2304
Let's then create the __toXML() method:
public function __toXML( $file = null )
{
$retVal = false;
$this->openStorageIfNeeded();
if ( ! $file )
$file = $this->determineDataFilename() . '.xml';
if ( $fp = fopen( $file,'w' ) )
{
fwrite( $fp, '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL);
fwrite( $fp,"<!-- Generated by IllicoDB3 on " . date( 'd-m-Y H:i:s' ) . " -->" . PHP_EOL );
fwrite( $fp,"<table name=\"{$this->name}\">" . PHP_EOL );
$this->recno = 1;
while ( ! $this->eof() )
{
fwrite( $fp,SP_4 . "<record recno=\"{$this->recno}\">" . PHP_EOL );
foreach( $this->fields as $name => $field )
fwrite( $fp,SP_8 . "<{$name} type=\"{$field->type}\" length=\"{$field->length}\"><![CDATA[" . htmlspecialchars( trim( $this->$name ) ) . "]]></{$name}>" . PHP_EOL );
fwrite( $fp,SP_4 . "</record>" . PHP_EOL . PHP_EOL );
$this->recno++;
if ( $this->recno > $this->reccount )
break;
} /* while ( ! $this->eof() ) */
fwrite( $fp,'</table>' . PHP_EOL );
end:
fclose( $fp) ;
$retVal = true;
} /* if ( $fp = fopen( $file,'w' ) ) */
return ( $retVal );
} /* End of IllicoDB3Table.__toXML() */
... which results in...
Tests of IllicoDB3
Testing __toXML()
LINE: 1882 XML file created
LINE: 1887 -- Perf: 0,038725 sec to export the data to an XML file
That's enough for today!
Conclusion
We have added 7 methods to IllicoDB3: delete(), recall(), addVirtualMethod(), removeVirtualMethod(), removeAllVirtualMethods(), and last but not least, toXML(). This is starting to give us a solid arsenal for MVP2, but... I think we still need to come up with a few more methods, including the inverse of toXML(), which we will call importXML(), before considering a production release of MVP2.We have made great progress, and the next article will aim to finalize this MVP2 with all the necessary documentation.
No complication, please ! :-)
Code included in the article (link to https://www.trql.fm/test.illicodb3.code-of-article10.zip) : test.illicodb3.code-of-article10.zip
Previous article - Next article