Last active
June 18, 2017 07:11
-
-
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 } )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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() | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is Partial Of Some Dependency Project Of Kimcil & MbamBleh Project
