Skip to content

3. Entity Relations Table

Bogdans edited this page May 21, 2018 · 2 revisions

ER Tables implement CRUD operations, Table locking (instead of transactions) and Relationships.

Operating ER Table

To perform CRUD operations on an ER Table a special TableIterator component was implement.

TableIterator allows jumping between records, getting table statistics and performing CRUD operations. Each TableIterator action (CRUD) moves the pointer to the next record or end of file.

Simplified Table interface internally uses TableIterator.

Iterator create operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# reserve the table
$table->reserve(Table::RESERVE_WRITE);
# get iterator
$iterator = $table->newIterator();
# jump to the end of file
$iterator->end();
# create record
$iterator->create(['ID' => 1, 'Profit' => 2.11, 'ProductTypeReference' => 0, 'ProductTitle' => 'My first product, yay!']);
# release the table
$table->release();

Important notes:

  • NULL type is not supported
  • when iterator is not at the end of file, create operation will replace the file
  • without the reserving the table operation will not be possible

Table create operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# create
$table->create([
    'ID' => 1, 
    'Profit' => 2.11, 
    'ProductTypeReference' => 0, 
    'ProductTitle' => 'My first product, yay!'
]);

Important notes:

  • lock are automatically acquired
  • it is possible to lock the table before running create manually, but then you need to manually release it as well

Iterator update operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# reserve the table
$table->reserve(Table::RESERVE_WRITE);
# get iterator
$iterator = $table->newIterator();
# jump to the record index
$iterator->jump(5); 
# update record
$iterator->update(['ProductTitle' => 'My first product update!']);
# release the table
$table->release();

Important notes:

  • if the record is deleted but not removed completely, it will still be updated
  • jump method allows jumping to any record in the table

Table update operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# find and update the table
$table->update(
    # search the record
    function(array $record) {
        if ($record['ID'] === 5) {
            return Table::OPERATION_UPDATE_INCLUDE_AND_STOP;
        }
    },
    # update each record that's included
    function(array $record) {
        return ['ProductTitle' => 'My first product update!'];
    }
);

Iterator read operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# reserve the table
$table->reserve(Table::RESERVE_READ);
# get iterator
$iterator = $table->newIterator();
# jump to the record index
$iterator->jump(5); 
# read record
$record = $iterator->read();
# read all the records in the table
$result = [];
# reset pointer
$iterator->jump(0);
# loop over table
while ($iterator->endOfTable() === false) {
    # read the record
    $record = $iterator->read();
    # check if it's not deleted
    if ($record === null) {
        continue;
    }
    # add to result
    $result[] = $record;
}
# release the table
$table->release();

Important notes:

  • read operation (as any) moves the pointer to the next record
  • if the record was deleted, then NULL is returned from "TableIterator::read" method

Table read operation

<?php
use DataManagement\Model\EntityRelationship\Table;
use DataManagement\Model\EntityRelationship\TableIterator;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# read all the table
$result = $table->read(function(){
    return Table::OPERATION_READ_INCLUDE;
});
# read the record with specific ID
$result = $table->read(function(array $record){
    if ($record['ID'] === 5) {
        return Table::OPERATION_READ_INCLUDE_AND_STOP;
    }
});
# read only first two record
$result = [];
$table->iterate(function(array $record) use (&$result) {
    $result[] = $record;
    if (count($result) === 2) {
        return Table::OPERATION_READ_STOP;
    }
});
# read id and pointer of all the records
$result = [];
$table->iterate(function(array $record, TableIterator $iterator) use (&$result) {
    $result[] = ['id' => $record['ID'], 'pointer' => $iterator->position()];
});

Important notes:

  • first parameter to the table callback is record
  • second parameter is TableIterator (this provides more control over iteraton)

Iterator delete operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# reserve the table
$table->reserve(Table::RESERVE_WRITE);
# get iterator
$iterator = $table->newIterator();
# jump to the record index
$iterator->jump(5); 
# update record
$iterator->delete();
# release the table
$table->release();

Important notes:

  • Record is marked as deleted, but do not disappear from the file (deleting does not change table file size)
  • To physically delete records from the file run bin/dmc dmc:er:table-optimize <table-instruction-file> command

Table delete operation

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# find and update the table
$table->delete(
    # search the record
    function(array $record) {
        if ($record['ID'] === 5) {
            return Table::OPERATION_DELETE_INCLUDE_AND_STOP;
        }
    }
);

Iterator operation combinations

TableIterator provides more sophisticated ways of working with the Table.

Example of search and update operations

<?php
use DataManagement\Model\EntityRelationship\Table;

$instructionFile = '/project-root/my-table-instruction.php';
$table = Table::newFromInstructionsFile($instructionFile);
# reserve the table
$table->reserve(Table::RESERVE_READ_AND_WRITE);
# get iterator
$iterator = $table->newIterator();
# reset pointer
$iterator->jump(0);
# loop over table
while ($iterator->endOfTable() === false) {
    # read the record
    $record = $iterator->read();
    # check if it's not deleted
    if ($record === null) {
        continue;
    }
    # check if record found
    if ($record['ID'] === 5) {
        # rewind pointer to the record location
        $iterator->rewind(1);
        # update
        $iterator->update(['ProductTitle' => 'Updating in the iterator']);
        # exit the loop
        break;
    }
}
# release the table
$table->release();