[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
Data Shendy
/
Back up Shendy
/
DATA
/
amd64
/
httpd
/
htdocs
/
bulian
/
lib
/
Table
/
[
Home
]
File: Blueprint.php
<?php /** * @author Drajat Hasan * @email drajathasan20@gmail.com * @create date 2022-05-30 11:08:37 * @modify date 2022-09-28 15:52:28 * @license GPLv3 * @desc [description] */ namespace SLiMS\Table; use RuntimeException; class Blueprint { /** * A collection for table data * * @var array */ private $data = [ 'columns' => [], 'rdbmsOpt' => ['engine' => '', 'charset' => '', 'collation' => ''], 'options' => [], ]; /** * Grammar supported * * @var string */ private $rdbmsGrammar = 'Mysql'; /** * Grammar class * * @var [type] */ private $grammarClass = null; /** * Mode type */ private $type = ''; /** * Set grammar class for static * call * * @return void */ private function setGrammarClass() { $rdbmsGrammarClass = '\SLiMS\Table\Grammar\\' . $this->rdbmsGrammar; if (!class_exists($rdbmsGrammarClass)) throw new RuntimeException("Error : grammar {$rdbmsGrammarClass} not found!"); if (is_null($this->grammarClass)) $this->grammarClass = $rdbmsGrammarClass; } /** * Get detail table data * * @return void */ public function getData() { return $this->data; } /** * Magic method to processing * method call in this object or in the * grammar * * @param string $method * @param array $params * @return void */ public function __call(string $method = '', array $params = []) { $this->setGrammarClass(); /** * Column type checking */ if (!is_null($type = $this->grammarClass::getType($method))) { $columnName = $params[0]; $constraint = isset($params[1]) ? '(' . $params[1] . ')' : ''; $this->data['columns'][] = trim(<<<SQL `{$columnName}` {$type}$constraint SQL); return $this; } /** * Special method in grammar */ if (method_exists($this->grammarClass, $method)) { $this->data['columns'][] = trim($this->grammarClass::$method($params[0], $params[1])); return $this; } /** * If method not exists in Grammar, chekck in scope */ $scopeMethod = 'scope' . ucfirst($method); if (method_exists($this, $scopeMethod) && !is_null($value = call_user_func_array([$this, $scopeMethod], $params))) { $this->data['columns'][] = $value; return $this; } return $this; } /** * Set a property for rdmsOpt * * @param string $key * @param [type] $value */ public function __set(string $key, $value) { if (isset($this->data['rdbmsOpt'][$key])) { $this->data['rdbmsOpt'][$key] = $value; } } /** * Default migrations table architecture * * @return void */ public static function migrationArchitecture() { $static = new static; $static->engine = 'MyISAM'; $static->autoIncrement('id'); $static->string('filehash', 256)->nullable(); $static->string('filepath', 256)->nullable(); $static->string('class', 256)->nullable(); $static->string('version', 50)->nullable(); $static->index('class'); $static->timestamps(); return $static->grammarClass::create('migrations', $static->getData(), true); } /** * Compile a data with grammar compiler and created * SQL text * * @param string $tableName * @return void */ public function create(string $tableName) { if (!class_exists($this->grammarClass)) return; return $this->grammarClass::create($tableName, $this->getData()); } /** * Alter existing table * * @param string $tableName * @return void */ public function alter(string $tableName) { if (!class_exists($this->grammarClass)) return; return $this->grammarClass::alter($tableName, $this->getData()); } /** * Scope for id column * * @return void */ private function scopeId() { return '`id` int(11) NOT NULL'; } /** * Scope for autoincrement column * * @param string $columnName * @return void */ private function scopeAutoIncrement(string $columnName) { return '`' . $columnName . '` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY'; } /** * Create timestamps column * by default created_at and updated_at as * default column name * * @return void */ private function scopeTimestamps() { return '`created_at` timestamp NULL, `updated_at` timestamp DEFAULT NOW()'; } /** * Create fulltext key * * @param string $columnName * @return void */ private function scopeFulltext(string $columnName) { $this->type = 'option'; $this->data['options'][] = 'FULLTEXT KEY `' . $columnName . '_fulltext` (`' . $columnName . '`)'; } /** * Create index key * * @param string $columnName * @return void */ private function scopeIndex(string $columnName) { $this->type = 'option'; $this->data['options'][] = 'KEY `' . $columnName . '_index` (`' . $columnName . '`)'; } /** * Set primarykey * * @param string $columnName * @return void */ private function scopePrimary($columnName = '') { $this->type = 'option'; if (empty($columnName) && !is_array($columnName)) { $lastIndexData = array_key_last($this->data['columns']); $this->data['columns'][$lastIndexData] = $this->data['columns'][$lastIndexData] . ' PRIMARY KEY'; } else if (is_array($columnName)) { $this->data['options'][] = 'PRIMARY KEY (`' . implode('`,`', $columnName) . '`)'; } else { $this->data['options'][] = 'PRIMARY KEY (`' . $columnName . '`)'; } } /** * Set null as default value * * @return void */ private function scopeNullable() { $lastIndexData = array_key_last($this->data['columns']); $this->data['columns'][$lastIndexData] = $this->data['columns'][$lastIndexData] . ' DEFAULT NULL'; } /** * Set not null as default value * * @return void */ private function scopeNotNull() { $lastIndexData = array_key_last($this->data['columns']); $this->data['columns'][$lastIndexData] = $this->data['columns'][$lastIndexData] . ' NOT NULL'; } /** * Set column after existsting column * * @param string $columnName * @return void */ private function scopeAfter(string $columnName) { $lastIndexData = array_key_last($this->data['columns']); $this->data['columns'][$lastIndexData] = $this->data['columns'][$lastIndexData] . ' AFTER `' . $columnName . '`'; } /** * Set a columnt at first order of table * * @return void */ private function scopeFirst() { $lastIndexData = array_key_last($this->data['columns']); $this->data['columns'][$lastIndexData] = $this->data['columns'][$lastIndexData] . ' FIRST'; } /** * Change column attribute * * @return void */ private function scopeChange(string $newColumnName = '') { $lastIndexData = array_key_last($this->data['columns']); $perWord = explode(' ', $this->data['columns'][$lastIndexData]); // 0 as column name $this->data['columns'][$lastIndexData] = 'CHANGE ' . $perWord[0] . ' ' . (!empty($newColumnName) ? $newColumnName : $this->data['columns'][$lastIndexData]); } /** * Add column into existing table */ private function scopeAdd() { $type = empty($this->type) ? 'columns' : 'options'; $lastIndexData = array_key_last($this->data[$type]); $perWord = explode(' ', $this->data[$type][$lastIndexData]??''); // 0 as column name $this->data[$type][$lastIndexData] = 'ADD ' . ($this->data[$type][$lastIndexData]??''); $this->type = ''; } /** * Delete existing column * * @param string $columnName * @return void */ private function scopeDrop(string $columnName) { $lastIndexData = array_key_last($this->data['columns']); if (count($this->data['columns']) === 0) $lastIndexData = 0; if (count($this->data['columns']) > 0) ++$lastIndexData; $this->data['columns'][$lastIndexData] = 'DROP ' . $columnName; } /** * Set default value with specific data * * @param string $value * @return void */ private function scopeDefault(string $value) { $lastIndexData = array_key_last($this->data['columns']); $this->data['columns'][$lastIndexData] = $this->data['columns'][$lastIndexData] . ' DEFAULT \'' . $value . '\''; } }