keboola/php-datatypes

View on GitHub
src/Definition/MySQL.php

Summary

Maintainability
F
3 days
Test Coverage
File `MySQL.php` has 257 lines of code (exceeds 250 allowed). Consider refactoring.
<?php
 
declare(strict_types=1);
 
namespace Keboola\Datatype\Definition;
 
use Keboola\Datatype\Definition\Exception\InvalidLengthException;
use Keboola\Datatype\Definition\Exception\InvalidOptionException;
use Keboola\Datatype\Definition\Exception\InvalidTypeException;
use LogicException;
 
The class MySQL has an overall complexity of 100 which is very high. The configured complexity threshold is 50.
class MySQL extends Common
{
public const TYPES = [
'INTEGER', 'INT',
'TINYINT', 'SMALLINT', 'MEDIUMINT', 'BIGINT',
'DECIMAL', 'DEC', 'FIXED', 'NUMERIC',
'FLOAT', 'DOUBLE PRECISION', 'REAL', 'DOUBLE',
'BIT',
'DATE',
'TIME',
'DATETIME',
'TIMESTAMP',
'YEAR',
'CHAR',
'VARCHAR',
'BLOB',
'TEXT',
];
 
/**
* Snowflake constructor.
*
* @param array{
* length?:string|null|array,
* nullable?:bool,
* default?:string|null
* } $options
* @throws InvalidOptionException
*/
public function __construct(string $type, array $options = [])
{
$this->validateType($type);
$options['length'] = $this->processLength($options);
$this->validateLength($type, $options['length'] ?? null);
$diff = array_diff(array_keys($options), ['length', 'nullable', 'default']);
if ($diff !== []) {
throw new InvalidOptionException("Option '{$diff[0]}' not supported");
}
parent::__construct($type, $options);
}
 
public function getSQLDefinition(): string
{
$definition = $this->getType();
if ($this->getLength() && $this->getLength() !== '') {
$definition .= '(' . $this->getLength() . ')';
}
if (!$this->isNullable()) {
$definition .= ' NOT NULL';
}
return $definition;
}
 
/**
* @return array{type:string,length:string|null,nullable:bool}
*/
public function toArray(): array
{
return [
'type' => $this->getType(),
'length' => $this->getLength(),
'nullable' => $this->isNullable(),
];
}
 
/**
* @param array{length?: string|null|array} $options
* @throws InvalidOptionException
*/
private function processLength(array $options): ?string
{
if (!isset($options['length'])) {
return null;
}
if (is_array($options['length'])) {
return $this->getLengthFromArray($options['length']);
}
return (string) $options['length'];
}
 
/**
* @param array{
* character_maximum?:string|int|null,
* numeric_precision?:string|int|null,
* numeric_scale?:string|int|null
* } $lengthOptions
* @throws InvalidOptionException
*/
Identical blocks of code found in 3 locations. Consider refactoring.
private function getLengthFromArray(array $lengthOptions): ?string
{
$expectedOptions = ['character_maximum', 'numeric_precision', 'numeric_scale'];
$diff = array_diff(array_keys($lengthOptions), $expectedOptions);
if ($diff !== []) {
throw new InvalidOptionException(sprintf('Length option "%s" not supported', $diff[0]));
}
 
$characterMaximum = $lengthOptions['character_maximum'] ?? null;
$numericPrecision = $lengthOptions['numeric_precision'] ?? null;
$numericScale = $lengthOptions['numeric_scale'] ?? null;
 
if (!is_null($characterMaximum)) {
return (string) $characterMaximum;
}
if (!is_null($numericPrecision) && !is_null($numericScale)) {
return $numericPrecision . ',' . $numericScale;
}
return $numericPrecision === null ? null : (string) $numericPrecision;
}
 
/**
* @throws InvalidTypeException
*/
private function validateType(string $type): void
{
if (!in_array(strtoupper($type), $this::TYPES)) {
throw new InvalidTypeException("'{$type}' is not a valid type");
}
}
 
/**
* @param null|int|string $length
* @throws InvalidLengthException
*/
//phpcs:ignore SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
Function `validateLength` has a Cognitive Complexity of 67 (exceeds 5 allowed). Consider refactoring.
Method `validateLength` has 124 lines of code (exceeds 25 allowed). Consider refactoring.
The method validateLength() has an NPath complexity of 1888. The configured NPath complexity threshold is 200.
The method validateLength() has 132 lines of code. Current threshold is set to 100. Avoid really long methods.
The method validateLength() has a Cyclomatic Complexity of 63. The configured cyclomatic complexity threshold is 10.
private function validateLength(string $type, $length = null): void
{
$valid = true;
switch (strtoupper($type)) {
case 'CHAR':
if (is_null($length) || $length === '') {
break;
}
if (!is_numeric($length)) {
$valid = false;
break;
}
if ((int) $length <= 0 || (int) $length > 255) {
$valid = false;
break;
}
break;
case 'VARCHAR':
if (is_null($length) || $length === '' || !is_numeric($length)) {
$valid = false;
break;
}
if ((int) $length <= 0 || (int) $length > 4_294_967_295) {
$valid = false;
break;
}
break;
 
case 'INT':
case 'INTEGER':
case 'TINYINT':
case 'SMALLINT':
case 'MEDIUMINT':
case 'BIGINT':
if (is_null($length) || $length === '') {
break;
}
if (!is_numeric($length)) {
$valid = false;
break;
}
if ((int) $length <= 0 || (int) $length > 255) {
$valid = false;
break;
}
break;
 
case 'DOUBLE PRECISION':
case 'REAL':
case 'DOUBLE':
case 'FLOAT':
if (is_null($length) || $length === '') {
break;
}
$parts = explode(',', (string) $length);
if (!in_array(count($parts), [1, 2])) {
$valid = false;
break;
}
if (!is_numeric($parts[0])) {
$valid = false;
break;
}
if (isset($parts[1]) && !is_numeric($parts[1])) {
$valid = false;
break;
}
if ((int) $parts[0] <= 0 || (int) $parts[0] > 255) {
$valid = false;
break;
}
if (isset($parts[1]) && ((int) $parts[1] >= (int) $parts[0] || (int) $parts[1] > 30)) {
$valid = false;
break;
}
break;
 
case 'DECIMAL':
case 'DEC':
case 'FIXED':
case 'NUMERIC':
if (is_null($length) || $length === '') {
break;
}
$parts = explode(',', (string) $length);
if (!in_array(count($parts), [1, 2])) {
$valid = false;
break;
}
if (!is_numeric($parts[0])) {
$valid = false;
break;
}
if (isset($parts[1]) && !is_numeric($parts[1])) {
$valid = false;
break;
}
if ((int) $parts[0] <= 0 || (int) $parts[0] > 65) {
$valid = false;
break;
}
if (isset($parts[1]) && ((int) $parts[1] > (int) $parts[0] || (int) $parts[1] > 30)) {
$valid = false;
break;
}
break;
 
case 'TIME':
if (is_null($length) || $length === '') {
break;
}
if (!is_numeric($length)) {
$valid = false;
break;
}
if ((int) $length < 0 || (int) $length > 6) {
$valid = false;
break;
}
break;
 
default:
if (!is_null($length) && $length !== '') {
$valid = false;
break;
}
break;
}
if (!$valid) {
throw new InvalidLengthException("'{$length}' is not valid length for {$type}");
}
}
 
Method `getBasetype` has 33 lines of code (exceeds 25 allowed). Consider refactoring.
Function `getBasetype` has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
The method getBasetype() has a Cyclomatic Complexity of 18. The configured cyclomatic complexity threshold is 10.
public function getBasetype(): string
{
switch (strtoupper($this->type)) {
case 'INT':
case 'INTEGER':
case 'BIGINT':
case 'SMALLINT':
case 'TINYINT':
case 'MEDIUMINT':
$basetype = BaseType::INTEGER;
break;
case 'NUMERIC':
case 'DECIMAL':
case 'DEC':
case 'FIXED':
$basetype = BaseType::NUMERIC;
break;
case 'FLOAT':
case 'DOUBLE PRECISION':
case 'REAL':
case 'DOUBLE':
$basetype = BaseType::FLOAT;
break;
case 'DATE':
$basetype = BaseType::DATE;
break;
case 'DATETIME':
case 'TIMESTAMP':
$basetype = BaseType::TIMESTAMP;
break;
default:
$basetype = BaseType::STRING;
break;
}
return $basetype;
}
 
Avoid unused parameters such as '$basetype'.
public static function getTypeByBasetype(string $basetype): string
{
throw new LogicException('Method is not implemented yet.');
}
}