/**
  * 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);
     }
 }