| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 | 
							- <?php
 
- declare(strict_types=1);
 
- namespace PhpMyAdmin;
 
- use function define;
 
- use function defined;
 
- use function property_exists;
 
- use const MYSQLI_BLOB_FLAG;
 
- use const MYSQLI_ENUM_FLAG;
 
- use const MYSQLI_MULTIPLE_KEY_FLAG;
 
- use const MYSQLI_NOT_NULL_FLAG;
 
- use const MYSQLI_PRI_KEY_FLAG;
 
- use const MYSQLI_SET_FLAG;
 
- use const MYSQLI_TYPE_BIT;
 
- use const MYSQLI_TYPE_BLOB;
 
- use const MYSQLI_TYPE_DATE;
 
- use const MYSQLI_TYPE_DATETIME;
 
- use const MYSQLI_TYPE_DECIMAL;
 
- use const MYSQLI_TYPE_DOUBLE;
 
- use const MYSQLI_TYPE_ENUM;
 
- use const MYSQLI_TYPE_FLOAT;
 
- use const MYSQLI_TYPE_GEOMETRY;
 
- use const MYSQLI_TYPE_INT24;
 
- use const MYSQLI_TYPE_JSON;
 
- use const MYSQLI_TYPE_LONG;
 
- use const MYSQLI_TYPE_LONG_BLOB;
 
- use const MYSQLI_TYPE_LONGLONG;
 
- use const MYSQLI_TYPE_MEDIUM_BLOB;
 
- use const MYSQLI_TYPE_NEWDATE;
 
- use const MYSQLI_TYPE_NEWDECIMAL;
 
- use const MYSQLI_TYPE_NULL;
 
- use const MYSQLI_TYPE_SET;
 
- use const MYSQLI_TYPE_SHORT;
 
- use const MYSQLI_TYPE_STRING;
 
- use const MYSQLI_TYPE_TIME;
 
- use const MYSQLI_TYPE_TIMESTAMP;
 
- use const MYSQLI_TYPE_TINY;
 
- use const MYSQLI_TYPE_TINY_BLOB;
 
- use const MYSQLI_TYPE_VAR_STRING;
 
- use const MYSQLI_TYPE_YEAR;
 
- use const MYSQLI_UNIQUE_KEY_FLAG;
 
- use const MYSQLI_UNSIGNED_FLAG;
 
- use const MYSQLI_ZEROFILL_FLAG;
 
- /**
 
-  * Handles fields Metadata
 
-  *
 
-  * NOTE: Getters are not used in all implementations due to the important cost of getters calls
 
-  */
 
- final class FieldMetadata
 
- {
 
-     public const TYPE_GEOMETRY = 1;
 
-     public const TYPE_BIT = 2;
 
-     public const TYPE_JSON = 3;
 
-     public const TYPE_REAL = 4;
 
-     public const TYPE_INT = 5;
 
-     public const TYPE_BLOB = 6;
 
-     public const TYPE_UNKNOWN = -1;
 
-     public const TYPE_NULL = 7;
 
-     public const TYPE_STRING = 8;
 
-     public const TYPE_DATE = 9;
 
-     public const TYPE_TIME = 10;
 
-     public const TYPE_TIMESTAMP = 11;
 
-     public const TYPE_DATETIME = 12;
 
-     public const TYPE_YEAR = 13;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isMultipleKey;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isPrimaryKey;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isUniqueKey;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isNotNull;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isUnsigned;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isZerofill;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isNumeric;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isBlob;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isBinary;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isEnum;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isSet;
 
-     /** @var int|null */
 
-     private $mappedType;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isMappedTypeBit;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isMappedTypeGeometry;
 
-     /**
 
-      * @var bool
 
-      * @readonly
 
-      */
 
-     public $isMappedTypeTimestamp;
 
-     /**
 
-      * The column name
 
-      *
 
-      * @var string
 
-      */
 
-     public $name;
 
-     /**
 
-      * The original column name if an alias did exist
 
-      *
 
-      * @var string
 
-      */
 
-     public $orgname;
 
-     /**
 
-      * The table name
 
-      *
 
-      * @var string
 
-      */
 
-     public $table;
 
-     /**
 
-      * The original table name
 
-      *
 
-      * @var string
 
-      */
 
-     public $orgtable;
 
-     /**
 
-      * The charset number
 
-      *
 
-      * @readonly
 
-      * @var int
 
-      */
 
-     public $charsetnr;
 
-     /**
 
-      * The number of decimals used (for integer fields)
 
-      *
 
-      * @readonly
 
-      * @var int
 
-      */
 
-     public $decimals;
 
-     /**
 
-      * The width of the field, as specified in the table definition.
 
-      *
 
-      * @readonly
 
-      * @var int
 
-      */
 
-     public $length;
 
-     /**
 
-      * A field only used by the Results class
 
-      *
 
-      * @var string
 
-      */
 
-     public $internalMediaType;
 
-     public function __construct(int $fieldType, int $fieldFlags, object $field)
 
-     {
 
-         $this->mappedType = $this->getTypeMap()[$fieldType] ?? null;
 
-         $this->isMultipleKey = (bool) ($fieldFlags & MYSQLI_MULTIPLE_KEY_FLAG);
 
-         $this->isPrimaryKey = (bool) ($fieldFlags & MYSQLI_PRI_KEY_FLAG);
 
-         $this->isUniqueKey = (bool) ($fieldFlags & MYSQLI_UNIQUE_KEY_FLAG);
 
-         $this->isNotNull = (bool) ($fieldFlags & MYSQLI_NOT_NULL_FLAG);
 
-         $this->isUnsigned = (bool) ($fieldFlags & MYSQLI_UNSIGNED_FLAG);
 
-         $this->isZerofill = (bool) ($fieldFlags & MYSQLI_ZEROFILL_FLAG);
 
-         $this->isBlob = (bool) ($fieldFlags & MYSQLI_BLOB_FLAG);
 
-         $this->isEnum = (bool) ($fieldFlags & MYSQLI_ENUM_FLAG);
 
-         $this->isSet = (bool) ($fieldFlags & MYSQLI_SET_FLAG);
 
-         // as flags 32768 can be NUM_FLAG or GROUP_FLAG
 
-         // reference: https://www.php.net/manual/en/mysqli-result.fetch-fields.php
 
-         // so check field type instead of flags
 
-         $this->isNumeric = $this->isType(self::TYPE_INT) || $this->isType(self::TYPE_REAL);
 
-         /*
 
-             MYSQLI_PART_KEY_FLAG => 'part_key',
 
-             MYSQLI_TIMESTAMP_FLAG => 'timestamp',
 
-             MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment',
 
-         */
 
-         $this->isMappedTypeBit = $this->isType(self::TYPE_BIT);
 
-         $this->isMappedTypeGeometry = $this->isType(self::TYPE_GEOMETRY);
 
-         $this->isMappedTypeTimestamp = $this->isType(self::TYPE_TIMESTAMP);
 
-         $this->name = property_exists($field, 'name') ? $field->name : '';
 
-         $this->orgname = property_exists($field, 'orgname') ? $field->orgname : '';
 
-         $this->table = property_exists($field, 'table') ? $field->table : '';
 
-         $this->orgtable = property_exists($field, 'orgtable') ? $field->orgtable : '';
 
-         $this->charsetnr = property_exists($field, 'charsetnr') ? $field->charsetnr : -1;
 
-         $this->decimals = property_exists($field, 'decimals') ? $field->decimals : 0;
 
-         $this->length = property_exists($field, 'length') ? $field->length : 0;
 
-         // 63 is the number for the MySQL charset "binary"
 
-         $this->isBinary = (
 
-             $fieldType === MYSQLI_TYPE_TINY_BLOB || $fieldType === MYSQLI_TYPE_BLOB
 
-             || $fieldType === MYSQLI_TYPE_MEDIUM_BLOB || $fieldType === MYSQLI_TYPE_LONG_BLOB
 
-             || $fieldType === MYSQLI_TYPE_VAR_STRING || $fieldType === MYSQLI_TYPE_STRING
 
-         ) && $this->charsetnr == 63;
 
-     }
 
-     /**
 
-      * @see https://dev.mysql.com/doc/connectors/en/apis-php-mysqli.constants.html
 
-      */
 
-     private function getTypeMap(): array
 
-     {
 
-         // Issue #16043 - client API mysqlnd seem not to have MYSQLI_TYPE_JSON defined
 
-         if (! defined('MYSQLI_TYPE_JSON')) {
 
-             define('MYSQLI_TYPE_JSON', 245);
 
-         }
 
-         // Build an associative array for a type look up
 
-         $typeAr = [];
 
-         $typeAr[MYSQLI_TYPE_DECIMAL] = self::TYPE_REAL;
 
-         $typeAr[MYSQLI_TYPE_NEWDECIMAL] = self::TYPE_REAL;
 
-         $typeAr[MYSQLI_TYPE_BIT] = self::TYPE_INT;
 
-         $typeAr[MYSQLI_TYPE_TINY] = self::TYPE_INT;
 
-         $typeAr[MYSQLI_TYPE_SHORT] = self::TYPE_INT;
 
-         $typeAr[MYSQLI_TYPE_LONG] = self::TYPE_INT;
 
-         $typeAr[MYSQLI_TYPE_FLOAT] = self::TYPE_REAL;
 
-         $typeAr[MYSQLI_TYPE_DOUBLE] = self::TYPE_REAL;
 
-         $typeAr[MYSQLI_TYPE_NULL] = self::TYPE_NULL;
 
-         $typeAr[MYSQLI_TYPE_TIMESTAMP] = self::TYPE_TIMESTAMP;
 
-         $typeAr[MYSQLI_TYPE_LONGLONG] = self::TYPE_INT;
 
-         $typeAr[MYSQLI_TYPE_INT24] = self::TYPE_INT;
 
-         $typeAr[MYSQLI_TYPE_DATE] = self::TYPE_DATE;
 
-         $typeAr[MYSQLI_TYPE_TIME] = self::TYPE_TIME;
 
-         $typeAr[MYSQLI_TYPE_DATETIME] = self::TYPE_DATETIME;
 
-         $typeAr[MYSQLI_TYPE_YEAR] = self::TYPE_YEAR;
 
-         $typeAr[MYSQLI_TYPE_NEWDATE] = self::TYPE_DATE;
 
-         $typeAr[MYSQLI_TYPE_ENUM] = self::TYPE_UNKNOWN;
 
-         $typeAr[MYSQLI_TYPE_SET] = self::TYPE_UNKNOWN;
 
-         $typeAr[MYSQLI_TYPE_TINY_BLOB] = self::TYPE_BLOB;
 
-         $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = self::TYPE_BLOB;
 
-         $typeAr[MYSQLI_TYPE_LONG_BLOB] = self::TYPE_BLOB;
 
-         $typeAr[MYSQLI_TYPE_BLOB] = self::TYPE_BLOB;
 
-         $typeAr[MYSQLI_TYPE_VAR_STRING] = self::TYPE_STRING;
 
-         $typeAr[MYSQLI_TYPE_STRING] = self::TYPE_STRING;
 
-         // MySQL returns MYSQLI_TYPE_STRING for CHAR
 
-         // and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY
 
-         // so this would override TINYINT and mark all TINYINT as string
 
-         // see https://github.com/phpmyadmin/phpmyadmin/issues/8569
 
-         //$typeAr[MYSQLI_TYPE_CHAR]        = self::TYPE_STRING;
 
-         $typeAr[MYSQLI_TYPE_GEOMETRY] = self::TYPE_GEOMETRY;
 
-         $typeAr[MYSQLI_TYPE_BIT] = self::TYPE_BIT;
 
-         $typeAr[MYSQLI_TYPE_JSON] = self::TYPE_JSON;
 
-         return $typeAr;
 
-     }
 
-     public function isNotNull(): bool
 
-     {
 
-         return $this->isNotNull;
 
-     }
 
-     public function isNumeric(): bool
 
-     {
 
-         return $this->isNumeric;
 
-     }
 
-     public function isBinary(): bool
 
-     {
 
-         return $this->isBinary;
 
-     }
 
-     public function isBlob(): bool
 
-     {
 
-         return $this->isBlob;
 
-     }
 
-     public function isPrimaryKey(): bool
 
-     {
 
-         return $this->isPrimaryKey;
 
-     }
 
-     public function isUniqueKey(): bool
 
-     {
 
-         return $this->isUniqueKey;
 
-     }
 
-     public function isMultipleKey(): bool
 
-     {
 
-         return $this->isMultipleKey;
 
-     }
 
-     public function isUnsigned(): bool
 
-     {
 
-         return $this->isUnsigned;
 
-     }
 
-     public function isZerofill(): bool
 
-     {
 
-         return $this->isZerofill;
 
-     }
 
-     public function isEnum(): bool
 
-     {
 
-         return $this->isEnum;
 
-     }
 
-     public function isSet(): bool
 
-     {
 
-         return $this->isSet;
 
-     }
 
-     /**
 
-      * Checks that it is type DATE/TIME/DATETIME
 
-      */
 
-     public function isDateTimeType(): bool
 
-     {
 
-         return $this->isType(self::TYPE_DATE)
 
-             || $this->isType(self::TYPE_TIME)
 
-             || $this->isType(self::TYPE_DATETIME)
 
-             || $this->isType(self::TYPE_TIMESTAMP);
 
-     }
 
-     /**
 
-      * Checks that it contains time
 
-      * A "DATE" field returns false for example
 
-      */
 
-     public function isTimeType(): bool
 
-     {
 
-         return $this->isType(self::TYPE_TIME)
 
-             || $this->isType(self::TYPE_TIMESTAMP)
 
-             || $this->isType(self::TYPE_DATETIME);
 
-     }
 
-     /**
 
-      * Get the mapped type as a string
 
-      *
 
-      * @return string Empty when nothing could be matched
 
-      */
 
-     public function getMappedType(): string
 
-     {
 
-         $types = [
 
-             self::TYPE_GEOMETRY => 'geometry',
 
-             self::TYPE_BIT => 'bit',
 
-             self::TYPE_JSON => 'json',
 
-             self::TYPE_REAL => 'real',
 
-             self::TYPE_INT => 'int',
 
-             self::TYPE_BLOB => 'blob',
 
-             self::TYPE_UNKNOWN => 'unknown',
 
-             self::TYPE_NULL => 'null',
 
-             self::TYPE_STRING => 'string',
 
-             self::TYPE_DATE => 'date',
 
-             self::TYPE_TIME => 'time',
 
-             self::TYPE_TIMESTAMP => 'timestamp',
 
-             self::TYPE_DATETIME => 'datetime',
 
-             self::TYPE_YEAR => 'year',
 
-         ];
 
-         return $types[$this->mappedType] ?? '';
 
-     }
 
-     /**
 
-      * Check if it is the mapped type
 
-      *
 
-      * @phpstan-param self::TYPE_* $type
 
-      */
 
-     public function isType(int $type): bool
 
-     {
 
-         return $this->mappedType === $type;
 
-     }
 
-     /**
 
-      * Check if it is NOT the mapped type
 
-      *
 
-      * @phpstan-param self::TYPE_* $type
 
-      */
 
-     public function isNotType(int $type): bool
 
-     {
 
-         return $this->mappedType !== $type;
 
-     }
 
- }
 
 
  |