From ec2721dc7727ebcd43b780892f3df6831dfff06b Mon Sep 17 00:00:00 2001 From: mirzaev Date: Fri, 8 Aug 2025 21:27:29 +0700 Subject: [PATCH] useless update --- mirzaev/baza/system/column.php | 55 ++- mirzaev/baza/system/database.php | 102 +++-- .../baza/system/enumerations/architecture.php | 97 +++++ mirzaev/baza/system/enumerations/type.php | 2 +- mirzaev/baza/tests/record.php | 371 ++++++++++++------ 5 files changed, 457 insertions(+), 170 deletions(-) create mode 100644 mirzaev/baza/system/enumerations/architecture.php diff --git a/mirzaev/baza/system/column.php b/mirzaev/baza/system/column.php index 96cfa49..69f69e8 100755 --- a/mirzaev/baza/system/column.php +++ b/mirzaev/baza/system/column.php @@ -51,38 +51,35 @@ class column * * Length of every binary value that will be written to the database file * - * @throws exception_logic if the length property is already initialized + * @throws exception_logic if the `length` property is already initialized * @throws exception_logic if the type is not initialized - * @throws exception_domain if the type can not has length + * @throws exception_domain if the type has fixed length * - * @var int $length Length of every binary values + * @var int $length Binary length of the column */ public protected(set) int $length { // Write - set (int $value) { + set(int $value) { if (isset($this->length)) { // Already been initialized // Exit (fail) - throw new exception_logic('The length property is already initialized'); + throw new exception_logic('The `length` property is already initialized'); } else if (!isset($this->type)) { // The type is not initialized // Exit (fail) throw new exception_logic('The type of the column values is not initialized'); - } else if (match ($this->type) { - type::string => true, - default => false - }) { - // The type has length + } else if ($this->type === type::string) { + // String // Writing into the property $this->length = $value; } else { - // The type has no length + // Other type // Exit (fail) - throw new exception_domain('The "' . $this->type->name . '" type can not has length'); + throw new exception_domain('The "' . $this->type->name . '" type has fixed ' . $this->type->size() . ' bit length'); } } } @@ -92,7 +89,7 @@ class column * * @param string $name Name of the column * @param type $type Type of the column values - * @param array $parameters Parameters of the column + * @param array $parameters Parameters of the column (length, segments) * * @return void */ @@ -120,4 +117,36 @@ class column } } } + + /** + * Pack + * + * @param string|int|float $value Data to packing + * + * @return string|false Packed binary value + */ + public function pack(string|int|float $value): string|false + { + // Exit (success) + return match ($this->type) { + type::string => pack($this->type->value . $this->length, $value), + default => pack($this->type->value, $value) + }; + } + + /** + * Unpack + * + * @param string $binary Packed binary data + * + * @return string|false Unpacked value + */ + public function unpack(string $binary): string|int|float|false + { + // Exit (success) + return match ($this->type) { + type::string => unpack($this->type->value . $this->length, $binary ?? str_repeat("\0", $this->length))[1], + default => unpack($this->type->value, $binary ?? "\0")[1] + } ?? false; + } } diff --git a/mirzaev/baza/system/database.php b/mirzaev/baza/system/database.php index 27c202f..1f016f5 100755 --- a/mirzaev/baza/system/database.php +++ b/mirzaev/baza/system/database.php @@ -5,13 +5,15 @@ declare(strict_types=1); namespace mirzaev\baza; // Files of the project -use mirzaev\baza\enumerations\encoding, +use mirzaev\baza\enumerations\architecture, + mirzaev\baza\enumerations\encoding, mirzaev\baza\enumerations\type; // Built-in libraries use LogicException as exception_logic, InvalidArgumentException as exception_invalid_argument, - RuntimeException as exception_runtime; + RuntimeException as exception_runtime, + DomainException as exception_domain; /** * Database @@ -80,6 +82,27 @@ class database */ public protected(set) int $length; + /** + * Architecture + * + * @var architecture $architecture Architecture of the CPU + */ + public architecture $architecture; + + /** + * Constructor + * + * @throws exception_domain If failed to detemine the system architecture + */ + public function __construct() + { + $this->architecture = match (PHP_INT_SIZE) { + 4 => architecture::x86, + 8 => architecture::x86_64, + default => throw new exception_domain('Failed to determine the system architecture'), + }; + } + /** * Encoding * @@ -125,7 +148,7 @@ class database if ($column->type === type::string) { // String - // Adding the column string maximum length to the database instance property + // Adding the column binary length into the database instance property $this->length += $column->length; } else { // Other types @@ -182,7 +205,7 @@ class database foreach ($this->columns as $index => $column) { // Iterating over columns - if (gettype($values[$index]) === $column->type->type()) { + if (gettype($values[$index]) === $column->type->abstract()) { // The value type matches the column values type // Writing named index value into the buffer of combined values @@ -228,19 +251,30 @@ class database foreach ($this->columns as $column) { // Iterating over columns - if ($column->type === type::string) { - // String + if ($column instanceof column) { + // Initialized the column - // Converting to the database encoding - $value = mb_convert_encoding($record->values()[$column->name], $this->encoding->value); + // Initializing the record value + $value = $record->values()[$column->name]; - // Packung the value and writing into the buffer of packed values - $packed .= pack($column->type->value . $column->length, $value); - } else { - // Other types + if (isset($value)) { + // Initialized the record value - // Packung the value and writing into the buffer of packed values - $packed .= pack($column->type->value, $record->values()[$column->name]); + if ($column->type === type::string) { + // String + + // Converting to the database encoding + $value = mb_convert_encoding($value, $this->encoding->value); + + // Packung the value and writing into the buffer of packed values + $packed .= $column->pack($value); + } else { + // Other types + + // Packung the value and writing into the buffer of packed values + $packed .= $column->pack($value); + } + } } } @@ -265,28 +299,32 @@ class database foreach ($this->columns as $index => $column) { // Iterating over columns - // Initializing link to the binary value - $binary = $binaries[$index] ?? null; + if ($column instanceof column) { + // Initialized the column - if ($column->type === type::string) { - // String + // Initializing link to the binary value + $binary = $binaries[$index] ?? null; - // Unpacking the value - $value = unpack($column->type->value . $column->length, $binary ?? str_repeat("\0", $column->length))[1]; + if ($column->type === type::string) { + // String - // Deleting NULL-characters - $unnulled = str_replace("\0", '', $value); + // Unpacking the value + $value = $column->unpack($binary); - // Encoding the unpacked value - $encoded = mb_convert_encoding($unnulled, $this->encoding->value); + // Deleting NULL-characters + $unnulled = str_replace("\0", '', $value); - // Writing into the buffer of readed values - $unpacked[] = $encoded; - } else { - // Other types + // Encoding the unpacked value + $encoded = mb_convert_encoding($unnulled, $this->encoding->value); - // Writing into the buffer of readed values - $unpacked[] = unpack($column->type->value, $binary ?? "\0")[1]; + // Writing into the buffer of readed values + $unpacked[] = $encoded; + } else { + // Other types + + // Writing into the buffer of readed values + $unpacked[] = $column->unpack($binary); + } } } @@ -553,9 +591,9 @@ class database * @throws exception_runtime if failed to copying the database file to the backup file * @throws exception_runtime if failed to initialize the backups files directory * - * @return int|false Unique identifier of the created backup file + * @return string|false Unique identifier of the created backup file */ - public function save(): int|false + public function save(): string|false { if ($this->backups()) { // Initialized the backups files directory diff --git a/mirzaev/baza/system/enumerations/architecture.php b/mirzaev/baza/system/enumerations/architecture.php new file mode 100644 index 0000000..dcb7cf8 --- /dev/null +++ b/mirzaev/baza/system/enumerations/architecture.php @@ -0,0 +1,97 @@ + + */ +enum architecture: int +{ + case x86 = 32; + case x86_64 = 64; + + /** + * Packable + * + * @return bool Is this architecture are packable without segmentating? + */ + public function packable(): bool + { + // Exit (success) + return $this->value <= architecture::segment(); + } + + /** + * Segments + * + * Calculate the amount of `architecture::segment()` bit segments + * + * @return int Amount of segments + */ + public function segments(): int + { + // Calculating amount of segments + $amount = $this->value / architecture::segment(); + + // Exit (success) + return $amount; + } + + /** + * Segment + * + * @see http://php.net/pack#109328 `pack()` works only with 32 bit commands + * + * @return int Length of a segment in bits + */ + public static function segment(): int + { + // Exit (success) + return architecture::x86->value; + } + + /** + * Segmentate + * + * Splits the value into `architecture::segment()` bit segments + * + * @param int $value The value for segmentating + * + * @return array Segments [int, int, int] + * + * @deprecated Just use `long long` type! + */ + public function segmentate(int $value): array + { + // Calculating expected amount of segments + $amount = $this->segments(); + + // Initializing length of a segment + $segment = architecture::segment(); + + // Declaring the buffer of generated segments + $segments = []; + + for ($i = 0; $i < $amount; ++$i) { + // Iterating over generating segments + + // Calculating offset from the right + $right = $amount - $i - 1; + + // Generating segments + $segments[] = ($value & (0xffffffff << ($segment * $right))) >> ($segment * $right); + } + + // Exit (success) + return $segments; + } +} diff --git a/mirzaev/baza/system/enumerations/type.php b/mirzaev/baza/system/enumerations/type.php index 4e62b46..26362bb 100755 --- a/mirzaev/baza/system/enumerations/type.php +++ b/mirzaev/baza/system/enumerations/type.php @@ -41,7 +41,7 @@ enum type: string * * @return string Type */ - public function type(): string + public function abstract(): string { // Exit (success) return match ($this) { diff --git a/mirzaev/baza/tests/record.php b/mirzaev/baza/tests/record.php index 72e00ea..9056c1d 100755 --- a/mirzaev/baza/tests/record.php +++ b/mirzaev/baza/tests/record.php @@ -6,26 +6,27 @@ use mirzaev\baza\database, mirzaev\baza\record, mirzaev\baza\column, mirzaev\baza\enumerations\encoding, + mirzaev\baza\enumerations\architecture, mirzaev\baza\enumerations\type; // Initializing path to the composer loader file (main project) -$autoload = - __DIR__ . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - 'vendor' . DIRECTORY_SEPARATOR . +$autoload = + __DIR__ . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; // Reinitializing path to the composer loaded file (depencendy project) -if (!file_exists($autoload)) - $autoload = - __DIR__ . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . - '..' . DIRECTORY_SEPARATOR . +if (!file_exists($autoload)) + $autoload = + __DIR__ . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . + '..' . DIRECTORY_SEPARATOR . 'autoload.php'; // Importing files of thr project and dependencies @@ -52,28 +53,59 @@ if (!file_exists($file) || unlink($file)) { } // Initializing the test database -/* $database = new database() */ -$database = (new database()) - ->encoding(encoding::utf8) - ->columns( - new column('name', type::string, ['length' => 32]), - new column('second_name', type::string, ['length' => 64]), - new column('age', type::integer), - new column('height', type::float), - new column('active', type::char) - ) - ->connect($file); +$database = new database(); + +if ($database->architecture === architecture::x86_64) { + $database + ->encoding(encoding::utf8) + ->columns( + new column('name', type::string, ['length' => 32]), + new column('second_name', type::string, ['length' => 64]), + new column('age', type::integer), + new column('height', type::float), + // 64-bit values test + new column('neuron_count', type::integer_unsigned), + new column('motivation', type::double), + new column('reputation', type::integer), + new column('active', type::char) + ) + ->connect($file); +} else { + $database + ->encoding(encoding::utf8) + ->columns( + new column('name', type::string, ['length' => 32]), + new column('second_name', type::string, ['length' => 64]), + new column('age', type::integer), + new column('height', type::float), + new column('active', type::char) + ) + ->connect($file); +} echo '[' . ++$action . "] Initialized the database\n"; // Initializing the record -$record = $database->record( - 'Arsen', - 'Mirzaev', - 24, - 165.5, - 1 -); +if ($database->architecture === architecture::x86_64) { + $record = $database->record( + 'Arsen', + 'Mirzaev', + 24, + 165.5, + 9100, + 1.7976931348623E+238, + 7355608, + 1 + ); +} else { + $record = $database->record( + 'Arsen', + 'Mirzaev', + 24, + 165.5, + 1 + ); +} echo '[' . ++$action . "] Initialized the record\n"; @@ -84,6 +116,11 @@ echo '[' . ++$action . '][' . ++$test . '][' . ($record->name === 'Arsen' ? 'SUC echo '[' . $action . '][' . ++$test . '][' . ($record->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . "][\"second_name\"] Expected: \"Mirzaev\" (string). Actual: \"$record->second_name\" (" . gettype($record->second_name) . ")\n"; echo '[' . $action . '][' . ++$test . '][' . ($record->age === 24 ? 'SUCCESS' : 'FAIL') . "][\"age\"] Expected: \"24\" (integer). Actual: \"$record->age\" (" . gettype($record->age) . ")\n"; echo '[' . $action . '][' . ++$test . '][' . ($record->height === 165.5 ? 'SUCCESS' : 'FAIL') . "][\"height\"] Expected: \"165.5\" (double). Actual: \"$record->height\" (" . gettype($record->height) . ")\n"; +if ($database->architecture === architecture::x86_64) { + echo '[' . $action . '][' . ++$test . '][' . ($record->neuron_count === 9100 ? 'SUCCESS' : 'FAIL') . "][\"neuron_count\"] Expected: \"9100\" (integer). Actual: \"$record->neuron_count\" (" . gettype($record->neuron_count) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record->motivation === 1.7976931348623E+238 ? 'SUCCESS' : 'FAIL') . "][\"motivation\"] Expected: \"1.7976931348623E+238\" (double). Actual: \"$record->motivation\" (" . gettype($record->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record->reputation === 7355608 ? 'SUCCESS' : 'FAIL') . "][\"reputation\"] Expected: \"7355608\" (integer). Actual: \"$record->reputation\" (" . gettype($record->reputation) . ")\n"; +} echo '[' . $action . '][' . ++$test . '][' . ($record->active === 1 ? 'SUCCESS' : 'FAIL') . "][\"active\"] Expected: \"1\" (integer). Actual: \"$record->active\" (" . gettype($record->active) . ")\n"; echo '[' . $action . "] The record parameters checks have been completed\n"; @@ -94,178 +131,255 @@ $test = 0; // Writing the record into the database $database->write($record); -echo '[' . ++$action . "] Writed the record into the database\n"; +echo '[' . ++$action . "] Wrote the record into the database\n"; // Initializing the second record -$record_ivan = $database->record( - 'Ivan', - 'Ivanov', - 24, - (float) 210, - 0 -); +if ($database->architecture === architecture::x86_64) { + $record_ivan = $database->record( + 'Ivan', + 'Ivanov', + 24, + (float) 210, + PHP_INT_MAX, + PHP_FLOAT_MIN, + PHP_INT_MIN, + 0 + ); +} else { + $record_ivan = $database->record( + 'Ivan', + 'Ivanov', + 24, + (float) 210, + 0 + ); +} echo '[' . ++$action . "] Initialized the record\n"; // Writing the second record into the databasse $database->write($record_ivan); -echo '[' . ++$action . "] Writed the record into the database\n"; +echo '[' . ++$action . "] Wrote the record into the database\n"; // Initializing the second record -$record_ivan = $database->record( - 'Margarita', - 'Esenina', - 19, - (float) 165, - 1 -); +if ($database->architecture === architecture::x86_64) { + $record_margarita = $database->record( + 'Margarita', + 'Esenina', + 19, + (float) 165, + 89000000000, + (float) 163, + PHP_INT_MAX, + 1 + ); +} else { + $record_margarita = $database->record( + 'Margarita', + 'Esenina', + 19, + (float) 165, + 1 + ); +} echo '[' . ++$action . "] Initialized the record\n"; // Writing the second record into the databasse -$database->write($record_ivan); +$database->write($record_margarita); -echo '[' . ++$action . "] Writed the record into the database\n"; +echo '[' . ++$action . "] Wrote the record into the database\n"; // Reading all records from the database -$records_readed_all = $database->read(amount: 99999); +$records_read_all = $database->read(amount: 99999); -echo '[' . ++$action . "] Readed all records from the database\n"; +echo '[' . ++$action . "] Read all records from the database\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_readed_all) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_readed_all) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_all) === 3 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 3 records. Actual: ' . count($records_readed_all) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($records_readed_all[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($records_readed_all[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_all[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_all[0]::class . "\"\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_read_all) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_read_all) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_all) === 3 ? 'SUCCESS' : 'FAIL') . '][amount of read records] Expected: 3 records. Actual: ' . count($records_read_all) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($records_read_all[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($records_read_all[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_all[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $records_read_all[0]::class . "\"\n"; + if ($database->architecture === architecture::x86_64) { + echo '[' . $action . '][' . ++$test . '][' . ($records_read_all[0]->neuron_count === 9100 ? 'SUCCESS' : 'FAIL') . ']["neuron_count"] Expected: "9100" (integer). Actual: "' . $records_read_all[0]->neuron_count . '" (' . gettype($records_read_all[0]->neuron_count) . ")\n"; + } - echo '[' . $action . "] The readed all records checks have been completed\n"; + echo '[' . $action . "] The read all records checks have been completed\n"; } catch (exception $e) { - echo '[' . $action . "][WARNING] The readed all records checks have been completed with errors\n"; + echo '[' . $action . "][WARNING] The read all records checks have been completed with errors\n"; } // Reinitializing the counter of tests $test = 0; // Reading the first record from the database -$record_readed_first = $database->read(amount: 1); +$record_read_first = $database->read(amount: 1); -echo '[' . ++$action . "] Readed the first record from the database\n"; +echo '[' . ++$action . "] Read the first record from the database\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($record_readed_first) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($record_readed_first) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($record_readed_first) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 1 records. Actual: ' . count($record_readed_first) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($record_readed_first[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($record_readed_first[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($record_readed_first[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $record_readed_first[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($record_readed_first[0]->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Mirzaev" (string). Actual: "' . $record_readed_first[0]->second_name . '" (' . gettype($record_readed_first[0]->second_name) . ")\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($record_read_first) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($record_read_first) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($record_read_first) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of read records] Expected: 1 records. Actual: ' . count($record_read_first) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($record_read_first[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($record_read_first[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_first[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $record_read_first[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_first[0]->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Mirzaev" (string). Actual: "' . $record_read_first[0]->second_name . '" (' . gettype($record_read_first[0]->second_name) . ")\n"; + if ($database->architecture === architecture::x86_64) { + echo '[' . $action . '][' . ++$test . '][' . ($record_read_first[0]->neuron_count === 9100 ? 'SUCCESS' : 'FAIL') . ']["neuron_count"] Expected: "9100" (integer). Actual: "' . $record_read_first[0]->neuron_count . '" (' . gettype($record_read_first[0]->neuron_count) . ")\n"; + } - echo '[' . $action . "] The readed first record checks have been completed\n"; + echo '[' . $action . "] The read first record checks have been completed\n"; } catch (exception $e) { - echo '[' . $action . "][WARNING] The readed first record checks have been completed with errors\n"; + echo '[' . $action . "][WARNING] The read first record checks have been completed with errors\n"; } // Reinitializing the counter of tests $test = 0; // Reading the second record from the database -$record_readed_second = $database->read(amount: 1, offset: 1); +$record_read_second = $database->read(amount: 1, offset: 1); -echo '[' . ++$action . "] Readed the second record from the database\n"; +echo '[' . ++$action . "] Read the second record from the database\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($record_readed_second) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($record_readed_second) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($record_readed_second) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 1 records. Actual: ' . count($record_readed_second) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($record_readed_second[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($record_readed_second[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($record_readed_second[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $record_readed_second[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($record_readed_second[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $record_readed_second[0]->second_name . '" (' . gettype($record_readed_second[0]->second_name) . ")\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($record_read_second) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($record_read_second) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($record_read_second) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of read records] Expected: 1 records. Actual: ' . count($record_read_second) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($record_read_second[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($record_read_second[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $record_read_second[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $record_read_second[0]->second_name . '" (' . gettype($record_read_second[0]->second_name) . ")\n"; + if ($database->architecture === architecture::x86_64) { + /** + * Due to IEEE 754 double precision format double equality is problematic + * + * @see https://www.php.net/manual/en/language.types.float.php#113703 + */ + echo '[' . $action . '][' . ++$test . '][' . (round($record_read_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_read_second[0]->motivation . '" (' . gettype($record_read_second[0]->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->reputation === (int) 0 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "0" (integer) (overflow). Actual: "' . $record_read_second[0]->reputation . '" (' . gettype($record_read_second[0]->reputation) . ")\n"; + } - echo '[' . $action . "] The readed second record checks have been completed\n"; + echo '[' . $action . "] The read second record checks have been completed\n"; } catch (exception $e) { - echo '[' . $action . "][WARNING] The readed second record checks have been completed with errors\n"; + echo '[' . $action . "][WARNING] The read second record checks have been completed with errors\n"; } // Reinitializing the counter of tests $test = 0; // Reading the record from the database by filter -$record_readed_filter = $database->read(filter: fn($record) => $record?->second_name === 'Ivanov', amount: 1); +$record_read_filter = $database->read(filter: fn($record) => $record?->second_name === 'Ivanov', amount: 1); -echo '[' . ++$action . "] Readed the record from the database by filter\n"; +echo '[' . ++$action . "] Read the record from the database by filter\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($record_readed_filter) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($record_readed_filter) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($record_readed_filter) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 1 records. Actual: ' . count($record_readed_filter) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($record_readed_filter[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($record_readed_filter[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($record_readed_filter[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $record_readed_filter[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($record_readed_filter[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $record_readed_filter[0]->second_name . '" (' . gettype($record_readed_filter[0]->second_name) . ")\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($record_read_filter) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($record_read_filter) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($record_read_filter) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of read records] Expected: 1 records. Actual: ' . count($record_read_filter) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($record_read_filter[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($record_read_filter[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_filter[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $record_read_filter[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_filter[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $record_read_filter[0]->second_name . '" (' . gettype($record_read_filter[0]->second_name) . ")\n"; + if ($database->architecture === architecture::x86_64) { + /** + * Due to IEEE 754 double precision format double equality is problematic + * + * @see https://www.php.net/manual/en/language.types.float.php#113703 + */ + echo '[' . $action . '][' . ++$test . '][' . (round($record_read_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_read_second[0]->motivation . '" (' . gettype($record_read_second[0]->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->reputation === (int) 0 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "0" (integer) (overflow). Actual: "' . $record_read_second[0]->reputation . '" (' . gettype($record_read_second[0]->reputation) . ")\n"; + } - echo '[' . $action . "] The readed record by filter checks have been completed\n"; + echo '[' . $action . "] The read record by filter checks have been completed\n"; } catch (exception $e) { - echo '[' . $action . "][WARNING] The readed record by filter checks have been completed with errors\n"; + echo '[' . $action . "][WARNING] The read record by filter checks have been completed with errors\n"; } // Reinitializing the counter of tests $test = 0; // Reading the record from the database by filter with amount limit -$records_readed_filter_amount = $database->read(filter: fn($record) => $record?->age === 24, amount: 1); +$records_read_filter_amount = $database->read(filter: fn($record) => $record?->age === 24, amount: 1); -echo '[' . ++$action . "] Readed the record from the database by filter with amount limit\n"; +echo '[' . ++$action . "] Read the record from the database by filter with amount limit\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_readed_filter_amount) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_readed_filter_amount) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_amount) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 1 records. Actual: ' . count($records_readed_filter_amount) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($records_readed_filter_amount[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($records_readed_filter_amount[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_amount[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount[0]->age === 24 ? 'SUCCESS' : 'FAIL') . ']["age"] Expected: "24" (integer). Actual: "' . $records_readed_filter_amount[0]->age . '" (' . gettype($records_readed_filter_amount[0]->age) . ")\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount[0]->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Mirzaev" (string). Actual: "' . $records_readed_filter_amount[0]->second_name . '" (' . gettype($records_readed_filter_amount[0]->second_name) . ")\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_read_filter_amount) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_read_filter_amount) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_filter_amount) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of read records] Expected: 1 records. Actual: ' . count($records_read_filter_amount) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($records_read_filter_amount[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($records_read_filter_amount[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_amount[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $records_read_filter_amount[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_amount[0]->age === 24 ? 'SUCCESS' : 'FAIL') . ']["age"] Expected: "24" (integer). Actual: "' . $records_read_filter_amount[0]->age . '" (' . gettype($records_read_filter_amount[0]->age) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_amount[0]->second_name === 'Mirzaev' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Mirzaev" (string). Actual: "' . $records_read_filter_amount[0]->second_name . '" (' . gettype($records_read_filter_amount[0]->second_name) . ")\n"; + if ($database->architecture === architecture::x86_64) { + /** + * Due to IEEE 754 double precision format double equality is problematic + * + * @see https://www.php.net/manual/en/language.types.float.php#113703 + */ + echo '[' . $action . '][' . ++$test . '][' . (round($record_read_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_read_second[0]->motivation . '" (' . gettype($record_read_second[0]->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->reputation === (int) 0 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "0" (integer) (overflow). Actual: "' . $record_read_second[0]->reputation . '" (' . gettype($record_read_second[0]->reputation) . ")\n"; + } - echo '[' . $action . "] The readed record by filter with amount limit checks have been completed\n"; + echo '[' . $action . "] The read record by filter with amount limit checks have been completed\n"; } catch (exception $e) { - echo '[' . $action . "][WARNING] The readed record by filter with amount limit checks have been completed with errors\n"; + echo '[' . $action . "][WARNING] The read record by filter with amount limit checks have been completed with errors\n"; } // Reinitializing the counter of tests $test = 0; // Reading the record from the database by filter with amount limit and offset -$records_readed_filter_amount_offset = $database->read(filter: fn($record) => $record?->age === 24, amount: 1, offset: 1); +$records_read_filter_amount_offset = $database->read(filter: fn($record) => $record?->age === 24, amount: 1, offset: 1); -echo '[' . ++$action . "] Readed the record from the database by filter with amount limit and offset\n"; +echo '[' . ++$action . "] Read the record from the database by filter with amount limit and offset\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_readed_filter_amount_offset) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_readed_filter_amount_offset) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_amount_offset) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of readed records] Expected: 1 records. Actual: ' . count($records_readed_filter_amount_offset) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($records_readed_filter_amount_offset[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($records_readed_filter_amount_offset[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_amount_offset[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0]->age === 24 ? 'SUCCESS' : 'FAIL') . ']["age"] Expected: "24" (integer). Actual: "' . $records_readed_filter_amount_offset[0]->age . '" (' . gettype($records_readed_filter_amount_offset[0]->age) . ")\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_amount_offset[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $records_readed_filter_amount_offset[0]->second_name . '" (' . gettype($records_readed_filter_amount_offset[0]->second_name) . ")\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_read_filter_amount_offset) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_read_filter_amount_offset) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_filter_amount_offset) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of read records] Expected: 1 records. Actual: ' . count($records_read_filter_amount_offset) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($records_read_filter_amount_offset[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($records_read_filter_amount_offset[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_amount_offset[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $records_read_filter_amount_offset[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_amount_offset[0]->age === 24 ? 'SUCCESS' : 'FAIL') . ']["age"] Expected: "24" (integer). Actual: "' . $records_read_filter_amount_offset[0]->age . '" (' . gettype($records_read_filter_amount_offset[0]->age) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_amount_offset[0]->second_name === 'Ivanov' ? 'SUCCESS' : 'FAIL') . ']["second_name"] Expected: "Ivanov" (string). Actual: "' . $records_read_filter_amount_offset[0]->second_name . '" (' . gettype($records_read_filter_amount_offset[0]->second_name) . ")\n"; + if ($database->architecture === architecture::x86_64) { + /** + * Due to IEEE 754 double precision format double equality is problematic + * + * @see https://www.php.net/manual/en/language.types.float.php#113703 + */ + echo '[' . $action . '][' . ++$test . '][' . (round($record_read_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_read_second[0]->motivation . '" (' . gettype($record_read_second[0]->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->reputation === (int) 0 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "0" (integer) (overflow). Actual: "' . $record_read_second[0]->reputation . '" (' . gettype($record_read_second[0]->reputation) . ")\n"; + } - echo '[' . $action . "] The readed record by filter with amount limit and offset checks have been completed\n"; + echo '[' . $action . "] The read record by filter with amount limit and offset checks have been completed\n"; } catch (exception $e) { - echo '[' . $action . "][WARNING] The readed record by filter with amount limit and offset checks have been completed with errors\n"; + echo '[' . $action . "][WARNING] The read record by filter with amount limit and offset checks have been completed with errors\n"; } // Reinitializing the counter of tests $test = 0; // Deleting the record in the database by filter -$records_readed_filter_delete = $database->read(filter: fn($record) => $record?->name === 'Ivan', delete: true, amount: 1); +$records_read_filter_delete = $database->read(filter: fn($record) => $record?->name === 'Ivan', delete: true, amount: 1); echo '[' . ++$action . "] Deleted the record from the database by filter\n"; // Reading records from the database after deleting -$records_readed_filter_delete_readed = $database->read(amount: 100); +$records_read_filter_delete_read = $database->read(amount: 100); -echo '[' . ++$action . "] Readed records from the database after deleting the record\n"; +echo '[' . ++$action . "] Read records from the database after deleting the record\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_readed_filter_delete) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_readed_filter_delete) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_delete) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of deleted records] Expected: 1 records. Actual: ' . count($records_readed_filter_delete) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($records_readed_filter_delete[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($records_readed_filter_delete[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_delete[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_delete[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_delete[0]->name === 'Ivan' ? 'SUCCESS' : 'FAIL') . ']["name"] Expected: "Ivan" (string). Actual: "' . $records_readed_filter_delete[0]->second_name . '" (' . gettype($records_readed_filter_delete[0]->second_name) . ")\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_delete_readed) === 2 ? 'SUCCESS' : 'FAIL') . '][amount of readed records after deleting] Expected: 2 records. Actual: ' . count($records_readed_filter_delete_readed) . " records\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_read_filter_delete) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_read_filter_delete) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_filter_delete) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of deleted records] Expected: 1 records. Actual: ' . count($records_read_filter_delete) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($records_read_filter_delete[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($records_read_filter_delete[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_delete[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $records_read_filter_delete[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_delete[0]->name === 'Ivan' ? 'SUCCESS' : 'FAIL') . ']["name"] Expected: "Ivan" (string). Actual: "' . $records_read_filter_delete[0]->second_name . '" (' . gettype($records_read_filter_delete[0]->second_name) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_filter_delete_read) === 2 ? 'SUCCESS' : 'FAIL') . '][amount of read records after deleting] Expected: 2 records. Actual: ' . count($records_read_filter_delete_read) . " records\n"; + if ($database->architecture === architecture::x86_64) { + /** + * Due to IEEE 754 double precision format double equality is problematic + * + * @see https://www.php.net/manual/en/language.types.float.php#113703 + */ + echo '[' . $action . '][' . ++$test . '][' . (round($records_read_filter_delete_read[1]->motivation, 2) === round(163, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "163" (double). Actual: "' . $records_read_filter_delete_read[1]->motivation . '" (' . gettype($records_read_filter_delete_read[1]->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->reputation === (int) 0 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "0" (integer) (overflow). Actual: "' . $record_read_second[0]->reputation . '" (' . gettype($record_read_second[0]->reputation) . ")\n"; + } echo '[' . $action . "] The deleted record by filter checks have been completed\n"; } catch (exception $e) { @@ -276,23 +390,32 @@ try { $test = 0; // Updating the record in the database -$records_readed_filter_update = $database->read(filter: fn($record) => $record?->name === 'Margarita', update: fn(&$record) => $record->height += 0.5, amount: 1); +$records_read_filter_update = $database->read(filter: fn($record) => $record?->name === 'Margarita', update: fn(&$record) => $record->height += 0.5, amount: 1); echo '[' . ++$action . "] Updated the record in the database by filter\n"; // Reading records from the database after updating -$records_readed_filter_update_readed = $database->read(amount: 100); +$records_read_filter_update_read = $database->read(amount: 100); -echo '[' . ++$action . "] Readed records from the database after updating the record\n"; +echo '[' . ++$action . "] Read records from the database after updating the record\n"; try { - echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_readed_filter_update) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_readed_filter_update) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_update) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of updated records] Expected: 1 records. Actual: ' . count($records_readed_filter_update) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . (gettype($records_readed_filter_update[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of readed values] Expected: "object". Actual: "' . gettype($records_readed_filter_update[0]) . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_update[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of readed object values] Expected: "' . record::class . '". Actual: "' . $records_readed_filter_update[0]::class . "\"\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_update[0]->height === 165.5 ? 'SUCCESS' : 'FAIL') . ']["height"] Expected: "165.5" (double). Actual: "' . $records_readed_filter_update[0]->height . '" (' . gettype($records_readed_filter_update[0]->height) . ")\n"; - echo '[' . $action . '][' . ++$test . '][' . (count($records_readed_filter_update_readed) === 2 ? 'SUCCESS' : 'FAIL') . '][amount of readed records after updating] Expected: 2 records. Actual: ' . count($records_readed_filter_update_readed) . " records\n"; - echo '[' . $action . '][' . ++$test . '][' . ($records_readed_filter_update_readed[1]->height === $records_readed_filter_update[0]->height ? 'SUCCESS' : 'FAIL') . "] Height from `update` process response matched height from the `read` preocess response\n"; + echo '[' . ++$action . '][' . ++$test . '][' . (gettype($records_read_filter_update) === 'array' ? 'SUCCESS' : 'FAIL') . '][type of returned value] Expected: "array". Actual: "' . gettype($records_read_filter_update) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_filter_update) === 1 ? 'SUCCESS' : 'FAIL') . '][amount of updated records] Expected: 1 records. Actual: ' . count($records_read_filter_update) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . (gettype($records_read_filter_update[0]) === 'object' ? 'SUCCESS' : 'FAIL') . '][type of read values] Expected: "object". Actual: "' . gettype($records_read_filter_update[0]) . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_update[0] instanceof record ? 'SUCCESS' : 'FAIL') . '][class of read object values] Expected: "' . record::class . '". Actual: "' . $records_read_filter_update[0]::class . "\"\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_update[0]->height === 165.5 ? 'SUCCESS' : 'FAIL') . ']["height"] Expected: "165.5" (double). Actual: "' . $records_read_filter_update[0]->height . '" (' . gettype($records_read_filter_update[0]->height) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . (count($records_read_filter_update_read) === 2 ? 'SUCCESS' : 'FAIL') . '][amount of read records after updating] Expected: 2 records. Actual: ' . count($records_read_filter_update_read) . " records\n"; + echo '[' . $action . '][' . ++$test . '][' . ($records_read_filter_update_read[1]->height === $records_read_filter_update[0]->height ? 'SUCCESS' : 'FAIL') . "] Height from `update` process response matched height from the `read` preocess response\n"; + if ($database->architecture === architecture::x86_64) { + /** + * Due to IEEE 754 double precision format double equality is problematic + * + * @see https://www.php.net/manual/en/language.types.float.php#113703 + */ + echo '[' . $action . '][' . ++$test . '][' . (round($record_read_second[0]->motivation, 2) === round(2.2250738585072E-308, 2) ? 'SUCCESS' : 'FAIL') . ']["motivation"] Expected: "2.2250738585072E-308" (double). Actual: "' . $record_read_second[0]->motivation . '" (' . gettype($record_read_second[0]->motivation) . ")\n"; + echo '[' . $action . '][' . ++$test . '][' . ($record_read_second[0]->reputation === (int) 0 ? 'SUCCESS' : 'FAIL') . ']["reputation"] Expected: "0" (integer) (overflow). Actual: "' . $record_read_second[0]->reputation . '" (' . gettype($record_read_second[0]->reputation) . ")\n"; + } echo '[' . $action . "] The updated record by filter checks have been completed\n"; } catch (exception $e) {