{"id":15706229,"url":"https://github.com/belgattitude/soluble-metadata","last_synced_at":"2025-05-12T21:02:43.980Z","repository":{"id":57055368,"uuid":"48878133","full_name":"belgattitude/soluble-metadata","owner":"belgattitude","description":"Extract metadata from sql queries (reflection over sql) ","archived":false,"fork":false,"pushed_at":"2019-09-19T19:14:20.000Z","size":486,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T03:35:31.674Z","etag":null,"topics":["database","metadata","mysql","mysqli","pdo-mysql","php","reflection","sql"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/belgattitude.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-01-01T12:58:45.000Z","updated_at":"2023-12-25T03:12:04.000Z","dependencies_parsed_at":"2022-08-24T06:01:01.592Z","dependency_job_id":null,"html_url":"https://github.com/belgattitude/soluble-metadata","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/belgattitude%2Fsoluble-metadata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/belgattitude%2Fsoluble-metadata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/belgattitude%2Fsoluble-metadata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/belgattitude%2Fsoluble-metadata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/belgattitude","download_url":"https://codeload.github.com/belgattitude/soluble-metadata/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253823412,"owners_count":21969846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","metadata","mysql","mysqli","pdo-mysql","php","reflection","sql"],"created_at":"2024-10-03T20:21:58.029Z","updated_at":"2025-05-12T21:02:43.937Z","avatar_url":"https://github.com/belgattitude.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PHP Version](http://img.shields.io/badge/php-7.1+-ff69b4.svg)](https://packagist.org/packages/soluble/metadata)\n[![PHP Version](http://img.shields.io/badge/php-5.4+-ff69b4.svg)](https://packagist.org/packages/soluble/metadata)\n[![Build Status](https://travis-ci.org/belgattitude/soluble-metadata.svg?branch=master)](https://travis-ci.org/belgattitude/soluble-metadata)\n[![codecov](https://codecov.io/gh/belgattitude/soluble-metadata/branch/master/graph/badge.svg)](https://codecov.io/gh/belgattitude/soluble-metadata)\n[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/belgattitude/soluble-metadata/badges/quality-score.png?s=6f3ab91f916bf642f248e82c29857f94cb50bb33)](https://scrutinizer-ci.com/g/belgattitude/soluble-metadata)\n[![Latest Stable Version](https://poser.pugx.org/soluble/metadata/v/stable.svg)](https://packagist.org/packages/soluble/metadata)\n[![Total Downloads](https://poser.pugx.org/soluble/metadata/downloads.png)](https://packagist.org/packages/soluble/metadata)\n[![License](https://poser.pugx.org/soluble/metadata/license.png)](https://packagist.org/packages/soluble/metadata)\n\n`soluble-metadata` is a *low level* library *currently focusing on MySQL* which extracts metadata from an sql query with extensibility, speed and portability in mind.\n\n## Use cases\n\nYou can take advantage of soluble/metadata to format/render resulting query data \naccording to their type (when rendering an html table, generating an excel sheet...), \nfor basic validation (max lengths, decimals)...\n\n## Features\n\n- Extract metadata information from an SQL query (datatypes,...)\n- Common API across various driver implementations.\n- Rely on native database driver information (does not parse the query in PHP)\n- Works even when the query does not return results (empty resultset).\n- Carefully tested with different implementations (libmariadb, mysqlnd, libmysql, pdo_mysql).\n\n\u003e Under the hood, the metadata extraction relies on the driver methods `mysqli_stmt::result_metadata()` and `PDO::getColumnMeta()`.\n\u003e Although the `soluble-metadata` API unify their usage and type detection, differences still exists for more advanced features. \n\u003e A specific effort has been made in the documentation to distinguish possible portability issues when switching from one driver to another.\n\u003e Keep that in mind when using it.\n\n## Requirements\n\n- PHP engine 7.1+ (v1.2.0), 7.0+ and 5.4 (v1.0.0) \n- Mysqli or PDO_mysql extension enabled *(Mysqli exposes more features)*\n\n## Documentation\n\n - This README and [API documentation](http://docs.soluble.io/soluble-metadata/api/) available.\n\n## Installation\n\nInstant installation via [composer](http://getcomposer.org/).\n\n```console\n$ composer require soluble/metadata\n```\n\nMost modern frameworks will include composer out of the box, but ensure the following file is included:\n\n```php\n\u003c?php\n// include the Composer autoloader\nrequire 'vendor/autoload.php';\n```\n\n## Basic example\n\n```php\n\u003c?php\n\nuse Soluble\\Metadata\\Reader;\nuse Soluble\\Datatype\\Column\\Type as DataType;\n\n\n$conn = new \\mysqli($hostname,$username,$password,$database);\n$conn-\u003eset_charset($charset);\n\n$metaReader = new Reader\\MysqliMetadataReader($conn);\n\n$sql = \"select * from `my_table`\";\n\ntry {\n    $md = $metaReader-\u003egetColumnsMetadata($sql);\n} catch (\\Soluble\\Metadata\\Exception\\InvalidQueryException $e) {\n    // ...\n}\n\nforeach($md as $column_name =\u003e $col_def) {\n   \n   $datatype = $col_def-\u003egetDatatype();\n   \n   echo $column_name . \"\\t\" . $datatype . \"\\t\";\n   \n   echo ($col_def-\u003eisNullable() ? 'Y' : 'N') . '\\t';\n   \n   switch ($datatype) {\n       case DataType::TYPE_STRING:  // equivalent to 'string'\n           echo $col_def-\u003egetCharacterOctetLength() . \"\\t\";\n           break;\n       case DataType::TYPE_INTEGER:\n           echo ($col_def-\u003eisNumericUnsigned() ? 'Y' : 'N') . \"\\t\";\n           break;\n       case DataType::TYPE_DECIMAL:\n           echo ($col_def-\u003eisNumericUnsigned() ? 'Y' : 'N') . \"\\t\";\n           echo $col-\u003egetNumericPrecision() . \"\\t\";  // For DECIMAL(5,2) -\u003e precision = 5 \n           echo $col-\u003egetNumericScale() . \"\\t\";      // For DECIMAL(5,2) -\u003e scale = 2\n           break;\n           \n       // ...see the doc for more possibilitities\n   }\n   \n   echo $col_def-\u003egetNativeType() . PHP_EOL;\n}  \n\n```\n\nCould print something like :\n\n| Column name   | Type             | Null | Unsigned | Length | Precision | Scale | Native        |\n|---------------|------------------|-----:|---------:|-------:|----------:|------:|---------------|\n| column_1      | integer          | N    | Y        |        |           |       | BIGINT        |\n| column_2      | string           | N    |          | 255    |           |       | VARCHAR       |\n| column_3      | decimal          | Y    | N        |        | 5         | 2     | DECIMAL       |\n| column_4      | datetime         | Y    |          |        |           |       | DATETIME      |\n| column_5      | date             | Y    |          |        |           |       | DATE          |\n| column_6      | time             | Y    |          |        |           |       | TIME          |\n| column_7      | float            | N    |          |        |           |       | FLOAT         |\n| column_8      | blob             | Y    |          | 16777215 |           |       | MEDIUMBLOB    |\n| column_9      | spatial_geometry | Y    |          |        |           |       | null *(N/A)*  |\n\n...\n\n## Usage\n\n### Step 1. Initiate a metadata reader\n\n- For **Mysqli**: send the existing mysqli connection to the `MysqlMetadataReader` :\n\n    ```php\n    \u003c?php\n    use Soluble\\Metadata\\Reader;\n    \n    $conn = new \\mysqli($hostname,$username,$password,$database);\n    $conn-\u003eset_charset($charset);\n    \n    $reader = new Reader\\MysqliMetadataReader($conn);\n    \n    ``` \n\n- For **Pdo_mysql**: send the existing pdo_mysql connection to the `PdoMysqlReader` :\n\n    ```php\n    \u003c?php\n    use Soluble\\Metadata\\Reader;\n    \n    $conn = new \\PDO(\"mysql:host=$hostname\", $username, $password, [\n                \\PDO::MYSQL_ATTR_INIT_COMMAND =\u003e \"SET NAMES utf8\"\n    ]);\n    \n    $reader = new Reader\\PDOMysqlMetadataReader($conn);\n    \n    ```\n\n### Step 2. Extract metadata from an SQL query\n\n```php\n\u003c?php\n\n//....\n\n$reader = new Reader\\MysqliMetadataReader($conn);\n\n$sql = \"\n         SELECT `p`.`post_id`,\n                `p`.`title` AS `post_title` \n                `p`.`created_at`,\n                'constant' AS `constant_col`,\n                1 + 2 AS `computed_col`, \n                null as `null_col`\n                COUNT(`c`.*) as `nb_comments`,\n                MAX(`c`.`created_at`) as latest_comment\n                 \n            FROM `post` AS `p`\n            LEFT OUTER JOIN `comment` as `c`  \n                 ON `c`.`post_id` = `p`.`post_id`\n            GROUP BY `p`.`post_id`, `p`.`title`, \n                     `p`.`created_at`, `constant_col`, \n                     `computed_col`, `null_col`     \n       \";\n\n\ntry {    \n    $meta = $reader-\u003egetColumnsMetadata($sql);\n} catch (\\Soluble\\Metadata\\Exception\\InvalidQueryException $e) { \n    //...\n}\n\n/*\n  The resulting ColumnsMetadata will contain something like:\n\n  [\n     \"post_id\"        =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\IntegerColumn\u003e',\n     \"post_title\"     =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\StringColumn\u003e',\n     \"created_at\"     =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\DatetimeColumn\u003e',\n     \"constant_col\"   =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\StringColumn\u003e',\n     \"computed_col\"   =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\IntegerColumn\u003e',\n     \"null_col\"       =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\NullColumn\u003e',\n     \"nb_comments\"    =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\IntegerColumn\u003e',\n     \"latest_comment\" =\u003e '\u003cSoluble\\Datatype\\Column\\Definition\\DateTimeColumn\u003e'\n     \n  ]\n    \n*/  \n\n```\n\n\u003e Alternatively, when you want to get the metadata from a table you can use\n\u003e the helper method `$reader-\u003egetTableMetadata($table)`. \n\n### Step 3: Getting column type (4 options)\n\n\n```php\n\u003c?php\n\n// ...\n\n$meta = $reader-\u003egetColumnsMetadata($sql);\n\n// Retrieve a specific column (i.e. 'post_title')\n// Note the parameter is the column alias if defined \n\n$col = $meta-\u003egetColumn('post_title'); \n\n                                       \n// Type detection\n// ----------------------\n\n// Option 1, type detection by datatype name\n// ------------------------------------------\n\necho $col-\u003egetDatatype(); // -\u003e 'string' (equivalent to Soluble\\Datatype\\Column\\Type::TYPE_STRING)  \n\n/* \n   The normalized datatypes are defined in the \n   Soluble\\Datatype\\Column\\Type::TYPE_(*) and can be :\n   'string', 'integer', 'decimal', 'float', 'boolean', \n   'datetime', 'date', 'time', 'bit', 'spatial_geometry'\n*/\n\n\n// Option 2, type detection by classname\n// --------------------------------------\n\nif ($col instanceof \\Soluble\\Datatype\\Column\\IntegerColumn) {\n    // ... could be also BitColumn, BlobColumn, BooleanColumn\n    // ... DateColumn, DateTimeColumn, DecimalColumn, FloatColumn\n    // ... GeometryColumn, IntegerColumn, StringColumn, TimeColumn,\n    // ... NullColumn\n}\n\n// Option 3, type detection by interface (more generic)\n// -----------------------------------------------------\n\nif ($col instanceof \\Soluble\\Datatype\\Column\\NumericColumnInterface) {\n   // ... for example NumericColumnInterface \n   // ... includes DecimalColumn, FloatColumn, IntegerColumn\n}\n\n// Option 4, type detection by helper functions (more generic)\n// -----------------------------------------------------------\n\n$col-\u003eisText();     // Whether the column contains text (CHAR, VARCHAR, ENUM...)\n$col-\u003eisNumeric();  // Whether the column is numeric (INT, DECIMAL, FLOAT...)\n$col-\u003eisDatetime(); // Whether the column is a datetime (DATETIME)\n$col-\u003eisDate();     // Whther the column is a date (DATE)\n\n```\n\n\n### Step 4: Getting datatype extra information  \n\nThe following methods are supported and portable between `mysqli` and `PDO_mysql` drivers:\n\n```php\n\u003c?php\n\n// ...\n\n// For all types\n// -------------\n\necho $col-\u003egetOrdinalPosition(); // -\u003e 2 (column position in the query)\necho $col-\u003eisNullable() ? 'nullable' : 'not null';\necho $col-\u003eisPrimary() ? 'PK' : '';  // Many columns may have the primary flag\n                                     // The meaning of it depends on your query\n\n// For integer and decimal types\necho $col-\u003eisNumericUnsigned();   // Whether the numeric value is unsigned.\n\n// For decimal based types\n// -----------------------\n\necho $col-\u003egetNumericPrecision(); // For DECIMAL(5,2) -\u003e 5 is the precision\necho $col-\u003egetNumericScale();     // For DECIMAL(5,2) -\u003e 2 is the scale\n\n// For character/blob based types\n// ------------------------------\n\necho $col-\u003egetCharacterOctetLength();  // Octet length (in multibyte context length might differs)\n \n```\n\n\n### Getting column specifications.\n\nThe following methods are also portable.  \n \n \n```php \n\u003c?php\n\n// ...\n\necho $col-\u003egetAlias(); // Column alias name -\u003e \"post_title\" (or column name if not aliased)\n\necho $col-\u003eisComputed(); // Whenever there's no table linked (for GROUP, constants, expression...)\n\necho $col-\u003egetTableAlias(); // Originating table alias -\u003e \"p\" (or table name if not aliased)\n                            // If empty, the column is computed (constant, group,...)\n```\n\n\u003e **The methods used in the example below gives different results with `pdo_mysql` and `mysqli` drivers.\n\u003e Use them with care if portability is required !!!**\n\n```php\n\u003c?php\n\n// ...\n\necho $col-\u003egetTableName();  // Originating table -\u003e \"post\"\n                            // (*) PDO_mysql always return the table alias if aliased \n\necho $col-\u003egetName();  // Column original name -\u003e \"title\". \n                       // (*) PDO_mysql always return the alias if aliased\n\necho $col-\u003egetNativeType(); // Return the column definition native type\n                            // i.e: BIGINT, SMALLINT, VARCHAR, ENUM\n                            // (*) PDO_mysql consider \n                            //        - ENUM, SET and VARCHAR as CHAR\n                            \necho $col-\u003eisGroup(); // Whenever the column is part of a group (MIN, MAX, AVG,...)\n                      // (*) PDO_mysql is not able to retrieve group information\n                      // (*) Mysqli: detection of group is linked to the internal driver\n                      //     Check your driver with mysqli_get_client_version().\n                      //       - mysqlnd detects:\n                      //          - COUNT, MIN, MAX\n                      //       - libmysql detects:\n                      //          - COUNT, MIN, MAX, AVG, GROUP_CONCAT\n                      //       - libmariadb detects:\n                      //          - COUNT, MIN, MAX, AVG, GROUP_CONCAT and growing    \n\n\n// For numeric types\n// -----------------\n\necho $col-\u003eisAutoIncrement();   // Only make sense for primary keys.\n                                // (*) Unsupported with PDO_mysql\n\necho $col-\u003eisNumericUnsigned(); // Whether the numeric value is unsigned.\n                                // (*) Unsupported with PDO_mysql\n```\n\n\n### Unsupported methods\n\nThose methods are still unsupported on both mysqli and PDO_mysql implementations but kept as reference\n\n```php\n\u003c?php\n\n// ... \n\necho $col-\u003egetColumnDefault(); // Always return null\necho $col-\u003egetCharacterMaximumLength();  // Returns $col-\u003egetCharacterOctetLength()\n                                         // and does not (yet) handle multibyte aspect.\n\n```\n\n\n## API\n\n### AbstractMetadataReader\n\nUse the `Reader\\AbstractMetadataReader::getColumnsMetadata($sql)` to extract query metadata.\n\n```php\n\u003c?php\n\nuse Soluble\\Metadata\\Reader;\nuse PDO;\n\n$conn = new PDO(\"mysql:host=$hostname\", $username, $password, [\n            PDO::MYSQL_ATTR_INIT_COMMAND =\u003e \"SET NAMES utf8\"\n]);\n\n$reader = new Reader\\PdoMysqlMetadataReader($conn);\n\n$sql = \"select id, name from my_table\";\n\n$columnsMeta = $reader-\u003egetColumnsMetadata($sql);\n\n```\n\n| Methods                      | Return            | Description                                                |\n|------------------------------|-------------------|------------------------------------------------------------|\n| `getColumnsMetadata($sql)`   | `ColumnsMetadata` | Metadata information: ArrayObject with column name/alias   |\n\n\n### ColumnsMetadata\n\nThe `Soluble\\Metadata\\ColumnsMetadata` allows to iterate over column information or return a specific column as\nan `Soluble\\Datatype\\Column\\Definition\\AbstractColumnDefinition`.\n\n```php\n\u003c?php\n\n$reader = new Reader\\PdoMysqlMetadataReader($conn);\n\n$sql = \"select id, name from my_table\";\n\n$columnsMeta = $reader-\u003egetColumnsMetadata($sql);\n\nforeach ($columnsMeta as $col_name =\u003e $col_def) {\n    echo $coldev-\u003egetDatatype() . PHP_EOL; \n}\n\n$col = $columnsMeta-\u003egetColumn('id');\necho $col-\u003egetDatatype();\n\n```\n\n| Methods                      | Return        | Description                                         |\n|------------------------------|---------------|-----------------------------------------------------|\n| `getColumn($name)`           | `AbstractColumnDefinition` | Information about a column             |\n\n\n### AbstractColumnDefinition\n\nMetadata information is stored as an `Soluble\\Datatype\\Column\\Definition\\AbstractColumnDefinition` object on which :\n\n\n| General methods              | Return        | Description                                         |\n|------------------------------|---------------|-----------------------------------------------------|\n| `getName()`                  | `string`      | Return column name (unaliased)                      |\n| `getAlias()`                 | `string`      | Return column alias                                 |\n| `getTableName()`             | `string`      | Return origin table                                 |\n| `getSchemaName()`            | `string`      | Originating schema for the column/table             |\n| `getOrdinalPosition()`       | `integer`     | Return position in the select                       |\n\n| Type related methods         | Return        | Description                                         |\n|------------------------------|---------------|-----------------------------------------------------|\n| `getDataType()`              | `string`      | Column datatype (see Column\\Type)                   |\n| `getNativeDataType()`        | `string`      | Return native datatype (VARCHAR, BIGINT...)         |\n| `isText()`                   | `boolean`     | Whether the column is textual (string, blog...)     |\n| `isNumeric()`                | `boolean`     | Whether the column is numeric (decimal, int...)     |\n| `isDatetime()`               | `boolean`     | Is a datetime type                                  |\n| `isDate()`                   | `boolean`     | Is a date type                                      |\n\n| Flags information            | Return        | Description                                         |\n|------------------------------|---------------|-----------------------------------------------------|\n| `isPrimary()`                | `boolean`     | Whether the column is (part of) primary key         |\n| `isAutoIncrement()`          | `boolean`     | If it's an autoincrement column (only mysqli)       |\n| `isNullable()`               | `boolean`     | Whether the column is nullable                      |\n| `getColumnDefault()`         | `string`      | Return default value for column (not working yet)   |\n\n\n| Extra information methods    | Return        | Description                                         |\n|------------------------------|---------------|-----------------------------------------------------|\n| `isComputed()`               | `boolean`     | Whether the column is computed, i.e. '1+1, sum()    |\n| `isGroup()`                  | `boolean`     | Grouped operation sum(), min(), max()               |\n\n| Numeric type specific        | Return        | Description                                         |\n|------------------------------|---------------|-----------------------------------------------------|\n| `getNumericScale()`          | `integer`     | Scale for numbers, i.e DECIMAL(10,2) -\u003e 10          |\n| `getNumericPrecision()`      | `integer`     | Precision, i.e. DECIMAL(10,2) -\u003e 2                  |\n| `isNumericUnsigned()`        | `boolean`     | Whether signed or unsigned                          |\n\n| Character type specific       | Return        | Description                                                |\n|-------------------------------|---------------|------------------------------------------------------------|\n| `getCharacterMaximumLength()` | `integer`     | Max string length for chars (unicode sensitive)            |\n| `getCharacterOctetLength()`   | `integer`     | Max octet length for chars, blobs... (binary, no unicode)  |\n\n\n\n### AbstractColumnDefinition implementations\n\nHere's the list of concrete implementations for `Soluble\\Datatype\\Column\\Definition\\AbstractColumnDefinition`.\n\nThey can be used as an alternative way to check column datatype. For example\n\n```php\nuse Soluble\\Datatype\\Column\\Definition;\n\nif ($coldef instanceof Definition\\DateColumnInterface) {\n\n    // equivalent to\n    // if ($coldef-\u003eisDate()) {\n\n    $date = new \\DateTime($value);\n    echo $value-\u003eformat('Y');\n} elseif ($coldef instanceof Definition\\NumericColumnInterface) {\n    echo number_format($value, $coldef-\u003egetNumericPrecision);\n}\n```\n\n| Definition Type      | Interface                 | Description                   |\n|----------------------|---------------------------|-------------------------------|\n| `BitColumn`          |                           |                               |\n| `BlobColumn`         |                           |                               |\n| `BooleanColumn`      |                           |                               |\n| `DateColumn`         | `DateColumnInterface`     |                               |\n| `DateTimeColumn`     | `DatetimeColumnInterface` |                               |\n| `DecimalColumn`      | `NumericColumnInterface`  |                               |\n| `FloatColumn`        | `NumericColumnInterface`  |                               |\n| `GeometryColumn`     |                           |                               |\n| `IntegerColumn`      | `NumericColumnInterface`  |                               |\n| `StringColumn`       | `TextColumnInterface`     |                               |\n| `TimeColumn`         |                           |                               |\n| `NullColumn`         |                           | Special case for columns aliasing 'NULL' value  |\n\n\n## Supported readers\n\nCurrently only pdo_mysql and mysqli drivers  are supported. \n\n| Drivers            | Reader implementation                                |\n|--------------------|------------------------------------------------------|\n| pdo_mysql          | `Soluble\\Metadata\\Reader\\PdoMysqlMetadataReader`     |\n| mysqli             | `Soluble\\Metadata\\Reader\\MysqliMetadataReader`       |\n\n\n## Future ideas\n\n- Implement more drivers (pgsql...), contributions welcome !!!\n\n## Contributing\n\nContribution are welcome see [contribution guide](./CONTRIBUTING.md)\n\n## Notes\n\nCurrently metadata are read from the underlying database driver by executing a query \nwith a limit 0 (almost no performance penalty). This ensure your query is always \ncorrectly parsed (even crazy ones) with almost no effort. \n\nThe underlying driver methods `mysqli_stmt::result_metadata()`, `PDO::getColumnMeta()` \nused respectively by the metadata readers Mysql and PdoMysql are marked as experimental \nand subject to change on the PHP website. In practice, they haven't changed since 5.4 and\nare stable. In case of a change in the php driver, it should be very easy to add a \nspecific driver. \n\nSadly there is some differences between PDO_mysql and mysqli in term of features. \nGenerally the best is to use mysqli instead of pdo. PDO lacks some features like \ndetection of autoincrement, enum, set, unsigned, grouped column and does not \ndistinguish between table/column aliases and their original table/column names. \n\nIf you want to rely on this specific feature (aliases) have a look to alternatives like [phpmyadmin sql-parser](https://github.com/phpmyadmin/sql-parser).\n\nAlso if you are looking for a more advanced metadata reader (but limited to table - not a query),\nhave a look to the [soluble-schema](https://github.com/belgattitude/soluble-schema) project which share\nthe same datatype standards while exposing more information like foreign keys,... in a more portable way. \n\n## Coding standards\n\n* [PSR 4 Autoloader](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md)\n* [PSR 2 Coding Style Guide](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)\n* [PSR 1 Coding Standards](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbelgattitude%2Fsoluble-metadata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbelgattitude%2Fsoluble-metadata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbelgattitude%2Fsoluble-metadata/lists"}