DBML parser for PHP8. It's a PHP parser for DBML syntax.

Overview

DBML parser written on PHP8

Support me on Patreon Latest Stable Version Build Status Total Downloads License

DBML-parser

DBML (database markup language) is a simple, readable DSL language designed to define database structures. This page outlines the full syntax documentations of DBML.

See https://www.dbml.org

Work on this parser inspired by service - https://dbdiagram.io/ I like using db diagram service for visualizing database structure. It will be great to use db diagram to build database schema and then convert it to Object tree and then generate, for example, Laravel models and migrations.

For parsing dbml structure I used a very useful php package - https://phplrt.org.

Features

  • DBML parser

Requirements

  • PHP 8.0 and above

Quick start

From the command line run

composer require butschster/dbml-parser

That's it!

Usage

use Butschster\Dbml\DbmlParserFactory;

$parser = DbmlParserFactory::create();

$schema = $parser->parse(<<<DBML
    Project test {
        database_type: 'PostgreSQL'
        Note: 'Description of the project'
    }
    
    //// -- LEVEL 1
    //// -- Tables and References
    
    // Creating tables
    Table users as U {
        id int [pk, unique, increment] // auto-increment
        full_name varchar [not null, unique, default: 1]
        created_at timestamp
        country_code int
        type int
        note int
        Note: 'khong hieu duoc'
    }
    
    Table merchants {
        id int
    }
    
    Table countries {
        code int [pk]
        name varchar
        continent_name varchar
    }
    
    // Creating references
    // You can also define relationship separately
    // > many-to-one; < one-to-many; - one-to-one
    Ref{
        U.country_code > countries.code
        merchants.country_code > countries.code
    }
    
    //----------------------------------------------//
    
    //// -- LEVEL 2
    //// -- Adding column settings
    
    Table order_items {
        order_id int [ref: > orders.id]
        product_id int
        quantity int [default: 1] // default value
    }
    
    Ref: order_items.product_id > products.id
    
    Table orders {
        id int [pk] // primary key
        user_id int [not null, unique]
        status varchar
        created_at varchar [note: '''When order created'''] // add column note
    }
    
    Table int {
        id int
    }
    
    //----------------------------------------------//
    
    //// -- Level 3
    //// -- Enum, Indexes
    
    // Enum for 'products' table below
    Enum products_status {
        out_of_stock
        in_stock
        running_low [note: 'less than 20'] // add column note
    }
    
    // Indexes: You can define a single or multi-column index
    Table products {
        id int [pk]
        name varchar
        merchant_id int [not null]
        price int
        status products_status
        created_at datetime [default: `now()`]
    
        Indexes {
            (merchant_id, status) [name:'product_status', type: hash]
            id [unique]
        }
    }
    
    Ref: products.merchant_id > merchants.id // many-to-one
    
    TableGroup hello_world {
        just_test
        just_a_test
    }

    DBML
);

Schema data

// List of tables
$tables = $schema->getTables(); // \Butschster\Dbml\Ast\TableNode[]

// Check if table exists
$schema->hasTable('users');

// Get table by name
$table = $schema->getTable('users'); // \Butschster\Dbml\Ast\TableNode[]

// Get project data
$project = $schema->getProject(); // \Butschster\Dbml\Ast\ProjectNode

// Get table groups
$tableGroups = $schema->getTableGroups(); // \Butschster\Dbml\Ast\TableGroupNode[]

// Check if table group with given name exists
$schema->hasTableGroup('name');

// Get table group object by name
$tableGroup = $schema->getTableGroup('name'); // \Butschster\Dbml\Ast\TableGroupNode

// Get enums
$enums = $schema->getEnums(); // \Butschster\Dbml\Ast\EnumNode[]

// Check if enum with given name exists
$schema->hasEnum('name');

// Get enum object by name
$enum = $schema->getEnum('name'); // \Butschster\Dbml\Ast\EnumNode

// Get refs
$refs = $schema->getRefs(); // \Butschster\Dbml\Ast\RefNode[]

Project data

Project test {
    database_type: 'PostgreSQL'
    Note: 'Description of the project'
}
/** @var \Butschster\Dbml\Ast\ProjectNode $project */
$project = $schema->getProject();
$name = $project->getName(); // test
$note = $project->getNote(); // Description of the project

/** @var \Butschster\Dbml\Ast\Project\SettingNode $setting */
$setting = $project->getSetting('database_type');
$databaseType = $setting->getValue(); // PostgreSQL
$key = $setting->getKey(); // database_type

Table data

Table users as U {
    id int [pk, unique, increment] // auto-increment
    full_name varchar [not null, unique, default: 1]
    created_at timestamp
    country_code int
    type int
    note int
    Note: 'khong hieu duoc'
}
/** @var \Butschster\Dbml\Ast\TableNode $table */
$table = $schema->getTable('users');

$name = $table->getName(); // users
$alias = $table->getAlias(); // U

$note = $table->getNote(); // khong hieu duoc

// Get table columns
$columns = $table->getColumns(); // \Butschster\Dbml\Ast\Table\ColumnNode[]

// Check if table column exists
$table->hasColumn('id');

// Get column by name
$column = $table->getColumn('id');

// Get table indexes
$indexes = $table->getIndexes(); // \Butschster\Dbml\Ast\Table\IndexNode[]

Table column data

Table users as U {
    id int [pk, unique, increment] // auto-increment
}
/** @var \Butschster\Dbml\Ast\Table\ColumnNode $column */
$column = $schema->getTable('users')->getColumn('id');

$name = $column->getName(); // id
$type = $column->getType()->getName(); // int
$size = $column->getType()->getSize(); // null|int

$note = $column->getNote(); // string

$refs = $column->getRefs(); // \Butschster\Dbml\Ast\RefNode[]

/** @var \Butschster\Dbml\Ast\Values\IntNode $default */
$default = $column->getDefault(); 
$value = $default->getValue(); // 1

// Check if column is primary
$column->isPrimaryKey();

// Check if column is auto increment
$column->isIncrement();

// Check if column is unique
$column->isUnique();

// heck if column is nullable
$column->isNull();

Table index data

Table products {
    id int [pk]
    name varchar
    merchant_id int [not null]
    price int
    status products_status
    created_at datetime [default: `now()`]
    
    Indexes {
        (merchant_id, status) [name:'product_status', type: hash]
        id [unique]
    }
}
/** @var \Butschster\Dbml\Ast\Table\IndexNode $index */
$index = $schema->getTable('products')->getIndexes()[0];

/** @var \Butschster\Dbml\Ast\Values\StringNode[]|\Butschster\Dbml\Ast\Values\ExpressionNode[] $columns */
$columns = $index->getColumns();

count($columns); // 2

$column1 = $index->getColumns()[0]->getValue(); // merchant_id
$column2 = $index->getColumns()[1]->getValue(); // status

$type = $index->getType(); // hash
$name = $index->getName(); // product_status

$note = $index->getNote();

// Check if index is pk
$index->isPrimaryKey(); 

// Check if index is unique
$index->isUnique(); 

Enum data

Enum products_status {
  out_of_stock
  in_stock
  running_low [note: 'less than 20'] // add column note
}
/** @var \Butschster\Dbml\Ast\EnumNode $enum */
$enum = $schema->getEnum('products_status');

$name = $enum->getName(); // products_status

// Get amount of values
$enum->count(); // 3

// Check if enum contains value
$enum->hasValue('out_of_stock'); // true

// Get enum value object by name
$value = $enum->getValue('running_low'); //  \Butschster\Dbml\Ast\Enum\ValueNode

$note = $value->getNote();
$value = $value->getValue();

Table group data

TableGroup hello_world {
    just_test
    just_a_test
}
/** @var \Butschster\Dbml\Ast\TableGroupNode $group */
$group = $schema->getTableGroup('hello_world');

$name = $group->getName(); // hello_world

// Check if table with given name contains in this group
$group->hasTable('just_test');

// Get list of tables
$tables = $group->getTables(); // string[]

Ref data

Ref optional_name: products.merchant_id > merchants.(id, name) [delete: cascade, update: no action]
/** @var \Butschster\Dbml\Ast\RefNode $ref */
$ref = $schema->getRefs()[0];

$name = $ref->getName(); // optional_name

$type = $ref->getType(); // \Butschster\Dbml\Ast\Ref\Type\ManyToOneNode

$leftTable = $ref->getLeftTable(); // \Butschster\Dbml\Ast\Ref\LeftTableNode
$table = $leftTable->getTable(); // products
$columns = $leftTable->getColumns(); // ['merchant_id']

$rightTable = $ref->getRightTable(); // \Butschster\Dbml\Ast\Ref\RightTableNode
$table = $rightTable->getTable(); // merchants
$columns = $rightTable->getColumns(); // ['id', 'name']

$onDelete = $ref->getAction('delete');
$action = $onDelete->getAction(); // cascade

$onUpdate = $ref->getAction('update');
$action = $onUpdate->getAction(); // no action

Enjoy!

You might also like...
A simple PHP package for sending messages to Slack, with a focus on ease of use and elegant syntax.

Slack for PHP A simple PHP package for sending messages to Slack with incoming webhooks, focussed on ease-of-use and elegant syntax. Note: this packag

Kiaan PHP is a web application framework with expressive, elegant syntax.

About Kiaan framework Kiaan is a web application framework for PHP. Kiaan is easy, flexible and professional. Documentation You can learn kiaan with t

Shiki is a beautiful syntax highlighter powered by the same language engine that many code editors use.
Shiki is a beautiful syntax highlighter powered by the same language engine that many code editors use.

Shiki is a beautiful syntax highlighter powered by the same language engine that many code editors use. This package allows you to use Shiki from PHP.

A Sublime Text 3 package for highlighting both Sass and SCSS syntax.

Syntax Highlighting for Sass This is a Sublime Text 3 package which purely forced on highlighting both Sass and SCSS syntax as accuracy as possible. P

Spf codemirror - CodeMirror syntax-highlighting for Textpattern
Spf codemirror - CodeMirror syntax-highlighting for Textpattern

spf_codemirror I’m no longer able to develop this plugin due to ill health. If anyone would like to take over, message me, and I’ll transfer the sourc

A PHP parser written in PHP

PHP Parser This is a PHP 5.2 to PHP 8.1 parser written in PHP. Its purpose is to simplify static code analysis and manipulation. Documentation for ver

Parsica - PHP Parser Combinators - The easiest way to build robust parsers.

Parsica The easiest way to build robust parsers in PHP. composer require parsica-php/parsica Documentation & API: parsica-php.github.io ?php $parser

PHP Simple M3U Parser, it clean the playlist and remove duplicate

SimpleM3UParser PHP Simple M3U Playlist Parser, it clean, remove duplicate, and group the playlist. Usage see example.php ?php require_once "M3UPars

Referer-parser PHP library

referer-parser PHP library This is the PHP implementation of referer-parser, the library for extracting search marketing data from referer (sic) URLs.

Comments
  • Combined changes

    Combined changes

    Hi Pavel,

    I made words as Project also a token als lowercase. I updated the way ref works, so that ref in the name of a column does not break Made isNull for a column the default value

    Made changes to tests according to above changes.

    enhancement 
    opened by JurjenRoels 2
  • Made changes through compiler and updated tests

    Made changes through compiler and updated tests

    I Made the changes this time through the pp2 file and recompiled. The output I put in the grammar.php.

    Also changed the tests, to see if the automatic build will succeed.

    bug enhancement 
    opened by JurjenRoels 1
  • Additions en suggestions

    Additions en suggestions

    Hello,

    nice work. I would like to suggest some changes:

    • instead of keyword ref|Ref I would use ref:|Ref: (This needs some rework probably. table columns starting with ref give an error now)
    • Also use lowercase for tables, projects, etc.
    • 'T_TABLE_SETTING_PK should be primary\skey|pk| (the y is missing)
    • null is not accepted. not null is. The default in ColumnNode is false. This should be true as default when null is not accepted. (See below)
     Syntax error, unexpected "null" (T_NULL)
      43. | identificatieString varchar [unique, null]
          |                                      ^^^^
    
    

    Maybe I will find more, I will be testing with some dbml's

    Good work!

    Jurjen Roels

    enhancement 
    opened by JurjenRoels 4
Releases(v0.2)
  • v0.2(Nov 2, 2022)

    What's Changed

    • Combined changes by @JurjenRoels in https://github.com/butschster/dbml-parser/pull/7

    New Contributors

    • @JurjenRoels made their first contribution in https://github.com/butschster/dbml-parser/pull/7

    Full Changelog: https://github.com/butschster/dbml-parser/compare/v0.1...v0.2

    Source code(tar.gz)
    Source code(zip)
Owner
Pavel Buchnev
You can get in touch with me by telegram @butschster
Pavel Buchnev
Validated properties in PHP8.1 and above using attribute rules

PHP Validated Properties Add Rule attributes to your model properties to make sure they are valid. Why this package? When validating external data com

null 23 Oct 18, 2022
JSON <=> PHP8+ objects serialization / deserialization library

A simple library for JSON to PHP Objects conversions Often times, we interact with an API, or data source that returns JSON. PHP only offers the possi

Square 90 Dec 20, 2022
Generally, a graceful shutdown is preferable in the case of any OS that saves its state

Graceful Shutdown with PHP Generally, a graceful shutdown is preferable in the case of any OS that saves its state.

Leonardo Carmo 17 Oct 14, 2022
This project has reached its end-of-life (EOL).

EOL Notice This project has reached its end-of-life (EOL). README Requirements The supported Magento version is 1.9.x Features ajax navigation using h

Catalin Ciobanu 136 Apr 2, 2022
yform 4 usability addon (temporary until yform gets its own)

massif_usability Package für REDAXO CMS >= 5.10.0 temporäres Ersatz-Plugin für yform_usability für yform >=4 – bietet ähnliche Funktionalität wie yfor

Yves Torres 6 Mar 4, 2022
An opinionated extension package for Laravel Orchid to extend its table handling capabilities, and some further useful helper methods.

OrchidTables An opinionated extension package for Laravel Orchid to extend its table handling capabilities, and some further useful helper methods. In

null 25 Dec 22, 2022
PHP Parallel Lint - This tool check syntax of PHP files faster than serial check with fancier output

PHP Parallel Lint This application checks syntax of PHP files in parallel. It can output in plain text, colored text, json and checksyntax formats. Ad

PHP Parallel lint 156 Apr 24, 2022
A lightweight php class for formatting sql statements. Handles automatic indentation and syntax highlighting.

A lightweight php class for formatting sql statements. Handles automatic indentation and syntax highlighting.

Doctrine 1.4k Dec 29, 2022
CPAY is a sdk that encapsulates the Orange Money api with an intuitive syntax allowing you to integrate the Orange Money payment into your PHP project.

CPAY CHOCO PAY is a sdk that encapsulates the Orange Money api with an intuitive syntax allowing you to integrate the Orange Money payment into your P

faso-dev 1 Oct 26, 2022
This tool check syntax of PHP files faster than serial check with fancier output.

PHP Parallel Lint This application checks syntax of PHP files in parallel. It can output in plain text, colored text, json and checksyntax formats. Ad

PHP Parallel lint 202 Dec 22, 2022