Preparing MVP2

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.

  • delete(): logical deletion of a record.
  • deleted(): determines whether the record is logically deleted.
  • recall(): recalls the record (the inverse operation of delete()).

These three methods are implemented. So, let’s move on!!!

  • record(): returns an entire record in a single operation.

That’s done too. Allez ... hue!

  • zap(): eliminates all data from a table and its blobs, and invalidates the indexes.
  • __toXML(): saves a table in XML. The structure of the table is saved along with its data. You can import the table into any table via the forthcoming inverse operation: importXML() ... only common fields are imported, and they are imported according to the constraints of the target fields. Note: depending on the size of the table, you could end up with a huge XML file.
  • __toForm(): generates the code for a tentative input form for a record from the table. The generated code serves as a programming aid in that it is understood that the generated code will be modified by a programmer to be integrated into a final program.
  • max(): searches for the maximum value of a field in an entire table. The record pointer (recno) is positioned on the last record found.
  • min(): searches for the minimum value of a field in an entire table. The record pointer (recno) is positioned on the last record found.
  • index() and search() on integers, floats, datetimes, dates, times
  • document(): returns an HTML documentation of the table, whose XML structure should be enriched with a description tag.
  • email field: during a write operation, it checks that the provided value satisfies filter_var($email, FILTER_VALIDATE_EMAIL) !== false;. If not, an exception is thrown.
  • lupdate: During a write(), append(), or delete(), if the table has an update-type field, it is automatically updated. A sort onlupdate event is generated. lupdate is a read-only field.
  • Check the uniqueness of fields of type "id" and "lupdate" in a table directly in readStructure(). If not unique, thrown exception. These are also read-only fields!
  • addVirtualMethod(): adds a virtual method to an IllicoDB3 table.
  • removeVirtualMethod(): removes a virtual method from an IllicoDB3 table.
  • removeAllVirtualMethods(): removes all virtual methods from an IllicoDB3 table.

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


要查看或添加评论,请登录

Patrick Boens的更多文章

  • Forging a ChatBot in the Digital Wilderness

    Forging a ChatBot in the Digital Wilderness

    In the relentless landscape of technological evolution, silence is not the absence of action—it is the crucible of…

  • AI Scanning an Invoice

    AI Scanning an Invoice

    This new issue, dedicated to ChatGPT and Sermo (my programming gateway to ChatGPT, Perplexity, and Claude 3.5 Sonnet)…

  • Software Engineers and AI

    Software Engineers and AI

    Through numerous articles written on the subject of artificial intelligence in the context of digital transformations…

  • Using templates to mimic sophisticated object

    Using templates to mimic sophisticated object

    The Power of Templates in IllicoDB3: Revolutionizing Database Structure In the realm of traditional databases, the…

  • More, Faster, Easier...

    More, Faster, Easier...

    In my previous article, I showed you how to create a small todo management app in record time. Now, based on this first…

  • AI at the Developers' Bedside

    AI at the Developers' Bedside

    Let's dive into the world of AI-powered app creation, showcasing just how effortless it can be to bring your ideas to…

    1 条评论
  • AI and IT

    AI and IT

    Here's the question I asked to "Sonar Huge", the AI model of Perplexity.ai: With the advent of AI taking by storm the…

  • The Imperative of AI in Digital Transformation Projects: A Wake-Up Call for Businesses

    The Imperative of AI in Digital Transformation Projects: A Wake-Up Call for Businesses

    In today's rapidly evolving digital landscape, companies that continue to approach their digital transformation and…

  • Data Migration Projects

    Data Migration Projects

    "Mise en bouche" My first interesting encounter with a data migration project dates back to 1999. The tech world was…

  • IllicoDB3 and AI

    IllicoDB3 and AI

    I have mentioned in the past that IllicoDB3 allows the use of artificial intelligence to generate code related to…

社区洞察

其他会员也浏览了