/** * Parse a a single column or index definition. * * This function can parse many (but not all) types of syntax used to define columns * and indexes in a "CREATE TABLE" query. * * @param string $line * @return array */ function parse_create_definition($line) { $line = preg_replace('@[,\\r\\n\\s]+$@', '', $line); //Strip the ", " line separator $pieces = preg_split('@\\s+|(?=\\()@', $line, -1, PREG_SPLIT_NO_EMPTY); if (empty($pieces)) { return null; } $token = strtolower(array_shift($pieces)); $index_modifier = ''; $index = false; //Determine if this line defines an index if (in_array($token, array('primary', 'unique', 'fulltext'))) { $index_modifier = $token; $index = true; $token = strtolower(array_shift($pieces)); } if (in_array($token, array('index', 'key'))) { $index = true; $token = strtolower(array_shift($pieces)); } //Determine column/index name $name = ''; if ($index) { //Names are optional for indexes; the INDEX/etc keyword can be immediately //followed by a column list (or index_type, but we're ignoring that possibility). if (strpos($token, '(') === false) { $name = $token; } else { if ($index_modifier == 'primary') { $name = 'primary'; } array_unshift($pieces, $token); } } else { $name = $token; } $name = strtolower(trim($name, '`')); $definition = compact('name', 'index', 'index_modifier'); //Parse the rest of the line $remainder = implode(' ', $pieces); if ($index) { $definition['columns'] = blcTableDelta::parse_index_column_list($remainder); //If the index doesn't have a name, use the name of the first column //(this is what MySQL does, but only when there isn't already an index with that name). if (empty($definition['name'])) { $definition['name'] = $definition['columns'][0]['column_name']; } //Rebuild the index def. in a normalized form $definition['index_definition'] = blcTableDelta::generate_index_string($definition); } else { $column_def = blcTableDelta::parse_column_definition($remainder); $definition = array_merge($definition, $column_def); } return $definition; }