diff --git a/classes/generate.php b/classes/generate.php index 0c15cc26..4ba3aa5f 100644 --- a/classes/generate.php +++ b/classes/generate.php @@ -286,7 +286,7 @@ public static function model($args, $build = true) throw new Exception('No fields have been provided, the model will not know how to build the table.'); } - $plural = \Cli::option('singular') ? $singular : \Inflector::pluralize($singular); + $plural = (\Cli::option('singular') or \Cli::option('no-standardisation')) ? $singular : \Inflector::pluralize($singular); $filename = trim(str_replace(array('_', '-'), DS, $singular), DS); $base_path = APPPATH; @@ -580,9 +580,15 @@ class Model_{$class_name} extends \Model_Crud $keys = array(); foreach($args as $arg) { - if (isset($arg['key']) and $arg['key'] == 'PRI') + if (isset($arg['indexes'])) { - $keys[] = $arg['name']; + foreach ($arg['indexes'] as $idx) + { + if ($idx['primary'] === true) + { + $keys[$idx['order']] = $idx['column']; + } + } } } @@ -1846,16 +1852,32 @@ public static function normalize_args(array $args) $pk = false; foreach ($args as $arg) { - if (isset($arg['key']) and $arg['key'] == 'PRI') + if (isset($arg['indexes'])) { - $pk = true; + foreach ($arg['indexes'] as $idx) + { + if ($idx['primary']) + { + $pk = true; + break; + } + } } } + // keep track of the primary keys added + $pk_counter = 0; + // add a PK if none are present if ( ! $pk and ! \Cli::option('no-standardisation')) { - $normalized['id'] = array('name' => 'id', 'data_type' => 'int', 'unsigned' => true, 'null' => false, 'auto_increment' => true, 'key' => 'PRI', 'constraint' => '11');; + // define the default key column + $normalized['id'] = array('name' => 'id', 'data_type' => 'int', 'unsigned' => true, 'null' => false, 'auto_increment' => true, 'constraint' => '11'); + + // and it's primary index + $normalized['id']['indexes'] = array('PRIMARY' => array( + 'name' => 'PRIMARY', 'column' => 'id', 'order' => strval(++$pk_counter), 'type' => 'BTREE', 'primary' => true, 'unique' => true, 'null' => false, 'ascending' => true, + )); } elseif ($normalized['id'] === null) { @@ -1870,7 +1892,7 @@ public static function normalize_args(array $args) $no_timestamp_default = false; // closure used to add a new field - $add_field = function($args, $name, $type, $options = array()) { + $add_field = function($args, $name, $type, $options = array()) use($pk_counter) { // create the field $field = static::$_field_defaults['_default_']; @@ -1886,6 +1908,20 @@ public static function normalize_args(array $args) $field['type'] = $type; $field['data_type'] = $type; + // need to add an index? + if (isset($options['key'])) + { + // add a primary key + if ($options['key'] == 'PRI') + { + $field['indexes'] = array('PRIMARY' => array( + 'name' => 'PRIMARY', 'column' => $name, 'order' => strval(++$pk_counter), 'type' => 'BTREE', 'primary' => true, 'unique' => true, 'null' => false, 'ascending' => true, + )); + } + + unset($options['key']); + } + // return the result return array_merge($args, array($name => array_merge($field, $options))); }; diff --git a/classes/generate/migration/actions.php b/classes/generate/migration/actions.php index 333ffa5e..9a933670 100644 --- a/classes/generate/migration/actions.php +++ b/classes/generate/migration/actions.php @@ -75,20 +75,62 @@ public static function create($subjects, $fields) // generate the code for the fields list($field_up_str, $not_used, $pks, $idx) = static::_generate_field_string($fields); + // construct the primary key list + $pk_str = ''; + if ($pks) + { + $pk_str = array(); + foreach ($pks as $pk) + { + $pk_str[$pk['order']] = $pk['column']; + } + ksort($pk_str); + $pk_str = ", array('".implode("', '", $pk_str)."')"; + } + + // generate the up() code $up = << $idxval); + } + else + { + $tidx[$idxval['name']][(int)$idxval['order']] = $idxval; + } + } + $up .= PHP_EOL; - foreach ($idx as $field) + foreach ($tidx as $name => $idx) { - $up .= PHP_EOL."\t\t\\DB::query('CREATE INDEX {$field}_idx ON {$table_prefix}{$subjects[1]}(`{$field}`)')->execute();"; - $down .= PHP_EOL."\t\t\\DB::query('DROP INDEX {$field}_idx ON {$table_prefix}{$subjects[1]}')->execute();"; + $field = array(); + foreach ($idx as $fidx) + { + $fidx['column'] = \DB::quote_identifier($fidx['column']); + if ( ! $fidx['ascending']) + { + $fidx['column'] .= ' DESC'; + } + $field[] = $fidx['column']; + } + $unique = reset($idx); + $unique = $unique['unique'] ? ' UNUQUE' : ''; + $field = implode(', ', $field); + $up .= PHP_EOL."\t\t\\DB::query('CREATE{$unique} INDEX {$name} ON {$table_prefix}{$subjects[1]}({$field})')->execute();"; + $down .= PHP_EOL."\t\t\\DB::query('DROP INDEX {$name} ON {$table_prefix}{$subjects[1]}')->execute();"; } $down = ltrim($down, PHP_EOL).PHP_EOL.PHP_EOL; } @@ -161,7 +203,7 @@ public static function add($subjects, $fields) } // generate the code for the fields - list($field_up_str, $field_down_str, $pks, $idx) = static::_generate_field_string($fields); + list($field_up_str, $field_down_str, $not_used, $not_used) = static::_generate_field_string($fields); $up = << \''.$subjects[0].'\', ', str_replace($subjects[0], $subjects[1], $field_up_str)); @@ -306,23 +348,28 @@ protected static function _generate_field_string($fields) // loop over the field options foreach($field as $option => $val) { - // deal with key data first - if ($option == 'key') + // deal with index data first + if ($option == 'indexes') { - // primary key field - if ($val == 'PRI') - { - $pks[] = $name; - } - if ($val == 'MUL') + foreach ($val as $validx) { - $idx[] = $name; + // deal with primary indexes + if ($validx['primary']) + { + $pks[] = $validx; + } + + // secondary index + else + { + $idx[] = $validx; + } } continue; } // skip option data from describe not supported by DBUtil::create_table() - if (in_array($option, array('max', 'min', 'name', 'type', 'ordinal_position', 'display', 'comment', 'privileges', 'collation_name', 'options', 'character_maximum_length', 'numeric_precision', 'numeric_scale', 'exact'))) + if (in_array($option, array('indexes', 'key', 'max', 'min', 'name', 'type', 'ordinal_position', 'display', 'comment', 'privileges', 'collation_name', 'options', 'character_maximum_length', 'numeric_precision', 'numeric_scale', 'exact'))) { continue; } @@ -381,7 +428,6 @@ protected static function _generate_field_string($fields) $fields_down[] = "\t\t\t'$name'".PHP_EOL; } - $pks = "'".implode("', '", $pks)."'"; $field_up_str = rtrim($field_up_str, PHP_EOL); $field_down_str = rtrim(implode(',', $fields_down), PHP_EOL); diff --git a/tasks/fromdb.php b/tasks/fromdb.php index 5d09b473..94f774ae 100644 --- a/tasks/fromdb.php +++ b/tasks/fromdb.php @@ -274,6 +274,17 @@ protected static function arguments($table, $type = 'model') exit(); } + // get the list of indexes from the table + try + { + $indexes = \DB::list_indexes(trim($table), null, \Cli::option('db', null)); + } + catch (\Exception $e) + { + \Cli::write($e->getMessage(), 'red'); + exit(); + } + // process the columns found foreach ($columns as $column) { @@ -308,8 +319,20 @@ protected static function arguments($table, $type = 'model') // store the constraint $column['constraint'] = $constraint; + // fetch index information + $column['indexes'] = array(); + foreach ($indexes as $index) + { + // check if we have an index on the current column + if ($column['name'] == $index['column']) + { + // add the index details for this field + $column['indexes'][$index['name']] = $index; + } + } + // store the column in the argument list - $arguments[] = $column; + $arguments[$column['name']] = $column; } // tell oil not to fiddle with column information