GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - iamcal/SQLParser: Parse MySQL schemas in PHP, fast

BranchesTags
Open more actions menu

Latest commit

 

History

132 Commits
132 Commits

Folders and files

NameName
Last commit message
Last commit date
.github/workflows
.github/workflows
 
 
data
data
 
 
src
src
 
 
tests
tests
 
 
.gitattributes
.gitattributes
 
 
.gitignore
.gitignore
 
 
LICENSE
LICENSE
 
 
Makefile
Makefile
 
 
README.md
README.md
 
 
composer.json
composer.json
 
 
phpunit.xml.dist
phpunit.xml.dist
 
 
run.php
run.php
 
 
x.php
x.php
 
 

Repository files navigation

SQLParser - Parse MySQL schemas in PHP, fast

Build Status Coverage Status

This library takes MySQL CREATE TABLE statements and returns a data structure representing the table that it defines. MySQL syntax version 5.7 is supported. This library does not try to validate input - the goal is to deconstruct valid CREATE TABLE statements.

Installation

You can install this package using composer. To add it to your composer.json:

composer require iamcal/sql-parser

You can then load it using the composer autoloader:

require_once 'vendor/autoload.php';
use iamcal\SQLParser;

$parser = new SQLParser();

If you don't use composer, you can skip the autoloader and include src/SQLParser.php directly.

Usage

To extract the tables defined in SQL:

$parser = new SQLParser();
$parser->parse($sql);

print_r($parser->tables);

The tables property is an array of tables, each of which is a nested array structure defining the table's structure:

CREATE TABLE `achievements_counts` (
  `achievement_id` int(10) unsigned NOT NULL,
  `num_players` int(10) unsigned NOT NULL,
  `date_updated` int(10) unsigned NOT NULL,
  PRIMARY KEY (`achievement_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[
    'achievements_counts' => [
        'name' => 'achievements_counts',
        'fields' => [
            [
                'name' => 'achievement_id',
                'type' => 'INT',
                'length' => '10',
                'unsigned' => true,
                'null' => false,
            ],
            [
                'name' => 'num_players',
                'type' => 'INT',
                'length' => '10',
                'unsigned' => true,
                'null' => false,
            ],
            [
                'name' => 'date_updated',
                'type' => 'INT',
                'length' => '10',
                'unsigned' => true,
                'null' => false,
            ],
        ],
        'indexes' => [
            [
                'type' => 'PRIMARY',
                'cols' => [
                    [
                        'name' => 'achievement_id',
                    ],
                ],
            ],
        ],
        'props' => [
            'ENGINE' => 'InnoDB',
            'CHARSET' => 'utf8',
        ],
    ],
]

You can also use the lexer directly to work with other piece of SQL:

$parser = new SQLParser();
$parser->lex($sql);

print($parser->tokens);

The tokens property contains an array of tokens. SQL keywords are returned as uppercase, with multi-word terms (e.g. DEFAULT CHARACTER SET) as a single token. Strings and escaped identifiers are not further processed; they are returned exactly as expressed in the input SQL.

By default, the tokenizer will ignore unterminated comments and strings, and stop parsing at that point, producing no further tokens. You can set $parser->throw_on_bad_syntax = true; to throw an exception of type iamcal\SQLParserSyntaxException instead.

Performance

My test target is an 88K SQL file containing 114 tables from Glitch's main database.

The first version, using php-sql-parser, took over 60 seconds just to lex the input. This was obviously not a great option.

The current implementation uses a hand-written lexer which takes around 140ms to lex the same input and imposes less odd restrictions. This seems to be the way to go.

History

This library was created to parse multiple CREATE TABLE schemas and compare them, so figure out what needs to be done to migrate one to the other.

This is based on the system used at b3ta, Flickr and then Tiny Speck to check the differences between production and development databases and between shard instances. The original system just showed a diff (see SchemaDiff), but that was a bit of a pain.

Unsupported features

MySQL table definitions have a lot of options, so some things just aren't supported. They include:

  • UNION table properties
  • TABLESPACE table properties
  • table partitions
  • FLOAT[(bits)] fields
  • Deprecated YEAR(2|4) fields
  • ASCII attribute as a shorthand for CHARACTER SET latin1
  • UNICODE attribute as a shorthand for CHARACTER SET ucs2
  • NATIONAL modified for CHAR and VARCHAR fields

If you need support for one of these features, open an issue or (better) send a pull request with tests.

The specs for each of the four field groupings can be found here:

  • https://dev.mysql.com/doc/refman/5.7/en/numeric-type-syntax.html
  • https://dev.mysql.com/doc/refman/5.7/en/date-and-time-type-syntax.html
  • https://dev.mysql.com/doc/refman/5.7/en/string-type-syntax.html
  • https://dev.mysql.com/doc/refman/5.7/en/spatial-type-overview.html

Alternatives

If you're using PHP, then Modyllic is a great SQL parser and set of schema management tools.

If you're using Hack, then Hack SQL Fake allows you to parse SQL and create a fake MySQL server for testing, with many (but not all!) features of MySQL.

Publishing

To publish a new version:

  • Commit changes to master
  • Add git tag
  • Go to https://packagist.org/packages/iamcal/sql-parser and hit "Update"

About

Parse MySQL schemas in PHP, fast

Topics

autoloadercomposerdatabaselexphpsql-parser

Resources

Readme
MIT license
Activity

Stars

78 stars

Watchers

3 watching

Forks

21 forks
Report repository

Releases

Packages

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.