예제 #1
0
 /**
  * Get the MySQL-specific representation of a value for a column
  * @param Column $column
  * @param mixed $value
  * @return mixed
  */
 public function getColumnDenormalizedValue(Column $column, $value)
 {
     if ($value === null) {
         return null;
     } else {
         switch ($column->getType()) {
             case 'date':
                 return date('Ymd', $value);
                 break;
             case 'datetime':
                 return date('Y-m-d\\TH:i:s', $value);
                 break;
             default:
                 return $value;
                 break;
         }
     }
 }
예제 #2
0
 /**
  * Get a Table object for the given name
  * TODO table/column properties should not be public
  * @param Database $database
  * @param string $name
  * @throws \Exception
  * @return Table
  */
 public function buildTable(Database $database, $name)
 {
     $createTableInfo = $this->fetchAll("SHOW CREATE TABLE `{$database->getPrefix()}{$name}`");
     if (!isset($createTableInfo[0]['Create Table'])) {
         throw new \Exception('Could not find table ' . $name);
     }
     $createTableSql = $createTableInfo[0]['Create Table'];
     $columns = [];
     $primaryKeys = [];
     $constraints = [];
     $lowerToRealCaseTableNames = [];
     $actualTableNames = [];
     foreach ($this->getTables($database) as $tableName) {
         $actualTableNames[$tableName] = true;
         $lowerToRealCaseTableNames[strtolower($tableName)] = $tableName;
     }
     // parse columns
     if (preg_match_all(self::CREATE_TABLE_SQL_COLUMNS_REGEX, $createTableSql, $columns, PREG_SET_ORDER)) {
         $tableClass = $database->getClassMapper()->getClassForTable($name);
         /** @var Table $table */
         $table = new $tableClass($name, $database);
         foreach ($columns as $ordinal => $columnInfo) {
             $column = new Column($table);
             $default = null;
             if (isset($columnInfo['default']) && $columnInfo['default'] !== 'NULL') {
                 if ($columnInfo['default'] === '') {
                     $default = '';
                 } else {
                     if ($columnInfo['default'] !== 'CURRENT_TIMESTAMP' && $columnInfo['default'] !== 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP') {
                         // we need to parse the SQL default value
                         $defaultResult = $this->fetchAll('SELECT ' . $columnInfo['default']);
                         $default = current(current($defaultResult));
                     }
                 }
             }
             $column->setName($columnInfo['name'])->setOrdinal($ordinal)->setType(strtolower($columnInfo['type']))->setDefault($default)->setAllowNull(!isset($columnInfo['allowNull']) || $columnInfo['allowNull'] === 'NULL')->setAutoIncrement(!empty($columnInfo['autoIncrement']));
             if ($column->getType() == 'set' || $column->getType() == 'enum') {
                 // we need to parse the SQL options
                 $optionsResult = $this->fetchAll('SELECT ' . $columnInfo['length']);
                 $options = [];
                 $i = 0;
                 foreach (current($optionsResult) as $option) {
                     $options[$column->getType() == 'set' ? pow(2, $i) : $i] = $option;
                     $i++;
                 }
                 $column->setOptions($options);
             } else {
                 $column->setLength(isset($columnInfo['length']) && $columnInfo['length'] !== '' ? $columnInfo['length'] : null);
             }
             $table->columns[$column->getName()] = $column;
         }
         // parse primary keys
         preg_match(self::CREATE_TABLE_SQL_PRIMARY_KEY_REGEX, $createTableSql, $primaryKeys);
         $primaryKeys = explode('`,`', trim($primaryKeys[1], '`'));
         foreach ($primaryKeys as $primaryKey) {
             $table->primaryKeys[] = $primaryKey;
             $table->columns[$primaryKey]->setPrimaryKey(true);
         }
         // parse relationships
         preg_match_all(self::CREATE_TABLE_SQL_CONSTRAINT_REGEX, $createTableSql, $constraints, PREG_SET_ORDER);
         $offset = strlen($database->getPrefix());
         foreach ($constraints as $constraint) {
             $localColumns = explode('`, `', trim($constraint['localColumns'], '`'));
             $relatedColumns = explode('`, `', trim($constraint['relatedColumns'], '`'));
             foreach ($localColumns as $localColumn) {
                 if (!isset($table->foreignKeys[$localColumn])) {
                     // columns can have multiple foreign keys; we can only use one of them
                     $table->foreignKeys[$localColumn] = $constraint['name'];
                 }
             }
             $foreignTableName = substr($constraint['relatedTable'], $offset);
             // workaround for http://bugs.mysql.com/bug.php?id=6555
             // map lower case table names to actual case table names
             if (!isset($actualTableNames[$foreignTableName]) && isset($lowerToRealCaseTableNames[$foreignTableName])) {
                 $foreignTableName = $lowerToRealCaseTableNames[$foreignTableName];
             }
             if (!isset($table->relatedTables[$foreignTableName])) {
                 // tables can be related to another table multiple times; we can only use one of them
                 $table->relatedTables[$foreignTableName] = $constraint['name'];
             }
             $table->constraints[$constraint['name']] = ['localColumns' => $localColumns, 'relatedTable' => $foreignTableName, 'relatedColumns' => $relatedColumns];
         }
         return $table;
     } else {
         throw new \Exception('Could not parse table definition');
     }
 }