/** * Parses CREATE TYPE command. * * @param database database * @param command CREATE TYPE command */ public static function parse($database, $command) { $line = $command; // CREATE PROCEDURAL LANGUAGE plpgsql; // CREATE [ PROCEDURAL ] LANGUAGE name // CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name // HANDLER call_handler [ VALIDATOR valfunction ] if (preg_match(self::PATTERN_CREATE_LANGUAGE, $line, $matches) > 0) { // simplify parsing by killing last semicolon $line = sql_parser::remove_last_semicolon($line); // break up the command by whitespace $chunks = preg_split('/[\\s]+/', $line, -1, PREG_SPLIT_NO_EMPTY); // shift the LANGUAGE keyword off array_shift($chunks); // shift the language name off $language_name = array_shift($chunks); // create language entry $language =& dbx::get_language($database, $language_name, true); // grab the language modifiers while (strcasecmp('LANGUAGE', $chunks[0]) != 0) { if (strcasecmp('CREATE', $chunks[0]) == 0) { // expected first CREATE lead doesn't modify anything } else { if (strcasecmp('TRUSTED', $chunks[0]) == 0) { dbx::set_attribute($language, 'trusted', $chunks[0]); } else { if (strcasecmp('PROCEDURAL', $chunks[0]) == 0) { dbx::set_attribute($language, 'procedural', $chunks[0]); } else { throw new exception("unknown CREATE LANGUAGE modifier: " . $chunks[0]); } } } // shift the lead chunk off now that it has been interpreted array_shift($chunks); } // if there are chunks left, figure out what optional parameteres they are and save them in the language object // make sure it's not the trailing ;, we don't care while (count($chunks) > 0 && trim(implode(' ', $chunks)) != ';') { if (strcasecmp('HANDLER', $chunks[0]) == 0) { dbx::set_attribute($language, 'handler', $chunks[1]); } else { if (strcasecmp('VALIDATOR', $chunks[0]) == 0) { dbx::set_attribute($language, 'validator', $chunks[1]); } else { throw new exception("unknown CREATE LANGUAGE callback: " . $chunks[0]); } } // shift the lead chunk and its value off now that it has been interpreted array_shift($chunks); array_shift($chunks); } } else { throw new exception("Cannot parse command: " . $line); } }
/** * Parses GRANT and REVOKE commands * * @param database database * @param command REVOKE command */ public static function parse($database, $command) { $command = sql_parser::remove_last_semicolon($command); if (preg_match(self::PATTERN_CONFIG_PARAMETER, $command, $matches) > 0) { if (count($matches) != 3) { var_dump($matches); throw new exception("Database configuration parameter call preg exploded into " . count($matches) . ", panic!"); } // just do what the call does push around the name -> value $configuration_parameter =& dbx::get_configuration_parameter($database, $matches[1], true); dbx::set_attribute($configuration_parameter, 'value', $matches[2]); } else { throw new exception("Cannot parse command: " . $command); } }
/** * Parses CREATE TYPE command. * * @param database database * @param command CREATE TYPE command */ public static function parse($database, $command) { $line = $command; if (preg_match(self::PATTERN_TYPE_NAME, $line, $matches) > 0) { $typeName = trim($matches[1]); $line = preg_replace(self::PATTERN_TYPE_NAME, '', $line); } else { throw new exception("Cannot parse command: " . $line); } $type = new pgsql8_type(sql_parser::get_object_name($typeName)); $schemaName = sql_parser::get_schema_name($typeName, $database); $schema = $database->get_schema($schemaName); if ($schema == null) { throw new exception("Cannot get schema '" . $schemaName . "'. Need to issue 'CREATE SCHEMA " . $schemaName . ";' before 'CREATE TYPE " . $typeName . "...;'?"); } $schema->add_type($type); self::parse_rows($type, sql_parser::remove_last_semicolon($line)); }
/** * Parses CREATE TABLE command. * * @param database database * @param command CREATE TABLE command * */ public static function parse($database, $command) { $line = $command; if (preg_match(self::PATTERN_TABLE_NAME, $line, $matches) > 0) { $table_name = trim($matches[1]); $line = preg_replace(self::PATTERN_TABLE_NAME, '', $line); } else { throw new exception("Cannot parse command: " . $line); } $table_name = sql_parser::get_schema_name($table_name, $database) . '.' . sql_parser::get_object_name($table_name); $schema_name = sql_parser::get_schema_name($table_name, $database); $node_schema = dbx::get_schema($database, $schema_name); if ($node_schema == null) { throw new exception("Cannot get schema '" . $schema_name . "'. Need to issue 'CREATE SCHEMA " . $schema_name . ";' before 'CREATE TABLE " . $table_name . "...;'?"); } $node_table = dbx::get_table($node_schema, sql_parser::get_object_name($table_name), true); self::parse_rows($node_schema, $node_table, sql_parser::remove_last_semicolon($line)); }
/** * Parses CREATE SEQUENCE command. * * @param database database * @param command CREATE SEQUENCE command */ public static function parse($database, $command) { $line = $command; if (preg_match(self::PATTERN_SEQUENCE_NAME, $line, $matches) > 0) { $sequence_name = trim($matches[1]); $line = preg_replace(self::PATTERN_SEQUENCE_NAME, '', $line); } else { throw new exception("Cannot parse line: " . $line); } $node_schema =& dbx::get_schema($database, sql_parser::get_schema_name($sequence_name, $database)); $node_sequence =& dbx::get_sequence($node_schema, sql_parser::get_object_name($sequence_name), true); $line = sql_parser::remove_last_semicolon($line); $line = self::processMaxValue($node_sequence, $line); $line = self::processMinValue($node_sequence, $line); $line = self::processCycle($node_sequence, $line); $line = self::processCache($node_sequence, $line); $line = self::processIncrement($node_sequence, $line); $line = self::processstart_with($node_sequence, $line); $line = trim($line); if (strlen($line) > 0) { throw new exception("Cannot parse commmand '" . $command . "', string '" . $line . "'"); } }
/** * Parses ALTER TABLE command. * * @param database database * @param command ALTER TABLE command * */ public static function parse($database, $command) { $line = $command; if (preg_match(self::PATTERN_OWNER, $command, $matches) > 0) { $table_name = trim($matches[1]); $table_owner = sql_parser::remove_last_semicolon(trim($matches[2])); $schema_name = sql_parser::get_schema_name($table_name, $database); $node_schema = dbx::get_schema($database, $schema_name); if ($node_schema == null) { throw new exception("schema " . $schema_name . " not found in database object"); } // is it actually a sequence ownership reference? if (substr($table_name, -4) == '_seq') { //@TODO: figure out what sequences are not table linked and need to have ownership set on them } else { $node_table = dbx::get_table($node_schema, sql_parser::get_object_name($table_name)); if ($node_table == null) { throw new exception("table " . sql_parser::get_object_name($table_name) . " not found in " . $node_schema['name'] . " schema object"); } dbx::set_attribute($node_table, 'owner', $table_owner); } } else { if (preg_match(self::PATTERN_START, $line, $matches) > 0) { $table_name = trim($matches[1]); } else { throw new exception("Cannot parse command: " . $line); } $schema_name = sql_parser::get_schema_name($table_name, $database); $node_schema = dbx::get_schema($database, $schema_name); $node_table = dbx::get_table($node_schema, sql_parser::get_object_name($table_name)); $line = sql_parser::remove_last_semicolon($matches[2]); self::parse_rows($database, $node_schema, $node_table, $line); } }
/** * Parses GRANT and REVOKE commands * * @param database database * @param command REVOKE command * */ public static function parse($database, $command) { $command = sql_parser::remove_last_semicolon($command); if (preg_match(self::PATTERN_GRANT_REVOKE, $command, $matches) > 0) { if (count($matches) != 5) { throw new exception("GRANT/REVOKE definition preg exploded into " . count($matches) . ", panic!"); } $action = strtoupper($matches[1]); switch ($action) { case 'GRANT': case 'REVOKE': break; default: throw new exception("permission action " . $action . " is unknown, panic!"); break; } $operations = preg_split("/[\\,\\s]+/", $matches[2], -1, PREG_SPLIT_NO_EMPTY); if (!is_array($operations)) { $permission = array($operations); } for ($i = 0; $i < count($operations); $i++) { $operations[$i] = strtoupper($operations[$i]); switch ($operations[$i]) { case 'ALL': case 'SELECT': case 'INSERT': case 'UPDATE': case 'DELETE': case 'USAGE': case 'REFERENCES': case 'TRIGGER': break; default: var_dump($operations); throw new exception("the operation " . $operations[$i] . " is unknown, panic!"); break; } } $object = $matches[3]; $chunks = preg_split("/[\\s]+/", $object, -1, PREG_SPLIT_NO_EMPTY); if (count($chunks) == 1) { // if there is no white space separating this bit // then let postgresql decide what it is when the grant is run $object_type = ''; $object_name = $chunks[0]; } else { if (count($chunks) == 2) { // SEQUENCE schema.table_table_id_seq // TABLE schema.table $object_type = $chunks[0]; $object_name = $chunks[1]; // if it's a schema, don't try to explode / default the schema prefix if (strcasecmp($object_type, 'SCHEMA') == 0) { $schema =& dbx::get_schema($database, $object_name); } else { $object_name = sql_parser::get_schema_name($object_name, $database) . '.' . sql_parser::get_object_name($object_name); $schema =& dbx::get_schema($database, sql_parser::get_schema_name($object_name, $database)); } if ($schema == null) { throw new exception("Failed to find schema for grant/revoke: " . sql_parser::get_schema_name($object_name, $database)); } } else { throw new exception("object definition exploded into " . count($chunks) . " chunks, panic!"); } } $role = $matches[4]; // find the node_object, swtich'd on $object_type // based on http://www.postgresql.org/docs/8.4/static/sql-grant.html // empty object_type should be considered a TABLE GRANT/REVOKE if (strlen($object_type) == 0) { $object_type = 'TABLE'; } /* var_dump($command); var_dump(sql_parser::get_schema_name($object_name, $database)); var_dump(sql_parser::get_object_name($object_name)); /**/ switch (strtoupper($object_type)) { case 'SCHEMA': $node_object =& dbx::get_schema($database, $object_name); break; case 'SEQUENCE': $node_schema =& dbx::get_schema($database, sql_parser::get_schema_name($object_name, $database)); $node_object =& dbx::get_sequence($node_schema, sql_parser::get_object_name($object_name)); break; case 'TABLE': $node_schema =& dbx::get_schema($database, sql_parser::get_schema_name($object_name, $database)); $node_object =& dbx::get_table($node_schema, sql_parser::get_object_name($object_name)); break; default: throw new exception("unknown object_type " . $object_type . " encountered, panic!"); break; } dbx::set_permission($node_object, $action, $operations, $role); } else { throw new exception("Cannot parse command: " . $command); } }