postgres7.class.php

来自「很棒的在线教学系统」· PHP 代码 · 共 575 行 · 第 1/2 页

PHP
575
字号
            ($xmldb_field->getType() == XMLDB_TYPE_CHAR) ||            ($xmldb_field->getType() == XMLDB_TYPE_TEXT) ||            ($xmldb_field->getType() == XMLDB_TYPE_BINARY) ||            (!$xmldb_field->getDecimals()) ||            (!$olddecimals) ||            ($xmldb_field->getDecimals() == $olddecimals)) {            $decimalchanged = false;        }    /// Detect if we are changing the default        if (($xmldb_field->getDefault() === null && $olddefault === null) ||            ($xmldb_field->getDefault() === $olddefault) ||             //Check both equality and            ("'" . $xmldb_field->getDefault() . "'" === $olddefault)) {  //Equality with quotes because ADOdb returns the default with quotes            $defaultchanged = false;        }    /// Detect if we are changing the nullability        if (($xmldb_field->getNotnull() === $oldnotnull)) {            $notnullchanged = false;        }    /// TODO: Some combinations like    /// TODO: integer->integer    /// TODO: integer->text    /// TODO: number->text    /// TODO: text->text    /// TODO: do not require the use of temp columns, because PG 8.0 supports them automatically    /// TODO: with a simple "alter table zzz alter column yyy type new specs"    /// TODO: Must be implemented that way. Eloy 09/2007    /// If the type or the precision or the decimals have changed, then we need to:    ///     - create one temp column with the new specs    ///     - fill the new column with the values from the old one (casting if needed)    ///     - drop the old column    ///     - rename the temp column to the original name        if ($typechanged || $precisionchanged || $decimalchanged) {            $tempcolname = $xmldb_field->getName() . '_alter_column_tmp';        /// Prevent temp field to have both NULL/NOT NULL and DEFAULT constraints            $this->alter_column_skip_notnull = true;            $this->alter_column_skip_default = true;            $xmldb_field->setName($tempcolname);        /// Create the temporal column            $results = array_merge($results, $this->getAddFieldSQL($xmldb_table, $xmldb_field));        /// Detect some basic casting options            if ((substr($oldmetatype, 0, 1) == 'C' && $xmldb_field->getType() == XMLDB_TYPE_NUMBER) ||                (substr($oldmetatype, 0, 1) == 'C' && $xmldb_field->getType() == XMLDB_TYPE_FLOAT)) {                $copyorigin = 'CAST(CAST('.$fieldname.' AS TEXT) AS REAL)'; //From char to number or float            } else if ((substr($oldmetatype, 0, 1) == 'C' && $xmldb_field->getType() == XMLDB_TYPE_INTEGER)) {                $copyorigin = 'CAST(CAST('.$fieldname.' AS TEXT) AS INTEGER)'; //From char to integer            } else {                $copyorigin = $fieldname; //Direct copy between columns            }        /// Copy contents from original col to the temporal one            $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = ' . $copyorigin;        /// Drop the old column            $xmldb_field->setName($fieldname); //Set back the original field name            $results = array_merge($results, $this->getDropFieldSQL($xmldb_table, $xmldb_field));        /// Rename the temp column to the original one            $results[] = 'ALTER TABLE ' . $tablename . ' RENAME COLUMN ' . $tempcolname . ' TO ' . $fieldname;        /// Mark we have performed one change based in temp fields            $from_temp_fields = true;        }    /// If the default has changed or we have used one temp field        if ($defaultchanged || $from_temp_fields) {            if ($default_clause = $this->getDefaultClause($xmldb_field)) {                $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $default_clause; /// Add default clause            } else {                if (!$from_temp_fields) { /// Only drop default if we haven't used the temp field, i.e. old column                    $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP DEFAULT'; /// Drop default clause                }            }        }    /// If the not null has changed or we have used one temp field        if ($notnullchanged || $from_temp_fields) {            if ($xmldb_field->getNotnull()) {                $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET NOT NULL';            } else {                $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP NOT NULL';            }        }    /// Return the results         return $results;    }    /**     * Returns the code (array of statements) needed to execute extra statements on field rename     */    function getRenameFieldExtraSQL ($xmldb_table, $xmldb_field, $newname) {        $results = array();    /// If the field is enum, drop and re-create the check constraint        if ($xmldb_field->getEnum()) {        /// Drop the current enum            $results = array_merge($results, $this->getDropEnumSQL($xmldb_table, $xmldb_field));        /// Change field name (over a clone to avoid some potential problems later)            $new_xmldb_field = clone($xmldb_field);            $new_xmldb_field->setName($newname);        /// Recreate the enum            $results = array_merge($results, $this->getCreateEnumSQL($xmldb_table, $new_xmldb_field));        }        return $results;    }    /**     * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum      * (usually invoked from getModifyEnumSQL()     */    function getCreateEnumSQL($xmldb_table, $xmldb_field) {    /// All we have to do is to create the check constraint        return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .                     ' ADD ' . $this->getEnumExtraSQL($xmldb_table, $xmldb_field));    }    /**     * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum      * (usually invoked from getModifyEnumSQL()     */    function getDropEnumSQL($xmldb_table, $xmldb_field) {    /// Let's introspect to know the real name of the check constraint        if ($check_constraints = $this->getCheckConstraintsFromDB($xmldb_table, $xmldb_field)) {            $check_constraint = array_shift($check_constraints); /// Get the 1st (should be only one)            $constraint_name = strtolower($check_constraint->name); /// Extract the REAL name        /// All we have to do is to drop the check constraint            return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .                     ' DROP CONSTRAINT ' . $constraint_name);        } else { /// Constraint not found. Nothing to do            return array();        }    }    /**     * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default      * (usually invoked from getModifyDefaultSQL()     */    function getCreateDefaultSQL($xmldb_table, $xmldb_field) {    /// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that    /// is capable of handling defaults        return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);    }    /**     * Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default      * (usually invoked from getModifyDefaultSQL()     */    function getDropDefaultSQL($xmldb_table, $xmldb_field) {    /// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that    /// is capable of handling defaults        return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);    }    /**     * Given one XMLDBTable returns one array with all the check constrainsts     * in the table (fetched from DB)     * Optionally the function allows one xmldb_field to be specified in     * order to return only the check constraints belonging to one field.     * Each element contains the name of the constraint and its description     * If no check constraints are found, returns an empty array     */    function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {        $results = array();        $tablename = $this->getTableName($xmldb_table);        if ($constraints = get_records_sql("SELECT co.conname AS name, co.consrc AS description                                              FROM pg_constraint co,                                                   pg_class cl                                             WHERE co.conrelid = cl.oid                                               AND co.contype = 'c'                                               AND cl.relname = '{$tablename}'")) {            foreach ($constraints as $constraint) {                $results[$constraint->name] = $constraint;            }        }    /// Filter by the required field if specified        if ($xmldb_field) {            $filtered_results = array();            $filter = $xmldb_field->getName();        /// Lets clean a bit each constraint description, looking for the filtered field            foreach ($results as $key => $result) {                $description = preg_replace('/\("(.*?)"\)/', '($1)', $result->description);// Double quotes out                $description = preg_replace('/[\(\)]/', '', $description);                 // Parenthesis out                $description = preg_replace('/::[a-z]+/i', '', $description);              // Casts out                $description = preg_replace("/({$filter})/i", '@$1@', $description);                $description = trim(preg_replace('/ or /i', ' OR ', $description));        // Uppercase or & trim            /// description starts by @$filter@ assume it's a constraint beloging to the field                if (preg_match("/^@{$filter}@/i", $description)) {                    $filtered_results[$key] = $result;                }            }        /// Assign filtered results to the final results array            $results =  $filtered_results;        }        return $results;    }/** * Given one XMLDBTable returns one string with the sequence of the table * in the table (fetched from DB) * The sequence name for Postgres has one standard name convention:  *     tablename_fieldname_seq * so we just calculate it and confirm it's present in pg_class * If no sequence is found, returns false */function getSequenceFromDB($xmldb_table) {    $tablename = $this->getTableName($xmldb_table);    $sequencename = $tablename . '_id_seq';    if (!get_record_sql("SELECT *                     FROM pg_class                     WHERE relname = '{$sequencename}'                       AND relkind = 'S'")) {        $sequencename = false;    }    return $sequencename;}    /**     * Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg)     * return if such name is currently in use (true) or no (false)     * (invoked from getNameForObject()     */    function isNameInUse($object_name, $type, $table_name) {        switch($type) {            case 'ix':            case 'uix':            case 'seq':                if ($check = get_records_sql("SELECT relname                                               FROM pg_class                                               WHERE lower(relname) = '" . strtolower($object_name) . "'")) {                    return true;                }                break;            case 'pk':            case 'uk':            case 'fk':            case 'ck':                if ($check = get_records_sql("SELECT conname                                               FROM pg_constraint                                              WHERE lower(conname) = '" . strtolower($object_name) . "'")) {                    return true;                }                break;            case 'trg':                if ($check = get_records_sql("SELECT tgname                                               FROM pg_trigger                                              WHERE lower(tgname) = '" . strtolower($object_name) . "'")) {                    return true;                }                break;        }        return false; //No name in use found    }    /**     * Returns an array of reserved words (lowercase) for this DB     */    function getReservedWords() {    /// This file contains the reserved words for PostgreSQL databases    /// http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html        $reserved_words = array (            'all', 'analyse', 'analyze', 'and', 'any', 'array', 'as', 'asc',            'asymmetric', 'authorization', 'between', 'binary', 'both', 'case',            'cast', 'check', 'collate', 'column', 'constraint', 'create', 'cross',            'current_date', 'current_role', 'current_time', 'current_timestamp',            'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do',            'else', 'end', 'except', 'false', 'for', 'foreign', 'freeze', 'from',            'full', 'grant', 'group', 'having', 'ilike', 'in', 'initially', 'inner',            'intersect', 'into', 'is', 'isnull', 'join', 'leading', 'left', 'like',            'limit', 'localtime', 'localtimestamp', 'natural', 'new', 'not',            'notnull', 'null', 'off', 'offset', 'old', 'on', 'only', 'or', 'order',            'outer', 'overlaps', 'placing', 'primary', 'references', 'returning', 'right', 'select',            'session_user', 'similar', 'some', 'symmetric', 'table', 'then', 'to',            'trailing', 'true', 'union', 'unique', 'user', 'using', 'verbose',            'when', 'where', 'with'        );        return $reserved_words;    }}?>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?