Exemplo n.º 1
0
 /**
  * Creates and returns SQL for dropping the trigger.
  *
  * @return created SQL
  */
 public static function get_drop_sql($node_schema, $node_trigger)
 {
     $node_table = dbx::get_table($node_schema, $node_trigger['table']);
     if ($node_table == null) {
         throw new exception("Failed to find trigger table " . $node_trigger['table'] . " in schema node " . $node_schema['name']);
     }
     $table_name = pgsql8::get_quoted_schema_name($node_schema['name']) . '.' . pgsql8::get_quoted_table_name($node_table['name']);
     $ddl = "DROP TRIGGER " . pgsql8::get_quoted_object_name($node_trigger['name']) . " ON " . $table_name . ";\n";
     return $ddl;
 }
 /**
  * Modify sequence values if they have changed
  *
  * @param $ofs        output file pointer
  * @param $old_schema original schema
  * @param $new_schema new schema
  */
 private static function add_modified_sequences($ofs, $old_schema, $new_schema)
 {
     foreach (dbx::get_sequences($new_schema) as $new_sequence) {
         if ($old_schema != null && pgsql8_schema::contains_sequence($old_schema, $new_sequence['name'])) {
             $old_sequence = dbx::get_sequence($old_schema, $new_sequence['name']);
             $sql = '';
             if ($new_sequence['inc'] != null && strcasecmp($new_sequence['inc'], $old_sequence['inc']) != 0) {
                 $sql .= "\n\tINCREMENT BY " . $new_sequence['inc'];
             }
             if ($new_sequence['min'] == null && $old_sequence['min'] != null) {
                 $sql .= "\n\tNO MINVALUE";
             } else {
                 if ($new_sequence['min'] != null && strcasecmp($new_sequence['min'], $old_sequence['min']) != 0) {
                     $sql .= "\n\tMINVALUE " . $new_sequence['min'];
                 }
             }
             if ($new_sequence['max'] == null && $old_sequence['max'] != null) {
                 $sql .= "\n\tNO MAXVALUE";
             } else {
                 if ($new_sequence['max'] != null && strcasecmp($new_sequence['max'], $old_sequence['max']) != 0) {
                     $sql .= "\n\tMAXVALUE " . $new_sequence['max'];
                 }
             }
             if (!pgsql8_diff::$ignore_start_with) {
                 if ($new_sequence['start'] != null && strcasecmp($new_sequence['start'], $old_sequence['start']) != 0) {
                     $sql .= "\n\tRESTART WITH " . $new_sequence['start'];
                 }
             }
             if ($new_sequence['cache'] != null && strcasecmp($new_sequence['cache'], $old_sequence['cache']) != 0) {
                 $sql .= "\n\tCACHE " . $new_sequence['cache'];
             }
             if ($old_sequence['cycle'] && !$new_sequence['cycle']) {
                 $sql .= "\n\tNO CYCLE";
             } else {
                 if (!$old_sequence['cycle'] && $new_sequence['cycle']) {
                     $sql .= "\n\tCYCLE";
                 }
             }
             if (strlen($sql) > 0) {
                 $ofs->write("ALTER SEQUENCE " . pgsql8::get_quoted_schema_name($new_schema['name']) . '.' . pgsql8::get_quoted_object_name($new_sequence['name']) . $sql . ";\n");
             }
         }
     }
 }
Exemplo n.º 3
0
 /**
  * Outputs commands for ALTER DOMAIN
  * @param $ofs          output file pointer
  * @param $old_schema   original schema
  * @param $old_type     original type
  * @param $new_schema   new schema
  * @param $new_type     new type
  */
 private static function apply_domain_changes($ofs, $old_schema, $old_type, $new_schema, $new_type)
 {
     // http://www.postgresql.org/docs/8.1/static/sql-alterdomain.html
     $domain = pgsql8::get_quoted_schema_name($new_schema['name']) . '.' . pgsql8::get_quoted_object_name($new_type['name']);
     $old_domain = $old_type->domainType;
     $new_domain = $new_type->domainType;
     // if base type changes, we need to drop and re-add
     if (strcasecmp($old_domain['baseType'], $new_domain['baseType']) !== 0) {
         $ofs->write("-- domain base type changed from {$old_domain['baseType']} to {$new_domain['baseType']} - recreating\n");
         $ofs->write(pgsql8_type::get_drop_sql($old_schema, $old_type) . "\n");
         $ofs->write(pgsql8_type::get_creation_sql($new_schema, $new_type) . "\n");
         return;
     }
     $base_type = strtolower($new_domain['baseType']);
     // default is dropped
     if (isset($old_domain['default']) && !isset($new_domain['default'])) {
         $ofs->write("-- domain default dropped\n");
         $ofs->write("ALTER DOMAIN {$domain} DROP DEFAULT;\n");
     } elseif (strcmp($old_domain['default'], $new_domain['default']) !== 0) {
         $old_default = pgsql8::value_escape($base_type, (string) $old_domain['default']);
         $new_default = pgsql8::value_escape($base_type, (string) $new_domain['default']);
         $ofs->write("-- domain default changed from {$old_default}\n");
         $ofs->write("ALTER DOMAIN {$domain} SET DEFAULT {$new_default};\n");
     }
     $old_null = strcasecmp($old_domain['null'], 'false') !== 0;
     $new_null = strcasecmp($new_domain['null'], 'false') !== 0;
     // NULL -> NOT NULL
     if ($old_null && !$new_null) {
         $ofs->write("-- domain changed from NULL to NOT NULL\n");
         $ofs->write("ALTER DOMAIN {$domain} SET NOT NULL;\n");
     } elseif (!$old_null && $new_null) {
         $ofs->write("-- domain changed from NOT NULL to NULL\n");
         $ofs->write("ALTER DOMAIN {$domain} DROP NOT NULL;\n");
     }
     // diff constraints
     $old_constraints = array();
     foreach ($old_type->domainConstraint as $old_constraint) {
         $old_constraints[(string) $old_constraint['name']] = pgsql8_type::normalize_domain_constraint($old_constraint);
     }
     foreach ($new_type->domainConstraint as $new_constraint) {
         $name = (string) $new_constraint['name'];
         $constraint = pgsql8_type::normalize_domain_constraint($new_constraint);
         if (array_key_exists($name, $old_constraints)) {
             if (strcmp($constraint, $old_constraints[$name]) !== 0) {
                 $ofs->write("-- domain constraint {$name} changed from {$old_constraints[$name]}\n");
                 $ofs->write("ALTER DOMAIN {$domain} DROP CONSTRAINT {$name};\n");
                 $ofs->write("ALTER DOMAIN {$domain} ADD CONSTRAINT {$name} CHECK({$constraint});\n");
             }
             unset($old_constraints[$name]);
         } else {
             $ofs->write("-- domain constraint {$name} added\n");
             $ofs->write("ALTER DOMAIN {$domain} ADD CONSTRAINT {$name} CHECK({$constraint});\n");
         }
     }
     foreach ($old_constraints as $name => $constraint) {
         $ofs->write("-- domain constraint {$name} removed\n");
         $ofs->write("ALTER DOMAIN {$domain} DROP CONSTRAINT {$name};\n");
     }
 }
Exemplo n.º 4
0
 public static function get_drop_sql($node_schema, $node_table, $node_index)
 {
     $ddl = "DROP INDEX " . pgsql8::get_quoted_schema_name($node_schema['name']) . "." . pgsql8::get_quoted_object_name($node_index['name']) . ";\n";
     return $ddl;
 }
Exemplo n.º 5
0
 /**
  * Creates and returns SQL command for dropping the sequence.
  *
  * @return string
  */
 public static function get_drop_sql($node_schema, $node_sequence)
 {
     format::set_context_replica_set_id($node_sequence);
     $ddl = "DROP SEQUENCE " . pgsql8::get_quoted_schema_name($node_schema['name']) . '.' . pgsql8::get_quoted_object_name($node_sequence['name']) . ";\n";
     return $ddl;
 }
Exemplo n.º 6
0
 /**
  * Creates and returns SQL for dropping the language.
  *
  * @return string
  */
 public static function get_drop_sql($node_language)
 {
     $ddl = "DROP " . (strcasecmp(dbsteward::string_cast($node_language['procedural']), 'true') == 0 ? "PROCEDURAL " : "") . " LANGUAGE " . pgsql8::get_quoted_object_name($node_language['name']) . " ;";
     return $ddl;
 }
Exemplo n.º 7
0
 /**
  * alter_column_type_placeholder's companion - restore $columns list of columns to $node_type type
  *
  * @param $columns      reference columns returned by reference
  * @param $node_schema
  * @param $node_type
  * @return string DDL
  */
 public static function alter_column_type_restore($columns, $node_schema, $node_type)
 {
     $ddl = '';
     foreach ($columns as $column_map) {
         $ddl .= "ALTER TABLE " . pgsql8::get_quoted_schema_name($column_map['alter_column_schema']['name']) . '.' . pgsql8::get_quoted_table_name($column_map['alter_column_table']['name']) . " ALTER COLUMN " . pgsql8::get_quoted_column_name($column_map['alter_column_column']['name']) . " TYPE " . pgsql8::get_quoted_schema_name($node_schema['name']) . '.' . pgsql8::get_quoted_object_name($node_type['name']) . " USING " . pgsql8::get_quoted_column_name($column_map['alter_column_column']['name']) . "::" . pgsql8::get_quoted_schema_name($node_schema['name']) . '.' . pgsql8::get_quoted_object_name($node_type['name']) . ";\n";
     }
     return $ddl;
 }
Exemplo n.º 8
0
 public static function column_type($db_doc, $schema, $table, $column, &$foreign)
 {
     // if it is a foreign keyed column, solve for the foreignKey type
     if (isset($column['foreignTable'])) {
         dbx::foreign_key($db_doc, $schema, $table, $column, $foreign);
         $column_type = $foreign['column']['type'];
         // for foreign keys, translate serial types to their integer base
         if (strcasecmp('serial', $column_type) == 0) {
             $column_type = 'int';
         } else {
             if (strcasecmp('bigserial', $column_type) == 0) {
                 $column_type = 'bigint';
             }
         }
     } else {
         if (!isset($column['type']) || strlen($column['type']) == 0) {
             throw new Exception("column missing type -- " . $schema['name'] . "." . $table['name'] . "." . $column['name']);
         }
         $column_type = $column['type'];
         if (dbx::get_type($schema, $column_type) != NULL) {
             // this is a user defined type or enum, enforce quoting if set
             $column_type = pgsql8::get_quoted_object_name($column_type);
         }
     }
     return $column_type;
 }
Exemplo n.º 9
0
    public static function apply_table_options_diff($ofs1, $ofs3, $schema, $table, $alter_options, $create_options, $drop_options)
    {
        $schema_name = (string) $schema['name'];
        $table_name = (string) $table['name'];
        $fq_name = pgsql8::get_fully_qualified_table_name($schema_name, $table_name);
        $actions = array();
        $sql = "";
        // create and alter have the same syntax:
        $create_alter = array_merge($create_options, $alter_options);
        foreach ($create_alter as $name => $value) {
            switch (strtolower($name)) {
                case 'with':
                    // ALTER TABLE ... SET (params) doesn't accept oids=true/false, unlike CREATE TABLE
                    // only WITH OIDS or WITHOUT OIDS
                    $params = pgsql8_table::parse_storage_params($value);
                    if (array_key_exists('oids', $params)) {
                        $oids = $params['oids'];
                        unset($params['oids']);
                        if (strcasecmp($oids, 'true') === 0) {
                            $actions[] = "SET WITH OIDS";
                        } else {
                            $actions[] = "SET WITHOUT OIDS";
                        }
                    } else {
                        // we might have gotten rid of the oids param
                        $actions[] = "SET WITHOUT OIDS";
                    }
                    // set the rest of the params normally
                    $params = pgsql8_table::compose_storage_params($params);
                    $actions[] = "SET {$params}";
                    break;
                case 'tablespace':
                    $tbsp = (string) $value;
                    $actions[] = "SET TABLESPACE " . pgsql8::get_quoted_object_name($tbsp);
                    $sql .= <<<SQL
CREATE FUNCTION __dbsteward_migrate_move_index_tablespace(TEXT,TEXT,TEXT) RETURNS void AS \$\$
  DECLARE idx RECORD;
BEGIN
  -- need to move the tablespace of the indexes as well
  FOR idx IN SELECT index_pgc.relname FROM pg_index
               INNER JOIN pg_class index_pgc ON index_pgc.oid = pg_index.indexrelid
               INNER JOIN pg_class table_pgc ON table_pgc.oid = pg_index.indrelid AND table_pgc.relname=\$2
               INNER JOIN pg_namespace ON pg_namespace.oid = table_pgc.relnamespace AND pg_namespace.nspname=\$1 LOOP
    EXECUTE 'ALTER INDEX ' || quote_ident(\$1) || '.' || quote_ident(idx.relname) || ' SET TABLESPACE ' || quote_ident(\$3) || ';';
  END LOOP;
END \$\$ LANGUAGE plpgsql;
SELECT __dbsteward_migrate_move_index_tablespace('{$schema_name}','{$table_name}','{$tbsp}');
DROP FUNCTION __dbsteward_migrate_move_index_tablespace(TEXT,TEXT,TEXT);

SQL;
                    break;
            }
        }
        foreach ($drop_options as $name => $value) {
            switch (strtolower($name)) {
                case 'with':
                    $params = pgsql8_table::parse_storage_params($value);
                    // handle oids separately, since pgsql doesn't recognise it as
                    // a storage parameter in an ALTER TABLE statement
                    if (array_key_exists('oids', $params)) {
                        $oids = $params['oids'];
                        unset($params['oids']);
                        $actions[] = "SET WITHOUT OIDS";
                    }
                    $names = '(' . implode(',', array_keys($params)) . ')';
                    $actions[] = "RESET {$names}";
                    break;
                case 'tablespace':
                    // the only way to switch table and index to an unknown-beforehand value
                    // is with a function that's immediately executed
                    $sql .= <<<SQL
CREATE OR REPLACE FUNCTION __dbsteward_migrate_reset_tablespace(TEXT,TEXT) RETURNS void AS \$\$
  DECLARE tbsp TEXT;
  DECLARE idx RECORD;
BEGIN
  SELECT setting FROM pg_settings WHERE name='default_tablespace' INTO tbsp;

  IF tbsp = '' THEN
    tbsp := 'pg_default';
  END IF;

  EXECUTE 'ALTER TABLE ' || quote_ident(\$1) || '.' || quote_ident(\$2) || ' SET TABLESPACE ' || quote_ident(tbsp) || ';';

  -- need to move the tablespace of the indexes as well
  FOR idx IN SELECT index_pgc.relname FROM pg_index
               INNER JOIN pg_class index_pgc ON index_pgc.oid = pg_index.indexrelid
               INNER JOIN pg_class table_pgc ON table_pgc.oid = pg_index.indrelid AND table_pgc.relname=\$2
               INNER JOIN pg_namespace ON pg_namespace.oid = table_pgc.relnamespace AND pg_namespace.nspname=\$1 LOOP
    EXECUTE 'ALTER INDEX ' || quote_ident(\$1) || '.' || quote_ident(idx.relname) || ' SET TABLESPACE ' || quote_ident(tbsp) || ';';
  END LOOP;
END \$\$ LANGUAGE plpgsql;
SELECT __dbsteward_migrate_reset_tablespace('{$schema_name}','{$table_name}');
DROP FUNCTION __dbsteward_migrate_reset_tablespace(TEXT,TEXT);

SQL;
            }
        }
        if (!empty($actions)) {
            $sql .= "\nALTER TABLE {$fq_name}\n  " . implode(",\n  ", $actions) . ";";
        }
        if (!empty($sql)) {
            $ofs1->write($sql . "\n");
        }
    }
Exemplo n.º 10
0
 public static function compile_sql_statement($action, $right, $object_type, $object_name, $role, $with = '')
 {
     // the PUBLIC role is actually a keyword, not an identifier, so don't quote it
     if (strcasecmp($role, "PUBLIC") !== 0) {
         $role = pgsql8::get_quoted_object_name($role);
     }
     $sql = $action . ' ' . $right . " ON " . $object_type . " " . $object_name . " TO " . $role;
     if (strlen($with) > 0) {
         $sql .= ' ' . $with;
     }
     $sql .= ";";
     return $sql;
 }