Skip to content

Commit

Permalink
improved index generation using DB::list_indexes()
Browse files Browse the repository at this point in the history
also: do not pluralize tablenames when using fromdb
  • Loading branch information
WanWizard committed Mar 10, 2017
1 parent 77e4932 commit d87c773
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 25 deletions.
50 changes: 43 additions & 7 deletions classes/generate.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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'];
}
}
}
}

Expand Down Expand Up @@ -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)
{
Expand All @@ -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_'];
Expand All @@ -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)));
};
Expand Down
80 changes: 63 additions & 17 deletions classes/generate/migration/actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <<<UP
\DBUtil::create_table('{$table_prefix}{$subjects[1]}', array(
$field_up_str
), array({$pks}));
)$pk_str);
UP;

// generate the down() code
$down = '';
if ($idx)
{
// transform the index data
$tidx = array();
foreach ($idx as $idxval)
{
if ( ! isset($tidx[$idxval['name']]))
{
$tidx[$idxval['name']] = array((int)$idxval['order'] => $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;
}
Expand Down Expand Up @@ -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 = <<<UP
\DBUtil::add_fields('{$subjects[1]}', array(
Expand Down Expand Up @@ -237,7 +279,7 @@ public static function rename_field($subjects, $fields)
}

// generate the code for the fields
list($field_up_str, $not_used, $not_used, $not_used) = static::_generate_field_string($column);
list($field_up_str, $field_down_str, $not_used, $not_used) = static::_generate_field_string($column);

// modify for different dbutil syntax
$field_down_str = str_replace('array(', 'array(\'name\' => \''.$subjects[0].'\', ', str_replace($subjects[0], $subjects[1], $field_up_str));
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down
25 changes: 24 additions & 1 deletion tasks/fromdb.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d87c773

Please sign in to comment.