src/Definition/Snowflake.php
File `Snowflake.php` has 312 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 Snowflake has an overall complexity of 100 which is very high. The configured complexity threshold is 50.class Snowflake extends Common{ public const METADATA_BACKEND = 'snowflake'; public const TYPE_NUMBER = 'NUMBER'; public const TYPE_DECIMAL = 'DECIMAL'; public const TYPE_NUMERIC = 'NUMERIC'; public const TYPE_INT = 'INT'; public const TYPE_INTEGER = 'INTEGER'; public const TYPE_BIGINT = 'BIGINT'; public const TYPE_SMALLINT = 'SMALLINT'; public const TYPE_TINYINT = 'TINYINT'; public const TYPE_BYTEINT = 'BYTEINT'; public const TYPE_FLOAT = 'FLOAT'; public const TYPE_FLOAT4 = 'FLOAT4'; public const TYPE_FLOAT8 = 'FLOAT8'; public const TYPE_DOUBLE = 'DOUBLE'; public const TYPE_DOUBLE_PRECISION = 'DOUBLE PRECISION'; public const TYPE_REAL = 'REAL'; public const TYPE_VARCHAR = 'VARCHAR'; public const TYPE_CHAR = 'CHAR'; public const TYPE_CHARACTER = 'CHARACTER'; public const TYPE_STRING = 'STRING'; public const TYPE_TEXT = 'TEXT'; public const TYPE_BOOLEAN = 'BOOLEAN'; public const TYPE_DATE = 'DATE'; public const TYPE_DATETIME = 'DATETIME'; public const TYPE_TIME = 'TIME'; public const TYPE_TIMESTAMP = 'TIMESTAMP'; public const TYPE_TIMESTAMP_NTZ = 'TIMESTAMP_NTZ'; public const TYPE_TIMESTAMP_LTZ = 'TIMESTAMP_LTZ'; public const TYPE_TIMESTAMP_TZ = 'TIMESTAMP_TZ'; public const TYPE_VARIANT = 'VARIANT'; public const TYPE_BINARY = 'BINARY'; public const TYPE_VARBINARY = 'VARBINARY'; public const TYPES = [ self::TYPE_NUMBER, self::TYPE_DECIMAL, self::TYPE_NUMERIC, self::TYPE_INT, self::TYPE_INTEGER, self::TYPE_BIGINT, self::TYPE_SMALLINT, self::TYPE_TINYINT, self::TYPE_BYTEINT, self::TYPE_FLOAT, self::TYPE_FLOAT4, self::TYPE_FLOAT8, self::TYPE_DOUBLE, self::TYPE_DOUBLE_PRECISION, self::TYPE_REAL, self::TYPE_VARCHAR, self::TYPE_CHAR, self::TYPE_CHARACTER, self::TYPE_STRING, self::TYPE_TEXT, self::TYPE_BOOLEAN, self::TYPE_DATE, self::TYPE_DATETIME, self::TYPE_TIME, self::TYPE_TIMESTAMP, self::TYPE_TIMESTAMP_NTZ, self::TYPE_TIMESTAMP_LTZ, self::TYPE_TIMESTAMP_TZ, self::TYPE_VARIANT, self::TYPE_BINARY, self::TYPE_VARBINARY, ]; public const MAX_VARCHAR_LENGTH = 16777216; public const MAX_VARBINARY_LENGTH = 8388608; /** * Snowflake constructor. * * @param array{ * length?:string|null|array, * nullable?:bool, * default?:string|null * } $options * @throws InvalidLengthException * @throws InvalidOptionException * @throws InvalidTypeException */ public function __construct(string $type, array $options = []) { $this->validateType($type); $options['length'] = $this->processLength($options); $this->validateLength($type, $options['length']); $diff = array_diff(array_keys($options), ['length', 'nullable', 'default']); if ($diff !== []) { throw new InvalidOptionException("Option '{$diff[0]}' not supported"); } if (array_key_exists('default', $options) && $options['default'] === '') { unset($options['default']); } parent::__construct($type, $options); } public function getTypeOnlySQLDefinition(): string { $out = $this->getType(); $length = $this->getLength(); if ($length !== null && $length !== '') { $out .= ' (' . $length . ')'; } return $out; } public function getSQLDefinition(): string { $definition = $this->getTypeOnlySQLDefinition(); if (!$this->isNullable()) { $definition .= ' NOT NULL'; } if ($this->getDefault() !== null) { $definition .= ' DEFAULT ' . $this->getDefault(); } 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.MissingNativeTypeHintFunction `validateLength` has a Cognitive Complexity of 45 (exceeds 5 allowed). Consider refactoring.
Method `validateLength` has 89 lines of code (exceeds 25 allowed). Consider refactoring.
The method validateLength() has an NPath complexity of 1002. The configured NPath complexity threshold is 200.
The method validateLength() has a Cyclomatic Complexity of 46. The configured cyclomatic complexity threshold is 10. private function validateLength(string $type, $length = null): void { $valid = true; switch (strtoupper($type)) { case self::TYPE_NUMBER: case self::TYPE_DECIMAL:Similar blocks of code found in 2 locations. Consider refactoring. case self::TYPE_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] > 38) { $valid = false; break; } if (isset($parts[1]) && ((int) $parts[1] > 38 || (int) $parts[1] > (int) $parts[0])) { $valid = false; break; } break; case self::TYPE_VARCHAR: case self::TYPE_CHAR: case self::TYPE_CHARACTER: case self::TYPE_STRING: case self::TYPE_TEXT: if (is_null($length) || $length === '') { break; } if (!is_numeric($length)) { $valid = false; break; } if ((int) $length <= 0 || (int) $length > self::MAX_VARCHAR_LENGTH) { $valid = false; break; } break; case self::TYPE_TIME: case self::TYPE_DATETIME: case self::TYPE_TIMESTAMP: case self::TYPE_TIMESTAMP_NTZ: case self::TYPE_TIMESTAMP_LTZ: case self::TYPE_TIMESTAMP_TZ: if (is_null($length) || $length === '') { break; } if (!is_numeric($length)) { $valid = false; break; } if ((int) $length < 0 || (int) $length > 9) { $valid = false; break; } break; case self::TYPE_BINARY: case self::TYPE_VARBINARY: if (is_null($length) || $length === '') { break; } if (!is_numeric($length)) { $valid = false; break; } if ((int) $length < 1 || (int) $length > self::MAX_VARBINARY_LENGTH) { $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 40 lines of code (exceeds 25 allowed). Consider refactoring.
Function `getBasetype` has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.
The method getBasetype() has a Cyclomatic Complexity of 23. The configured cyclomatic complexity threshold is 10. public function getBasetype(): string { switch (strtoupper($this->type)) { case self::TYPE_INT: case self::TYPE_INTEGER: case self::TYPE_BIGINT: case self::TYPE_SMALLINT: case self::TYPE_TINYINT: case self::TYPE_BYTEINT: $basetype = BaseType::INTEGER; break; case self::TYPE_NUMBER: case self::TYPE_DECIMAL: case self::TYPE_NUMERIC: $basetype = BaseType::NUMERIC; break; case self::TYPE_FLOAT: case self::TYPE_FLOAT4: case self::TYPE_FLOAT8: case self::TYPE_DOUBLE: case self::TYPE_DOUBLE_PRECISION: case self::TYPE_REAL: $basetype = BaseType::FLOAT; break; case self::TYPE_BOOLEAN: $basetype = BaseType::BOOLEAN; break; case self::TYPE_DATE: $basetype = BaseType::DATE; break; case self::TYPE_DATETIME: case self::TYPE_TIMESTAMP: case self::TYPE_TIMESTAMP_NTZ: case self::TYPE_TIMESTAMP_LTZ: case self::TYPE_TIMESTAMP_TZ: $basetype = BaseType::TIMESTAMP; break; default: $basetype = BaseType::STRING; break; } return $basetype; } Similar blocks of code found in 3 locations. Consider refactoring. public static function getTypeByBasetype(string $basetype): string { $basetype = strtoupper($basetype); Avoid using static access to class 'Keboola\Datatype\Definition\BaseType' in method 'getTypeByBasetype'. if (!BaseType::isValid($basetype)) { throw new InvalidTypeException(sprintf('Base type "%s" is not valid.', $basetype)); } switch ($basetype) { case BaseType::BOOLEAN: return self::TYPE_BOOLEAN; case BaseType::DATE: return self::TYPE_DATE; case BaseType::FLOAT: return self::TYPE_FLOAT; case BaseType::INTEGER: return self::TYPE_INTEGER; case BaseType::NUMERIC:Avoid too many `return` statements within this method. return self::TYPE_NUMBER; case BaseType::STRING:Avoid too many `return` statements within this method. return self::TYPE_VARCHAR; case BaseType::TIMESTAMP:Avoid too many `return` statements within this method. return self::TYPE_TIMESTAMP; } throw new LogicException(sprintf('Definition for base type "%s" is missing.', $basetype)); }}