public static function column_type($db_doc, $node_schema, $node_table, $node_column, &$foreign = NULL) { // if the column is a foreign key, solve for the foreignKey type if (isset($node_column['foreignTable'])) { $foreign = format_constraint::foreign_key_lookup($db_doc, $node_schema, $node_table, $node_column); $foreign_type = static::un_auto_increment($foreign['column']['type']); if (static::is_serial($foreign_type)) { return static::convert_serial($foreign_type); } return $foreign_type; } // if there's no type specified, that's a problem if (!isset($node_column['type'])) { throw new Exception("column missing type -- " . $table['name'] . "." . $column['name']); } // get the type of the column, ignoring any possible auto-increment flag $type = static::un_auto_increment($node_column['type']); // if the column type matches an enum type, inject the enum declaration here if ($node_type = mysql5_type::get_type_node($db_doc, $node_schema, $type)) { return mysql5_type::get_enum_type_declaration($node_type); } // translate serials to their corresponding int types if (static::is_serial($type)) { return static::convert_serial($type); } // nothing special about this type return $type; }
public static function get_creation_sql($node_schema, $node_function) { $name = static::get_declaration($node_schema, $node_function); $definer = strlen($node_function['owner']) > 0 ? xml_parser::role_enum(dbsteward::$new_database, $node_function['owner']) : 'CURRENT_USER'; // always drop the function first, just to be safe, and to be compatible with pgsql8's CREATE OR REPLACE $sql = static::get_drop_sql($node_schema, $node_function) . "\n"; if (mysql5::$swap_function_delimiters) { $sql .= 'DELIMITER ' . static::ALT_DELIMITER . "\n"; } $function_type = static::is_procedure($node_function) ? 'PROCEDURE' : 'FUNCTION'; $sql .= "CREATE DEFINER = {$definer} {$function_type} {$name} ("; if (isset($node_function->functionParameter)) { $params = array(); foreach ($node_function->functionParameter as $param) { if (isset($param['direction']) && !static::is_procedure($node_function)) { throw new exception("Parameter directions are not supported in MySQL functions"); } if (empty($param['name'])) { throw new exception("Function parameters must have names in MySQL. In function '{$node_function['name']}'"); } $type = $param['type']; if ($node_type = mysql5_type::get_type_node(dbsteward::$new_database, $node_schema, $type)) { $type = mysql5_type::get_enum_type_declaration($node_type); } $sparam = ''; if (isset($param['direction'])) { $sparam .= (string) $param['direction'] . ' '; } $sparam .= mysql5::get_quoted_function_parameter($param['name']) . ' ' . $type; $params[] = $sparam; } $sql .= implode(', ', $params); } $sql .= ")\n"; // Procedures don't have a return statement if (!static::is_procedure($node_function)) { $returns = $node_function['returns']; if ($node_type = mysql5_type::get_type_node(dbsteward::$new_database, $node_schema, $returns)) { $returns = mysql5_type::get_enum_type_declaration($node_type); } $sql .= "RETURNS " . $returns . "\n"; } $sql .= "LANGUAGE SQL\n"; list($eval_type, $determinism) = static::get_characteristics((string) $node_function['cachePolicy'], (string) $node_function['mysqlEvalType']); $eval_type = str_replace('_', ' ', $eval_type); $sql .= "{$eval_type}\n{$determinism}\n"; // unlike pgsql8, mysql5 defaults to SECURITY DEFINER, so we need to set it to INVOKER unless explicitly told to leave it DEFINER if (!isset($node_function['securityDefiner']) || strcasecmp($node_function['securityDefiner'], 'false') == 0) { $sql .= "SQL SECURITY INVOKER\n"; } else { $sql .= "SQL SECURITY DEFINER\n"; } if (!empty($node_function['description'])) { $sql .= "COMMENT " . mysql5::quote_string_value($node_function['description']) . "\n"; } $sql .= trim(static::get_definition($node_function)); $sql = rtrim($sql, ';'); if (mysql5::$swap_function_delimiters) { $sql .= static::ALT_DELIMITER . "\nDELIMITER ;"; } else { $sql .= ';'; } return $sql; }