/** * Add one field to the table, allowing to specify the desired order * If it's not specified, then the field is added at the end * @param xmldb_field $field * @param xmldb_object $after * @return xmldb_field */ public function addField($field, $after=null) { // Detect duplicates first if ($this->getField($field->getName())) { throw new coding_exception('Duplicate field '.$field->getName().' specified in table '.$this->getName()); } // Calculate the previous and next fields $prevfield = null; $nextfield = null; if (!$after) { $allfields = $this->getFields(); if (!empty($allfields)) { end($allfields); $prevfield = $allfields[key($allfields)]; } } else { $prevfield = $this->getField($after); } if ($prevfield && $prevfield->getNext()) { $nextfield = $this->getField($prevfield->getNext()); } // Set current field previous and next attributes if ($prevfield) { $field->setPrevious($prevfield->getName()); $prevfield->setNext($field->getName()); } if ($nextfield) { $field->setNext($nextfield->getName()); $nextfield->setPrevious($field->getName()); } // Some more attributes $field->setLoaded(true); $field->setChanged(true); // Add the new field $this->fields[] = $field; // Reorder the field $this->orderFields($this->fields); // Recalculate the hash $this->calculateHash(true); // We have one new field, so the table has changed $this->setChanged(true); return $field; }
/** * Given one correct xmldb_field and the new name, returns the SQL statements * to rename it (inside one array). * * @param xmldb_table $xmldb_table The table related to $xmldb_field. * @param xmldb_field $xmldb_field The instance of xmldb_field to get the renamed field from. * @param string $newname The new name to rename the field to. * @return array The SQL statements for renaming the field. */ public function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) { $results = array(); //Array where all the sentences will be stored /// Although this is checked in database_manager::rename_field() - double check /// that we aren't trying to rename one "id" field. Although it could be /// implemented (if adding the necessary code to rename sequences, defaults, /// triggers... and so on under each getRenameFieldExtraSQL() function, it's /// better to forbid it, mainly because this field is the default PK and /// in the future, a lot of FKs can be pointing here. So, this field, more /// or less, must be considered immutable! if ($xmldb_field->getName() == 'id') { return array(); } $rename = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_column_sql); $rename = str_replace('OLDFIELDNAME', $this->getEncQuoted($xmldb_field->getName()), $rename); $rename = str_replace('NEWFIELDNAME', $this->getEncQuoted($newname), $rename); $results[] = $rename; /// Call to getRenameFieldExtraSQL(), override if needed $extra_sentences = $this->getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname); $results = array_merge($results, $extra_sentences); return $results; }
/** * Returns the code (array of statements) needed to execute extra statements on table rename */ public function getRenameTableExtraSQL($xmldb_table, $newname) { $results = array(); $xmldb_field = new xmldb_field('id'); // Fields having sequences should be exclusively, id. $oldseqname = $this->getSequenceFromDB($xmldb_table); $newseqname = $this->getNameForObject($newname, $xmldb_field->getName(), 'seq'); $oldtriggername = $this->getTriggerFromDB($xmldb_table); $newtriggername = $this->getNameForObject($newname, $xmldb_field->getName(), 'trg'); /// Drop old trigger (first of all) $results[] = "DROP TRIGGER " . $oldtriggername; /// Rename the sequence, disablig CACHE before and enablig it later /// to avoid consuming of values on rename $results[] = 'ALTER SEQUENCE ' . $oldseqname . ' NOCACHE'; $results[] = 'RENAME ' . $oldseqname . ' TO ' . $newseqname; $results[] = 'ALTER SEQUENCE ' . $newseqname . ' CACHE ' . $this->sequence_cache_size; /// Create new trigger $newt = new xmldb_table($newname); /// Temp table for trigger code generation $results = array_merge($results, $this->getCreateTriggerSQL($newt, $xmldb_field, $newseqname)); /// Rename all the check constraints in the table $oldtablename = $this->getTableName($xmldb_table); $newtablename = $this->getTableName($newt); $oldconstraintprefix = $this->getNameForObject($xmldb_table->getName(), ''); $newconstraintprefix = $this->getNameForObject($newt->getName(), '', ''); if ($constraints = $this->getCheckConstraintsFromDB($xmldb_table)) { foreach ($constraints as $constraint) { /// Drop the old constraint $results[] = 'ALTER TABLE ' . $newtablename . ' DROP CONSTRAINT ' . $constraint->name; } } return $results; }
/** * Function to emulate full ALTER TABLE which SQLite does not support. * The function can be used to drop a column ($xmldb_delete_field != null and * $xmldb_add_field == null), add a column ($xmldb_delete_field == null and * $xmldb_add_field != null), change/rename a column ($xmldb_delete_field == null * and $xmldb_add_field == null). * @param xmldb_table $xmldb_table table to change * @param xmldb_field $xmldb_add_field column to create/modify (full specification is required) * @param xmldb_field $xmldb_delete_field column to delete/modify (only name field is required) * @return array of strings (SQL statements to alter the table structure) */ protected function getAlterTableSchema($xmldb_table, $xmldb_add_field = NULL, $xmldb_delete_field = NULL) { /// Get the quoted name of the table and field $tablename = $this->getTableName($xmldb_table); $oldname = $xmldb_delete_field ? $xmldb_delete_field->getName() : NULL; $newname = $xmldb_add_field ? $xmldb_add_field->getName() : NULL; if ($xmldb_delete_field) { $xmldb_table->deleteField($oldname); } if ($xmldb_add_field) { $xmldb_table->addField($xmldb_add_field); } if ($oldname) { // alter indexes $indexes = $xmldb_table->getIndexes(); foreach ($indexes as $index) { $fields = $index->getFields(); $i = array_search($oldname, $fields); if ($i !== FALSE) { if ($newname) { $fields[$i] = $newname; } else { unset($fields[$i]); } $xmldb_table->deleteIndex($index->getName()); if (count($fields)) { $index->setFields($fields); $xmldb_table->addIndex($index); } } } // alter keys $keys = $xmldb_table->getKeys(); foreach ($keys as $key) { $fields = $key->getFields(); $reffields = $key->getRefFields(); $i = array_search($oldname, $fields); if ($i !== FALSE) { if ($newname) { $fields[$i] = $newname; } else { unset($fields[$i]); unset($reffields[$i]); } $xmldb_table->deleteKey($key->getName()); if (count($fields)) { $key->setFields($fields); $key->setRefFields($fields); $xmldb_table->addkey($key); } } } } // prepare data copy $fields = $xmldb_table->getFields(); foreach ($fields as $key => $field) { $fieldname = $field->getName(); if ($fieldname == $newname && $oldname && $oldname != $newname) { // field rename operation $fields[$key] = $this->getEncQuoted($oldname) . ' AS ' . $this->getEncQuoted($newname); } else { $fields[$key] = $this->getEncQuoted($field->getName()); } } $fields = implode(',', $fields); $results[] = 'BEGIN TRANSACTION'; $results[] = 'CREATE TEMPORARY TABLE temp_data AS SELECT * FROM ' . $tablename; $results[] = 'DROP TABLE ' . $tablename; $results = array_merge($results, $this->getCreateTableSQL($xmldb_table)); $results[] = 'INSERT INTO ' . $tablename . ' SELECT ' . $fields . ' FROM temp_data'; $results[] = 'DROP TABLE temp_data'; $results[] = 'COMMIT'; return $results; }
/** * Returns the code (array of statements) needed to execute extra statements on table rename */ public function getRenameTableExtraSQL($xmldb_table, $newname) { $results = array(); $xmldb_field = new xmldb_field('id'); // Fields having sequences should be exclusively, id. $oldseqname = $this->getSequenceFromDB($xmldb_table); $newseqname = $this->getNameForObject($newname, $xmldb_field->getName(), 'seq'); /// Rename de sequence $results[] = 'RENAME ' . $oldseqname . ' TO ' . $newseqname; $oldtriggername = $this->getTriggerFromDB($xmldb_table); $newtriggername = $this->getNameForObject($newname, $xmldb_field->getName(), 'trg'); /// Drop old trigger $results[] = "DROP TRIGGER " . $oldtriggername; $newt = new xmldb_table($newname); /// Temp table for trigger code generation /// Create new trigger $results = array_merge($results, $this->getCreateTriggerSQL($newt, $xmldb_field)); /// Rename all the check constraints in the table $oldtablename = $this->getTableName($xmldb_table); $newtablename = $this->getTableName($newt); $oldconstraintprefix = $this->getNameForObject($xmldb_table->getName(), ''); $newconstraintprefix = $this->getNameForObject($newt->getName(), '', ''); if ($constraints = $this->getCheckConstraintsFromDB($xmldb_table)) { foreach ($constraints as $constraint) { /// Drop the old constraint $results[] = 'ALTER TABLE ' . $newtablename . ' DROP CONSTRAINT ' . $constraint->name; } } return $results; }
/** * Given one correct xmldb_field and the new name, returns the SQL statements * to rename it (inside one array). * * @param xmldb_table $xmldb_table The table related to $xmldb_field. * @param xmldb_field $xmldb_field The instance of xmldb_field to get the renamed field from. * @param string $newname The new name to rename the field to. * @return array The SQL statements for renaming the field. */ public function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) { // NOTE: MySQL is pretty different from the standard to justify this overloading. // Need a clone of xmldb_field to perform the change leaving original unmodified $xmldb_field_clone = clone $xmldb_field; // Change the name of the field to perform the change $xmldb_field_clone->setName($newname); $fieldsql = $this->getFieldSQL($xmldb_table, $xmldb_field_clone); $sql = 'ALTER TABLE ' . $this->getTableName($xmldb_table) . ' CHANGE ' . $xmldb_field->getName() . ' ' . $fieldsql; return array($sql); }
/** * Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table. * * PostgreSQL has some severe limits: * - Any change of type or precision requires a new temporary column to be created, values to * be transfered potentially casting them, to apply defaults if the column is not null and * finally, to rename it * - Changes in null/not null require the SET/DROP NOT NULL clause * - Changes in default require the SET/DROP DEFAULT clause * * @param xmldb_table $xmldb_table The table related to $xmldb_field. * @param xmldb_field $xmldb_field The instance of xmldb_field to create the SQL from. * @param string $skip_type_clause The type clause on alter columns, NULL by default. * @param string $skip_default_clause The default clause on alter columns, NULL by default. * @param string $skip_notnull_clause The null/notnull clause on alter columns, NULL by default. * @return string The field altering SQL statement. */ public function getAlterFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause = NULL, $skip_default_clause = NULL, $skip_notnull_clause = NULL) { $results = array(); // To store all the needed SQL commands // Get the normal names of the table and field $tablename = $xmldb_table->getName(); $fieldname = $xmldb_field->getName(); // Take a look to field metadata $meta = $this->mdb->get_columns($tablename); $metac = $meta[$xmldb_field->getName()]; $oldmetatype = $metac->meta_type; $oldlength = $metac->max_length; $olddecimals = empty($metac->scale) ? null : $metac->scale; $oldnotnull = empty($metac->not_null) ? false : $metac->not_null; $olddefault = empty($metac->has_default) ? null : $metac->default_value; $typechanged = true; //By default, assume that the column type has changed $precisionchanged = true; //By default, assume that the column precision has changed $decimalchanged = true; //By default, assume that the column decimal has changed $defaultchanged = true; //By default, assume that the column default has changed $notnullchanged = true; //By default, assume that the column notnull has changed // Detect if we are changing the type of the column if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I' || $xmldb_field->getType() == XMLDB_TYPE_NUMBER && $oldmetatype == 'N' || $xmldb_field->getType() == XMLDB_TYPE_FLOAT && $oldmetatype == 'F' || $xmldb_field->getType() == XMLDB_TYPE_CHAR && $oldmetatype == 'C' || $xmldb_field->getType() == XMLDB_TYPE_TEXT && $oldmetatype == 'X' || $xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B') { $typechanged = false; } // Detect if we are changing the precision if ($xmldb_field->getType() == XMLDB_TYPE_TEXT || $xmldb_field->getType() == XMLDB_TYPE_BINARY || $oldlength == -1 || $xmldb_field->getLength() == $oldlength) { $precisionchanged = false; } // Detect if we are changing the decimals if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER || $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) { $defaultchanged = false; } // Detect if we are changing the nullability if ($xmldb_field->getNotnull() === $oldnotnull) { $notnullchanged = false; } // Get the quoted name of the table and field $tablename = $this->getTableName($xmldb_table); $fieldname = $this->getEncQuoted($xmldb_field->getName()); // Decide if we have changed the column specs (type/precision/decimals) $specschanged = $typechanged || $precisionchanged || $decimalchanged; // if specs have changed, need to alter column if ($specschanged) { // Always drop any exiting default before alter column (some type changes can cause casting error in default for column) if ($olddefault !== null) { $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP DEFAULT'; // Drop default clause } $alterstmt = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $this->getEncQuoted($xmldb_field->getName()) . ' TYPE' . $this->getFieldSQL($xmldb_table, $xmldb_field, null, true, true, null, false); // Some castings must be performed explicitly (mainly from text|char to numeric|integer) if (($oldmetatype == 'C' || $oldmetatype == 'X') && ($xmldb_field->getType() == XMLDB_TYPE_NUMBER || $xmldb_field->getType() == XMLDB_TYPE_FLOAT)) { $alterstmt .= ' USING CAST(' . $fieldname . ' AS NUMERIC)'; // from char or text to number or float } else { if (($oldmetatype == 'C' || $oldmetatype == 'X') && $xmldb_field->getType() == XMLDB_TYPE_INTEGER) { $alterstmt .= ' USING CAST(CAST(' . $fieldname . ' AS NUMERIC) AS INTEGER)'; // From char to integer } } $results[] = $alterstmt; } // If the default has changed or we have performed one change in specs if ($defaultchanged || $specschanged) { $default_clause = $this->getDefaultClause($xmldb_field); if ($default_clause) { $sql = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $default_clause; // Add default clause $results[] = $sql; } else { if (!$specschanged) { // Only drop default if we haven't performed one specs change $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP DEFAULT'; // Drop default clause } } } // If the not null has changed if ($notnullchanged) { 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 table rename */ public function getRenameTableExtraSQL($xmldb_table, $newname) { $results = array(); $newt = new xmldb_table($newname); $xmldb_field = new xmldb_field('id'); // Fields having sequences should be exclusively, id. $oldseqname = $this->getTableName($xmldb_table) . '_' . $xmldb_field->getName() . '_seq'; $newseqname = $this->getTableName($newt) . '_' . $xmldb_field->getName() . '_seq'; /// Rename de sequence $results[] = 'ALTER TABLE ' . $oldseqname . ' RENAME TO ' . $newseqname; return $results; }
/** * Given one xmldb_table and one xmldb_field, returns the name of its default constraint in DB * or false if not found * This function should be considered internal and never used outside from generator * * @param xmldb_table $xmldb_table The xmldb_table object instance. * @param xmldb_field $xmldb_field The xmldb_field object instance. * @return mixed */ protected function getDefaultConstraintName($xmldb_table, $xmldb_field) { // Get the quoted name of the table and field $tablename = $this->getTableName($xmldb_table); $fieldname = $xmldb_field->getName(); // Look for any default constraint in this field and drop it if ($default = $this->mdb->get_record_sql("SELECT id, object_name(cdefault) AS defaultconstraint\n FROM syscolumns\n WHERE id = object_id(?)\n AND name = ?", array($tablename, $fieldname))) { return $default->defaultconstraint; } else { return false; } }
/** * Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table. * * Oracle has some severe limits: * - clob and blob fields doesn't allow type to be specified * - error is dropped if the null/not null clause is specified and hasn't changed * - changes in precision/decimals of numeric fields drop an ORA-1440 error * * @param xmldb_table $xmldb_table The table related to $xmldb_field. * @param xmldb_field $xmldb_field The instance of xmldb_field to create the SQL from. * @param string $skip_type_clause The type clause on alter columns, NULL by default. * @param string $skip_default_clause The default clause on alter columns, NULL by default. * @param string $skip_notnull_clause The null/notnull clause on alter columns, NULL by default. * @return string The field altering SQL statement. */ public function getAlterFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause = NULL, $skip_default_clause = NULL, $skip_notnull_clause = NULL) { $skip_type_clause = is_null($skip_type_clause) ? $this->alter_column_skip_type : $skip_type_clause; $skip_default_clause = is_null($skip_default_clause) ? $this->alter_column_skip_default : $skip_default_clause; $skip_notnull_clause = is_null($skip_notnull_clause) ? $this->alter_column_skip_notnull : $skip_notnull_clause; $results = array(); // To store all the needed SQL commands // Get the quoted name of the table and field $tablename = $this->getTableName($xmldb_table); $fieldname = $xmldb_field->getName(); // Take a look to field metadata $meta = $this->mdb->get_columns($xmldb_table->getName()); $metac = $meta[$fieldname]; $oldmetatype = $metac->meta_type; $oldlength = $metac->max_length; // To calculate the oldlength if the field is numeric, we need to perform one extra query // because ADOdb has one bug here. http://phplens.com/lens/lensforum/msgs.php?id=15883 if ($oldmetatype == 'N') { $uppertablename = strtoupper($tablename); $upperfieldname = strtoupper($fieldname); if ($col = $this->mdb->get_record_sql("SELECT cname, precision\n FROM col\n WHERE tname = ? AND cname = ?", array($uppertablename, $upperfieldname))) { $oldlength = $col->precision; } } $olddecimals = empty($metac->scale) ? null : $metac->scale; $oldnotnull = empty($metac->not_null) ? false : $metac->not_null; $olddefault = empty($metac->default_value) || strtoupper($metac->default_value) == 'NULL' ? null : $metac->default_value; $typechanged = true; //By default, assume that the column type has changed $precisionchanged = true; //By default, assume that the column precision has changed $decimalchanged = true; //By default, assume that the column decimal has changed $defaultchanged = true; //By default, assume that the column default has changed $notnullchanged = true; //By default, assume that the column notnull has changed $from_temp_fields = false; //By default don't assume we are going to use temporal fields // Detect if we are changing the type of the column if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I' || $xmldb_field->getType() == XMLDB_TYPE_NUMBER && $oldmetatype == 'N' || $xmldb_field->getType() == XMLDB_TYPE_FLOAT && $oldmetatype == 'F' || $xmldb_field->getType() == XMLDB_TYPE_CHAR && $oldmetatype == 'C' || $xmldb_field->getType() == XMLDB_TYPE_TEXT && $oldmetatype == 'X' || $xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B') { $typechanged = false; } // Detect if precision has changed if ($xmldb_field->getType() == XMLDB_TYPE_TEXT || $xmldb_field->getType() == XMLDB_TYPE_BINARY || $oldlength == -1 || $xmldb_field->getLength() == $oldlength) { $precisionchanged = false; } // Detect if decimal has changed if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER || $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 || "'" . $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; } // If type has changed or precision or decimal has changed and we are in one numeric field // - create one temp column with the new specs // - fill the new column with the values from the old one // - drop the old column // - rename the temp column to the original name if ($typechanged || ($oldmetatype == 'N' || $oldmetatype == 'I') && ($precisionchanged || $decimalchanged)) { $tempcolname = $xmldb_field->getName() . '___tmp'; // Short tmp name, surely not conflicting ever if (strlen($tempcolname) > 30) { // Safeguard we don't excess the 30cc limit $tempcolname = 'ongoing_alter_column_tmp'; } // Prevent temp field to have both NULL/NOT NULL and DEFAULT constraints $skip_notnull_clause = true; $skip_default_clause = true; $xmldb_field->setName($tempcolname); // Drop the temp column, in case it exists (due to one previous failure in conversion) // really ugly but we cannot enclose DDL into transaction :-( if (isset($meta[$tempcolname])) { $results = array_merge($results, $this->getDropFieldSQL($xmldb_table, $xmldb_field)); } // Create the temporal column $results = array_merge($results, $this->getAddFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause, $skip_type_clause, $skip_notnull_clause)); // Copy contents from original col to the temporal one // From TEXT to integer/number we need explicit conversion if ($oldmetatype == 'X' && $xmldb_field->GetType() == XMLDB_TYPE_INTEGER) { $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = CAST(' . $this->mdb->sql_compare_text($fieldname) . ' AS INT)'; } else { if ($oldmetatype == 'X' && $xmldb_field->GetType() == XMLDB_TYPE_NUMBER) { $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = CAST(' . $this->mdb->sql_compare_text($fieldname) . ' AS NUMBER)'; // Normal cases, implicit conversion } else { $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = ' . $fieldname; } } // 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; // Re-enable the notnull and default sections so the general AlterFieldSQL can use it $skip_notnull_clause = false; $skip_default_clause = false; // Disable the type section because we have done it with the temp field $skip_type_clause = true; // If new field is nullable, nullability hasn't changed if (!$xmldb_field->getNotnull()) { $notnullchanged = false; } // If new field hasn't default, default hasn't changed if ($xmldb_field->getDefault() === null) { $defaultchanged = false; } } // If type and precision and decimals hasn't changed, prevent the type clause if (!$typechanged && !$precisionchanged && !$decimalchanged) { $skip_type_clause = true; } // If NULL/NOT NULL hasn't changed // prevent null clause to be specified if (!$notnullchanged) { $skip_notnull_clause = true; // Initially, prevent the notnull clause // But, if we have used the temp field and the new field is not null, then enforce the not null clause if ($from_temp_fields && $xmldb_field->getNotnull()) { $skip_notnull_clause = false; } } // If default hasn't changed // prevent default clause to be specified if (!$defaultchanged) { $skip_default_clause = true; // Initially, prevent the default clause // But, if we have used the temp field and the new field has default clause, then enforce the default clause if ($from_temp_fields) { $default_clause = $this->getDefaultClause($xmldb_field); if ($default_clause) { $skip_notnull_clause = false; } } } // If arriving here, something is not being skipped (type, notnull, default), calculate the standard AlterFieldSQL if (!$skip_type_clause || !$skip_notnull_clause || !$skip_default_clause) { $results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause, $skip_default_clause, $skip_notnull_clause)); return $results; } // Finally return results return $results; }
/** * Returns the code (array of statements) needed to execute extra statements on table rename */ public function getRenameTableExtraSQL($xmldb_table, $newname) { $results = array(); $newt = new xmldb_table($newname); $xmldb_field = new xmldb_field('id'); // Fields having sequences should be exclusively, id. $oldseqname = $this->getTableName($xmldb_table) . '_' . $xmldb_field->getName() . '_seq'; $newseqname = $this->getTableName($newt) . '_' . $xmldb_field->getName() . '_seq'; /// Rename de sequence $results[] = 'ALTER TABLE ' . $oldseqname . ' RENAME TO ' . $newseqname; /// Rename all the check constraints in the table $oldtablename = $this->getTableName($xmldb_table); $newtablename = $this->getTableName($newt); $oldconstraintprefix = $this->getNameForObject($xmldb_table->getName(), ''); $newconstraintprefix = $this->getNameForObject($newt->getName(), '', ''); if ($constraints = $this->getCheckConstraintsFromDB($xmldb_table)) { foreach ($constraints as $constraint) { /// Drop the old constraint $results[] = 'ALTER TABLE ' . $newtablename . ' DROP CONSTRAINT ' . $constraint->name; } } return $results; }
/** * Returns the code (array of statements) needed to execute extra statements on table rename */ public function getRenameTableExtraSQL($xmldb_table, $newname) { $results = array(); $xmldb_field = new xmldb_field('id'); // Fields having sequences should be exclusively, id. $oldseqname = $this->getSequenceFromDB($xmldb_table); $newseqname = $this->getNameForObject($newname, $xmldb_field->getName(), 'seq'); $oldtriggername = $this->getTriggerFromDB($xmldb_table); $newtriggername = $this->getNameForObject($newname, $xmldb_field->getName(), 'trg'); /// Drop old trigger (first of all) $results[] = "DROP TRIGGER " . $oldtriggername; /// Rename the sequence, disablig CACHE before and enablig it later /// to avoid consuming of values on rename $results[] = 'ALTER SEQUENCE ' . $oldseqname . ' NOCACHE'; $results[] = 'RENAME ' . $oldseqname . ' TO ' . $newseqname; $results[] = 'ALTER SEQUENCE ' . $newseqname . ' CACHE ' . $this->sequence_cache_size; /// Create new trigger $newt = new xmldb_table($newname); /// Temp table for trigger code generation $results = array_merge($results, $this->getCreateTriggerSQL($newt, $xmldb_field, $newseqname)); return $results; }