diff --git a/.travis.yml b/.travis.yml index af8cf0081..8262167b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ php: - nightly services: - mysql + - postgresql - redis - memcached before_script: diff --git a/DataStorage/Cache/Connection/FileCache.php b/DataStorage/Cache/Connection/FileCache.php index 7b4672a9f..04a4c0971 100644 --- a/DataStorage/Cache/Connection/FileCache.php +++ b/DataStorage/Cache/Connection/FileCache.php @@ -231,8 +231,10 @@ class FileCache extends ConnectionAbstract */ private function stringify($value, int $type) : string { - if ($type === CacheValueType::_INT || $type === CacheValueType::_FLOAT || $type === CacheValueType::_STRING || $type === CacheValueType::_BOOL) { + if ($type === CacheValueType::_INT || $type === CacheValueType::_STRING || $type === CacheValueType::_BOOL) { return (string) $value; + } elseif ($type === CacheValueType::_FLOAT) { + return \rtrim(\rtrim(\number_format($value, 5, '.', ''), '0'), '.'); } elseif ($type === CacheValueType::_ARRAY) { return (string) \json_encode($value); } elseif ($type === CacheValueType::_SERIALIZABLE) { diff --git a/DataStorage/Database/Connection/ConnectionAbstract.php b/DataStorage/Database/Connection/ConnectionAbstract.php index 59b2047cf..15ad0e50d 100644 --- a/DataStorage/Database/Connection/ConnectionAbstract.php +++ b/DataStorage/Database/Connection/ConnectionAbstract.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database\Connection; use phpOMS\DataStorage\Database\DatabaseStatus; +use phpOMS\DataStorage\Database\DatabaseType; use phpOMS\DataStorage\Database\Query\Grammar\Grammar; use phpOMS\DataStorage\Database\Schema\Grammar\Grammar as SchemaGrammar; @@ -66,7 +67,7 @@ abstract class ConnectionAbstract implements ConnectionInterface * @var string * @since 1.0.0 */ - protected $type = 'undefined'; + protected $type = DatabaseType::UNDEFINED; /** * Database status. @@ -92,25 +93,6 @@ abstract class ConnectionAbstract implements ConnectionInterface */ protected $schemaGrammar = null; - /** - * Set values - * - * @param string $name Variable name - * @param string $value Variable value - * - * @return void - * - * @since 1.0.0 - */ - public function __set($name, $value) : void - { - if (!empty($this->$name)) { - return; - } - - $this->$name = $value; - } - /** * {@inheritdoc} */ @@ -180,11 +162,7 @@ abstract class ConnectionAbstract implements ConnectionInterface */ public function getGrammar() : Grammar { - if ($this->grammar === null) { - $this->grammar = new Grammar(); - } - - return $this->grammar; + return $this->grammar ?? new Grammar(); } /** @@ -192,11 +170,7 @@ abstract class ConnectionAbstract implements ConnectionInterface */ public function getSchemaGrammar() : SchemaGrammar { - if ($this->schemaGrammar === null) { - $this->schemaGrammar = new SchemaGrammar(); - } - - return $this->schemaGrammar; + return $this->schemaGrammar ?? new SchemaGrammar(); } /** diff --git a/DataStorage/Database/Connection/ConnectionFactory.php b/DataStorage/Database/Connection/ConnectionFactory.php index 3d89957ea..b526e1550 100644 --- a/DataStorage/Database/Connection/ConnectionFactory.php +++ b/DataStorage/Database/Connection/ConnectionFactory.php @@ -55,8 +55,12 @@ final class ConnectionFactory switch ($dbdata['db']) { case DatabaseType::MYSQL: return new MysqlConnection($dbdata); + case DatabaseType::PGSQL: + return new PostgresConnection($dbdata); case DatabaseType::SQLSRV: return new SqlServerConnection($dbdata); + case DatabaseType::SQLITE: + return new SQLiteConnection($dbdata); default: throw new \InvalidArgumentException('Database "' . $dbdata['db'] . '" is not supported.'); } diff --git a/DataStorage/Database/Connection/MysqlConnection.php b/DataStorage/Database/Connection/MysqlConnection.php index d18e6fa6f..a7817ef5b 100644 --- a/DataStorage/Database/Connection/MysqlConnection.php +++ b/DataStorage/Database/Connection/MysqlConnection.php @@ -58,7 +58,9 @@ final class MysqlConnection extends ConnectionAbstract { $this->dbdata = isset($dbdata) ? $dbdata : $this->dbdata; - if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password'])) { + if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password']) + || !DatabaseType::isValidValue($this->dbdata['db']) + ) { $this->status = DatabaseStatus::FAILURE; throw new InvalidConnectionConfigException((string) \json_encode($this->dbdata)); } diff --git a/DataStorage/Database/Connection/PostgresConnection.php b/DataStorage/Database/Connection/PostgresConnection.php index ae61b9338..77f53c000 100644 --- a/DataStorage/Database/Connection/PostgresConnection.php +++ b/DataStorage/Database/Connection/PostgresConnection.php @@ -57,7 +57,10 @@ final class PostgresConnection extends ConnectionAbstract { $this->dbdata = isset($dbdata) ? $dbdata : $this->dbdata; - if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password'])) { + if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password']) + || !DatabaseType::isValidValue($this->dbdata['db']) + ) { + $this->status = DatabaseStatus::FAILURE; throw new InvalidConnectionConfigException((string) \json_encode($this->dbdata)); } @@ -65,7 +68,7 @@ final class PostgresConnection extends ConnectionAbstract $this->prefix = $dbdata['prefix'] ?? ''; try { - $this->con = new \PDO($this->dbdata['db'] . ':host=' . $this->dbdata['host'] . ':' . $this->dbdata['port'] . ';dbname=' . $this->dbdata['database'] . ';charset=utf8', $this->dbdata['login'], $this->dbdata['password']); + $this->con = new \PDO($this->dbdata['db'] . ':host=' . $this->dbdata['host'] . ';port=' . $this->dbdata['port'] . ';dbname=' . $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password']); $this->con->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); $this->con->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); diff --git a/DataStorage/Database/Connection/SQLiteConnection.php b/DataStorage/Database/Connection/SQLiteConnection.php index 23374e332..2c8e67819 100644 --- a/DataStorage/Database/Connection/SQLiteConnection.php +++ b/DataStorage/Database/Connection/SQLiteConnection.php @@ -17,6 +17,8 @@ namespace phpOMS\DataStorage\Database\Connection; use phpOMS\DataStorage\Database\DatabaseStatus; use phpOMS\DataStorage\Database\DatabaseType; use phpOMS\DataStorage\Database\Query\Grammar\SQLiteGrammar; +use phpOMS\DataStorage\Database\Schema\Grammar\SQLiteGrammar as SQLiteSchemaGrammar; +use phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException; /** * Database handler. @@ -43,8 +45,9 @@ final class SQLiteConnection extends ConnectionAbstract */ public function __construct(array $dbdata) { - $this->type = DatabaseType::SQLITE; - $this->grammar = new SQLiteGrammar(); + $this->type = DatabaseType::SQLITE; + $this->grammar = new SQLiteGrammar(); + $this->schemaGrammar = new SQLiteSchemaGrammar(); $this->connect($dbdata); } @@ -53,13 +56,20 @@ final class SQLiteConnection extends ConnectionAbstract */ public function connect(array $dbdata = null) : void { - $this->close(); + $this->dbdata = isset($dbdata) ? $dbdata : $this->dbdata; - $this->dbdata = $dbdata !== null ? $dbdata : $this->dbdata; - $this->prefix = $dbdata['prefix']; + if (!isset($this->dbdata['db'], $this->dbdata['database']) + || !DatabaseType::isValidValue($this->dbdata['db']) + ) { + $this->status = DatabaseStatus::FAILURE; + throw new InvalidConnectionConfigException((string) \json_encode($this->dbdata)); + } + + $this->close(); + $this->prefix = $dbdata['prefix'] ?? ''; try { - $this->con = new \PDO($this->dbdata['db'] . ':' . $this->dbdata['path']); + $this->con = new \PDO($this->dbdata['db'] . ':' . $this->dbdata['database']); $this->con->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); $this->con->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); diff --git a/DataStorage/Database/DatabaseType.php b/DataStorage/Database/DatabaseType.php index 8fa1a2491..d76b9004f 100644 --- a/DataStorage/Database/DatabaseType.php +++ b/DataStorage/Database/DatabaseType.php @@ -28,9 +28,9 @@ use phpOMS\Stdlib\Base\Enum; */ abstract class DatabaseType extends Enum { - public const MYSQL = 'mysql'; /* MySQL */ - public const SQLITE = 'sqlite'; /* SQLITE */ - public const PGSQL = 'postgresql'; /* PostgreSQL */ - public const ORACLE = 3; /* Oracle */ - public const SQLSRV = 'mssql'; /* Microsoft SQL Server */ + public const MYSQL = 'mysql'; /* MySQL */ + public const SQLITE = 'sqlite'; /* SQLITE */ + public const PGSQL = 'pgsql'; /* PostgreSQL */ + public const SQLSRV = 'mssql'; /* Microsoft SQL Server */ + public const UNDEFINED = 'undefined'; } diff --git a/DataStorage/Database/Query/Grammar/Grammar.php b/DataStorage/Database/Query/Grammar/Grammar.php index 0421d6605..df695b32a 100644 --- a/DataStorage/Database/Query/Grammar/Grammar.php +++ b/DataStorage/Database/Query/Grammar/Grammar.php @@ -353,7 +353,7 @@ class Grammar extends GrammarAbstract } elseif (\is_bool($value)) { return (string) ((int) $value); } elseif (\is_float($value)) { - return (string) $value; + return \rtrim(\rtrim(\number_format($value, 5, '.', ''), '0'), '.'); } elseif ($value instanceof Column) { return $this->compileSystem($value->getColumn(), $prefix); } else { diff --git a/Math/Matrix/InverseType.php b/Math/Matrix/InverseType.php deleted file mode 100644 index 6f756f5a8..000000000 --- a/Math/Matrix/InverseType.php +++ /dev/null @@ -1,30 +0,0 @@ -m = $m; for ($i = 0; $i < $m; ++$i) { - $this->matrix[$i] = array_fill(0, $n, 0); + $this->matrix[$i] = \array_fill(0, $n, 0); } } @@ -675,15 +675,13 @@ class Matrix implements \ArrayAccess, \Iterator /** * Inverse matrix. * - * @param int $algorithm Algorithm for inversion - * * @return Matrix * * @throws InvalidDimensionException * * @since 1.0.0 */ - public function inverse(int $algorithm = InverseType::GAUSS_JORDAN) : Matrix + public function inverse() : Matrix { return $this->solve(new IdentityMatrix($this->m)); } diff --git a/Math/Matrix/SingularValueDecomposition.php b/Math/Matrix/SingularValueDecomposition.php index 14e113912..03f794606 100644 --- a/Math/Matrix/SingularValueDecomposition.php +++ b/Math/Matrix/SingularValueDecomposition.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace phpOMS\Math\Matrix; +use phpOMS\Math\Geometry\Shape\D2\Triangle; + /** * Singular value decomposition * @@ -64,6 +66,385 @@ final class SingularValueDecomposition */ private $n = 0; + public function __construct(Matrix $M) + { + $A = $M->toArray(); + $this->m = $M->getM(); + $this->n = $M->getN(); + $nu = \min($this->m, $this->n); + $e = []; + $work = []; + $nct = \min($this->m - 1, $this->n); + $nrt = \max(0, \min($this->n - 2, $this->m)); + $eps = 0.00001; + + for ($k = 0; $k < \max($nct, $nrt); ++$k) { + if ($k < $nct) { + $this->S[$k] = 0; + for ($i = $k; $i < $this->m; ++$i) { + $this->S[$k] = Triangle::getHypot($this->S[$k], $A[$i][$k]); + } + + if ($this->S[$k] != 0) { + if ($A[$k][$k] < 0.0) { + $this->S[$k] = -$this->S[$k]; + } + + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$k] /= $this->S[$k]; + } + + $A[$k][$k] += 1.0; + } + + $this->S[$k] = -$this->S[$k]; + } + + for ($j = $k + 1; $j < $this->n; ++$j) { + if ($k < $nct && $this->S[$k] != 0) { + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $A[$i][$k] * $A[$i][$j]; + } + + $t = -$t / $A[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $A[$i][$k]; + } + + $e[$j] = $A[$k][$j]; + } + } + + if ($k < $nct) { + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$k] = $A[$i][$k]; + } + } + + if ($k < $nrt) { + $e[$k] = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$k] = Triangle::getHypot($e[$k], $e[$i]); + } + + if ($e[$k] != 0) { + if ($e[$k + 1] < 0.0) { + $e[$k] = -$e[$k]; + } + + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$i] /= $e[$k]; + } + + $e[$k + 1] += 1.0; + } + + $e[$k] = -$e[$k]; + if ($k + 1 < $this->m && $e[$k] != 0) { + for ($i = $k + 1; $i < $this->m; ++$i) { + $work[$i] = 0.0; + } + + for ($j = $k + 1; $j < $this->n; ++$j) { + for ($i = $k + 1; $i < $this->m; ++$i) { + $work[$i] += $e[$j] * $A[$i][$j]; + } + } + + for ($j = $k + 1; $j < $this->n; ++$j) { + $t = -$e[$j] / $e[$k + 1]; + for ($i = $k + 1; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $work[$i]; + } + } + } + + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$k] = $e[$i]; + } + } + } + + $p = \min($this->n, $this->m + 1); + if ($nct < $this->n) { + $this->S[$nct] = $A[$nct][$nct]; + } + + if ($this->m < $p) { + $this->S[$p - 1] = 0.0; + } + + if ($nrt + 1 < $p) { + $e[$nrt] = $A[$nrt][$p - 1]; + } + + $e[$p - 1] = 0.0; + + for ($j = $nct; $j < $nu; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$j] = 0.0; + } + + $this->U[$j][$j] = 1.0; + } + + for ($k = $nct - 1; $k >= 0; --$k) { + if ($this->S[$k] != 0) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $this->U[$i][$k] * $this->U[$i][$j]; + } + + $t = -$t / $this->U[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$j] += $t * $this->U[$i][$k]; + } + } + + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$k] = -$this->U[$i][$k]; + } + + $this->U[$k][$k] = 1.0 + $this->U[$k][$k]; + for ($i = 0; $i < $k - 1; ++$i) { + $this->U[$i][$k] = 0.0; + } + } else { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$k] = 0.0; + } + + $this->U[$k][$k] = 1.0; + } + } + + for ($k = $this->n - 1; $k >= 0; --$k) { + if ($k < $nrt && $e[$k] != 0) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $t += $this->V[$i][$k] * $this->V[$i][$j]; + } + + $t = -$t / $this->V[$k + 1][$k]; + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$j] += $t * $this->V[$i][$k]; + } + } + } + + for ($i = 0; $i < $this->n; ++$i) { + $this->V[$i][$k] = 0.0; + } + + $this->V[$k][$k] = 1.0; + } + + $pp = $p - 1; + $iter = 0; + + while ($p > 0) { + for ($k = $p - 2; $k >= -1; --$k) { + if ($k === -1) { + break; + } + + if (\abs($e[$k]) <= $eps * (\abs($this->S[$k]) + \abs($this->S[$k + 1]))) { + $e[$k] = 0.0; + break; + } + } + + if ($k === $p - 2) { + $kase = 4; + } else { + for ($ks = $p - 1; $ks >= $k; --$ks) { + if ($ks === $k) { + break; + } + + $t = ($ks !== $p ? \abs($e[$ks]) : 0) + ($ks !== $k + 1 ? \abs($e[$ks - 1]) : 0); + if (\abs($this->S[$ks]) <= $eps * $t) { + $this->S[$ks] = 0.0; + break; + } + } + + if ($ks === $k) { + $kase = 3; + } elseif ($ks === $p - 1) { + $kase = 1; + } else { + $kase = 2; + $k = $ks; + } + } + ++$k; + + switch ($kase) { + case 1: + $f = $e[$p - 2]; + $e[$p - 2] = 0.0; + + for ($j = $p - 2; $j >= $k; --$j) { + $t = Triangle::getHypot($this->S[$j],$f); + $cs = $this->S[$j] / $t; + $sn = $f / $t; + $this->S[$j] = $t; + + if ($j !== $k) { + $f = -$sn * $e[$j - 1]; + $e[$j - 1] = $cs * $e[$j - 1]; + } + + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p - 1]; + $this->V[$i][$p - 1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p - 1]; + $this->V[$i][$j] = $t; + } + } + break; + case 2: + $f = $e[$k - 1]; + $e[$k - 1] = 0.0; + + for ($j = $k; $j < $p; ++$j) { + $t = Triangle::getHypot($this->S[$j], $f); + $cs = $this->S[$j] / $t; + $sn = $f / $t; + $this->S[$j] = $t; + $f = -$sn * $e[$j]; + $e[$j] = $cs * $e[$j]; + + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k - 1]; + $this->U[$i][$k - 1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k - 1]; + $this->U[$i][$j] = $t; + } + } + break; + case 3: + $scale = \max( + \max( + \max( + \max( + \abs($this->S[$p - 1]), + \abs($this->S[$p - 2]) + ), + \abs($e[$p - 2]) + ), + \abs($this->S[$k]) + ), + \abs($e[$k]) + ); + + $sp = $this->S[$p - 1] / $scale; + $spm1 = $this->S[$p - 2] / $scale; + $epm1 = $e[$p - 2] / $scale; + $sk = $this->S[$k] / $scale; + $ek = $e[$k] / $scale; + $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; + $c = ($sp * $epm1) * ($sp * $epm1); + $shift = 0.0; + + if ($b != 0 || $c != 0) { + $shift = sqrt($b * $b + $c); + if ($b < 0.0) { + $shift = -$shift; + } + + $shift = $c / ($b + $shift); + } + + $f = ($sk + $sp) * ($sk - $sp) + $shift; + $g = $sk * $ek; + + for ($j = $k; $j < $p - 1; ++$j) { + $t = Triangle::getHypot($f,$g); + $cs = $f / $t; + $sn = $g / $t; + + if ($j !== $k) { + $e[$j - 1] = $t; + } + + $f = $cs * $this->S[$j] + $sn * $e[$j]; + $e[$j] = $cs * $e[$j] - $sn * $this->S[$j]; + $g = $sn * $this->S[$j + 1]; + $this->S[$j + 1] = $cs * $this->S[$j + 1]; + + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j + 1]; + $this->V[$i][$j + 1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j + 1]; + $this->V[$i][$j] = $t; + } + + $t = Triangle::getHypot($f,$g); + $cs = $f / $t; + $sn = $g / $t; + $this->S[$j] = $t; + $f = $cs * $e[$j] + $sn * $this->S[$j + 1]; + $this->S[$j + 1] = -$sn * $e[$j] + $cs * $this->S[$j + 1]; + $g = $sn * $e[$j + 1]; + $e[$j + 1] = $cs * $e[$j + 1]; + + if ($j < $this->m - 1) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j + 1]; + $this->U[$i][$j + 1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j + 1]; + $this->U[$i][$j] = $t; + } + } + } + + $e[$p - 2] = $f; + $iter = $iter + 1; + break; + case 4: + if ($this->S[$k] <= 0.0) { + $this->S[$k] = ($this->S[$k] < 0.0 ? -$this->S[$k] : 0.0); + + for ($i = 0; $i <= $pp; ++$i) { + $this->V[$i][$k] = -$this->V[$i][$k]; + } + } + + while ($k < $pp) { + if ($this->S[$k] >= $this->S[$k + 1]) { + break; + } + + $t = $this->S[$k]; + $this->S[$k] = $this->S[$k + 1]; + $this->S[$k + 1] = $t; + + if ($k < $this->n - 1) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $this->V[$i][$k + 1]; + $this->V[$i][$k + 1] = $this->V[$i][$k]; + $this->V[$i][$k] = $t; + } + } + + if ($k < $this->m - 1) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $this->U[$i][$k + 1]; + $this->U[$i][$k + 1] = $this->U[$i][$k]; + $this->U[$i][$k] = $t; + } + } + ++$k; + } + + $iter = 0; + --$p; + break; + } + } + } + public function getU() : Matrix { $matrix = new Matrix(); @@ -87,9 +468,9 @@ final class SingularValueDecomposition for ($j = 0; $j < $this->n; ++$j) { $S[$i][$j] = 0.0; } - $S[$i][$i] = $this->s[$i]; + $S[$i][$i] = $this->S[$i]; } - + $matrix = new Matrix(); $matrix->setMatrix($this->V); diff --git a/Uri/Argument.php b/Uri/Argument.php index 435e4ada5..68b7861d9 100644 --- a/Uri/Argument.php +++ b/Uri/Argument.php @@ -30,7 +30,7 @@ use phpOMS\Utils\StringUtils; */ final class Argument implements UriInterface { - + /** * Root path. * diff --git a/Utils/Converter/File.php b/Utils/Converter/File.php index cf5e9fa64..8303c2d5e 100644 --- a/Utils/Converter/File.php +++ b/Utils/Converter/File.php @@ -38,42 +38,46 @@ class File /** * Get file size string. * - * @param int $bytes Amount of bytes + * @param int $bytes Amount of bytes + * @param string $decimal Decimal char + * @param string $thousands Thousands char * * @return string * * @since 1.0.0 */ - public static function byteSizeToString(int $bytes) : string + public static function byteSizeToString(int $bytes, string $decimal = '.', string $thousands = ',') : string { if ($bytes < 1000) { return $bytes . 'b'; } elseif ($bytes > 999 && $bytes < 1000000) { - return ((float) number_format($bytes / 1000, 1)) . 'kb'; + return \rtrim(\rtrim(\number_format($bytes / 1000, 1, $decimal, $thousands), '0'), $decimal) . 'kb'; } elseif ($bytes > 999999 && $bytes < 1000000000) { - return ((float) number_format($bytes / 1000000, 1)) . 'mb'; + return \rtrim(\rtrim(\number_format($bytes / 1000000, 1, $decimal, $thousands), '0'), $decimal) . 'mb'; } else { - return ((float) number_format($bytes / 1000000000, 1)) . 'gb'; + return \rtrim(\rtrim(\number_format($bytes / 1000000000, 1, $decimal, $thousands), '0'), $decimal) . 'gb'; } } /** * Get file size string. * - * @param int $kilobytes Amount of kilobytes + * @param int $kilobytes Amount of kilobytes + * @param string $decimal Decimal char + * @param string $thousands Thousands char * * @return string * * @since 1.0.0 */ - public static function kilobyteSizeToString(int $kilobytes) : string + public static function kilobyteSizeToString(int $kilobytes, string $decimal = '.', string $thousands = ',') : string { if ($kilobytes < 1000) { - return ((float) number_format($kilobytes, 1)) . 'kb'; + return \rtrim(\rtrim(\number_format($kilobytes, 1, $decimal, $thousands), '0'), $decimal) . 'kb'; } elseif ($kilobytes > 999 && $kilobytes < 1000000) { - return ((float) number_format($kilobytes / 1000, 1)) . 'mb'; + return \rtrim(\rtrim(\number_format($kilobytes / 1000, 1, $decimal, $thousands), '0'), $decimal) . 'mb'; } else { - return ((float) number_format($kilobytes / 1000000, 1)) . 'gb'; + return \rtrim(\rtrim(\number_format($kilobytes / 1000000, 1, $decimal, $thousands), '0'), $decimal) . 'gb'; } } } diff --git a/Utils/Parser/Php/ArrayParser.php b/Utils/Parser/Php/ArrayParser.php index 9438a77d8..828fff8e6 100644 --- a/Utils/Parser/Php/ArrayParser.php +++ b/Utils/Parser/Php/ArrayParser.php @@ -45,10 +45,10 @@ class ArrayParser $key = '\'' . \str_replace('\'', '\\\'', $key) . '\''; } - $stringify .= str_repeat(' ', $depth * 4) . $key . ' => ' . self::parseVariable($val, $depth + 1) . ',' . "\n"; + $stringify .= \str_repeat(' ', $depth * 4) . $key . ' => ' . self::parseVariable($val, $depth + 1) . ',' . "\n"; } - return $stringify . str_repeat(' ', ($depth - 1) * 4) . ']'; + return $stringify . \str_repeat(' ', ($depth - 1) * 4) . ']'; } /** @@ -71,6 +71,8 @@ class ArrayParser return $value ? 'true' : 'false'; } elseif ($value === null) { return 'null'; + } elseif (\is_float($value)) { + return \rtrim(\rtrim(\number_format($value, 5, '.', ''), '0'), '.'); } elseif (\is_scalar($value)) { return (string) $value; } elseif ($value instanceof \Serializable) { diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index a50130af4..a4ec2c4b0 100644 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -79,6 +79,168 @@ $CONFIG = [ 'weight' => 1000, /* db table prefix */ ], ], + 'postgresql' => [ + 'admin' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'pgsql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + ], + 'sqlite' => [ + 'admin' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'sqlite', /* db type */ + 'database' => __DIR__ . '/test.sqlite', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + ], + 'mssql' => [ + 'admin' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'insert' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'select' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'update' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'delete' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + 'schema' => [ + 'db' => 'mssql', /* db type */ + 'host' => '127.0.0.1', /* db host address */ + 'port' => '5432', /* db host port */ + 'login' => 'postgres', /* db login name */ + 'password' => '', /* db login password */ + 'database' => 'oms', /* db name */ + 'prefix' => 'oms_', /* db table prefix */ + 'weight' => 1000, /* db table prefix */ + ], + ], ], ], 'cache' => [ @@ -125,6 +287,15 @@ $db->exec('DROP DATABASE IF EXISTS ' . $CONFIG['db']['core']['masters']['admin' $db->exec('CREATE DATABASE IF NOT EXISTS ' . $CONFIG['db']['core']['masters']['admin']['database']); $db = null; +$db = new \PDO($CONFIG['db']['core']['postgresql']['admin']['db'] . ':host=' . + $CONFIG['db']['core']['postgresql']['admin']['host'], + $CONFIG['db']['core']['postgresql']['admin']['login'], + $CONFIG['db']['core']['postgresql']['admin']['password'] +); +$db->exec('DROP DATABASE ' . $CONFIG['db']['core']['postgresql']['admin']['database']); +$db->exec('CREATE DATABASE ' . $CONFIG['db']['core']['postgresql']['admin']['database']); +$db = null; + $httpSession = new HttpSession(); $GLOBALS['session'] = $httpSession; diff --git a/tests/DataStorage/Database/Connection/ConnectionFactoryTest.php b/tests/DataStorage/Database/Connection/ConnectionFactoryTest.php index 805ce5c34..d17b9f688 100644 --- a/tests/DataStorage/Database/Connection/ConnectionFactoryTest.php +++ b/tests/DataStorage/Database/Connection/ConnectionFactoryTest.php @@ -15,17 +15,76 @@ namespace phpOMS\tests\DataStorage\Database\Connection; use phpOMS\DataStorage\Database\Connection\ConnectionFactory; use phpOMS\DataStorage\Database\Connection\MysqlConnection; +use phpOMS\DataStorage\Database\Connection\PostgresConnection; +use phpOMS\DataStorage\Database\Connection\SqlServerConnection; +use phpOMS\DataStorage\Database\Connection\SQLiteConnection; class ConnectionFactoryTest extends \PHPUnit\Framework\TestCase { - public function testCreate() + public function testCreateMysql() { + if (!extension_loaded('pdo_mysql')) { + $this->markTestSkipped( + 'The Mysql extension is not available.' + ); + + return; + } + self::assertInstanceOf( MysqlConnection::class, ConnectionFactory::create($GLOBALS['CONFIG']['db']['core']['masters']['admin']) ); } + public function testCreatePostgres() + { + if (!extension_loaded('pdo_pgsql')) { + $this->markTestSkipped( + 'The Postresql extension is not available.' + ); + + return; + } + + self::assertInstanceOf( + PostgresConnection::class, + ConnectionFactory::create($GLOBALS['CONFIG']['db']['core']['postgresql']['admin']) + ); + } + + public function testCreateSqlsrv() + { + if (!extension_loaded('pdo_sqlsrv')) { + $this->markTestSkipped( + 'The Sqlsrv extension is not available.' + ); + + return; + } + + self::assertInstanceOf( + SqlServerConnection::class, + ConnectionFactory::create($GLOBALS['CONFIG']['db']['core']['mssql']['admin']) + ); + } + + public function testCreateSqlite() + { + if (!extension_loaded('pdo_sqlite')) { + $this->markTestSkipped( + 'The SQLite extension is not available.' + ); + + return; + } + + self::assertInstanceOf( + SQLiteConnection::class, + ConnectionFactory::create($GLOBALS['CONFIG']['db']['core']['sqlite']['admin']) + ); + } + /** * @expectedException \InvalidArgumentException */ diff --git a/tests/DataStorage/Database/Connection/MysqlConnectionTest.php b/tests/DataStorage/Database/Connection/MysqlConnectionTest.php index 26a2c30d0..272246cb2 100644 --- a/tests/DataStorage/Database/Connection/MysqlConnectionTest.php +++ b/tests/DataStorage/Database/Connection/MysqlConnectionTest.php @@ -18,6 +18,15 @@ use phpOMS\DataStorage\Database\DatabaseStatus; class MysqlConnectionTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('pdo_mysql')) { + $this->markTestSkipped( + 'The Mysql extension is not available.' + ); + } + } + public function testConnect() { $mysql = new MysqlConnection($GLOBALS['CONFIG']['db']['core']['masters']['admin']); @@ -98,11 +107,22 @@ class MysqlConnectionTest extends \PHPUnit\Framework\TestCase /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ - public function testInvalidDatabaseName() + public function testInvalidDatabaseTypeName() { $db = $GLOBALS['CONFIG']['db']['core']['masters']['admin']; $db['db'] = 'invalid'; $mysql = new MysqlConnection($db); } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabaseName() + { + $db = $GLOBALS['CONFIG']['db']['core']['masters']['admin']; + $db['database'] = 'invalid'; + + $mysql = new MysqlConnection($db); + } } diff --git a/tests/DataStorage/Database/Connection/NullConnectionTest.php b/tests/DataStorage/Database/Connection/NullConnectionTest.php new file mode 100644 index 000000000..fb83f56a0 --- /dev/null +++ b/tests/DataStorage/Database/Connection/NullConnectionTest.php @@ -0,0 +1,29 @@ +connect(); + + self::assertEquals(DatabaseType::UNDEFINED, $null->getType()); + } +} \ No newline at end of file diff --git a/tests/DataStorage/Database/Connection/PostgresConnectionTest.php b/tests/DataStorage/Database/Connection/PostgresConnectionTest.php index 6ba8e44dd..88746a66a 100644 --- a/tests/DataStorage/Database/Connection/PostgresConnectionTest.php +++ b/tests/DataStorage/Database/Connection/PostgresConnectionTest.php @@ -17,76 +17,103 @@ use phpOMS\DataStorage\Database\DatabaseStatus; class PostgresConnectionTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('pdo_pgsql')) { + $this->markTestSkipped( + 'The Postresql extension is not available.' + ); + } + } + public function testConnect() { - $psql = new PostgresConnection($GLOBALS['CONFIG']['db']['core']['postgres']['admin']); + $psql = new PostgresConnection($GLOBALS['CONFIG']['db']['core']['postgresql']['admin']); self::assertEquals(DatabaseStatus::OK, $psql->getStatus()); - self::assertEquals($GLOBALS['CONFIG']['db']['core']['postgres']['admin']['database'], $psql->getDatabase()); - self::assertEquals($GLOBALS['CONFIG']['db']['core']['postgres']['admin']['host'], $psql->getHost()); - self::assertEquals((int) $GLOBALS['CONFIG']['db']['core']['postgres']['admin']['port'], $psql->getPort()); + self::assertEquals($GLOBALS['CONFIG']['db']['core']['postgresql']['admin']['database'], $psql->getDatabase()); + self::assertEquals($GLOBALS['CONFIG']['db']['core']['postgresql']['admin']['host'], $psql->getHost()); + self::assertEquals((int) $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']['port'], $psql->getPort()); self::assertInstanceOf('\phpOMS\DataStorage\Database\Query\Grammar\PostgresGrammar', $psql->getGrammar()); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ public function testInvalidDatabaseType() { - $db = $GLOBALS['CONFIG']['db']['core']['postgres']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; unset($db['db']); $psql = new PostgresConnection($db); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ public function testInvalidHost() { - $db = $GLOBALS['CONFIG']['db']['core']['postgres']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; unset($db['host']); $psql = new PostgresConnection($db); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ public function testInvalidPort() { - $db = $GLOBALS['CONFIG']['db']['core']['postgres']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; unset($db['port']); $psql = new PostgresConnection($db); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ public function testInvalidDatabase() { - $db = $GLOBALS['CONFIG']['db']['core']['masters']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; unset($db['database']); $psql = new PostgresConnection($db); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ public function testInvalidLogin() { - $db = $GLOBALS['CONFIG']['db']['core']['postgres']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; unset($db['login']); $psql = new PostgresConnection($db); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ public function testInvalidPassword() { - $db = $GLOBALS['CONFIG']['db']['core']['postgres']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; unset($db['password']); $psql = new PostgresConnection($db); } + /** * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException */ - public function testInvalidDatabaseName() + public function testInvalidDatabaseTypeName() { - $db = $GLOBALS['CONFIG']['db']['core']['postgres']['admin']; + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; $db['db'] = 'invalid'; $psql = new PostgresConnection($db); } + + /** + * todo: apparently this doesn't throw an exception in postgresql?! + */ + public function testInvalidDatabaseName() + { + $db = $GLOBALS['CONFIG']['db']['core']['postgresql']['admin']; + $db['database'] = 'invalid'; + + $mysql = new PostgresConnection($db); + } } diff --git a/tests/DataStorage/Database/Connection/SQLiteConnectionTest.php b/tests/DataStorage/Database/Connection/SQLiteConnectionTest.php index 77fb14692..7b95355b8 100644 --- a/tests/DataStorage/Database/Connection/SQLiteConnectionTest.php +++ b/tests/DataStorage/Database/Connection/SQLiteConnectionTest.php @@ -10,15 +10,47 @@ * @version 1.0.0 * @link http://website.orange-management.de */ - namespace phpOMS\tests\DataStorage\Database\Connection; use phpOMS\DataStorage\Database\Connection\SQLiteConnection; +use phpOMS\DataStorage\Database\DatabaseStatus; class SQLiteConnectionTest extends \PHPUnit\Framework\TestCase { - public function testPlaceholder() + protected function setUp() { - self::markTestIncomplete(); + if (!extension_loaded('pdo_sqlite')) { + $this->markTestSkipped( + 'The SQLite extension is not available.' + ); + } + } + + public function testConnect() + { + $sqlite = new SQLiteConnection($GLOBALS['CONFIG']['db']['core']['sqlite']['admin']); + self::assertEquals(DatabaseStatus::OK, $sqlite->getStatus()); + self::assertEquals($GLOBALS['CONFIG']['db']['core']['sqlite']['admin']['database'], $sqlite->getDatabase()); + self::assertInstanceOf('\phpOMS\DataStorage\Database\Query\Grammar\SQLiteGrammar', $sqlite->getGrammar()); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabaseType() + { + $db = $GLOBALS['CONFIG']['db']['core']['sqlite']['admin']; + unset($db['db']); + $sqlite = new SQLiteConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabase() + { + $db = $GLOBALS['CONFIG']['db']['core']['sqlite']['admin']; + unset($db['database']); + $sqlite = new SQLiteConnection($db); } } diff --git a/tests/DataStorage/Database/Connection/SqlServerConnectionTest.php b/tests/DataStorage/Database/Connection/SqlServerConnectionTest.php index eb1e6beed..7b12ad662 100644 --- a/tests/DataStorage/Database/Connection/SqlServerConnectionTest.php +++ b/tests/DataStorage/Database/Connection/SqlServerConnectionTest.php @@ -17,8 +17,103 @@ use phpOMS\DataStorage\Database\Connection\SqlServerConnection; class SqlServerConnectionTest extends \PHPUnit\Framework\TestCase { - public function testPlaceholder() + protected function setUp() { - self::markTestIncomplete(); + if (!extension_loaded('pdo_sqlsrv')) { + $this->markTestSkipped( + 'The Sqlsrv extension is not available.' + ); + } + } + + public function testConnect() + { + $psql = new SqlServerConnection($GLOBALS['CONFIG']['db']['core']['mssql']['admin']); + self::assertEquals(DatabaseStatus::OK, $psql->getStatus()); + self::assertEquals($GLOBALS['CONFIG']['db']['core']['mssql']['admin']['database'], $psql->getDatabase()); + self::assertEquals($GLOBALS['CONFIG']['db']['core']['mssql']['admin']['host'], $psql->getHost()); + self::assertEquals((int) $GLOBALS['CONFIG']['db']['core']['mssql']['admin']['port'], $psql->getPort()); + self::assertInstanceOf('\phpOMS\DataStorage\Database\Query\Grammar\SqlServerGrammar', $psql->getGrammar()); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabaseType() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + unset($db['db']); + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidHost() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + unset($db['host']); + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidPort() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + unset($db['port']); + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabase() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + unset($db['database']); + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidLogin() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + unset($db['login']); + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidPassword() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + unset($db['password']); + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabaseTypeName() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + $db['db'] = 'invalid'; + $psql = new SqlServerConnection($db); + } + + /** + * @expectedException \phpOMS\DataStorage\Database\Exception\InvalidConnectionConfigException + */ + public function testInvalidDatabaseName() + { + $db = $GLOBALS['CONFIG']['db']['core']['mssql']['admin']; + $db['database'] = 'invalid'; + + $mysql = new SqlServerConnection($db); } } diff --git a/tests/DataStorage/Database/DatabaseTypeTest.php b/tests/DataStorage/Database/DatabaseTypeTest.php index 81c929dc0..5718a3ca1 100644 --- a/tests/DataStorage/Database/DatabaseTypeTest.php +++ b/tests/DataStorage/Database/DatabaseTypeTest.php @@ -21,7 +21,9 @@ class DatabaseTypeTest extends \PHPUnit\Framework\TestCase { self::assertEquals(5, \count(DatabaseType::getConstants())); self::assertEquals('mysql', DatabaseType::MYSQL); + self::assertEquals('pgsql', DatabaseType::PGSQL); self::assertEquals('sqlite', DatabaseType::SQLITE); self::assertEquals('mssql', DatabaseType::SQLSRV); + self::assertEquals('undefined', DatabaseType::UNDEFINED); } } diff --git a/tests/Localization/Defaults/CityMapperTest.php b/tests/Localization/Defaults/CityMapperTest.php index 16007cb58..875456be5 100644 --- a/tests/Localization/Defaults/CityMapperTest.php +++ b/tests/Localization/Defaults/CityMapperTest.php @@ -27,7 +27,7 @@ class CityMapperTest extends \PHPUnit\Framework\TestCase $con = new SqliteConnection([ 'prefix' => '', 'db' => 'sqlite', - 'path' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), + 'database' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), ]); DataMapperAbstract::setConnection($con); diff --git a/tests/Localization/Defaults/CountryMapperTest.php b/tests/Localization/Defaults/CountryMapperTest.php index 8d9436f62..4b6a8e65b 100644 --- a/tests/Localization/Defaults/CountryMapperTest.php +++ b/tests/Localization/Defaults/CountryMapperTest.php @@ -27,7 +27,7 @@ class CountryMapperTest extends \PHPUnit\Framework\TestCase $con = new SqliteConnection([ 'prefix' => '', 'db' => 'sqlite', - 'path' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), + 'database' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), ]); DataMapperAbstract::setConnection($con); diff --git a/tests/Localization/Defaults/CurrencyMapperTest.php b/tests/Localization/Defaults/CurrencyMapperTest.php index fac421d58..dd8a62114 100644 --- a/tests/Localization/Defaults/CurrencyMapperTest.php +++ b/tests/Localization/Defaults/CurrencyMapperTest.php @@ -27,7 +27,7 @@ class CurrencyMapperTest extends \PHPUnit\Framework\TestCase $con = new SqliteConnection([ 'prefix' => '', 'db' => 'sqlite', - 'path' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), + 'database' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), ]); DataMapperAbstract::setConnection($con); diff --git a/tests/Localization/Defaults/IbanMapperTest.php b/tests/Localization/Defaults/IbanMapperTest.php index 9049346cc..523622b05 100644 --- a/tests/Localization/Defaults/IbanMapperTest.php +++ b/tests/Localization/Defaults/IbanMapperTest.php @@ -27,7 +27,7 @@ class IbanMapperTest extends \PHPUnit\Framework\TestCase $con = new SqliteConnection([ 'prefix' => '', 'db' => 'sqlite', - 'path' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), + 'database' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), ]); DataMapperAbstract::setConnection($con); diff --git a/tests/Localization/Defaults/LanguageMapperTest.php b/tests/Localization/Defaults/LanguageMapperTest.php index 59000abaa..84bee243d 100644 --- a/tests/Localization/Defaults/LanguageMapperTest.php +++ b/tests/Localization/Defaults/LanguageMapperTest.php @@ -27,7 +27,7 @@ class LanguageMapperTest extends \PHPUnit\Framework\TestCase $con = new SqliteConnection([ 'prefix' => '', 'db' => 'sqlite', - 'path' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), + 'database' => realpath(__DIR__ . '/../../../Localization/Defaults/localization.sqlite'), ]); DataMapperAbstract::setConnection($con); diff --git a/tests/Math/Matrix/InverseTypeTest.php b/tests/Math/Matrix/InverseTypeTest.php deleted file mode 100644 index e8f7d6460..000000000 --- a/tests/Math/Matrix/InverseTypeTest.php +++ /dev/null @@ -1,27 +0,0 @@ -setMatrix([ + [2, -2, 1], + [5, 1, 4], + ]); + + $svd = new SingularValueDecomposition($A); + + self::assertEquals(2, $svd->rank()); + + self::assertEquals([ + [-0.3092, -0.9510], + [-0.9510, -0.3092], + ], $svd->getU()->toArray(), '', 0.2); + + self::assertEquals([ + [6.7751, 0, 0], + [0, 2.2578, 0], + [0, 0, 0], + ], $svd->getS()->toArray(), '', 0.2); + + self::assertEquals([ + [-0.7931, -0.1576, -0.5883], + [-0.0491, 0.9794, -0.1961], + [-0.6071, 0.1267, 0.7845], + ], $svd->getV()->toArray(), '', 0.2); } } diff --git a/tests/Utils/Barcode/C128aTest.php b/tests/Utils/Barcode/C128aTest.php index 6f556ea5d..378eae3f4 100644 --- a/tests/Utils/Barcode/C128aTest.php +++ b/tests/Utils/Barcode/C128aTest.php @@ -17,6 +17,15 @@ use phpOMS\Utils\Barcode\C128a; class C128aTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped( + 'The GD extension is not available.' + ); + } + } + public function testImage() { $path = __DIR__ . '/c128a.png'; diff --git a/tests/Utils/Barcode/C128bTest.php b/tests/Utils/Barcode/C128bTest.php index 74c8c9867..647430362 100644 --- a/tests/Utils/Barcode/C128bTest.php +++ b/tests/Utils/Barcode/C128bTest.php @@ -17,6 +17,15 @@ use phpOMS\Utils\Barcode\C128b; class C128bTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped( + 'The GD extension is not available.' + ); + } + } + public function testImage() { $path = __DIR__ . '/c128b.png'; diff --git a/tests/Utils/Barcode/C128cTest.php b/tests/Utils/Barcode/C128cTest.php index 5759e56ca..769f1e50d 100644 --- a/tests/Utils/Barcode/C128cTest.php +++ b/tests/Utils/Barcode/C128cTest.php @@ -17,6 +17,15 @@ use phpOMS\Utils\Barcode\C128c; class C128cTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped( + 'The GD extension is not available.' + ); + } + } + public function testImage() { $path = __DIR__ . '/c128c.png'; diff --git a/tests/Utils/Barcode/C25Test.php b/tests/Utils/Barcode/C25Test.php index fe5156494..279d6bc62 100644 --- a/tests/Utils/Barcode/C25Test.php +++ b/tests/Utils/Barcode/C25Test.php @@ -17,6 +17,15 @@ use phpOMS\Utils\Barcode\C25; class C25Test extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped( + 'The GD extension is not available.' + ); + } + } + public function testImage() { $path = __DIR__ . '/c25.png'; diff --git a/tests/Utils/Barcode/C39Test.php b/tests/Utils/Barcode/C39Test.php index 1f9dc1ad8..33b14df32 100644 --- a/tests/Utils/Barcode/C39Test.php +++ b/tests/Utils/Barcode/C39Test.php @@ -17,6 +17,15 @@ use phpOMS\Utils\Barcode\C39; class C39Test extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped( + 'The GD extension is not available.' + ); + } + } + public function testImage() { $path = __DIR__ . '/c39.png'; diff --git a/tests/Utils/Barcode/CodebarTest.php b/tests/Utils/Barcode/CodebarTest.php index 87074f7f2..25d43aae7 100644 --- a/tests/Utils/Barcode/CodebarTest.php +++ b/tests/Utils/Barcode/CodebarTest.php @@ -17,6 +17,15 @@ use phpOMS\Utils\Barcode\Codebar; class CodebarTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped( + 'The GD extension is not available.' + ); + } + } + public function testImage() { $path = __DIR__ . '/codebar.png'; diff --git a/tests/Utils/IO/Zip/ZipTest.php b/tests/Utils/IO/Zip/ZipTest.php index 9a1ad6cbc..f80345ebc 100644 --- a/tests/Utils/IO/Zip/ZipTest.php +++ b/tests/Utils/IO/Zip/ZipTest.php @@ -17,6 +17,15 @@ use phpOMS\Utils\IO\Zip\Zip; class ZipTest extends \PHPUnit\Framework\TestCase { + protected function setUp() + { + if (!extension_loaded('zip')) { + $this->markTestSkipped( + 'The ZIP extension is not available.' + ); + } + } + public function testZip() { self::assertTrue(Zip::pack(