/** * setup / update table schema * @static * @param $db * @param $table * @param $fields * @return bool */ public static function setup($db = null, $table = null, $fields = null) { /** @var Cortex $self */ $self = get_called_class(); if (is_null($db) || is_null($table) || is_null($fields)) { $df = $self::resolveConfiguration(); } if (!is_object($db = is_string($db = $db ?: $df['db']) ? \Base::instance()->get($db) : $db)) { trigger_error(self::E_CONNECTION); } if (strlen($table = $table ?: $df['table']) == 0) { trigger_error(self::E_NO_TABLE); } if (is_null($fields)) { if (!empty($df['fieldConf'])) { $fields = $df['fieldConf']; } elseif (!$df['fluid']) { trigger_error(self::E_FIELD_SETUP); return false; } else { $fields = array(); } } if ($db instanceof SQL) { $schema = new Schema($db); // prepare field configuration if (!empty($fields)) { foreach ($fields as $key => &$field) { // fetch relation field types $field = static::resolveRelationConf($field); // check m:m relation if (array_key_exists('has-many', $field)) { // m:m relation conf [class,to-key,from-key] if (!is_array($relConf = $field['has-many'])) { continue; } $rel = $relConf[0]::resolveConfiguration(); // check if foreign conf matches m:m if (array_key_exists($relConf[1], $rel['fieldConf']) && !is_null($rel['fieldConf'][$relConf[1]]) && $relConf['hasRel'] == 'has-many') { // compute mm table name $fConf = $rel['fieldConf'][$relConf[1]]['has-many']; $mmTable = static::getMMTableName($rel['table'], $relConf[1], $table, $key, $fConf); // create dummy to invoke table $mmRel = new Cortex($db, $mmTable, true); $rand = rand(0, 1000000); $mmRel->{$relConf[1]} = $rand; $mmRel->{$key} = $rand; $mmRel->save(); $mmRel->reset(); $mmRel->erase(array($relConf[1] . ' = :rand AND ' . $key . ' = :rand', ':rand' => $rand)); } } // skip virtual fields with no type if (!array_key_exists('type', $field)) { unset($fields[$key]); continue; } // transform array fields if (in_array($field['type'], array(self::DT_JSON, self::DT_SERIALIZED))) { $field['type'] = $schema::DT_TEXT; } // defaults values if (!array_key_exists('nullable', $field)) { $field['nullable'] = true; } } } if (!in_array($table, $schema->getTables())) { // create table $table = $schema->createTable($table); foreach ($fields as $field_key => $field_conf) { $table->addColumn($field_key, $field_conf); } $table->build(); } else { // add missing fields $table = $schema->alterTable($table); $existingCols = $table->getCols(); foreach ($fields as $field_key => $field_conf) { if (!in_array($field_key, $existingCols)) { $table->addColumn($field_key, $field_conf); } } // remove unused fields // foreach ($existingCols as $col) // if (!in_array($col, array_keys($fields)) && $col!='id') // $table->dropColumn($col); $table->build(); } } return true; }