Compare commits
	
		
			18 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 22fe7f894f | |||
| ec2721dc77 | |||
| 93078df174 | |||
| e263eb3f0b | |||
| 260be006ae | |||
| 6937c70c9c | |||
| d0a661016b | |||
| dd6fc42732 | |||
| 1cd4fe8a9a | |||
| d7e3a61e63 | |||
| 1ea9c1f41f | |||
| 273cc1ac2d | |||
| 6d332c7cf9 | |||
| 19978574a3 | |||
| c6fd8cf9f9 | |||
| 00e4b256f7 | |||
| 54b7ab07f1 | |||
| a9f90966e0 | 
							
								
								
									
										6
									
								
								.editorconfig
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								.editorconfig
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
root = true
 | 
			
		||||
 | 
			
		||||
[README.md]
 | 
			
		||||
charset = utf-8
 | 
			
		||||
indent_style = tab
 | 
			
		||||
tab_width = 2
 | 
			
		||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1 +1,2 @@
 | 
			
		||||
vendor
 | 
			
		||||
composer.lock
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,8 @@
 | 
			
		||||
Lightweight binary database by pure PHP<br>
 | 
			
		||||
 | 
			
		||||
## Dependencies
 | 
			
		||||
1. 
 | 
			
		||||
2.  (php package manager)
 | 
			
		||||
1. [PHP 8.4](https://www.php.net/releases/8.4/en.php)
 | 
			
		||||
2. [Composer](https://getcomposer.org/) (php package manager)
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
`composer require mirzaev/baza`
 | 
			
		||||
@@ -12,7 +12,7 @@ Lightweight binary database by pure PHP<br>
 | 
			
		||||
```php
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use use mirzaev\baza\database,
 | 
			
		||||
use mirzaev\baza\database,
 | 
			
		||||
    mirzaev\baza\column,
 | 
			
		||||
    mirzaev\baza\record,
 | 
			
		||||
    mirzaev\baza\enumerations\encoding,
 | 
			
		||||
@@ -66,4 +66,4 @@ if ($database->write($record)) {
 | 
			
		||||
## Used by
 | 
			
		||||
- My site-article about how i was kidnapped by PMC Wagner operatives [mirzaev/repression](https://git.svoboda.works/mirzaev/repression)
 | 
			
		||||
- My decentralized P2P blockchain chats project [mirzaev/notchat](https://git.svoboda.works/mirzaev/notchat)
 | 
			
		||||
- Svoboda Telegram chat-robot [svoboda/negotiator](https://git.svoboda.works/svoboda/negotiator)
 | 
			
		||||
- Svoboda Telegram chat-robot negotiator [svoboda/negotiator](https://git.svoboda.works/svoboda/negotiator)
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,9 @@
 | 
			
		||||
	"require": {
 | 
			
		||||
		"php": "^8.4"
 | 
			
		||||
	},
 | 
			
		||||
	"suggest": {
 | 
			
		||||
		"mirzaev/record": "Active Record pattern"
 | 
			
		||||
	},
 | 
			
		||||
	"autoload": {
 | 
			
		||||
		"psr-4": {
 | 
			
		||||
			"mirzaev\\baza\\": "mirzaev/baza/system/"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										20
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@@ -1,20 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "_readme": [
 | 
			
		||||
        "This file locks the dependencies of your project to a known state",
 | 
			
		||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
			
		||||
        "This file is @generated automatically"
 | 
			
		||||
    ],
 | 
			
		||||
    "content-hash": "a83cda6b5d1de267690c8b7e2a2ddf86",
 | 
			
		||||
    "packages": [],
 | 
			
		||||
    "packages-dev": [],
 | 
			
		||||
    "aliases": [],
 | 
			
		||||
    "minimum-stability": "stable",
 | 
			
		||||
    "stability-flags": {},
 | 
			
		||||
    "prefer-stable": false,
 | 
			
		||||
    "prefer-lowest": false,
 | 
			
		||||
    "platform": {
 | 
			
		||||
        "php": "^8.4"
 | 
			
		||||
    },
 | 
			
		||||
    "platform-dev": {},
 | 
			
		||||
    "plugin-api-version": "2.6.0"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								mirzaev/baza/system/column.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										55
									
								
								mirzaev/baza/system/column.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										121
									
								
								mirzaev/baza/system/database.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										121
									
								
								mirzaev/baza/system/database.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -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
 | 
			
		||||
@@ -48,7 +50,7 @@ class database
 | 
			
		||||
	 *
 | 
			
		||||
	 * @var string $database Path to the database file
 | 
			
		||||
	 */
 | 
			
		||||
	public protected(set) string $database = __DIR__ . DIRECTORY_SEPARATOR . 'database.ba';
 | 
			
		||||
	public protected(set) string $database = __DIR__ . DIRECTORY_SEPARATOR . 'database.baza';
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Backups
 | 
			
		||||
@@ -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 instanceof column) {
 | 
			
		||||
				// Initialized the column
 | 
			
		||||
 | 
			
		||||
				// Initializing the record value
 | 
			
		||||
				$value = $record->values()[$column->name];
 | 
			
		||||
 | 
			
		||||
				if (isset($value)) {
 | 
			
		||||
					// Initialized the record value
 | 
			
		||||
 | 
			
		||||
					if ($column->type === type::string) {
 | 
			
		||||
						// String
 | 
			
		||||
 | 
			
		||||
						// Converting to the database encoding
 | 
			
		||||
				$value = mb_convert_encoding($record->values()[$column->name], $this->encoding->value);
 | 
			
		||||
						$value = mb_convert_encoding($value, $this->encoding->value);
 | 
			
		||||
 | 
			
		||||
						// Packung the value and writing into the buffer of packed values
 | 
			
		||||
				$packed .= pack($column->type->value . $column->length, $value);
 | 
			
		||||
						$packed .= $column->pack($value);
 | 
			
		||||
					} else {
 | 
			
		||||
						// Other types
 | 
			
		||||
 | 
			
		||||
						// Packung the value and writing into the buffer of packed values
 | 
			
		||||
				$packed .= pack($column->type->value, $record->values()[$column->name]);
 | 
			
		||||
						$packed .= $column->pack($value);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -259,20 +293,23 @@ class database
 | 
			
		||||
	 */
 | 
			
		||||
	public function unpack(array $binaries): record
 | 
			
		||||
	{
 | 
			
		||||
		if (count($binaries) === count($this->columns)) {
 | 
			
		||||
			// Amount of binery values matches amount of columns
 | 
			
		||||
 | 
			
		||||
		// Declaring the buffer of unpacked values
 | 
			
		||||
		$unpacked = [];
 | 
			
		||||
 | 
			
		||||
			foreach (array_combine($binaries, $this->columns) as $binary => $column) {
 | 
			
		||||
		foreach ($this->columns as $index => $column) {
 | 
			
		||||
			// Iterating over columns
 | 
			
		||||
 | 
			
		||||
			if ($column instanceof column) {
 | 
			
		||||
				// Initialized the column
 | 
			
		||||
 | 
			
		||||
				// Initializing link to the binary value
 | 
			
		||||
				$binary = $binaries[$index] ?? null;
 | 
			
		||||
 | 
			
		||||
				if ($column->type === type::string) {
 | 
			
		||||
					// String
 | 
			
		||||
 | 
			
		||||
					// Unpacking the value
 | 
			
		||||
					$value = unpack($column->type->value . $column->length, $binary)[1];
 | 
			
		||||
					$value = $column->unpack($binary);
 | 
			
		||||
 | 
			
		||||
					// Deleting NULL-characters
 | 
			
		||||
					$unnulled = str_replace("\0", '', $value);
 | 
			
		||||
@@ -286,7 +323,8 @@ class database
 | 
			
		||||
					// Other types
 | 
			
		||||
 | 
			
		||||
					// Writing into the buffer of readed values
 | 
			
		||||
					$unpacked[] = unpack($column->type->value, $binary)[1];
 | 
			
		||||
					$unpacked[] = $column->unpack($binary);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -295,12 +333,6 @@ class database
 | 
			
		||||
 | 
			
		||||
		// Exit (success)
 | 
			
		||||
		return $record;
 | 
			
		||||
		} else {
 | 
			
		||||
			// Amount of binery values not matches amount of columns
 | 
			
		||||
 | 
			
		||||
			// Exit (fail)
 | 
			
		||||
			throw new exception_invalid_argument('Amount of binary values not matches amount of columns');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -374,10 +406,15 @@ class database
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array|null Readed records
 | 
			
		||||
	 */
 | 
			
		||||
	public function read(?callable $filter = null, ?callable $update = null, bool $delete = false, int $amount = 1, int $offset = 0): ?array
 | 
			
		||||
	{
 | 
			
		||||
	public function read(
 | 
			
		||||
		?callable $filter = null,
 | 
			
		||||
		?callable $update = null,
 | 
			
		||||
		bool $delete = false,
 | 
			
		||||
		int $amount = 1,
 | 
			
		||||
		int $offset = 0
 | 
			
		||||
	): ?array {
 | 
			
		||||
		// Opening the database file
 | 
			
		||||
		$file = fopen($this->database, 'r+b');
 | 
			
		||||
		$file = fopen($this->database, 'c+b');
 | 
			
		||||
 | 
			
		||||
		if (flock($file, LOCK_EX)) {
 | 
			
		||||
			// The file was locked
 | 
			
		||||
@@ -408,6 +445,9 @@ class database
 | 
			
		||||
						// Reading the binary value from the database
 | 
			
		||||
						$binaries[] = fread($file, $column->type->size());
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Terminate loop when end of file is reached
 | 
			
		||||
					/* if (feof($file)) break 2; */
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Terminate loop when end of file is reached
 | 
			
		||||
@@ -417,6 +457,9 @@ class database
 | 
			
		||||
					// Unpacking the record
 | 
			
		||||
					$record = $this->unpack($binaries);
 | 
			
		||||
 | 
			
		||||
					if ((bool) array_filter($record->values())) {
 | 
			
		||||
						// The record contains at least one non-empty value
 | 
			
		||||
 | 
			
		||||
						if (is_null($filter) || $filter($record, $records)) {
 | 
			
		||||
							// Passed the filter
 | 
			
		||||
 | 
			
		||||
@@ -460,9 +503,14 @@ class database
 | 
			
		||||
								--$amount;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
				} catch (exception_logic | exception_invalid_argument $exception) {
 | 
			
		||||
					} else {
 | 
			
		||||
						// The record contains only empty values
 | 
			
		||||
					}
 | 
			
		||||
				} catch (exception_logic | exception_invalid_argument | exception_domain $exception) {
 | 
			
		||||
					// Writing into the buffer of failed to reading records
 | 
			
		||||
					/* $failed[] = $record; */
 | 
			
		||||
 | 
			
		||||
					// Exit (fail)
 | 
			
		||||
					throw new exception_runtime('Failed to processing the record', previous: $exception);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -480,6 +528,25 @@ class database
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Count
 | 
			
		||||
	 *
 | 
			
		||||
	 * @throws exception_runtime If the database is corrupted (counting result is float)
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return int Amount of records
 | 
			
		||||
	 */
 | 
			
		||||
	public function count(): int
 | 
			
		||||
	{
 | 
			
		||||
		// Deleting the database file cache
 | 
			
		||||
		clearstatcache(true, $this->database);
 | 
			
		||||
 | 
			
		||||
		// Counting
 | 
			
		||||
		$amount = $this->length > 0 && file_exists($this->database) ? filesize($this->database) / $this->length : 0;
 | 
			
		||||
 | 
			
		||||
		// Exit (success/fail)
 | 
			
		||||
		return is_int($amount) ? $amount : throw new exception_runtime('The database is corrupted');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Backups
 | 
			
		||||
	 *
 | 
			
		||||
@@ -524,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								mirzaev/baza/system/enumerations/architecture.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								mirzaev/baza/system/enumerations/architecture.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace mirzaev\baza\enumerations;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Architecture
 | 
			
		||||
 *
 | 
			
		||||
 * @see http://php.net/pack#109328 `pack()` works only with 32 bit commands
 | 
			
		||||
 *
 | 
			
		||||
 * @package mirzaev\baza\enumerations
 | 
			
		||||
 *
 | 
			
		||||
 * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
 | 
			
		||||
 * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
 | 
			
		||||
 */
 | 
			
		||||
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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										0
									
								
								mirzaev/baza/system/enumerations/encoding.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								mirzaev/baza/system/enumerations/encoding.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
									
										6
									
								
								mirzaev/baza/system/enumerations/type.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										6
									
								
								mirzaev/baza/system/enumerations/type.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -41,12 +41,12 @@ enum type: string
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string Type
 | 
			
		||||
	 */
 | 
			
		||||
	public function type(): string
 | 
			
		||||
	public function abstract(): string
 | 
			
		||||
	{
 | 
			
		||||
		// Exit (success)
 | 
			
		||||
		return match ($this) {
 | 
			
		||||
			type::char, type::string, type::short => 'string',
 | 
			
		||||
			type::char_unsigned, type::short_unsigned, type::integer, type::integer_unsigned, type::long, type::long_unsigned, type::long_long, type::long_long_unsigned => 'integer',
 | 
			
		||||
			type::string, type::short => 'string',
 | 
			
		||||
			type::char, type::char_unsigned, type::short_unsigned, type::integer, type::integer_unsigned, type::long, type::long_unsigned, type::long_long, type::long_long_unsigned => 'integer',
 | 
			
		||||
			type::float, type::double => 'double',
 | 
			
		||||
			type::null => 'NULL',
 | 
			
		||||
			default => throw new exception_unexpected_value('Not found the type')
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								mirzaev/baza/system/record.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										14
									
								
								mirzaev/baza/system/record.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -4,6 +4,9 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace mirzaev\baza;
 | 
			
		||||
 | 
			
		||||
// Built-in libraries
 | 
			
		||||
use DomainException as exception_domain;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Record
 | 
			
		||||
 *
 | 
			
		||||
@@ -63,12 +66,23 @@ class record
 | 
			
		||||
	 * @param string $name Name of the parameter
 | 
			
		||||
	 * @param mixed $value Content of the parameter
 | 
			
		||||
	 *
 | 
			
		||||
	 * @throws exception_domain if not found the parameter
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return void
 | 
			
		||||
	 */
 | 
			
		||||
	public function __set(string $name, mixed $value = null): void
 | 
			
		||||
	{
 | 
			
		||||
		if (isset($this->values[$name])) {
 | 
			
		||||
			// Initialized the parameter
 | 
			
		||||
 | 
			
		||||
			// Writing the value and exit
 | 
			
		||||
			$this->values[$name] = $value;
 | 
			
		||||
		} else {
 | 
			
		||||
			// Not initialized the parameter
 | 
			
		||||
 | 
			
		||||
			// Exit (fail)
 | 
			
		||||
			throw new exception_domain("Not found the parameter: $name"); 
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								mirzaev/baza/tests/.gitignore
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										2
									
								
								mirzaev/baza/tests/.gitignore
									
									
									
									
										vendored
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1 +1 @@
 | 
			
		||||
temporary
 | 
			
		||||
temporary/*
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										332
									
								
								mirzaev/baza/tests/record.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										332
									
								
								mirzaev/baza/tests/record.php
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,16 +1,39 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
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.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 .
 | 
			
		||||
		'autoload.php';
 | 
			
		||||
 | 
			
		||||
// Importing files of thr project and dependencies
 | 
			
		||||
require(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php');
 | 
			
		||||
require($autoload);
 | 
			
		||||
 | 
			
		||||
// Initializing path to the database file
 | 
			
		||||
$file = __DIR__ . DIRECTORY_SEPARATOR . 'temporary' . DIRECTORY_SEPARATOR . 'database.ba';
 | 
			
		||||
$file = __DIR__ . DIRECTORY_SEPARATOR . 'temporary' . DIRECTORY_SEPARATOR . 'database.baza';
 | 
			
		||||
 | 
			
		||||
echo "Started testing\n\n\n";
 | 
			
		||||
 | 
			
		||||
@@ -30,26 +53,59 @@ if (!file_exists($file) || unlink($file)) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initializing the test database
 | 
			
		||||
/* $database = new database() */
 | 
			
		||||
$database = (new database())
 | 
			
		||||
$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)
 | 
			
		||||
			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(__DIR__ . DIRECTORY_SEPARATOR . 'temporary' . DIRECTORY_SEPARATOR . 'database.ba');
 | 
			
		||||
		->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(
 | 
			
		||||
if ($database->architecture === architecture::x86_64) {
 | 
			
		||||
	$record = $database->record(
 | 
			
		||||
		'Arsen',
 | 
			
		||||
		'Mirzaev',
 | 
			
		||||
		24,
 | 
			
		||||
	165.5
 | 
			
		||||
);
 | 
			
		||||
		165.5,
 | 
			
		||||
		9100,
 | 
			
		||||
		1.7976931348623E+238,
 | 
			
		||||
		7355608,
 | 
			
		||||
		1
 | 
			
		||||
	);
 | 
			
		||||
} else {
 | 
			
		||||
	$record = $database->record(
 | 
			
		||||
		'Arsen',
 | 
			
		||||
		'Mirzaev',
 | 
			
		||||
		24,
 | 
			
		||||
		165.5,
 | 
			
		||||
		1
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
echo '[' . ++$action . "] Initialized the record\n";
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +116,12 @@ 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";
 | 
			
		||||
 | 
			
		||||
@@ -69,176 +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(
 | 
			
		||||
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(
 | 
			
		||||
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) {
 | 
			
		||||
@@ -249,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) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user