-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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.
<?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
<?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
<?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
<?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!'];
}
);
<?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
<?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)
<?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
<?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;
}
}
);
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();