Skip to content

Instantly share code, notes, and snippets.

@pentagonal
Last active June 18, 2017 07:11
Show Gist options
  • Save pentagonal/6e0cdb5116e66f74890676cd8a83f102 to your computer and use it in GitHub Desktop.
Save pentagonal/6e0cdb5116e66f74890676cd8a83f102 to your computer and use it in GitHub Desktop.
Custom Array Table Schema With SQL Migration (Use Doctrine DBAL { @link https://github.com/doctrine/dbal } )
<?php
/**
* prototype of Builder & Extending Doctrine DBAL
* please see { @link https://github.com/PentagonalProject/ProjectSeventh/tree/development }
*/
use Doctrine\DBAL\DriverManager;
/**
* List Scheme
*/
$scheme = [
"user" => [
"id" => [
"bigint", // type
[
"autoincrement" => true,// auto increments
"length" => 10, // length
'index' => true, // add indexing
]
],
"username" => [
"varchar", // varchar detect as string
[
"default" => "", // use default
'length' => 500
]
],
"password" => [
"string",
[
"length" => 64
]
],
"property" => [
"text", // text by default and set no length will be use LONGTEXT
[
"comment" => "This Is Comments"
]
]
],
"inventory" => [
"id" => [
"bigint",
[
"autoincrement" => 1,
"length" => 10,
"primaryKey" => true
]
],
"goods_name" => [
"string",
[
"length" => 255
]
],
"goods_stocks" => [
"int",
[
"length" => 6
]
],
]
];
$params = [
'host' => 'localhost',
'user' => 'root',
'password' => 'mysql',
'dbname' => 'dbname',
'port' => 3306,
'driver' => 'mysql',
'charset' => 'utf8',
'collate' => 'utf8_unicode_ci',
];
$database = DriverManager::getConnection($params);
$queryArray = getSQLWithDatabase(
$scheme,
$database->getDatabasePlatform(),
$database->getSchemaManager()->createSchema()
);
<?php
/**
* prototype of Builder & Extending Doctrine DBAL
* please see { @link https://github.com/PentagonalProject/ProjectSeventh/tree/development }
*/
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
/**
* Additional Doctrine Mapping Type Helper To Fix Type Map
*
* @param string $type
* @return string|null null if not match
*/
function resolveDoctrineTypeMap($type)
{
if (!is_string($type)) {
return null;
}
$type = strtolower($type);
preg_match(
'#
(?P<binary>bin)
| (?P<datetimez>datetimez|timez)
| (?P<guid>gu|id)
| (?P<datetime>date)
| (?P<time>time?)
| (?P<blob>blob)
| (?P<text>text|long)
| (?P<string>enum|char|string|var)
| (?P<boolean>bool)
| (?P<smallint>small)
| (?P<bigint>big)
| (?P<decimal>dec)
| (?P<float>float)
| (?P<integer>int|num(?:ber)?)
| (?P<json_array>json)
| (?P<array>array)
| (?P<object>obj)
#x',
$type,
$match,
PREG_NO_ERROR
);
$match = array_filter($match, function ($value, $key) {
return ! is_numeric($key) && ! empty($value);
}, ARRAY_FILTER_USE_BOTH);
return key($match);
}
/**
* Build Scheme
*
* @param array $scheme
* @return array
*/
function buildSchemes(array $scheme) : array
{
/**
* List Available Properties
*
* @var array
*/
$availableOptions = [
'column' => [
'autoincrement' => 'boolean',
'length' => 'integer',
'precision' => 'integer',
'scale' => 'integer',
'unsigned' => 'boolean',
'fixed' => 'boolean',
'notnull' => 'boolean',
'default' => 'mixed',
'comment' => 'string',
],
'table_set' => [
'primarykey' => 'mixed',
],
'table_add' => [
'index' => 'mixed',
'uniqueindex' => 'mixed',
'foreignkey' => 'array',
'foreignkeyconstraint' => 'array',
],
];
// list Invalid Scheme for cached
$invalidScheme = [];
// list valid Scheme
$schemes = [];
foreach ($scheme as $table => $definitions) {
if (!is_array($definitions)) {
$invalidScheme[$table] = true;
continue;
}
foreach ($definitions as $column => $definition) {
$columnType = resolveDoctrineTypeMap(reset($definition));
if (!$columnType) {
$invalidScheme[$table] = true;
break;
}
$options = (array) next($definition);
$properties = [];
foreach ($options as $optionKey => $value) {
unset($options[$optionKey]);
if (is_numeric($optionKey)) {
continue;
}
$optionKey = strtolower($optionKey);
if (isset($availableOptions['column'][$optionKey])) {
$type = $availableOptions['column'][$optionKey];
if ($type !== 'mixed') {
$oldValue = $value;
if (!settype($value, $type)) {
$value = $oldValue;
}
}
$options[$optionKey] = $value;
continue;
}
if (isset($availableOptions['table_set'][$optionKey])) {
if (!is_string($value)) {
$value = (bool) $value;
}
if ($value === false) {
continue;
}
$properties['set'][$optionKey][$column] = $value === '' ? true : $value;
} elseif (isset($availableOptions['table_add'][$optionKey])) {
if ($optionKey == 'unique') {
$optionKey = 'uniqueindex';
} elseif ($optionKey == 'foreignkeyconstraint') {
$optionKey = 'foreignkeyconstraint';
}
$type = $availableOptions['table_add'][$optionKey];
if ($type === 'array') {
if (gettype($value) !== 'array') {
continue;
}
if (!empty($value)) {
$properties['add'][$optionKey][$column] = $value;
}
continue;
}
if (strpos($optionKey, 'index') !== false) {
$value = ! is_string($value) ? $column . '_' . (string) $value : $value;
$value = preg_replace('/[^a-z0-9\_]/i', '_', $value);
}
if (!is_string($value)) {
$value = (bool) $value;
}
$properties['add'][$optionKey][$column] = $value;
}
}
if (isset($options['autoincrement']) && ! isset($properties['set']['primarykey'][$column])) {
$properties['set']['primarykey'][$column] = true;
}
$definitions[$column] = [
"type" => $columnType,
"options" => $options,
"properties" => $properties
];
}
if (!isset($invalidScheme[$table])) {
$schemes[$table] = $definitions;
}
}
return $schemes;
}
/**
* Convert Into Column
*
* @param array $scheme
* @return array|Table[]
*/
function getTablesFromSchemes(array $scheme) : array
{
$cachedTable = [];
foreach (buildSchemes($scheme) as $tableName => $columns) {
$table = new Table(
$tableName
);
foreach ($columns as $columnName => $definitions) {
$table->addColumn(
$columnName,
$definitions['type'],
$definitions['options']
);
if (isset($definitions['properties']['set'])) {
foreach ($definitions['properties']['set'] as $context => $value) {
foreach ($value as $newContext => $realValue) {
$args = [ [$newContext], (is_string($realValue) ? $realValue : false)];
call_user_func_array(
[
$table,
"set{$context}"
],
$args
);
}
}
}
if (! empty($definitions['properties']['add']) && is_array($definitions['properties']['add'])) {
foreach ($definitions['properties']['add'] as $context => $value) {
foreach ($value as $newContext => $realValue) {
// use for Foreign Key
if (is_array($realValue)) {
$args = [$newContext, $realValue];
$context = 'foreignkeyconstraint';
} else {
$args = [ [$newContext], (is_string($realValue) ? $realValue : false)];
}
call_user_func_array(
[
$table,
"add{$context}"
],
$args
);
}
}
}
}
$cachedTable[$tableName] = $table;
}
return $cachedTable;
}
/**
* Get SQL Migration Of Query as Array
*
* @param array $scheme
* @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
* @param \Doctrine\DBAL\Schema\Schema $schema
* @return array|string[] Query String as Array
*/
function getSQLWithDatabase(
array $scheme,
AbstractPlatform $platform,
Schema $schema = null
) : array {
/**
* @var \Doctrine\DBAL\Schema\Schema $schemaTables
*/
$schemaTables = new Schema(getTablesFromSchemes($scheme));
$schema = $schema?: new \Doctrine\DBAL\Schema\Schema();
return $schemaTables->getMigrateFromSql(
$schema,
$platform
);
}
@pentagonal
Copy link
Author

This is Partial Of Some Dependency Project Of Kimcil & MbamBleh Project
BeautiPulll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment