MDL-32003 fix phpdocs in DDL layer
This commit is contained in:
@@ -14,13 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* Database manager instance is responsible for all database structure modifications.
|
||||
*
|
||||
* @package core
|
||||
* @category ddl
|
||||
* @subpackage ddl
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* 2008 Petr Skoda http://skodak.org
|
||||
@@ -34,9 +31,7 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*
|
||||
* It is using db specific generators to find out the correct SQL syntax to do that.
|
||||
*
|
||||
* @package core
|
||||
* @category ddl
|
||||
* @subpackage ddl
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* 2008 Petr Skoda http://skodak.org
|
||||
@@ -44,8 +39,9 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
class database_manager {
|
||||
|
||||
/** @var moodle_database A moodle_database driver speific instance.*/
|
||||
/** @var moodle_database A moodle_database driver specific instance.*/
|
||||
protected $mdb;
|
||||
|
||||
/** @var sql_generator A driver specific SQL generator instance. Public because XMLDB editor needs to access it.*/
|
||||
public $generator;
|
||||
|
||||
@@ -55,8 +51,6 @@ class database_manager {
|
||||
* @param sql_generator $generator A driver specific SQL generator instance.
|
||||
*/
|
||||
public function __construct($mdb, $generator) {
|
||||
global $CFG;
|
||||
|
||||
$this->mdb = $mdb;
|
||||
$this->generator = $generator;
|
||||
}
|
||||
@@ -100,7 +94,7 @@ class database_manager {
|
||||
/**
|
||||
* Given one xmldb_table, check if it exists in DB (true/false).
|
||||
*
|
||||
* @param mixed $table The table to be searched (string name or xmldb_table instance).
|
||||
* @param string|xmldb_table $table The table to be searched (string name or xmldb_table instance).
|
||||
* @return bool true/false True is a table exists, false otherwise.
|
||||
*/
|
||||
public function table_exists($table) {
|
||||
@@ -138,14 +132,14 @@ class database_manager {
|
||||
* @throws ddl_table_missing_exception
|
||||
*/
|
||||
public function field_exists($table, $field) {
|
||||
/// Calculate the name of the table
|
||||
// Calculate the name of the table
|
||||
if (is_string($table)) {
|
||||
$tablename = $table;
|
||||
} else {
|
||||
$tablename = $table->getName();
|
||||
}
|
||||
|
||||
/// Check the table exists
|
||||
// Check the table exists
|
||||
if (!$this->table_exists($table)) {
|
||||
throw new ddl_table_missing_exception($tablename);
|
||||
}
|
||||
@@ -153,11 +147,11 @@ class database_manager {
|
||||
if (is_string($field)) {
|
||||
$fieldname = $field;
|
||||
} else {
|
||||
/// Calculate the name of the table
|
||||
// Calculate the name of the table
|
||||
$fieldname = $field->getName();
|
||||
}
|
||||
|
||||
/// Get list of fields in table
|
||||
// Get list of fields in table
|
||||
$columns = $this->mdb->get_columns($tablename);
|
||||
|
||||
$exists = array_key_exists($fieldname, $columns);
|
||||
@@ -175,32 +169,32 @@ class database_manager {
|
||||
* @throws ddl_table_missing_exception Thrown when table is not found.
|
||||
*/
|
||||
public function find_index_name(xmldb_table $xmldb_table, xmldb_index $xmldb_index) {
|
||||
/// Calculate the name of the table
|
||||
// Calculate the name of the table
|
||||
$tablename = $xmldb_table->getName();
|
||||
|
||||
/// Check the table exists
|
||||
// Check the table exists
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
throw new ddl_table_missing_exception($tablename);
|
||||
}
|
||||
|
||||
/// Extract index columns
|
||||
// Extract index columns
|
||||
$indcolumns = $xmldb_index->getFields();
|
||||
|
||||
/// Get list of indexes in table
|
||||
// Get list of indexes in table
|
||||
$indexes = $this->mdb->get_indexes($tablename);
|
||||
|
||||
/// Iterate over them looking for columns coincidence
|
||||
// Iterate over them looking for columns coincidence
|
||||
foreach ($indexes as $indexname => $index) {
|
||||
$columns = $index['columns'];
|
||||
/// Check if index matchs queried index
|
||||
// Check if index matches queried index
|
||||
$diferences = array_merge(array_diff($columns, $indcolumns), array_diff($indcolumns, $columns));
|
||||
/// If no diferences, we have find the index
|
||||
// If no differences, we have find the index
|
||||
if (empty($diferences)) {
|
||||
return $indexname;
|
||||
}
|
||||
}
|
||||
|
||||
/// Arriving here, index not found
|
||||
// Arriving here, index not found
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,23 +227,23 @@ class database_manager {
|
||||
|
||||
$keycolumns = $xmldb_key->getFields();
|
||||
|
||||
/// Get list of keys in table
|
||||
/// first primaries (we aren't going to use this now, because the MetaPrimaryKeys is awful)
|
||||
///TODO: To implement when we advance in relational integrity
|
||||
/// then uniques (note that Moodle, for now, shouldn't have any UNIQUE KEY for now, but unique indexes)
|
||||
///TODO: To implement when we advance in relational integrity (note that AdoDB hasn't any MetaXXX for this.
|
||||
/// then foreign (note that Moodle, for now, shouldn't have any FOREIGN KEY for now, but indexes)
|
||||
///TODO: To implement when we advance in relational integrity (note that AdoDB has one MetaForeignKeys()
|
||||
///but it's far from perfect.
|
||||
/// TODO: To create the proper functions inside each generator to retrieve all the needed KEY info (name
|
||||
/// columns, reftable and refcolumns
|
||||
// Get list of keys in table
|
||||
// first primaries (we aren't going to use this now, because the MetaPrimaryKeys is awful)
|
||||
//TODO: To implement when we advance in relational integrity
|
||||
// then uniques (note that Moodle, for now, shouldn't have any UNIQUE KEY for now, but unique indexes)
|
||||
//TODO: To implement when we advance in relational integrity (note that AdoDB hasn't any MetaXXX for this.
|
||||
// then foreign (note that Moodle, for now, shouldn't have any FOREIGN KEY for now, but indexes)
|
||||
//TODO: To implement when we advance in relational integrity (note that AdoDB has one MetaForeignKeys()
|
||||
//but it's far from perfect.
|
||||
// TODO: To create the proper functions inside each generator to retrieve all the needed KEY info (name
|
||||
// columns, reftable and refcolumns
|
||||
|
||||
/// So all we do is to return the official name of the requested key without any confirmation!)
|
||||
/// One exception, hardcoded primary constraint names
|
||||
// So all we do is to return the official name of the requested key without any confirmation!)
|
||||
// One exception, hardcoded primary constraint names
|
||||
if ($this->generator->primary_key_name && $xmldb_key->getType() == XMLDB_KEY_PRIMARY) {
|
||||
return $this->generator->primary_key_name;
|
||||
} else {
|
||||
/// Calculate the name suffix
|
||||
// Calculate the name suffix
|
||||
switch ($xmldb_key->getType()) {
|
||||
case XMLDB_KEY_PRIMARY:
|
||||
$suffix = 'pk';
|
||||
@@ -262,7 +256,7 @@ class database_manager {
|
||||
$suffix = 'fk';
|
||||
break;
|
||||
}
|
||||
/// And simply, return the official name
|
||||
// And simply, return the official name
|
||||
return $this->generator->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), $suffix);
|
||||
}
|
||||
}
|
||||
@@ -285,7 +279,7 @@ class database_manager {
|
||||
$structure = $xmldb_file->getStructure();
|
||||
|
||||
if (!$loaded || !$xmldb_file->isLoaded()) {
|
||||
/// Show info about the error if we can find it
|
||||
// Show info about the error if we can find it
|
||||
if ($structure) {
|
||||
if ($errors = $structure->getAllErrors()) {
|
||||
throw new ddl_exception('ddlxmlfileerror', null, 'Errors found in XMLDB file: '. implode (', ', $errors));
|
||||
@@ -312,7 +306,7 @@ class database_manager {
|
||||
* @return void
|
||||
*/
|
||||
public function drop_table(xmldb_table $xmldb_table) {
|
||||
/// Check table exists
|
||||
// Check table exists
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
@@ -338,7 +332,7 @@ class database_manager {
|
||||
|
||||
$loaded = $xmldb_file->loadXMLStructure();
|
||||
if (!$loaded || !$xmldb_file->isLoaded()) {
|
||||
/// Show info about the error if we can find it
|
||||
// Show info about the error if we can find it
|
||||
if ($structure =& $xmldb_file->getStructure()) {
|
||||
if ($errors = $structure->getAllErrors()) {
|
||||
throw new ddl_exception('ddlxmlfileerror', null, 'Errors found in XMLDB file: '. implode (', ', $errors));
|
||||
@@ -418,7 +412,7 @@ class database_manager {
|
||||
* @return void
|
||||
*/
|
||||
public function create_table(xmldb_table $xmldb_table) {
|
||||
/// Check table doesn't exist
|
||||
// Check table doesn't exist
|
||||
if ($this->table_exists($xmldb_table)) {
|
||||
throw new ddl_exception('ddltablealreadyexists', $xmldb_table->getName());
|
||||
}
|
||||
@@ -477,14 +471,14 @@ class database_manager {
|
||||
* @return void
|
||||
*/
|
||||
public function rename_table(xmldb_table $xmldb_table, $newname) {
|
||||
/// Check newname isn't empty
|
||||
// Check newname isn't empty
|
||||
if (!$newname) {
|
||||
throw new ddl_exception('ddlunknownerror', null, 'newname can not be empty');
|
||||
}
|
||||
|
||||
$check = new xmldb_table($newname);
|
||||
|
||||
/// Check table already renamed
|
||||
// Check table already renamed
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
if ($this->table_exists($check)) {
|
||||
throw new ddl_exception('ddlunknownerror', null, 'table probably already renamed');
|
||||
@@ -493,7 +487,7 @@ class database_manager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check new table doesn't exist
|
||||
// Check new table doesn't exist
|
||||
if ($this->table_exists($check)) {
|
||||
throw new ddl_exception('ddltablealreadyexists', $xmldb_table->getName(), 'can not rename table');
|
||||
}
|
||||
@@ -505,7 +499,6 @@ class database_manager {
|
||||
$this->execute_sql_arr($sqlarr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will add the field to the table passed as arguments
|
||||
*
|
||||
@@ -514,13 +507,13 @@ class database_manager {
|
||||
* @return void
|
||||
*/
|
||||
public function add_field(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
|
||||
/// Check the field doesn't exist
|
||||
// Check the field doesn't exist
|
||||
if ($this->field_exists($xmldb_table, $xmldb_field)) {
|
||||
throw new ddl_exception('ddlfieldalreadyexists', $xmldb_field->getName());
|
||||
}
|
||||
|
||||
/// If NOT NULL and no default given (we ask the generator about the
|
||||
/// *real* default that will be used) check the table is empty
|
||||
// If NOT NULL and no default given (we ask the generator about the
|
||||
// *real* default that will be used) check the table is empty
|
||||
if ($xmldb_field->getNotNull() && $this->generator->getDefaultValue($xmldb_field) === NULL && $this->mdb->count_records($xmldb_table->getName())) {
|
||||
throw new ddl_exception('ddlunknownerror', null, 'Field ' . $xmldb_table->getName() . '->' . $xmldb_field->getName() .
|
||||
' cannot be added. Not null fields added to non empty tables require default value. Create skipped');
|
||||
@@ -543,11 +536,11 @@ class database_manager {
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
/// Check the field exists
|
||||
// Check the field exists
|
||||
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
|
||||
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
|
||||
}
|
||||
/// Check for dependencies in the DB before performing any action
|
||||
// Check for dependencies in the DB before performing any action
|
||||
$this->check_field_dependencies($xmldb_table, $xmldb_field);
|
||||
|
||||
if (!$sqlarr = $this->generator->getDropFieldSQL($xmldb_table, $xmldb_field)) {
|
||||
@@ -568,11 +561,11 @@ class database_manager {
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
/// Check the field exists
|
||||
// Check the field exists
|
||||
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
|
||||
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
|
||||
}
|
||||
/// Check for dependencies in the DB before performing any action
|
||||
// Check for dependencies in the DB before performing any action
|
||||
$this->check_field_dependencies($xmldb_table, $xmldb_field);
|
||||
|
||||
if (!$sqlarr = $this->generator->getAlterFieldSQL($xmldb_table, $xmldb_field)) {
|
||||
@@ -590,7 +583,7 @@ class database_manager {
|
||||
* @return void
|
||||
*/
|
||||
public function change_field_precision(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
|
||||
/// Just a wrapper over change_field_type. Does exactly the same processing
|
||||
// Just a wrapper over change_field_type. Does exactly the same processing
|
||||
$this->change_field_type($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
@@ -615,7 +608,7 @@ class database_manager {
|
||||
* @return void
|
||||
*/
|
||||
public function change_field_notnull(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
|
||||
/// Just a wrapper over change_field_type. Does exactly the same processing
|
||||
// Just a wrapper over change_field_type. Does exactly the same processing
|
||||
$this->change_field_type($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
@@ -631,11 +624,11 @@ class database_manager {
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
/// Check the field exists
|
||||
// Check the field exists
|
||||
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
|
||||
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
|
||||
}
|
||||
/// Check for dependencies in the DB before performing any action
|
||||
// Check for dependencies in the DB before performing any action
|
||||
$this->check_field_dependencies($xmldb_table, $xmldb_field);
|
||||
|
||||
if (!$sqlarr = $this->generator->getModifyDefaultSQL($xmldb_table, $xmldb_field)) {
|
||||
@@ -663,19 +656,19 @@ class database_manager {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Check the field exists
|
||||
// Check the field exists
|
||||
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
|
||||
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Check we have included full field specs
|
||||
// Check we have included full field specs
|
||||
if (!$xmldb_field->getType()) {
|
||||
throw new ddl_exception('ddlunknownerror', null,
|
||||
'Field ' . $xmldb_table->getName() . '->' . $xmldb_field->getName() .
|
||||
' must contain full specs. Rename skipped');
|
||||
}
|
||||
|
||||
/// Check field isn't id. Renaming over that field is not allowed
|
||||
// Check field isn't id. Renaming over that field is not allowed
|
||||
if ($xmldb_field->getName() == 'id') {
|
||||
throw new ddl_exception('ddlunknownerror', null,
|
||||
'Field ' . $xmldb_table->getName() . '->' . $xmldb_field->getName() .
|
||||
@@ -701,17 +694,17 @@ class database_manager {
|
||||
*/
|
||||
private function check_field_dependencies(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
|
||||
|
||||
/// Check the table exists
|
||||
// Check the table exists
|
||||
if (!$this->table_exists($xmldb_table)) {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Check the field exists
|
||||
// Check the field exists
|
||||
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
|
||||
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Check the field isn't in use by any index in the table
|
||||
// Check the field isn't in use by any index in the table
|
||||
if ($indexes = $this->mdb->get_indexes($xmldb_table->getName(), false)) {
|
||||
foreach ($indexes as $indexname => $index) {
|
||||
$columns = $index['columns'];
|
||||
@@ -774,7 +767,7 @@ class database_manager {
|
||||
public function rename_key(xmldb_table $xmldb_table, xmldb_key $xmldb_key, $newname) {
|
||||
debugging('rename_key() is one experimental feature. You must not use it in production!', DEBUG_DEVELOPER);
|
||||
|
||||
/// Check newname isn't empty
|
||||
// Check newname isn't empty
|
||||
if (!$newname) {
|
||||
throw new ddl_exception('ddlunknownerror', null, 'newname can not be empty');
|
||||
}
|
||||
@@ -799,7 +792,7 @@ class database_manager {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Check index doesn't exist
|
||||
// Check index doesn't exist
|
||||
if ($this->index_exists($xmldb_table, $xmldb_intex)) {
|
||||
throw new ddl_exception('ddlunknownerror', null,
|
||||
'Index ' . $xmldb_table->getName() . '->' . $xmldb_intex->getName() .
|
||||
@@ -826,7 +819,7 @@ class database_manager {
|
||||
throw new ddl_table_missing_exception($xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Check index exists
|
||||
// Check index exists
|
||||
if (!$this->index_exists($xmldb_table, $xmldb_intex)) {
|
||||
throw new ddl_exception('ddlunknownerror', null,
|
||||
'Index ' . $xmldb_table->getName() . '->' . $xmldb_intex->getName() .
|
||||
@@ -853,12 +846,12 @@ class database_manager {
|
||||
public function rename_index($xmldb_table, $xmldb_intex, $newname) {
|
||||
debugging('rename_index() is one experimental feature. You must not use it in production!', DEBUG_DEVELOPER);
|
||||
|
||||
/// Check newname isn't empty
|
||||
// Check newname isn't empty
|
||||
if (!$newname) {
|
||||
throw new ddl_exception('ddlunknownerror', null, 'newname can not be empty');
|
||||
}
|
||||
|
||||
/// Check index exists
|
||||
// Check index exists
|
||||
if (!$this->index_exists($xmldb_table, $xmldb_intex)) {
|
||||
throw new ddl_exception('ddlunknownerror', null,
|
||||
'Index ' . $xmldb_table->getName() . '->' . $xmldb_intex->getName() .
|
||||
|
||||
+173
-88
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* MSSQL specific SQL code generator.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage ddl_generator
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -30,51 +27,70 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir.'/ddl/sql_generator.php');
|
||||
|
||||
/// This class generate SQL code to be used against MSSQL
|
||||
/// It extends XMLDBgenerator so everything can be
|
||||
/// overridden as needed to generate correct SQL.
|
||||
|
||||
/**
|
||||
* This class generate SQL code to be used against MSSQL
|
||||
* It extends XMLDBgenerator so everything can be
|
||||
* overridden as needed to generate correct SQL.
|
||||
*
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mssql_sql_generator extends sql_generator {
|
||||
|
||||
/// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
|
||||
public $statement_end = "\ngo"; // String to be automatically added at the end of each statement
|
||||
/** @var string To be automatically added at the end of each statement. */
|
||||
public $statement_end = "\ngo";
|
||||
|
||||
public $number_type = 'DECIMAL'; // Proper type for NUMBER(x) in this DB
|
||||
/** @var string Proper type for NUMBER(x) in this DB. */
|
||||
public $number_type = 'DECIMAL';
|
||||
|
||||
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
|
||||
/** @var string To define the default to set for NOT NULLs CHARs without default (null=do nothing).*/
|
||||
public $default_for_char = '';
|
||||
|
||||
public $specify_nulls = true; //To force the generator if NULL clauses must be specified. It shouldn't be necessary
|
||||
//but some mssql drivers require them or everything is created as NOT NULL :-(
|
||||
/**
|
||||
* @var bool To force the generator if NULL clauses must be specified. It shouldn't be necessary.
|
||||
* note: some mssql drivers require them or everything is created as NOT NULL :-(
|
||||
*/
|
||||
public $specify_nulls = true;
|
||||
|
||||
public $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
|
||||
public $sequence_name = 'IDENTITY(1,1)'; //Particular name for inline sequences in this generator
|
||||
public $sequence_only = false; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable
|
||||
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
|
||||
public $sequence_extra_code = false;
|
||||
|
||||
public $add_table_comments = false; // Does the generator need to add code for table comments
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name = 'IDENTITY(1,1)';
|
||||
|
||||
public $concat_character = '+'; //Characters to be used as concatenation operator. If not defined
|
||||
//MySQL CONCAT function will be use
|
||||
/** @var bool To avoid outputting the rest of the field specs, leaving only the name and the sequence_name returned.*/
|
||||
public $sequence_only = false;
|
||||
|
||||
public $rename_table_sql = "sp_rename 'OLDNAME', 'NEWNAME'"; //SQL sentence to rename one table, both
|
||||
//OLDNAME and NEWNAME are dynamically replaced
|
||||
/** @var bool True if the generator needs to add code for table comments.*/
|
||||
public $add_table_comments = false;
|
||||
|
||||
/** @var string Characters to be used as concatenation operator.*/
|
||||
public $concat_character = '+';
|
||||
|
||||
/** @var string SQL sentence to rename one table, both 'OLDNAME' and 'NEWNAME' keywords are dynamically replaced.*/
|
||||
public $rename_table_sql = "sp_rename 'OLDNAME', 'NEWNAME'";
|
||||
|
||||
/** @var string SQL sentence to rename one column where 'TABLENAME', 'OLDFIELDNAME' and 'NEWFIELDNAME' keywords are dynamically replaced.*/
|
||||
public $rename_column_sql = "sp_rename 'TABLENAME.OLDFIELDNAME', 'NEWFIELDNAME', 'COLUMN'";
|
||||
///TABLENAME, OLDFIELDNAME and NEWFIELDNAME are dyanmically replaced
|
||||
|
||||
public $drop_index_sql = 'DROP INDEX TABLENAME.INDEXNAME'; //SQL sentence to drop one index
|
||||
//TABLENAME, INDEXNAME are dynamically replaced
|
||||
/** @var string SQL sentence to drop one index where 'TABLENAME', 'INDEXNAME' keywords are dynamically replaced.*/
|
||||
public $drop_index_sql = 'DROP INDEX TABLENAME.INDEXNAME';
|
||||
|
||||
public $rename_index_sql = "sp_rename 'TABLENAME.OLDINDEXNAME', 'NEWINDEXNAME', 'INDEX'"; //SQL sentence to rename one index
|
||||
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dynamically replaced
|
||||
/** @var string SQL sentence to rename one index where 'TABLENAME', 'OLDINDEXNAME' and 'NEWINDEXNAME' are dynamically replaced.*/
|
||||
public $rename_index_sql = "sp_rename 'TABLENAME.OLDINDEXNAME', 'NEWINDEXNAME', 'INDEX'";
|
||||
|
||||
public $rename_key_sql = null; //SQL sentence to rename one key
|
||||
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dynamically replaced
|
||||
/** @var string SQL sentence to rename one key 'TABLENAME', 'OLDKEYNAME' and 'NEWKEYNAME' are dynamically replaced.*/
|
||||
public $rename_key_sql = null;
|
||||
|
||||
/**
|
||||
* Reset a sequence to the id field of a table.
|
||||
* @param string $table name of table or xmldb_table object
|
||||
* @return array sql commands to execute
|
||||
*
|
||||
* @param xmldb_table|string $table name of table or the table object.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getResetSequenceSQL($table) {
|
||||
|
||||
@@ -109,14 +125,14 @@ class mssql_sql_generator extends sql_generator {
|
||||
* @return string the correct name of the table
|
||||
*/
|
||||
public function getTableName(xmldb_table $xmldb_table, $quoted=true) {
|
||||
/// Get the name, supporting special mssql names for temp tables
|
||||
// Get the name, supporting special mssql names for temp tables
|
||||
if ($this->temptables->is_temptable($xmldb_table->getName())) {
|
||||
$tablename = $this->temptables->get_correct_name($xmldb_table->getName());
|
||||
} else {
|
||||
$tablename = $this->prefix . $xmldb_table->getName();
|
||||
}
|
||||
|
||||
/// Apply quotes optionally
|
||||
// Apply quotes optionally
|
||||
if ($quoted) {
|
||||
$tablename = $this->getEncQuoted($tablename);
|
||||
}
|
||||
@@ -124,10 +140,12 @@ class mssql_sql_generator extends sql_generator {
|
||||
return $tablename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_table, returns the SQL statements
|
||||
* to create temporary table (inside one array)
|
||||
* to create temporary table (inside one array).
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getCreateTempTableSQL($xmldb_table) {
|
||||
$this->temptables->add_temptable($xmldb_table->getName());
|
||||
@@ -151,7 +169,12 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type.
|
||||
*
|
||||
* @param int $xmldb_type The xmldb_type defined constant. XMLDB_TYPE_INTEGER and other XMLDB_TYPE_* constants.
|
||||
* @param int $xmldb_length The length of that data type.
|
||||
* @param int $xmldb_decimals The decimal places of precision of the data type.
|
||||
* @return string The DB defined data type.
|
||||
*/
|
||||
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
|
||||
|
||||
@@ -171,7 +194,7 @@ class mssql_sql_generator extends sql_generator {
|
||||
case XMLDB_TYPE_NUMBER:
|
||||
$dbtype = $this->number_type;
|
||||
if (!empty($xmldb_length)) {
|
||||
/// 38 is the max allowed
|
||||
// 38 is the max allowed
|
||||
if ($xmldb_length > 38) {
|
||||
$xmldb_length = 38;
|
||||
}
|
||||
@@ -211,23 +234,27 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop the field from the table
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop the field from the table.
|
||||
* MSSQL overwrites the standard sentence because it needs to do some extra work dropping the default and
|
||||
* check constraints
|
||||
*
|
||||
* @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.
|
||||
* @return array The SQL statement for dropping a field from the table.
|
||||
*/
|
||||
public function getDropFieldSQL($xmldb_table, $xmldb_field) {
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $this->getEncQuoted($xmldb_field->getName());
|
||||
|
||||
/// Look for any default constraint in this field and drop it
|
||||
// Look for any default constraint in this field and drop it
|
||||
if ($defaultname = $this->getDefaultConstraintName($xmldb_table, $xmldb_field)) {
|
||||
$results[] = 'ALTER TABLE ' . $tablename . ' DROP CONSTRAINT ' . $defaultname;
|
||||
}
|
||||
|
||||
/// Build the standard alter table drop column
|
||||
// Build the standard alter table drop column
|
||||
$results[] = 'ALTER TABLE ' . $tablename . ' DROP COLUMN ' . $fieldname;
|
||||
|
||||
return $results;
|
||||
@@ -235,33 +262,43 @@ class mssql_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_field and the new name, returns the SQL statements
|
||||
* to rename it (inside one array)
|
||||
* to rename it (inside one array).
|
||||
*
|
||||
* MSSQL is special, so we overload the function here. It needs to
|
||||
* drop the constraints BEFORE renaming the field
|
||||
*
|
||||
* @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!
|
||||
// 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();
|
||||
}
|
||||
|
||||
/// Call to standard (parent) getRenameFieldSQL() function
|
||||
// Call to standard (parent) getRenameFieldSQL() function
|
||||
$results = array_merge($results, parent::getRenameFieldSQL($xmldb_table, $xmldb_field, $newname));
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (array of statements) needed to execute extra statements on table rename
|
||||
* Returns the code (array of statements) needed to execute extra statements on table rename.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param string $newname The new name for the table.
|
||||
* @return array Array of extra SQL statements to rename a table.
|
||||
*/
|
||||
public function getRenameTableExtraSQL($xmldb_table, $newname) {
|
||||
|
||||
@@ -271,17 +308,24 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table.
|
||||
*
|
||||
* @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
|
||||
$results = array(); // To store all the needed SQL commands
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $xmldb_table->getName();
|
||||
$fieldname = $xmldb_field->getName();
|
||||
|
||||
/// Take a look to field metadata
|
||||
// Take a look to field metadata
|
||||
$meta = $this->mdb->get_columns($tablename);
|
||||
$metac = $meta[$fieldname];
|
||||
$oldmetatype = $metac->meta_type;
|
||||
@@ -294,7 +338,7 @@ class mssql_sql_generator extends sql_generator {
|
||||
$typechanged = true; //By default, assume that the column type has changed
|
||||
$lengthchanged = true; //By default, assume that the column length has changed
|
||||
|
||||
/// Detect if we are changing the type of the column
|
||||
// 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') ||
|
||||
@@ -304,8 +348,8 @@ class mssql_sql_generator extends sql_generator {
|
||||
$typechanged = false;
|
||||
}
|
||||
|
||||
/// If the new field (and old) specs are for integer, let's be a bit more specific differentiating
|
||||
/// types of integers. Else, some combinations can cause things like MDL-21868
|
||||
// If the new field (and old) specs are for integer, let's be a bit more specific differentiating
|
||||
// types of integers. Else, some combinations can cause things like MDL-21868
|
||||
if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I') {
|
||||
if ($xmldb_field->getLength() > 9) { // Convert our new lenghts to detailed meta types
|
||||
$newmssqlinttype = 'I8';
|
||||
@@ -326,20 +370,20 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Detect if we are changing the length of the column, not always necessary to drop defaults
|
||||
/// if only the length changes, but it's safe to do it always
|
||||
// Detect if we are changing the length of the column, not always necessary to drop defaults
|
||||
// if only the length changes, but it's safe to do it always
|
||||
if ($xmldb_field->getLength() == $oldlength) {
|
||||
$lengthchanged = false;
|
||||
}
|
||||
|
||||
/// If type or length have changed drop the default if exists
|
||||
// If type or length have changed drop the default if exists
|
||||
if ($typechanged || $lengthchanged) {
|
||||
$results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
/// Some changes of type require multiple alter statements, because mssql lacks direct implicit cast between such types
|
||||
/// Here it is the matrix: http://msdn.microsoft.com/en-us/library/ms187928(SQL.90).aspx
|
||||
/// Going to store such intermediate alters in array of objects, storing all the info needed
|
||||
// Some changes of type require multiple alter statements, because mssql lacks direct implicit cast between such types
|
||||
// Here it is the matrix: http://msdn.microsoft.com/en-us/library/ms187928(SQL.90).aspx
|
||||
// Going to store such intermediate alters in array of objects, storing all the info needed
|
||||
$multiple_alter_stmt = array();
|
||||
$targettype = $xmldb_field->getType();
|
||||
|
||||
@@ -377,7 +421,7 @@ class mssql_sql_generator extends sql_generator {
|
||||
$multiple_alter_stmt[0]->length = 255;
|
||||
}
|
||||
|
||||
/// Just prevent default clauses in this type of sentences for mssql and launch the parent one
|
||||
// Just prevent default clauses in this type of sentences for mssql and launch the parent one
|
||||
if (empty($multiple_alter_stmt)) { // Direct implicit conversion allowed, launch it
|
||||
$results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, NULL, true, NULL));
|
||||
|
||||
@@ -394,25 +438,29 @@ class mssql_sql_generator extends sql_generator {
|
||||
$results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, NULL, true, NULL));
|
||||
}
|
||||
|
||||
/// Finally, process the default clause to add it back if necessary
|
||||
// Finally, process the default clause to add it back if necessary
|
||||
if ($typechanged || $lengthchanged) {
|
||||
$results = array_merge($results, $this->getCreateDefaultSQL($xmldb_table, $xmldb_field));
|
||||
}
|
||||
|
||||
/// Return results
|
||||
// Return results
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to modify the default of the field in the table
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to modify the default of the field in the table.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The table related to $xmldb_field.
|
||||
* @param xmldb_field $xmldb_field The instance of xmldb_field to get the modified default value from.
|
||||
* @return array The SQL statement for modifying the default value.
|
||||
*/
|
||||
public function getModifyDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// MSSQL is a bit special with default constraints because it implements them as external constraints so
|
||||
/// normal ALTER TABLE ALTER COLUMN don't work to change defaults. Because this, we have this method overloaded here
|
||||
// MSSQL is a bit special with default constraints because it implements them as external constraints so
|
||||
// normal ALTER TABLE ALTER COLUMN don't work to change defaults. Because this, we have this method overloaded here
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Decide if we are going to create/modify or to drop the default
|
||||
// Decide if we are going to create/modify or to drop the default
|
||||
if ($xmldb_field->getDefault() === null) {
|
||||
$results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); //Drop but, under some circumstances, re-enable
|
||||
$default_clause = $this->getDefaultClause($xmldb_field);
|
||||
@@ -428,22 +476,26 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to create its default
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to add its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*/
|
||||
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// MSSQL is a bit special and it requires the corresponding DEFAULT CONSTRAINT to be dropped
|
||||
// MSSQL is a bit special and it requires the corresponding DEFAULT CONSTRAINT to be dropped
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $this->getEncQuoted($xmldb_field->getName());
|
||||
|
||||
/// Now, check if, with the current field attributes, we have to build one default
|
||||
// Now, check if, with the current field attributes, we have to build one default
|
||||
$default_clause = $this->getDefaultClause($xmldb_field);
|
||||
if ($default_clause) {
|
||||
/// We need to build the default (Moodle) default, so do it
|
||||
// We need to build the default (Moodle) default, so do it
|
||||
$sql = 'ALTER TABLE ' . $tablename . ' ADD' . $default_clause . ' FOR ' . $fieldname;
|
||||
$results[] = $sql;
|
||||
}
|
||||
@@ -454,17 +506,25 @@ class mssql_sql_generator extends sql_generator {
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* Note that this method may be dropped in future.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*
|
||||
* @todo MDL-31147 Moodle 2.1 - Drop getDropDefaultSQL()
|
||||
*/
|
||||
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// MSSQL is a bit special and it requires the corresponding DEFAULT CONSTRAINT to be dropped
|
||||
// MSSQL is a bit special and it requires the corresponding DEFAULT CONSTRAINT to be dropped
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $this->getEncQuoted($xmldb_field->getName());
|
||||
|
||||
/// Look for the default contraint and, if found, drop it
|
||||
// Look for the default contraint and, if found, drop it
|
||||
if ($defaultname = $this->getDefaultConstraintName($xmldb_table, $xmldb_field)) {
|
||||
$results[] = 'ALTER TABLE ' . $tablename . ' DROP CONSTRAINT ' . $defaultname;
|
||||
}
|
||||
@@ -476,14 +536,18 @@ class mssql_sql_generator extends sql_generator {
|
||||
* 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
|
||||
*/
|
||||
public function getDefaultConstraintName($xmldb_table, $xmldb_field) {
|
||||
protected function getDefaultConstraintName($xmldb_table, $xmldb_field) {
|
||||
|
||||
/// Get the quoted name of the table and 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
|
||||
// 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
|
||||
FROM syscolumns
|
||||
WHERE id = object_id(?)
|
||||
@@ -508,6 +572,10 @@ class mssql_sql_generator extends sql_generator {
|
||||
* but the alternative involves modifying all the creation table code to avoid naming
|
||||
* constraints for temp objects and that will dupe a lot of code.
|
||||
*
|
||||
* @param string $tablename The table name.
|
||||
* @param string $fields A list of comma separated fields.
|
||||
* @param string $suffix A suffix for the object name.
|
||||
* @return string Object's name.
|
||||
*/
|
||||
public function getNameForObject($tablename, $fields, $suffix='') {
|
||||
if ($this->temptables->is_temptable($tablename)) { // Is temp table, inject random field names
|
||||
@@ -518,9 +586,17 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
*
|
||||
* (MySQL requires the whole xmldb_table object to be specified, so we add it always)
|
||||
*
|
||||
* This is invoked from getNameForObject().
|
||||
* Only some DB have this implemented.
|
||||
*
|
||||
* @param string $object_name The object's name to check for.
|
||||
* @param string $type The object's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
* @param string $table_name The table's name to check in
|
||||
* @return bool If such name is currently in use (true) or no (false)
|
||||
*/
|
||||
public function isNameInUse($object_name, $type, $table_name) {
|
||||
switch($type) {
|
||||
@@ -549,12 +625,20 @@ class mssql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (in array) needed to add one comment to the table
|
||||
* Returns the code (array of statements) needed to add one comment to the table.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array Array of SQL statements to add one comment to the table.
|
||||
*/
|
||||
public function getCommentSQL($xmldb_table) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds slashes to string.
|
||||
* @param string $s
|
||||
* @return string The escaped string.
|
||||
*/
|
||||
public function addslashes($s) {
|
||||
// do not use php addslashes() because it depends on PHP quote settings!
|
||||
$s = str_replace("'", "''", $s);
|
||||
@@ -563,10 +647,11 @@ class mssql_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Returns an array of reserved words (lowercase) for this DB
|
||||
* @return array An array of database specific reserved words
|
||||
*/
|
||||
public static function getReservedWords() {
|
||||
/// This file contains the reserved words for MSSQL databases
|
||||
/// from http://msdn2.microsoft.com/en-us/library/ms189822.aspx
|
||||
// This file contains the reserved words for MSSQL databases
|
||||
// from http://msdn2.microsoft.com/en-us/library/ms189822.aspx
|
||||
$reserved_words = array (
|
||||
'add', 'all', 'alter', 'and', 'any', 'as', 'asc', 'authorization',
|
||||
'avg', 'backup', 'begin', 'between', 'break', 'browse', 'bulk',
|
||||
|
||||
+110
-55
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* Mysql specific SQL code generator.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage ddl_generator
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -30,55 +27,72 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir.'/ddl/sql_generator.php');
|
||||
|
||||
/// This class generate SQL code to be used against MySQL
|
||||
/// It extends XMLDBgenerator so everything can be
|
||||
/// overridden as needed to generate correct SQL.
|
||||
|
||||
/**
|
||||
* This class generate SQL code to be used against MySQL
|
||||
* It extends XMLDBgenerator so everything can be
|
||||
* overridden as needed to generate correct SQL.
|
||||
*
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mysql_sql_generator extends sql_generator {
|
||||
|
||||
/// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
|
||||
public $quote_string = '`'; // String used to quote names
|
||||
/** @var string Used to quote names. */
|
||||
public $quote_string = '`';
|
||||
|
||||
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
|
||||
/** @var string To define the default to set for NOT NULLs CHARs without default (null=do nothing).*/
|
||||
public $default_for_char = '';
|
||||
|
||||
public $drop_default_value_required = true; //To specify if the generator must use some DEFAULT clause to drop defaults
|
||||
public $drop_default_value = NULL; //The DEFAULT clause required to drop defaults
|
||||
/** @var bool To specify if the generator must use some DEFAULT clause to drop defaults.*/
|
||||
public $drop_default_value_required = true;
|
||||
|
||||
public $primary_key_name = ''; //To force primary key names to one string (null=no force)
|
||||
/** @var string The DEFAULT clause required to drop defaults.*/
|
||||
public $drop_default_value = null;
|
||||
|
||||
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP PRIMARY KEY'; // Template to drop PKs
|
||||
// with automatic replace for TABLENAME and KEYNAME
|
||||
/** @var string To force primary key names to one string (null=no force).*/
|
||||
public $primary_key_name = '';
|
||||
|
||||
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP KEY KEYNAME'; // Template to drop UKs
|
||||
// with automatic replace for TABLENAME and KEYNAME
|
||||
/** @var string Template to drop PKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP PRIMARY KEY';
|
||||
|
||||
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP FOREIGN KEY KEYNAME'; // Template to drop FKs
|
||||
// with automatic replace for TABLENAME and KEYNAME
|
||||
/** @var string Template to drop UKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP KEY KEYNAME';
|
||||
|
||||
public $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
|
||||
public $sequence_name = 'auto_increment'; //Particular name for inline sequences in this generator
|
||||
/** @var string Template to drop FKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP FOREIGN KEY KEYNAME';
|
||||
|
||||
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
|
||||
public $sequence_extra_code = false;
|
||||
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name = 'auto_increment';
|
||||
|
||||
public $add_after_clause = true; // Does the generator need to add the after clause for fields
|
||||
|
||||
public $concat_character = null; //Characters to be used as concatenation operator. If not defined
|
||||
//MySQL CONCAT function will be use
|
||||
/** @var string Characters to be used as concatenation operator.*/
|
||||
public $concat_character = null;
|
||||
|
||||
public $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY COLUMN COLUMNSPECS'; //The SQL template to alter columns
|
||||
/** @var string The SQL template to alter columns where the 'TABLENAME' and 'COLUMNSPECS' keywords are dynamically replaced.*/
|
||||
public $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY COLUMN COLUMNSPECS';
|
||||
|
||||
public $drop_index_sql = 'ALTER TABLE TABLENAME DROP INDEX INDEXNAME'; //SQL sentence to drop one index
|
||||
//TABLENAME, INDEXNAME are dynamically replaced
|
||||
/** @var string SQL sentence to drop one index where 'TABLENAME', 'INDEXNAME' keywords are dynamically replaced.*/
|
||||
public $drop_index_sql = 'ALTER TABLE TABLENAME DROP INDEX INDEXNAME';
|
||||
|
||||
public $rename_index_sql = null; //SQL sentence to rename one index (MySQL doesn't support this!)
|
||||
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dynamically replaced
|
||||
/** @var string SQL sentence to rename one index where 'TABLENAME', 'OLDINDEXNAME' and 'NEWINDEXNAME' are dynamically replaced.*/
|
||||
public $rename_index_sql = null;
|
||||
|
||||
public $rename_key_sql = null; //SQL sentence to rename one key (MySQL doesn't support this!)
|
||||
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dynamically replaced
|
||||
/** @var string SQL sentence to rename one key 'TABLENAME', 'OLDKEYNAME' and 'NEWKEYNAME' are dynamically replaced.*/
|
||||
public $rename_key_sql = null;
|
||||
|
||||
/**
|
||||
* Reset a sequence to the id field of a table.
|
||||
* @param string $table name of table or xmldb_table object
|
||||
* @return array sql commands to execute
|
||||
*
|
||||
* @param xmldb_table|string $table name of table or the table object.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getResetSequenceSQL($table) {
|
||||
|
||||
@@ -96,7 +110,11 @@ class mysql_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_table, returns the SQL statements
|
||||
* to create it (inside one array)
|
||||
* to create it (inside one array).
|
||||
*
|
||||
* @param xmldb_table $xmldb_table An xmldb_table instance.
|
||||
* @return array An array of SQL statements, starting with the table creation SQL followed
|
||||
* by any of its comments, indexes and sequence creation SQL statements.
|
||||
*/
|
||||
public function getCreateTableSQL($xmldb_table) {
|
||||
// first find out if want some special db engine
|
||||
@@ -124,7 +142,10 @@ class mysql_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_table, returns the SQL statements
|
||||
* to create temporary table (inside one array)
|
||||
* to create temporary table (inside one array).
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getCreateTempTableSQL($xmldb_table) {
|
||||
$this->temptables->add_temptable($xmldb_table->getName());
|
||||
@@ -150,7 +171,12 @@ class mysql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type.
|
||||
*
|
||||
* @param int $xmldb_type The xmldb_type defined constant. XMLDB_TYPE_INTEGER and other XMLDB_TYPE_* constants.
|
||||
* @param int $xmldb_length The length of that data type.
|
||||
* @param int $xmldb_decimals The decimal places of precision of the data type.
|
||||
* @return string The DB defined data type.
|
||||
*/
|
||||
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
|
||||
|
||||
@@ -219,26 +245,35 @@ class mysql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to create its default
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to add its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*/
|
||||
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// Just a wrapper over the getAlterFieldSQL() function for MySQL that
|
||||
/// is capable of handling defaults
|
||||
// Just a wrapper over the getAlterFieldSQL() function for MySQL that
|
||||
// is capable of handling defaults
|
||||
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_field and the new name, returns the SQL statements
|
||||
* to rename it (inside one array)
|
||||
* MySQL is pretty different from the standard to justify this overloading
|
||||
* 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
|
||||
// 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
|
||||
// Change the name of the field to perform the change
|
||||
$xmldb_field_clone->setName($newname);
|
||||
|
||||
$fieldsql = $this->getFieldSQL($xmldb_table, $xmldb_field_clone);
|
||||
@@ -252,15 +287,26 @@ class mysql_sql_generator extends sql_generator {
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* Note that this method may be dropped in future.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*
|
||||
* @todo MDL-31147 Moodle 2.1 - Drop getDropDefaultSQL()
|
||||
*/
|
||||
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// Just a wrapper over the getAlterFieldSQL() function for MySQL that
|
||||
/// is capable of handling defaults
|
||||
// Just a wrapper over the getAlterFieldSQL() function for MySQL that
|
||||
// is capable of handling defaults
|
||||
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (in array) needed to add one comment to the table
|
||||
* Returns the code (array of statements) needed to add one comment to the table.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array Array of SQL statements to add one comment to the table.
|
||||
*/
|
||||
function getCommentSQL ($xmldb_table) {
|
||||
$comment = '';
|
||||
@@ -273,25 +319,33 @@ class mysql_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
*
|
||||
* (MySQL requires the whole xmldb_table object to be specified, so we add it always)
|
||||
*
|
||||
* This is invoked from getNameForObject().
|
||||
* Only some DB have this implemented.
|
||||
*
|
||||
* @param string $object_name The object's name to check for.
|
||||
* @param string $type The object's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
* @param string $table_name The table's name to check in
|
||||
* @return bool If such name is currently in use (true) or no (false)
|
||||
*/
|
||||
public function isNameInUse($object_name, $type, $table_name) {
|
||||
|
||||
/// Calculate the real table name
|
||||
// Calculate the real table name
|
||||
$xmldb_table = new xmldb_table($table_name);
|
||||
$tname = $this->getTableName($xmldb_table);
|
||||
|
||||
switch($type) {
|
||||
case 'ix':
|
||||
case 'uix':
|
||||
/// First of all, check table exists
|
||||
// First of all, check table exists
|
||||
$metatables = $this->mdb->get_tables();
|
||||
if (isset($metatables[$tname])) {
|
||||
/// Fetch all the indexes in the table
|
||||
// Fetch all the indexes in the table
|
||||
if ($indexes = $this->mdb->get_indexes($tname)) {
|
||||
/// Look for existing index in array
|
||||
// Look for existing index in array
|
||||
if (isset($indexes[$object_name])) {
|
||||
return true;
|
||||
}
|
||||
@@ -305,10 +359,11 @@ class mysql_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Returns an array of reserved words (lowercase) for this DB
|
||||
* @return array An array of database specific reserved words
|
||||
*/
|
||||
public static function getReservedWords() {
|
||||
/// This file contains the reserved words for MySQL databases
|
||||
/// from http://dev.mysql.com/doc/refman/6.0/en/reserved-words.html
|
||||
// This file contains the reserved words for MySQL databases
|
||||
// from http://dev.mysql.com/doc/refman/6.0/en/reserved-words.html
|
||||
$reserved_words = array (
|
||||
'accessible', 'add', 'all', 'alter', 'analyze', 'and', 'as', 'asc',
|
||||
'asensitive', 'before', 'between', 'bigint', 'binary',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* Oracle specific SQL code generator.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage ddl_generator
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -30,37 +27,61 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir.'/ddl/sql_generator.php');
|
||||
|
||||
/// This class generate SQL code to be used against Oracle
|
||||
/// It extends XMLDBgenerator so everything can be
|
||||
/// overridden as needed to generate correct SQL.
|
||||
|
||||
/**
|
||||
* This class generate SQL code to be used against Oracle
|
||||
* It extends XMLDBgenerator so everything can be
|
||||
* overridden as needed to generate correct SQL.
|
||||
*
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class oracle_sql_generator extends sql_generator {
|
||||
|
||||
/// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
|
||||
public $statement_end = "\n/"; // String to be automatically added at the end of each statement
|
||||
// Using "/" because the standard ";" isn't good for stored procedures (triggers)
|
||||
/**
|
||||
* @var string To be automatically added at the end of each statement.
|
||||
* note: Using "/" because the standard ";" isn't good for stored procedures (triggers)
|
||||
*/
|
||||
public $statement_end = "\n/";
|
||||
|
||||
public $number_type = 'NUMBER'; // Proper type for NUMBER(x) in this DB
|
||||
/** @var string Proper type for NUMBER(x) in this DB. */
|
||||
public $number_type = 'NUMBER';
|
||||
|
||||
public $default_for_char = ' '; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
|
||||
// Using this whitespace here because Oracle doesn't distinguish empty and null! :-(
|
||||
/**
|
||||
* @var string To define the default to set for NOT NULLs CHARs without default (null=do nothing).
|
||||
* note: Using this whitespace here because Oracle doesn't distinguish empty and null! :-(
|
||||
*/
|
||||
public $default_for_char = ' ';
|
||||
|
||||
public $drop_default_value_required = true; //To specify if the generator must use some DEFAULT clause to drop defaults
|
||||
public $drop_default_value = NULL; //The DEFAULT clause required to drop defaults
|
||||
/** @var bool To specify if the generator must use some DEFAULT clause to drop defaults.*/
|
||||
public $drop_default_value_required = true;
|
||||
|
||||
public $default_after_null = false; //To decide if the default clause of each field must go after the null clause
|
||||
/** @var string The DEFAULT clause required to drop defaults.*/
|
||||
public $drop_default_value = null;
|
||||
|
||||
public $sequence_extra_code = true; //Does the generator need to add extra code to generate the sequence fields
|
||||
public $sequence_name = ''; //Particular name for inline sequences in this generator
|
||||
public $sequence_cache_size = 20; //Size of the sequences values cache (20 = Oracle Default)
|
||||
/** @var bool To decide if the default clause of each field must go after the null clause.*/
|
||||
public $default_after_null = false;
|
||||
|
||||
public $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY (COLUMNSPECS)'; //The SQL template to alter columns
|
||||
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
|
||||
public $sequence_extra_code = true;
|
||||
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name = '';
|
||||
|
||||
/** @var string The SQL template to alter columns where the 'TABLENAME' and 'COLUMNSPECS' keywords are dynamically replaced.*/
|
||||
public $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY (COLUMNSPECS)';
|
||||
|
||||
/** @var int var ugly Oracle hack - size of the sequences values cache (20 = Default)*/
|
||||
public $sequence_cache_size = 20;
|
||||
|
||||
/**
|
||||
* Reset a sequence to the id field of a table.
|
||||
* @param string $table name of table or xmldb_table object
|
||||
* @return array sql commands to execute
|
||||
*
|
||||
* @param xmldb_table|string $table name of table or the table object.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getResetSequenceSQL($table) {
|
||||
|
||||
@@ -78,7 +99,7 @@ class oracle_sql_generator extends sql_generator {
|
||||
$seqname = $this->getSequenceFromDB($xmldb_table);
|
||||
|
||||
if (!$seqname) {
|
||||
/// Fallback, seqname not found, something is wrong. Inform and use the alternative getNameForObject() method
|
||||
// Fallback, seqname not found, something is wrong. Inform and use the alternative getNameForObject() method
|
||||
$seqname = $this->getNameForObject($table, 'id', 'seq');
|
||||
}
|
||||
|
||||
@@ -95,14 +116,14 @@ class oracle_sql_generator extends sql_generator {
|
||||
* @return string the correct name of the table
|
||||
*/
|
||||
public function getTableName(xmldb_table $xmldb_table, $quoted=true) {
|
||||
/// Get the name, supporting special oci names for temp tables
|
||||
// Get the name, supporting special oci names for temp tables
|
||||
if ($this->temptables->is_temptable($xmldb_table->getName())) {
|
||||
$tablename = $this->temptables->get_correct_name($xmldb_table->getName());
|
||||
} else {
|
||||
$tablename = $this->prefix . $xmldb_table->getName();
|
||||
}
|
||||
|
||||
/// Apply quotes optionally
|
||||
// Apply quotes optionally
|
||||
if ($quoted) {
|
||||
$tablename = $this->getEncQuoted($tablename);
|
||||
}
|
||||
@@ -112,7 +133,10 @@ class oracle_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_table, returns the SQL statements
|
||||
* to create temporary table (inside one array)
|
||||
* to create temporary table (inside one array).
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getCreateTempTableSQL($xmldb_table) {
|
||||
$this->temptables->add_temptable($xmldb_table->getName());
|
||||
@@ -138,7 +162,12 @@ class oracle_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type.
|
||||
*
|
||||
* @param int $xmldb_type The xmldb_type defined constant. XMLDB_TYPE_INTEGER and other XMLDB_TYPE_* constants.
|
||||
* @param int $xmldb_length The length of that data type.
|
||||
* @param int $xmldb_decimals The decimal places of precision of the data type.
|
||||
* @return string The DB defined data type.
|
||||
*/
|
||||
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
|
||||
|
||||
@@ -152,7 +181,7 @@ class oracle_sql_generator extends sql_generator {
|
||||
case XMLDB_TYPE_FLOAT:
|
||||
case XMLDB_TYPE_NUMBER:
|
||||
$dbtype = $this->number_type;
|
||||
/// 38 is the max allowed
|
||||
// 38 is the max allowed
|
||||
if ($xmldb_length > 38) {
|
||||
$xmldb_length = 38;
|
||||
}
|
||||
@@ -188,7 +217,12 @@ class oracle_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code needed to create one sequence for the xmldb_table and xmldb_field passes
|
||||
* Returns the code (array of statements) needed
|
||||
* to create one sequence for the xmldb_table and xmldb_field passed in.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create the sequence.
|
||||
*/
|
||||
public function getCreateSequenceSQL($xmldb_table, $xmldb_field) {
|
||||
|
||||
@@ -207,6 +241,11 @@ class oracle_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Returns the code needed to create one trigger for the xmldb_table and xmldb_field passed
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @param string $sequence_name
|
||||
* @return array Array of SQL statements to create the sequence.
|
||||
*/
|
||||
public function getCreateTriggerSQL($xmldb_table, $xmldb_field, $sequence_name) {
|
||||
|
||||
@@ -228,6 +267,11 @@ class oracle_sql_generator extends sql_generator {
|
||||
/**
|
||||
* Returns the code needed to drop one sequence for the xmldb_table and xmldb_field passed
|
||||
* Can, optionally, specify if the underlying trigger will be also dropped
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @param bool $include_trigger
|
||||
* @return array Array of SQL statements to create the sequence.
|
||||
*/
|
||||
public function getDropSequenceSQL($xmldb_table, $xmldb_field, $include_trigger=false) {
|
||||
|
||||
@@ -245,7 +289,10 @@ class oracle_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (in array) needed to add one comment to the table
|
||||
* Returns the code (array of statements) needed to add one comment to the table.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array Array of SQL statements to add one comment to the table.
|
||||
*/
|
||||
function getCommentSQL ($xmldb_table) {
|
||||
|
||||
@@ -257,6 +304,9 @@ class oracle_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Returns the code (array of statements) needed to execute extra statements on table drop
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array Array of extra SQL statements to drop a table.
|
||||
*/
|
||||
public function getDropTableExtraSQL($xmldb_table) {
|
||||
$xmldb_field = new xmldb_field('id'); // Fields having sequences should be exclusively, id.
|
||||
@@ -264,7 +314,11 @@ class oracle_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (array of statements) needed to execute extra statements on table rename
|
||||
* Returns the code (array of statements) needed to execute extra statements on table rename.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param string $newname The new name for the table.
|
||||
* @return array Array of extra SQL statements to rename a table.
|
||||
*/
|
||||
public function getRenameTableExtraSQL($xmldb_table, $newname) {
|
||||
|
||||
@@ -278,28 +332,36 @@ class oracle_sql_generator extends sql_generator {
|
||||
$oldtriggername = $this->getTriggerFromDB($xmldb_table);
|
||||
$newtriggername = $this->getNameForObject($newname, $xmldb_field->getName(), 'trg');
|
||||
|
||||
/// Drop old trigger (first of all)
|
||||
// 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
|
||||
// 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
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table
|
||||
* 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) {
|
||||
|
||||
@@ -307,20 +369,20 @@ class oracle_sql_generator extends sql_generator {
|
||||
$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
|
||||
$results = array(); // To store all the needed SQL commands
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $xmldb_field->getName();
|
||||
|
||||
/// Take a look to field metadata
|
||||
// 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
|
||||
// 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);
|
||||
@@ -343,7 +405,7 @@ class oracle_sql_generator extends sql_generator {
|
||||
|
||||
$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
|
||||
// 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') ||
|
||||
@@ -352,14 +414,14 @@ class oracle_sql_generator extends sql_generator {
|
||||
($xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B')) {
|
||||
$typechanged = false;
|
||||
}
|
||||
/// Detect if precision has changed
|
||||
// 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
|
||||
// Detect if decimal has changed
|
||||
if (($xmldb_field->getType() == XMLDB_TYPE_INTEGER) ||
|
||||
($xmldb_field->getType() == XMLDB_TYPE_CHAR) ||
|
||||
($xmldb_field->getType() == XMLDB_TYPE_TEXT) ||
|
||||
@@ -369,29 +431,29 @@ class oracle_sql_generator extends sql_generator {
|
||||
($xmldb_field->getDecimals() == $olddecimals)) {
|
||||
$decimalchanged = false;
|
||||
}
|
||||
/// Detect if we are changing the default
|
||||
// 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
|
||||
// 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 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
|
||||
// Prevent temp field to have both NULL/NOT NULL and DEFAULT constraints
|
||||
$skip_notnull_clause = true;
|
||||
$skip_default_clause = true;
|
||||
$xmldb_field->setName($tempcolname);
|
||||
@@ -400,9 +462,9 @@ class oracle_sql_generator extends sql_generator {
|
||||
if (isset($meta[$tempcolname])) {
|
||||
$results = array_merge($results, $this->getDropFieldSQL($xmldb_table, $xmldb_field));
|
||||
}
|
||||
/// Create the temporal column
|
||||
// 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
|
||||
// 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) {
|
||||
@@ -414,47 +476,47 @@ class oracle_sql_generator extends sql_generator {
|
||||
} else {
|
||||
$results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = ' . $fieldname;
|
||||
}
|
||||
/// Drop the old column
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// Re-enable the notnull and default sections so the general AlterFieldSQL can use it
|
||||
$skip_notnull_clause = false;
|
||||
$skip_default_clause = false;
|
||||
/// Dissable the type section because we have done it with the temp field
|
||||
// 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 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 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 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 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
|
||||
$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 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
|
||||
$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) {
|
||||
@@ -463,33 +525,45 @@ class oracle_sql_generator extends sql_generator {
|
||||
}
|
||||
}
|
||||
|
||||
/// If arriving here, something is not being skipped (type, notnull, default), calculate the standard AlterFieldSQL
|
||||
// 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
|
||||
// Finally return results
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to create its default
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to add its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*/
|
||||
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// Just a wrapper over the getAlterFieldSQL() function for Oracle that
|
||||
/// is capable of handling defaults
|
||||
// Just a wrapper over the getAlterFieldSQL() function for Oracle that
|
||||
// is capable of handling defaults
|
||||
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needded to drop its default
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* Note that this method may be dropped in future.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*
|
||||
* @todo MDL-31147 Moodle 2.1 - Drop getDropDefaultSQL()
|
||||
*/
|
||||
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// Just a wrapper over the getAlterFieldSQL() function for Oracle that
|
||||
/// is capable of handling defaults
|
||||
// Just a wrapper over the getAlterFieldSQL() function for Oracle that
|
||||
// is capable of handling defaults
|
||||
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
@@ -499,7 +573,8 @@ class oracle_sql_generator extends sql_generator {
|
||||
* The sequence name for oracle is calculated by looking the corresponding
|
||||
* trigger and retrieving the sequence name from it (because sequences are
|
||||
* independent elements)
|
||||
* If no sequence is found, returns false
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return string|bool If no sequence is found, returns false
|
||||
*/
|
||||
public function getSequenceFromDB($xmldb_table) {
|
||||
|
||||
@@ -511,7 +586,7 @@ class oracle_sql_generator extends sql_generator {
|
||||
FROM user_triggers
|
||||
WHERE table_name = ? AND trigger_name LIKE ?",
|
||||
array($tablename, "{$prefixupper}%_ID%_TRG"))) {
|
||||
/// If trigger found, regexp it looking for the sequence name
|
||||
// If trigger found, regexp it looking for the sequence name
|
||||
preg_match('/.*SELECT (.*)\.nextval/i', $trigger->trigger_body, $matches);
|
||||
if (isset($matches[1])) {
|
||||
$sequencename = $matches[1];
|
||||
@@ -524,7 +599,9 @@ class oracle_sql_generator extends sql_generator {
|
||||
/**
|
||||
* Given one xmldb_table returns one string with the trigger
|
||||
* in the table (fetched from DB)
|
||||
* If no trigger is found, returns false
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return string|bool If no trigger is found, returns false
|
||||
*/
|
||||
public function getTriggerFromDB($xmldb_table) {
|
||||
|
||||
@@ -543,9 +620,17 @@ class oracle_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
*
|
||||
* (MySQL requires the whole xmldb_table object to be specified, so we add it always)
|
||||
*
|
||||
* This is invoked from getNameForObject().
|
||||
* Only some DB have this implemented.
|
||||
*
|
||||
* @param string $object_name The object's name to check for.
|
||||
* @param string $type The object's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
* @param string $table_name The table's name to check in
|
||||
* @return bool If such name is currently in use (true) or no (false)
|
||||
*/
|
||||
public function isNameInUse($object_name, $type, $table_name) {
|
||||
switch($type) {
|
||||
@@ -573,6 +658,11 @@ class oracle_sql_generator extends sql_generator {
|
||||
return false; //No name in use found
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds slashes to string.
|
||||
* @param string $s
|
||||
* @return string The escaped string.
|
||||
*/
|
||||
public function addslashes($s) {
|
||||
// do not use php addslashes() because it depends on PHP quote settings!
|
||||
$s = str_replace("'", "''", $s);
|
||||
@@ -581,10 +671,11 @@ class oracle_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Returns an array of reserved words (lowercase) for this DB
|
||||
* @return array An array of database specific reserved words
|
||||
*/
|
||||
public static function getReservedWords() {
|
||||
/// This file contains the reserved words for Oracle databases
|
||||
/// from http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96540/ap_keywd.htm
|
||||
// This file contains the reserved words for Oracle databases
|
||||
// from http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96540/ap_keywd.htm
|
||||
$reserved_words = array (
|
||||
'access', 'add', 'all', 'alter', 'and', 'any',
|
||||
'as', 'asc', 'audit', 'between', 'by', 'char',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* PostgreSQL specific SQL code generator.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage ddl_generator
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -30,35 +27,53 @@ defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir.'/ddl/sql_generator.php');
|
||||
|
||||
/// This class generate SQL code to be used against PostgreSQL
|
||||
/// It extends XMLDBgenerator so everything can be
|
||||
/// overridden as needed to generate correct SQL.
|
||||
/**
|
||||
* This class generate SQL code to be used against PostgreSQL
|
||||
* It extends XMLDBgenerator so everything can be
|
||||
* overridden as needed to generate correct SQL.
|
||||
*
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
class postgres_sql_generator extends sql_generator {
|
||||
|
||||
/// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
|
||||
public $number_type = 'NUMERIC'; // Proper type for NUMBER(x) in this DB
|
||||
/** @var string Proper type for NUMBER(x) in this DB. */
|
||||
public $number_type = 'NUMERIC';
|
||||
|
||||
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
|
||||
/** @var string To define the default to set for NOT NULLs CHARs without default (null=do nothing).*/
|
||||
public $default_for_char = '';
|
||||
|
||||
public $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
|
||||
public $sequence_name = 'BIGSERIAL'; //Particular name for inline sequences in this generator
|
||||
public $sequence_name_small = 'SERIAL'; //Particular name for inline sequences in this generator
|
||||
public $sequence_only = true; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable
|
||||
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
|
||||
public $sequence_extra_code = false;
|
||||
|
||||
public $rename_index_sql = 'ALTER TABLE OLDINDEXNAME RENAME TO NEWINDEXNAME'; //SQL sentence to rename one index
|
||||
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dynamically replaced
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name = 'BIGSERIAL';
|
||||
|
||||
public $rename_key_sql = null; //SQL sentence to rename one key (PostgreSQL doesn't support this!)
|
||||
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dynamically replaced
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name_small = 'SERIAL';
|
||||
|
||||
protected $std_strings = null; // '' or \' quotes
|
||||
/** @var bool To avoid outputting the rest of the field specs, leaving only the name and the sequence_name returned.*/
|
||||
public $sequence_only = true;
|
||||
|
||||
/** @var string SQL sentence to rename one index where 'TABLENAME', 'OLDINDEXNAME' and 'NEWINDEXNAME' are dynamically replaced.*/
|
||||
public $rename_index_sql = 'ALTER TABLE OLDINDEXNAME RENAME TO NEWINDEXNAME';
|
||||
|
||||
/** @var string SQL sentence to rename one key 'TABLENAME', 'OLDKEYNAME' and 'NEWKEYNAME' are dynamically replaced.*/
|
||||
public $rename_key_sql = null;
|
||||
|
||||
/** @var string type of string quoting used - '' or \' quotes*/
|
||||
protected $std_strings = null;
|
||||
|
||||
/**
|
||||
* Reset a sequence to the id field of a table.
|
||||
* @param string $table name of table or xmldb_table object
|
||||
* @return array sql commands to execute
|
||||
*
|
||||
* @param xmldb_table|string $table name of table or the table object.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getResetSequenceSQL($table) {
|
||||
|
||||
@@ -76,7 +91,10 @@ class postgres_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_table, returns the SQL statements
|
||||
* to create temporary table (inside one array)
|
||||
* to create temporary table (inside one array).
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getCreateTempTableSQL($xmldb_table) {
|
||||
$this->temptables->add_temptable($xmldb_table->getName());
|
||||
@@ -101,7 +119,12 @@ class postgres_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type.
|
||||
*
|
||||
* @param int $xmldb_type The xmldb_type defined constant. XMLDB_TYPE_INTEGER and other XMLDB_TYPE_* constants.
|
||||
* @param int $xmldb_length The length of that data type.
|
||||
* @param int $xmldb_decimals The decimal places of precision of the data type.
|
||||
* @return string The DB defined data type.
|
||||
*/
|
||||
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
|
||||
|
||||
@@ -157,7 +180,10 @@ class postgres_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (in array) needed to add one comment to the table
|
||||
* Returns the code (array of statements) needed to add one comment to the table.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array Array of SQL statements to add one comment to the table.
|
||||
*/
|
||||
function getCommentSQL ($xmldb_table) {
|
||||
|
||||
@@ -168,7 +194,11 @@ class postgres_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (array of statements) needed to execute extra statements on table rename
|
||||
* Returns the code (array of statements) needed to execute extra statements on table rename.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param string $newname The new name for the table.
|
||||
* @return array Array of extra SQL statements to rename a table.
|
||||
*/
|
||||
public function getRenameTableExtraSQL($xmldb_table, $newname) {
|
||||
|
||||
@@ -181,29 +211,37 @@ class postgres_sql_generator extends sql_generator {
|
||||
$oldseqname = $this->getTableName($xmldb_table) . '_' . $xmldb_field->getName() . '_seq';
|
||||
$newseqname = $this->getTableName($newt) . '_' . $xmldb_field->getName() . '_seq';
|
||||
|
||||
/// Rename de sequence
|
||||
// Rename de sequence
|
||||
$results[] = 'ALTER TABLE ' . $oldseqname . ' RENAME TO ' . $newseqname;
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table
|
||||
* 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
|
||||
$results = array(); // To store all the needed SQL commands
|
||||
|
||||
/// Get the normla names of the table and field
|
||||
// Get the normal names of the table and field
|
||||
$tablename = $xmldb_table->getName();
|
||||
$fieldname = $xmldb_field->getName();
|
||||
|
||||
/// Take a look to field metadata
|
||||
// Take a look to field metadata
|
||||
$meta = $this->mdb->get_columns($tablename);
|
||||
$metac = $meta[$xmldb_field->getName()];
|
||||
$oldmetatype = $metac->meta_type;
|
||||
@@ -218,7 +256,7 @@ class postgres_sql_generator extends sql_generator {
|
||||
$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
|
||||
// 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') ||
|
||||
@@ -227,14 +265,14 @@ class postgres_sql_generator extends sql_generator {
|
||||
($xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B')) {
|
||||
$typechanged = false;
|
||||
}
|
||||
/// Detect if we are changing the precision
|
||||
// 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
|
||||
// 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) ||
|
||||
@@ -244,32 +282,32 @@ class postgres_sql_generator extends sql_generator {
|
||||
($xmldb_field->getDecimals() == $olddecimals)) {
|
||||
$decimalchanged = false;
|
||||
}
|
||||
/// Detect if we are changing the default
|
||||
// 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
|
||||
// Detect if we are changing the nullability
|
||||
if (($xmldb_field->getNotnull() === $oldnotnull)) {
|
||||
$notnullchanged = false;
|
||||
}
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// 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)
|
||||
// Decide if we have changed the column specs (type/precision/decimals)
|
||||
$specschanged = $typechanged || $precisionchanged || $decimalchanged;
|
||||
|
||||
/// if specs have changed, need to alter column
|
||||
// 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)
|
||||
// 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
|
||||
$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 explicity (mainly from text|char to numeric|integer)
|
||||
// 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
|
||||
@@ -280,20 +318,20 @@ class postgres_sql_generator extends sql_generator {
|
||||
$results[] = $alterstmt;
|
||||
}
|
||||
|
||||
/// If the default has changed or we have performed one change in specs
|
||||
// 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
|
||||
$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 (!$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 the not null has changed
|
||||
if ($notnullchanged) {
|
||||
if ($xmldb_field->getNotnull()) {
|
||||
$results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET NOT NULL';
|
||||
@@ -302,30 +340,47 @@ class postgres_sql_generator extends sql_generator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the results
|
||||
// Return the results
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to create its default
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to add its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*/
|
||||
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
|
||||
/// is capable of handling defaults
|
||||
// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
|
||||
// is capable of handling defaults
|
||||
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* Note that this method may be dropped in future.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*
|
||||
* @todo MDL-31147 Moodle 2.1 - Drop getDropDefaultSQL()
|
||||
*/
|
||||
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
/// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
|
||||
/// is capable of handling defaults
|
||||
// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
|
||||
// is capable of handling defaults
|
||||
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds slashes to string.
|
||||
* @param string $s
|
||||
* @return string The escaped string.
|
||||
*/
|
||||
public function addslashes($s) {
|
||||
// Postgres is gradually switching to ANSI quotes, we need to check what is expected
|
||||
if (!isset($this->std_strings)) {
|
||||
@@ -344,33 +399,43 @@ class postgres_sql_generator extends sql_generator {
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table 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) {
|
||||
/**
|
||||
* Given one xmldb_table 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
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return string|bool If no sequence is found, returns false
|
||||
*/
|
||||
function getSequenceFromDB($xmldb_table) {
|
||||
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$sequencename = $tablename . '_id_seq';
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$sequencename = $tablename . '_id_seq';
|
||||
|
||||
if (!$this->mdb->get_record_sql("SELECT *
|
||||
FROM pg_class
|
||||
WHERE relname = ? AND relkind = 'S'",
|
||||
array($sequencename))) {
|
||||
$sequencename = false;
|
||||
if (!$this->mdb->get_record_sql("SELECT *
|
||||
FROM pg_class
|
||||
WHERE relname = ? AND relkind = 'S'",
|
||||
array($sequencename))) {
|
||||
$sequencename = false;
|
||||
}
|
||||
|
||||
return $sequencename;
|
||||
}
|
||||
|
||||
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()
|
||||
* Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
*
|
||||
* (MySQL requires the whole xmldb_table object to be specified, so we add it always)
|
||||
*
|
||||
* This is invoked from getNameForObject().
|
||||
* Only some DB have this implemented.
|
||||
*
|
||||
* @param string $object_name The object's name to check for.
|
||||
* @param string $type The object's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
* @param string $table_name The table's name to check in
|
||||
* @return bool If such name is currently in use (true) or no (false)
|
||||
*/
|
||||
public function isNameInUse($object_name, $type, $table_name) {
|
||||
switch($type) {
|
||||
@@ -406,10 +471,11 @@ function getSequenceFromDB($xmldb_table) {
|
||||
|
||||
/**
|
||||
* Returns an array of reserved words (lowercase) for this DB
|
||||
* @return array An array of database specific reserved words
|
||||
*/
|
||||
public static function getReservedWords() {
|
||||
/// This file contains the reserved words for PostgreSQL databases
|
||||
/// http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
|
||||
// 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',
|
||||
|
||||
+158
-166
@@ -14,16 +14,13 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* This class represent the base generator class where all the needed functions to generate proper SQL are defined.
|
||||
*
|
||||
* The rest of classes will inherit, by default, the same logic.
|
||||
* Functions will be overridden as needed to generate correct SQL.
|
||||
*
|
||||
* @package core
|
||||
* @category ddl
|
||||
* @subpackage ddl
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -34,19 +31,17 @@ defined('MOODLE_INTERNAL') || die();
|
||||
/**
|
||||
* Abstract sql generator class, base for all db specific implementations.
|
||||
*
|
||||
* @package core
|
||||
* @category ddl
|
||||
* @subpackage ddl
|
||||
* @package core_ddl
|
||||
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
|
||||
* 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class sql_generator {
|
||||
|
||||
/// Please, avoid editing this defaults in this base class!
|
||||
/// It could change the behaviour of the rest of generators
|
||||
/// that, by default, inherit this configuration.
|
||||
/// To change any of them, do it in extended classes instead.
|
||||
// Please, avoid editing this defaults in this base class!
|
||||
// It could change the behaviour of the rest of generators
|
||||
// that, by default, inherit this configuration.
|
||||
// To change any of them, do it in extended classes instead.
|
||||
|
||||
/** @var string Used to quote names. */
|
||||
public $quote_string = '"';
|
||||
@@ -55,10 +50,11 @@ abstract class sql_generator {
|
||||
public $statement_end = ';';
|
||||
|
||||
/** @var bool To decide if we want to quote all the names or only the reserved ones. */
|
||||
public $quote_all = false;
|
||||
public $quote_all = false;
|
||||
|
||||
/** @var bool To create all the integers as NUMBER(x) (also called DECIMAL, NUMERIC...). */
|
||||
public $integer_to_number = false;
|
||||
|
||||
/** @var bool To create all the floats as NUMBER(x) (also called DECIMAL, NUMERIC...). */
|
||||
public $float_to_number = false;
|
||||
|
||||
@@ -70,16 +66,14 @@ abstract class sql_generator {
|
||||
|
||||
/** @var bool To specify if the generator must use some DEFAULT clause to drop defaults.*/
|
||||
public $drop_default_value_required = false;
|
||||
|
||||
/** @var string The DEFAULT clause required to drop defaults.*/
|
||||
public $drop_default_value = '';
|
||||
|
||||
/** @var bool To decide if the default clause of each field must go after the null clause.*/
|
||||
public $default_after_null = true;
|
||||
|
||||
/**
|
||||
* @var bool To force the generator if NULL clauses must be specified. It shouldn't be necessary.
|
||||
* note: some mssql drivers require them or everything is created as NOT NULL :-(
|
||||
*/
|
||||
/** @var bool To force the generator if NULL clauses must be specified. It shouldn't be necessary.*/
|
||||
public $specify_nulls = false;
|
||||
|
||||
/** @var string To force primary key names to one string (null=no force).*/
|
||||
@@ -87,34 +81,31 @@ abstract class sql_generator {
|
||||
|
||||
/** @var bool True if the generator builds primary keys.*/
|
||||
public $primary_keys = true;
|
||||
|
||||
/** @var bool True if the generator builds unique keys.*/
|
||||
public $unique_keys = false;
|
||||
|
||||
/** @var bool True if the generator builds foreign keys.*/
|
||||
public $foreign_keys = false;
|
||||
|
||||
/**
|
||||
* @var string Template to drop PKs.
|
||||
* 'TABLENAME' and 'KEYNAME' will be replaced from this template.
|
||||
*/
|
||||
/** @var string Template to drop PKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME';
|
||||
|
||||
/**
|
||||
* @var string Template to drop UKs.
|
||||
* 'TABLENAME' and 'KEYNAME' will be replaced from this template.
|
||||
*/
|
||||
/** @var string Template to drop UKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME';
|
||||
|
||||
/** @var string Template to drop FKs.
|
||||
* 'TABLENAME' and 'KEYNAME' will be replaced from this template.
|
||||
*/
|
||||
/** @var string Template to drop FKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME';
|
||||
|
||||
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
|
||||
public $sequence_extra_code = true;
|
||||
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name = 'auto_increment';
|
||||
|
||||
/** @var string|bool Different name for small (4byte) sequences or false if same.*/
|
||||
public $sequence_name_small = false;
|
||||
|
||||
/**
|
||||
* @var bool To avoid outputting the rest of the field specs, leaving only the name and the sequence_name returned.
|
||||
* @see getFieldSQL()
|
||||
@@ -136,9 +127,7 @@ abstract class sql_generator {
|
||||
/** @var int Maximum length for key/index/sequence/trigger/check names (keep 30 for all!).*/
|
||||
public $names_max_length = 30;
|
||||
|
||||
/** @var string Characters to be used as concatenation operator.
|
||||
* If not defined, MySQL CONCAT function will be used.
|
||||
*/
|
||||
/** @var string Characters to be used as concatenation operator. If not defined, MySQL CONCAT function will be used.*/
|
||||
public $concat_character = '||';
|
||||
|
||||
/** @var string SQL sentence to rename one table, both 'OLDNAME' and 'NEWNAME' keywords are dynamically replaced.*/
|
||||
@@ -179,6 +168,7 @@ abstract class sql_generator {
|
||||
|
||||
/** @var moodle_database The moodle_database instance.*/
|
||||
public $mdb;
|
||||
|
||||
/** @var Control existing temptables.*/
|
||||
protected $temptables;
|
||||
|
||||
@@ -207,6 +197,7 @@ abstract class sql_generator {
|
||||
* @see $statement_end
|
||||
*
|
||||
* @param array|string $input SQL statement(s).
|
||||
* @return array|string
|
||||
*/
|
||||
public function getEndedStatements($input) {
|
||||
|
||||
@@ -231,11 +222,11 @@ abstract class sql_generator {
|
||||
if (is_string($table)) {
|
||||
$tablename = $table;
|
||||
} else {
|
||||
/// Calculate the name of the table
|
||||
// Calculate the name of the table
|
||||
$tablename = $table->getName();
|
||||
}
|
||||
|
||||
/// get all tables in moodle database
|
||||
// get all tables in moodle database
|
||||
$tables = $this->mdb->get_tables();
|
||||
$exists = in_array($tablename, $tables);
|
||||
|
||||
@@ -244,10 +235,10 @@ abstract class sql_generator {
|
||||
|
||||
/**
|
||||
* This function will return the SQL code needed to create db tables and statements.
|
||||
* @see xmldb_structure
|
||||
*
|
||||
* @param xmldb_structure $xmldb_structure An xmldb_structure instance.
|
||||
*
|
||||
* @see xmldb_structure
|
||||
* @return array
|
||||
*/
|
||||
public function getCreateStructureSQL($xmldb_structure) {
|
||||
$results = array();
|
||||
@@ -272,10 +263,10 @@ abstract class sql_generator {
|
||||
* @return string The correct name of the table.
|
||||
*/
|
||||
public function getTableName(xmldb_table $xmldb_table, $quoted=true) {
|
||||
/// Get the name
|
||||
// Get the name
|
||||
$tablename = $this->prefix.$xmldb_table->getName();
|
||||
|
||||
/// Apply quotes optionally
|
||||
// Apply quotes optionally
|
||||
if ($quoted) {
|
||||
$tablename = $this->getEncQuoted($tablename);
|
||||
}
|
||||
@@ -298,7 +289,7 @@ abstract class sql_generator {
|
||||
|
||||
$results = array(); //Array where all the sentences will be stored
|
||||
|
||||
/// Table header
|
||||
// Table header
|
||||
$table = 'CREATE TABLE ' . $this->getTableName($xmldb_table) . ' (';
|
||||
|
||||
if (!$xmldb_fields = $xmldb_table->getFields()) {
|
||||
@@ -307,7 +298,7 @@ abstract class sql_generator {
|
||||
|
||||
$sequencefield = null;
|
||||
|
||||
/// Add the fields, separated by commas
|
||||
// Add the fields, separated by commas
|
||||
foreach ($xmldb_fields as $xmldb_field) {
|
||||
if ($xmldb_field->getSequence()) {
|
||||
$sequencefield = $xmldb_field->getName();
|
||||
@@ -315,21 +306,21 @@ abstract class sql_generator {
|
||||
$table .= "\n " . $this->getFieldSQL($xmldb_table, $xmldb_field);
|
||||
$table .= ',';
|
||||
}
|
||||
/// Add the keys, separated by commas
|
||||
// Add the keys, separated by commas
|
||||
if ($xmldb_keys = $xmldb_table->getKeys()) {
|
||||
foreach ($xmldb_keys as $xmldb_key) {
|
||||
if ($keytext = $this->getKeySQL($xmldb_table, $xmldb_key)) {
|
||||
$table .= "\nCONSTRAINT " . $keytext . ',';
|
||||
}
|
||||
/// If the key is XMLDB_KEY_FOREIGN_UNIQUE, create it as UNIQUE too
|
||||
// If the key is XMLDB_KEY_FOREIGN_UNIQUE, create it as UNIQUE too
|
||||
if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE) {
|
||||
///Duplicate the key
|
||||
//Duplicate the key
|
||||
$xmldb_key->setType(XMLDB_KEY_UNIQUE);
|
||||
if ($keytext = $this->getKeySQL($xmldb_table, $xmldb_key)) {
|
||||
$table .= "\nCONSTRAINT " . $keytext . ',';
|
||||
}
|
||||
}
|
||||
/// make sure sequence field is unique
|
||||
// make sure sequence field is unique
|
||||
if ($sequencefield and $xmldb_key->getType() == XMLDB_KEY_PRIMARY) {
|
||||
$field = reset($xmldb_key->getFields());
|
||||
if ($sequencefield === $field) {
|
||||
@@ -338,45 +329,45 @@ abstract class sql_generator {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// throw error if sequence field does not have unique key defined
|
||||
// throw error if sequence field does not have unique key defined
|
||||
if ($sequencefield) {
|
||||
throw new ddl_exception('ddsequenceerror', $xmldb_table->getName());
|
||||
}
|
||||
|
||||
/// Table footer, trim the latest comma
|
||||
// Table footer, trim the latest comma
|
||||
$table = trim($table,',');
|
||||
$table .= "\n)";
|
||||
|
||||
/// Add the CREATE TABLE to results
|
||||
// Add the CREATE TABLE to results
|
||||
$results[] = $table;
|
||||
|
||||
/// Add comments if specified and it exists
|
||||
// Add comments if specified and it exists
|
||||
if ($this->add_table_comments && $xmldb_table->getComment()) {
|
||||
$comment = $this->getCommentSQL($xmldb_table);
|
||||
/// Add the COMMENT to results
|
||||
// Add the COMMENT to results
|
||||
$results = array_merge($results, $comment);
|
||||
}
|
||||
|
||||
/// Add the indexes (each one, one statement)
|
||||
// Add the indexes (each one, one statement)
|
||||
if ($xmldb_indexes = $xmldb_table->getIndexes()) {
|
||||
foreach ($xmldb_indexes as $xmldb_index) {
|
||||
///tables do not exist yet, which means indexed can not exist yet
|
||||
//tables do not exist yet, which means indexed can not exist yet
|
||||
if ($indextext = $this->getCreateIndexSQL($xmldb_table, $xmldb_index)) {
|
||||
$results = array_merge($results, $indextext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Also, add the indexes needed from keys, based on configuration (each one, one statement)
|
||||
// Also, add the indexes needed from keys, based on configuration (each one, one statement)
|
||||
if ($xmldb_keys = $xmldb_table->getKeys()) {
|
||||
foreach ($xmldb_keys as $xmldb_key) {
|
||||
/// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
|
||||
/// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists)
|
||||
// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
|
||||
// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists)
|
||||
if (!$this->getKeySQL($xmldb_table, $xmldb_key) || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) {
|
||||
/// Create the interim index
|
||||
// Create the interim index
|
||||
$index = new xmldb_index('anyname');
|
||||
$index->setFields($xmldb_key->getFields());
|
||||
///tables do not exist yet, which means indexed can not exist yet
|
||||
//tables do not exist yet, which means indexed can not exist yet
|
||||
$createindex = false; //By default
|
||||
switch ($xmldb_key->getType()) {
|
||||
case XMLDB_KEY_UNIQUE:
|
||||
@@ -391,7 +382,7 @@ abstract class sql_generator {
|
||||
}
|
||||
if ($createindex) {
|
||||
if ($indextext = $this->getCreateIndexSQL($xmldb_table, $index)) {
|
||||
/// Add the INDEX to the array
|
||||
// Add the INDEX to the array
|
||||
$results = array_merge($results, $indextext);
|
||||
}
|
||||
}
|
||||
@@ -399,14 +390,14 @@ abstract class sql_generator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Add sequence extra code if needed
|
||||
// Add sequence extra code if needed
|
||||
if ($this->sequence_extra_code) {
|
||||
/// Iterate over fields looking for sequences
|
||||
// Iterate over fields looking for sequences
|
||||
foreach ($xmldb_fields as $xmldb_field) {
|
||||
if ($xmldb_field->getSequence()) {
|
||||
/// returns an array of statements needed to create one sequence
|
||||
// returns an array of statements needed to create one sequence
|
||||
$sequence_sentences = $this->getCreateSequenceSQL($xmldb_table, $xmldb_field);
|
||||
/// Add the SEQUENCE to the array
|
||||
// Add the SEQUENCE to the array
|
||||
$results = array_merge($results, $sequence_sentences);
|
||||
}
|
||||
}
|
||||
@@ -467,13 +458,13 @@ abstract class sql_generator {
|
||||
$skip_notnull_clause = is_null($skip_notnull_clause) ? $this->alter_column_skip_notnull : $skip_notnull_clause;
|
||||
$specify_nulls_clause = is_null($specify_nulls_clause) ? $this->specify_nulls : $specify_nulls_clause;
|
||||
|
||||
/// First of all, convert integers to numbers if defined
|
||||
// First of all, convert integers to numbers if defined
|
||||
if ($this->integer_to_number) {
|
||||
if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER) {
|
||||
$xmldb_field->setType(XMLDB_TYPE_NUMBER);
|
||||
}
|
||||
}
|
||||
/// Same for floats
|
||||
// Same for floats
|
||||
if ($this->float_to_number) {
|
||||
if ($xmldb_field->getType() == XMLDB_TYPE_FLOAT) {
|
||||
$xmldb_field->setType(XMLDB_TYPE_NUMBER);
|
||||
@@ -481,19 +472,19 @@ abstract class sql_generator {
|
||||
}
|
||||
|
||||
$field = ''; // Let's accumulate the whole expression based on params and settings
|
||||
/// The name
|
||||
// The name
|
||||
if ($specify_field_name) {
|
||||
$field .= $this->getEncQuoted($xmldb_field->getName());
|
||||
}
|
||||
/// The type and length only if we don't want to skip it
|
||||
// The type and length only if we don't want to skip it
|
||||
if (!$skip_type_clause) {
|
||||
/// The type and length
|
||||
// The type and length
|
||||
$field .= ' ' . $this->getTypeSQL($xmldb_field->getType(), $xmldb_field->getLength(), $xmldb_field->getDecimals());
|
||||
}
|
||||
/// note: unsigned is not supported any more since moodle 2.3, all numbers are signed
|
||||
/// Calculate the not null clause
|
||||
// note: unsigned is not supported any more since moodle 2.3, all numbers are signed
|
||||
// Calculate the not null clause
|
||||
$notnull = '';
|
||||
/// Only if we don't want to skip it
|
||||
// Only if we don't want to skip it
|
||||
if (!$skip_notnull_clause) {
|
||||
if ($xmldb_field->getNotNull()) {
|
||||
$notnull = ' NOT NULL';
|
||||
@@ -503,18 +494,18 @@ abstract class sql_generator {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Calculate the default clause
|
||||
// Calculate the default clause
|
||||
$default_clause = '';
|
||||
if (!$skip_default_clause) { //Only if we don't want to skip it
|
||||
$default_clause = $this->getDefaultClause($xmldb_field);
|
||||
}
|
||||
/// Based on default_after_null, set both clauses properly
|
||||
// Based on default_after_null, set both clauses properly
|
||||
if ($this->default_after_null) {
|
||||
$field .= $notnull . $default_clause;
|
||||
} else {
|
||||
$field .= $default_clause . $notnull;
|
||||
}
|
||||
/// The sequence
|
||||
// The sequence
|
||||
if ($xmldb_field->getSequence()) {
|
||||
if($xmldb_field->getLength()<=9 && $this->sequence_name_small) {
|
||||
$sequencename=$this->sequence_name_small;
|
||||
@@ -523,8 +514,8 @@ abstract class sql_generator {
|
||||
}
|
||||
$field .= ' ' . $sequencename;
|
||||
if ($this->sequence_only) {
|
||||
/// We only want the field name and sequence name to be printed
|
||||
/// so, calculate it and return
|
||||
// We only want the field name and sequence name to be printed
|
||||
// so, calculate it and return
|
||||
$sql = $this->getEncQuoted($xmldb_field->getName()) . ' ' . $sequencename;
|
||||
return $sql;
|
||||
}
|
||||
@@ -596,15 +587,15 @@ abstract class sql_generator {
|
||||
$default = $xmldb_field->getDefault();
|
||||
}
|
||||
} else {
|
||||
/// We force default '' for not null char columns without proper default
|
||||
/// some day this should be out!
|
||||
// We force default '' for not null char columns without proper default
|
||||
// some day this should be out!
|
||||
if ($this->default_for_char !== NULL &&
|
||||
$xmldb_field->getType() == XMLDB_TYPE_CHAR &&
|
||||
$xmldb_field->getNotNull()) {
|
||||
$default = "'" . $this->default_for_char . "'";
|
||||
} else {
|
||||
/// If the DB requires to explicity define some clause to drop one default, do it here
|
||||
/// never applying defaults to TEXT and BINARY fields
|
||||
// If the DB requires to explicity define some clause to drop one default, do it here
|
||||
// never applying defaults to TEXT and BINARY fields
|
||||
if ($this->drop_default_value_required &&
|
||||
$xmldb_field->getType() != XMLDB_TYPE_TEXT &&
|
||||
$xmldb_field->getType() != XMLDB_TYPE_BINARY && !$xmldb_field->getNotNull()) {
|
||||
@@ -651,7 +642,7 @@ abstract class sql_generator {
|
||||
|
||||
$results[] = $rename;
|
||||
|
||||
/// Call to getRenameTableExtraSQL() override if needed
|
||||
// Call to getRenameTableExtraSQL() override if needed
|
||||
$extra_sentences = $this->getRenameTableExtraSQL($xmldb_table, $newname);
|
||||
$results = array_merge($results, $extra_sentences);
|
||||
|
||||
@@ -673,7 +664,7 @@ abstract class sql_generator {
|
||||
|
||||
$results[] = $drop;
|
||||
|
||||
/// call to getDropTableExtraSQL(), override if needed
|
||||
// call to getDropTableExtraSQL(), override if needed
|
||||
$extra_sentences = $this->getDropTableExtraSQL($xmldb_table);
|
||||
$results = array_merge($results, $extra_sentences);
|
||||
|
||||
@@ -698,15 +689,15 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
|
||||
/// Build the standard alter table add
|
||||
// Build the standard alter table add
|
||||
$sql = $this->getFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause,
|
||||
$skip_default_clause,
|
||||
$skip_notnull_clause);
|
||||
$altertable = 'ALTER TABLE ' . $tablename . ' ADD ' . $sql;
|
||||
/// Add the after clause if necesary
|
||||
// Add the after clause if necessary
|
||||
if ($this->add_after_clause && $xmldb_field->getPrevious()) {
|
||||
$altertable .= ' AFTER ' . $this->getEncQuoted($xmldb_field->getPrevious());
|
||||
}
|
||||
@@ -726,11 +717,11 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $this->getEncQuoted($xmldb_field->getName());
|
||||
|
||||
/// Build the standard alter table drop
|
||||
// Build the standard alter table drop
|
||||
$results[] = 'ALTER TABLE ' . $tablename . ' DROP COLUMN ' . $fieldname;
|
||||
|
||||
return $results;
|
||||
@@ -754,11 +745,11 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $this->getEncQuoted($xmldb_field->getName());
|
||||
|
||||
/// Build de alter sentence using the alter_column_sql template
|
||||
// Build de alter sentence using the alter_column_sql template
|
||||
$alter = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->alter_column_sql);
|
||||
$colspec = $this->getFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause,
|
||||
$skip_default_clause,
|
||||
@@ -766,12 +757,12 @@ abstract class sql_generator {
|
||||
true);
|
||||
$alter = str_replace('COLUMNSPECS', $colspec, $alter);
|
||||
|
||||
/// Add the after clause if necesary
|
||||
// Add the after clause if necessary
|
||||
if ($this->add_after_clause && $xmldb_field->getPrevious()) {
|
||||
$alter .= ' after ' . $this->getEncQuoted($xmldb_field->getPrevious());
|
||||
}
|
||||
|
||||
/// Build the standard alter table modify
|
||||
// Build the standard alter table modify
|
||||
$results[] = $alter;
|
||||
|
||||
return $results;
|
||||
@@ -788,11 +779,11 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the quoted name of the table and field
|
||||
// Get the quoted name of the table and field
|
||||
$tablename = $this->getTableName($xmldb_table);
|
||||
$fieldname = $this->getEncQuoted($xmldb_field->getName());
|
||||
|
||||
/// Decide if we are going to create/modify or to drop the default
|
||||
// Decide if we are going to create/modify or to drop the default
|
||||
if ($xmldb_field->getDefault() === null) {
|
||||
$results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); //Drop
|
||||
} else {
|
||||
@@ -815,13 +806,13 @@ abstract class sql_generator {
|
||||
|
||||
$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!
|
||||
// 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();
|
||||
}
|
||||
@@ -832,7 +823,7 @@ abstract class sql_generator {
|
||||
|
||||
$results[] = $rename;
|
||||
|
||||
/// Call to getRenameFieldExtraSQL(), override if needed
|
||||
// Call to getRenameFieldExtraSQL(), override if needed
|
||||
$extra_sentences = $this->getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname);
|
||||
$results = array_merge($results, $extra_sentences);
|
||||
|
||||
@@ -851,18 +842,18 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Just use the CreateKeySQL function
|
||||
// Just use the CreateKeySQL function
|
||||
if ($keyclause = $this->getKeySQL($xmldb_table, $xmldb_key)) {
|
||||
$key = 'ALTER TABLE ' . $this->getTableName($xmldb_table) .
|
||||
' ADD CONSTRAINT ' . $keyclause;
|
||||
$results[] = $key;
|
||||
}
|
||||
|
||||
/// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
|
||||
/// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists)
|
||||
// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
|
||||
// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists)
|
||||
if (!$keyclause || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) {
|
||||
/// Only if they don't exist
|
||||
if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN) { ///Calculate type of index based on type ok key
|
||||
// Only if they don't exist
|
||||
if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN) { //Calculate type of index based on type ok key
|
||||
$indextype = XMLDB_INDEX_NOTUNIQUE;
|
||||
} else {
|
||||
$indextype = XMLDB_INDEX_UNIQUE;
|
||||
@@ -873,14 +864,14 @@ abstract class sql_generator {
|
||||
}
|
||||
}
|
||||
|
||||
/// If the key is XMLDB_KEY_FOREIGN_UNIQUE, create it as UNIQUE too
|
||||
// If the key is XMLDB_KEY_FOREIGN_UNIQUE, create it as UNIQUE too
|
||||
if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE && $this->unique_keys) {
|
||||
///Duplicate the key
|
||||
//Duplicate the key
|
||||
$xmldb_key->setType(XMLDB_KEY_UNIQUE);
|
||||
$results = array_merge($results, $this->getAddKeySQL($xmldb_table, $xmldb_key));
|
||||
}
|
||||
|
||||
/// Return results
|
||||
// Return results
|
||||
return $results;
|
||||
}
|
||||
|
||||
@@ -895,14 +886,14 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the key name (note that this doesn't introspect DB, so could cause some problems sometimes!)
|
||||
/// TODO: We'll need to overwrite the whole getDropKeySQL() method inside each DB to do the proper queries
|
||||
/// against the dictionary or require ADOdb to support it or change the find_key_name() method to
|
||||
/// perform DB introspection directly. But, for now, as we aren't going to enable referential integrity
|
||||
/// it won't be a problem at all
|
||||
// Get the key name (note that this doesn't introspect DB, so could cause some problems sometimes!)
|
||||
// TODO: We'll need to overwrite the whole getDropKeySQL() method inside each DB to do the proper queries
|
||||
// against the dictionary or require ADOdb to support it or change the find_key_name() method to
|
||||
// perform DB introspection directly. But, for now, as we aren't going to enable referential integrity
|
||||
// it won't be a problem at all
|
||||
$dbkeyname = $this->mdb->get_manager()->find_key_name($xmldb_table, $xmldb_key);
|
||||
|
||||
/// Only if such type of key generation is enabled
|
||||
// Only if such type of key generation is enabled
|
||||
$dropkey = false;
|
||||
switch ($xmldb_key->getType()) {
|
||||
case XMLDB_KEY_PRIMARY:
|
||||
@@ -925,33 +916,33 @@ abstract class sql_generator {
|
||||
}
|
||||
break;
|
||||
}
|
||||
/// If we have decided to drop the key, let's do it
|
||||
// If we have decided to drop the key, let's do it
|
||||
if ($dropkey) {
|
||||
/// Replace TABLENAME, CONSTRAINTTYPE and KEYNAME as needed
|
||||
// Replace TABLENAME, CONSTRAINTTYPE and KEYNAME as needed
|
||||
$dropsql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $template);
|
||||
$dropsql = str_replace('KEYNAME', $dbkeyname, $dropsql);
|
||||
|
||||
$results[] = $dropsql;
|
||||
}
|
||||
|
||||
/// If we aren't dropping the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
|
||||
/// automatically by the RDBMS) drop the underlying (created by us) index (if exists)
|
||||
// If we aren't dropping the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
|
||||
// automatically by the RDBMS) drop the underlying (created by us) index (if exists)
|
||||
if (!$dropkey || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) {
|
||||
/// Only if they exist
|
||||
// Only if they exist
|
||||
$xmldb_index = new xmldb_index('anyname', XMLDB_INDEX_UNIQUE, $xmldb_key->getFields());
|
||||
if ($this->mdb->get_manager()->index_exists($xmldb_table, $xmldb_index)) {
|
||||
$results = array_merge($results, $this->getDropIndexSQL($xmldb_table, $xmldb_index));
|
||||
}
|
||||
}
|
||||
|
||||
/// If the key is XMLDB_KEY_FOREIGN_UNIQUE, drop the UNIQUE too
|
||||
// If the key is XMLDB_KEY_FOREIGN_UNIQUE, drop the UNIQUE too
|
||||
if ($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE && $this->unique_keys) {
|
||||
///Duplicate the key
|
||||
//Duplicate the key
|
||||
$xmldb_key->setType(XMLDB_KEY_UNIQUE);
|
||||
$results = array_merge($results, $this->getDropKeySQL($xmldb_table, $xmldb_key));
|
||||
}
|
||||
|
||||
/// Return results
|
||||
// Return results
|
||||
return $results;
|
||||
}
|
||||
|
||||
@@ -968,27 +959,27 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the real key name
|
||||
// Get the real key name
|
||||
$dbkeyname = $this->mdb->get_manager()->find_key_name($xmldb_table, $xmldb_key);
|
||||
|
||||
/// Check we are really generating this type of keys
|
||||
// Check we are really generating this type of keys
|
||||
if (($xmldb_key->getType() == XMLDB_KEY_PRIMARY && !$this->primary_keys) ||
|
||||
($xmldb_key->getType() == XMLDB_KEY_UNIQUE && !$this->unique_keys) ||
|
||||
($xmldb_key->getType() == XMLDB_KEY_FOREIGN && !$this->foreign_keys) ||
|
||||
($xmldb_key->getType() == XMLDB_KEY_FOREIGN_UNIQUE && !$this->unique_keys && !$this->foreign_keys)) {
|
||||
/// We aren't generating this type of keys, delegate to child indexes
|
||||
// We aren't generating this type of keys, delegate to child indexes
|
||||
$xmldb_index = new xmldb_index($xmldb_key->getName());
|
||||
$xmldb_index->setFields($xmldb_key->getFields());
|
||||
return $this->getRenameIndexSQL($xmldb_table, $xmldb_index, $newname);
|
||||
}
|
||||
|
||||
/// Arrived here so we are working with keys, lets rename them
|
||||
/// Replace TABLENAME and KEYNAME as needed
|
||||
// Arrived here so we are working with keys, lets rename them
|
||||
// Replace TABLENAME and KEYNAME as needed
|
||||
$renamesql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_key_sql);
|
||||
$renamesql = str_replace('OLDKEYNAME', $dbkeyname, $renamesql);
|
||||
$renamesql = str_replace('NEWKEYNAME', $newname, $renamesql);
|
||||
|
||||
/// Some DB doesn't support key renaming so this can be empty
|
||||
// Some DB doesn't support key renaming so this can be empty
|
||||
if ($renamesql) {
|
||||
$results[] = $renamesql;
|
||||
}
|
||||
@@ -1005,7 +996,7 @@ abstract class sql_generator {
|
||||
*/
|
||||
public function getAddIndexSQL($xmldb_table, $xmldb_index) {
|
||||
|
||||
/// Just use the CreateIndexSQL function
|
||||
// Just use the CreateIndexSQL function
|
||||
return $this->getCreateIndexSQL($xmldb_table, $xmldb_index);
|
||||
}
|
||||
|
||||
@@ -1020,10 +1011,10 @@ abstract class sql_generator {
|
||||
|
||||
$results = array();
|
||||
|
||||
/// Get the real index name
|
||||
// Get the real index name
|
||||
$dbindexname = $this->mdb->get_manager()->find_index_name($xmldb_table, $xmldb_index);
|
||||
|
||||
/// Replace TABLENAME and INDEXNAME as needed
|
||||
// Replace TABLENAME and INDEXNAME as needed
|
||||
$dropsql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->drop_index_sql);
|
||||
$dropsql = str_replace('INDEXNAME', $this->getEncQuoted($dbindexname), $dropsql);
|
||||
|
||||
@@ -1042,14 +1033,14 @@ abstract class sql_generator {
|
||||
* @return array An array of SQL statements to rename the index.
|
||||
*/
|
||||
function getRenameIndexSQL($xmldb_table, $xmldb_index, $newname) {
|
||||
/// Some DB doesn't support index renaming (MySQL) so this can be empty
|
||||
// Some DB doesn't support index renaming (MySQL) so this can be empty
|
||||
if (empty($this->rename_index_sql)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/// Get the real index name
|
||||
// Get the real index name
|
||||
$dbindexname = $this->mdb->get_manager()->find_index_name($xmldb_table, $xmldb_index);
|
||||
/// Replace TABLENAME and INDEXNAME as needed
|
||||
// Replace TABLENAME and INDEXNAME as needed
|
||||
$renamesql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_index_sql);
|
||||
$renamesql = str_replace('OLDINDEXNAME', $this->getEncQuoted($dbindexname), $renamesql);
|
||||
$renamesql = str_replace('NEWINDEXNAME', $this->getEncQuoted($newname), $renamesql);
|
||||
@@ -1073,14 +1064,14 @@ abstract class sql_generator {
|
||||
|
||||
$name = '';
|
||||
|
||||
/// Implement one basic cache to avoid object name duplication
|
||||
/// along all the request life, but never to return cached results
|
||||
/// We need this because sql statements are created before executing
|
||||
/// them, hence names doesn't exist "physically" yet in DB, so we need
|
||||
/// to known which ones have been used
|
||||
// Implement one basic cache to avoid object name duplication
|
||||
// along all the request life, but never to return cached results
|
||||
// We need this because sql statements are created before executing
|
||||
// them, hence names doesn't exist "physically" yet in DB, so we need
|
||||
// to known which ones have been used
|
||||
static $used_names = array();
|
||||
|
||||
/// Use standard naming. See http://docs.moodle.org/en/XMLDB_key_and_index_naming
|
||||
// Use standard naming. See http://docs.moodle.org/en/XMLDB_key_and_index_naming
|
||||
$tablearr = explode ('_', $tablename);
|
||||
foreach ($tablearr as $table) {
|
||||
$name .= substr(trim($table),0,4);
|
||||
@@ -1090,24 +1081,24 @@ abstract class sql_generator {
|
||||
foreach ($fieldsarr as $field) {
|
||||
$name .= substr(trim($field),0,3);
|
||||
}
|
||||
/// Prepend the prefix
|
||||
// Prepend the prefix
|
||||
$name = $this->prefix . $name;
|
||||
|
||||
$name = substr(trim($name), 0, $this->names_max_length - 1 - strlen($suffix)); //Max names_max_length
|
||||
|
||||
/// Add the suffix
|
||||
// Add the suffix
|
||||
$namewithsuffix = $name;
|
||||
if ($suffix) {
|
||||
$namewithsuffix = $namewithsuffix . '_' . $suffix;
|
||||
}
|
||||
|
||||
/// If the calculated name is in the cache, or if we detect it by introspecting the DB let's modify if
|
||||
// If the calculated name is in the cache, or if we detect it by introspecting the DB let's modify if
|
||||
if (in_array($namewithsuffix, $used_names) || $this->isNameInUse($namewithsuffix, $suffix, $tablename)) {
|
||||
$counter = 2;
|
||||
/// If have free space, we add 2
|
||||
// If have free space, we add 2
|
||||
if (strlen($namewithsuffix) < $this->names_max_length) {
|
||||
$newname = $name . $counter;
|
||||
/// Else replace the last char by 2
|
||||
// Else replace the last char by 2
|
||||
} else {
|
||||
$newname = substr($name, 0, strlen($name)-1) . $counter;
|
||||
}
|
||||
@@ -1115,7 +1106,7 @@ abstract class sql_generator {
|
||||
if ($suffix) {
|
||||
$newnamewithsuffix = $newnamewithsuffix . '_' . $suffix;
|
||||
}
|
||||
/// Now iterate until not used name is found, incrementing the counter
|
||||
// Now iterate until not used name is found, incrementing the counter
|
||||
while (in_array($newnamewithsuffix, $used_names) || $this->isNameInUse($newnamewithsuffix, $suffix, $tablename)) {
|
||||
$counter++;
|
||||
$newname = substr($name, 0, strlen($newname)-1) . $counter;
|
||||
@@ -1127,10 +1118,10 @@ abstract class sql_generator {
|
||||
$namewithsuffix = $newnamewithsuffix;
|
||||
}
|
||||
|
||||
/// Add the name to the cache
|
||||
// Add the name to the cache
|
||||
$used_names[] = $namewithsuffix;
|
||||
|
||||
/// Quote it if necessary (reserved words)
|
||||
// Quote it if necessary (reserved words)
|
||||
$namewithsuffix = $this->getEncQuoted($namewithsuffix);
|
||||
|
||||
return $namewithsuffix;
|
||||
@@ -1141,7 +1132,7 @@ abstract class sql_generator {
|
||||
* if it's a reserved word
|
||||
*
|
||||
* @param string|array $input String to quote.
|
||||
* @return Quoted string.
|
||||
* @return string Quoted string.
|
||||
*/
|
||||
public function getEncQuoted($input) {
|
||||
|
||||
@@ -1151,9 +1142,9 @@ abstract class sql_generator {
|
||||
}
|
||||
return $input;
|
||||
} else {
|
||||
/// Always lowercase
|
||||
// Always lowercase
|
||||
$input = strtolower($input);
|
||||
/// if reserved or quote_all or has hyphens, quote it
|
||||
// if reserved or quote_all or has hyphens, quote it
|
||||
if ($this->quote_all || in_array($input, $this->reserved_words) || strpos($input, '-') !== false) {
|
||||
$input = $this->quote_string . $input . $this->quote_string;
|
||||
}
|
||||
@@ -1173,39 +1164,39 @@ abstract class sql_generator {
|
||||
|
||||
if ($sentences = $statement->getSentences()) {
|
||||
foreach ($sentences as $sentence) {
|
||||
/// Get the list of fields
|
||||
// Get the list of fields
|
||||
$fields = $statement->getFieldsFromInsertSentence($sentence);
|
||||
/// Get the values of fields
|
||||
// Get the values of fields
|
||||
$values = $statement->getValuesFromInsertSentence($sentence);
|
||||
/// Look if we have some CONCAT value and transform it dynamically
|
||||
// Look if we have some CONCAT value and transform it dynamically
|
||||
foreach($values as $key => $value) {
|
||||
/// Trim single quotes
|
||||
// Trim single quotes
|
||||
$value = trim($value,"'");
|
||||
if (stristr($value, 'CONCAT') !== false){
|
||||
/// Look for data between parenthesis
|
||||
// Look for data between parenthesis
|
||||
preg_match("/CONCAT\s*\((.*)\)$/is", trim($value), $matches);
|
||||
if (isset($matches[1])) {
|
||||
$part = $matches[1];
|
||||
/// Convert the comma separated string to an array
|
||||
// Convert the comma separated string to an array
|
||||
$arr = xmldb_object::comma2array($part);
|
||||
if ($arr) {
|
||||
$value = $this->getConcatSQL($arr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Values to be sent to DB must be properly escaped
|
||||
// Values to be sent to DB must be properly escaped
|
||||
$value = $this->addslashes($value);
|
||||
/// Back trimmed quotes
|
||||
// Back trimmed quotes
|
||||
$value = "'" . $value . "'";
|
||||
/// Back to the array
|
||||
// Back to the array
|
||||
$values[$key] = $value;
|
||||
}
|
||||
|
||||
/// Iterate over fields, escaping them if necessary
|
||||
// Iterate over fields, escaping them if necessary
|
||||
foreach($fields as $key => $field) {
|
||||
$fields[$key] = $this->getEncQuoted($field);
|
||||
}
|
||||
/// Build the final SQL sentence and add it to the array of results
|
||||
// Build the final SQL sentence and add it to the array of results
|
||||
$sql = 'INSERT INTO ' . $this->getEncQuoted($this->prefix . $statement->getTable()) .
|
||||
'(' . implode(', ', $fields) . ') ' .
|
||||
'VALUES (' . implode(', ', $values) . ')';
|
||||
@@ -1228,7 +1219,7 @@ abstract class sql_generator {
|
||||
*/
|
||||
public function getConcatSQL($elements) {
|
||||
|
||||
/// Replace double quoted elements by single quotes
|
||||
// Replace double quoted elements by single quotes
|
||||
foreach($elements as $key => $element) {
|
||||
$element = trim($element);
|
||||
if (substr($element, 0, 1) == '"' &&
|
||||
@@ -1237,7 +1228,7 @@ abstract class sql_generator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Now call the standard $DB->sql_concat() DML function
|
||||
// Now call the standard $DB->sql_concat() DML function
|
||||
return call_user_func_array(array($this->mdb, 'sql_concat'), $elements);
|
||||
}
|
||||
|
||||
@@ -1271,22 +1262,22 @@ abstract class sql_generator {
|
||||
}
|
||||
|
||||
|
||||
/// ALL THESE FUNCTION MUST BE CUSTOMISED BY ALL THE XMLDGenerator classes
|
||||
// ====== FOLLOWING FUNCTION MUST BE CUSTOMISED BY ALL THE XMLDGenerator classes ========
|
||||
|
||||
/**
|
||||
* Reset a sequence to the id field of a table.
|
||||
*
|
||||
* @param string $tablename name of table.
|
||||
* @return success
|
||||
* @param xmldb_table|string $table name of table or the table object.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public abstract function getResetSequenceSQL($tablename);
|
||||
public abstract function getResetSequenceSQL($table);
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_table, returns the SQL statements
|
||||
* to create temporary table (inside one array).
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array SQL statements.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
abstract public function getCreateTempTableSQL($xmldb_table);
|
||||
|
||||
@@ -1360,6 +1351,7 @@ abstract class sql_generator {
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*
|
||||
* @todo MDL-31147 Moodle 2.1 - Drop getDropDefaultSQL()
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
/**
|
||||
* Experimental SQLite specific SQL code generator.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage ddl_generator
|
||||
* @package core_ddl
|
||||
* @copyright 2008 Andrei Bautu
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
@@ -37,31 +34,41 @@ class sqlite_sql_generator extends sql_generator {
|
||||
|
||||
/// Only set values that are different from the defaults present in XMLDBgenerator
|
||||
|
||||
public $drop_default_value_required = true; //To specify if the generator must use some DEFAULT clause to drop defaults
|
||||
public $drop_default_value = NULL; //The DEFAULT clause required to drop defaults
|
||||
/** @var bool To specify if the generator must use some DEFAULT clause to drop defaults.*/
|
||||
public $drop_default_value_required = true;
|
||||
|
||||
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP PRIMARY KEY'; // Template to drop PKs
|
||||
// with automatic replace for TABLENAME and KEYNAME
|
||||
/** @var string The DEFAULT clause required to drop defaults.*/
|
||||
public $drop_default_value = NULL;
|
||||
|
||||
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP KEY KEYNAME'; // Template to drop UKs
|
||||
// with automatic replace for TABLENAME and KEYNAME
|
||||
/** @var string Template to drop PKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP PRIMARY KEY';
|
||||
|
||||
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP FOREIGN KEY KEYNAME'; // Template to drop FKs
|
||||
// with automatic replace for TABLENAME and KEYNAME
|
||||
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
|
||||
/** @var string Template to drop UKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP KEY KEYNAME';
|
||||
|
||||
public $sequence_only = true; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name publiciable
|
||||
public $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
|
||||
public $sequence_name = 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL'; //Particular name for inline sequences in this generator
|
||||
/** @var string Template to drop FKs. 'TABLENAME' and 'KEYNAME' will be replaced from this template.*/
|
||||
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP FOREIGN KEY KEYNAME';
|
||||
|
||||
public $drop_index_sql = 'ALTER TABLE TABLENAME DROP INDEX INDEXNAME'; //SQL sentence to drop one index
|
||||
//TABLENAME, INDEXNAME are dynamically replaced
|
||||
/** @var string To define the default to set for NOT NULLs CHARs without default (null=do nothing).*/
|
||||
public $default_for_char = '';
|
||||
|
||||
public $rename_index_sql = null; //SQL sentence to rename one index (MySQL doesn't support this!)
|
||||
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dynamically replaced
|
||||
/** @var bool To avoid outputting the rest of the field specs, leaving only the name and the sequence_name returned.*/
|
||||
public $sequence_only = true;
|
||||
|
||||
public $rename_key_sql = null; //SQL sentence to rename one key (MySQL doesn't support this!)
|
||||
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dynamically replaced
|
||||
/** @var bool True if the generator needs to add extra code to generate the sequence fields.*/
|
||||
public $sequence_extra_code = false;
|
||||
|
||||
/** @var string The particular name for inline sequences in this generator.*/
|
||||
public $sequence_name = 'INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL';
|
||||
|
||||
/** @var string SQL sentence to drop one index where 'TABLENAME', 'INDEXNAME' keywords are dynamically replaced.*/
|
||||
public $drop_index_sql = 'ALTER TABLE TABLENAME DROP INDEX INDEXNAME';
|
||||
|
||||
/** @var string SQL sentence to rename one index where 'TABLENAME', 'OLDINDEXNAME' and 'NEWINDEXNAME' are dynamically replaced.*/
|
||||
public $rename_index_sql = null;
|
||||
|
||||
/** @var string SQL sentence to rename one key 'TABLENAME', 'OLDKEYNAME' and 'NEWKEYNAME' are dynamically replaced.*/
|
||||
public $rename_key_sql = null;
|
||||
|
||||
/**
|
||||
* Creates one new XMLDBmysql
|
||||
@@ -72,8 +79,9 @@ class sqlite_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Reset a sequence to the id field of a table.
|
||||
* @param string $table name of table or xmldb_object
|
||||
* @return bool success
|
||||
*
|
||||
* @param xmldb_table|string $table name of table or the table object.
|
||||
* @return array of sql statements
|
||||
*/
|
||||
public function getResetSequenceSQL($table) {
|
||||
|
||||
@@ -125,7 +133,12 @@ class sqlite_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type
|
||||
* Given one XMLDB Type, length and decimals, returns the DB proper SQL type.
|
||||
*
|
||||
* @param int $xmldb_type The xmldb_type defined constant. XMLDB_TYPE_INTEGER and other XMLDB_TYPE_* constants.
|
||||
* @param int $xmldb_length The length of that data type.
|
||||
* @param int $xmldb_decimals The decimal places of precision of the data type.
|
||||
* @return string The DB defined data type.
|
||||
*/
|
||||
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
|
||||
|
||||
@@ -263,7 +276,14 @@ class sqlite_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to alter the field in the table.
|
||||
*
|
||||
* @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) {
|
||||
return $this->getAlterTableSchema($xmldb_table, $xmldb_field, $xmldb_field);
|
||||
@@ -279,8 +299,12 @@ class sqlite_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to create its default
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to add its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*/
|
||||
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
return $this->getAlterTableSchema($xmldb_table, $xmldb_field, $xmldb_field);
|
||||
@@ -288,8 +312,12 @@ class sqlite_sql_generator extends sql_generator {
|
||||
|
||||
/**
|
||||
* Given one correct xmldb_field and the new name, returns the SQL statements
|
||||
* to rename it (inside one array)
|
||||
* SQLite is pretty different from the standard to justify this overloading
|
||||
* 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) {
|
||||
$oldfield = clone($xmldb_field);
|
||||
@@ -321,7 +349,11 @@ class sqlite_sql_generator extends sql_generator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop the field from the table
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop the field from the table.
|
||||
*
|
||||
* @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.
|
||||
* @return array The SQL statement for dropping a field from the table.
|
||||
*/
|
||||
public function getDropFieldSQL($xmldb_table, $xmldb_field) {
|
||||
return $this->getAlterTableSchema($xmldb_table, NULL, $xmldb_field);
|
||||
@@ -346,31 +378,50 @@ class sqlite_sql_generator extends sql_generator {
|
||||
/**
|
||||
* Given one xmldb_table and one xmldb_field, return the SQL statements needed to drop its default
|
||||
* (usually invoked from getModifyDefaultSQL()
|
||||
*
|
||||
* Note that this method may be dropped in future.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @param xmldb_field $xmldb_field The xmldb_field object instance.
|
||||
* @return array Array of SQL statements to create a field's default.
|
||||
*
|
||||
* @todo MDL-31147 Moodle 2.1 - Drop getDropDefaultSQL()
|
||||
*/
|
||||
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
|
||||
return $this->getAlterTableSchema($xmldb_table, $xmldb_field, $xmldb_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the code (in array) needed to add one comment to the table
|
||||
* Returns the code (array of statements) needed to add one comment to the table.
|
||||
*
|
||||
* @param xmldb_table $xmldb_table The xmldb_table object instance.
|
||||
* @return array Array of SQL statements to add one comment to the table.
|
||||
*/
|
||||
function getCommentSQL ($xmldb_table) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* Given one object name and it's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
*
|
||||
* (MySQL requires the whole xmldb_table object to be specified, so we add it always)
|
||||
*
|
||||
* This is invoked from getNameForObject().
|
||||
* Only some DB have this implemented.
|
||||
*
|
||||
* @param string $object_name The object's name to check for.
|
||||
* @param string $type The object's type (pk, uk, fk, ck, ix, uix, seq, trg).
|
||||
* @param string $table_name The table's name to check in
|
||||
* @return bool If such name is currently in use (true) or no (false)
|
||||
*/
|
||||
public function isNameInUse($object_name, $type, $table_name) {
|
||||
// TODO: add introspection code
|
||||
return false; //No name in use found
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of reserved words (lowercase) for this DB
|
||||
* @return array An array of database specific reserved words
|
||||
*/
|
||||
public static function getReservedWords() {
|
||||
/// From http://www.sqlite.org/lang_keywords.html
|
||||
@@ -399,6 +450,11 @@ class sqlite_sql_generator extends sql_generator {
|
||||
return $reserved_words;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds slashes to string.
|
||||
* @param string $s
|
||||
* @return string The escaped string.
|
||||
*/
|
||||
public function addslashes($s) {
|
||||
// do not use php addslashes() because it depends on PHP quote settings!
|
||||
$s = str_replace("'", "''", $s);
|
||||
|
||||
+11
-12
@@ -17,8 +17,7 @@
|
||||
/**
|
||||
* DDL layer tests
|
||||
*
|
||||
* @package core
|
||||
* @subpackage ddl
|
||||
* @package core_ddl
|
||||
* @category phpunit
|
||||
* @copyright 2008 Nicolas Connault
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -646,7 +645,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
// fill the table with some records before adding fields
|
||||
$this->fill_deftable('test_table1');
|
||||
|
||||
/// add one not null field without specifying default value (throws ddl_exception)
|
||||
// add one not null field without specifying default value (throws ddl_exception)
|
||||
$field = new xmldb_field('onefield');
|
||||
$field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null);
|
||||
try {
|
||||
@@ -656,7 +655,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
$this->assertTrue($e instanceof ddl_exception);
|
||||
}
|
||||
|
||||
/// add one existing field (throws ddl_exception)
|
||||
// add one existing field (throws ddl_exception)
|
||||
$field = new xmldb_field('course');
|
||||
$field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 2);
|
||||
try {
|
||||
@@ -670,7 +669,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
// TODO: add one text field with default, must throw exception
|
||||
// TODO: add one binary field with default, must throw exception
|
||||
|
||||
/// add one integer field and check it
|
||||
// add one integer field and check it
|
||||
$field = new xmldb_field('oneinteger');
|
||||
$field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 2);
|
||||
$dbman->add_field($table, $field);
|
||||
@@ -686,7 +685,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
$this->assertEquals($columns['oneinteger']->meta_type ,'I');
|
||||
$this->assertEquals($DB->get_field('test_table1', 'oneinteger', array(), IGNORE_MULTIPLE), 2); //check default has been applied
|
||||
|
||||
/// add one numeric field and check it
|
||||
// add one numeric field and check it
|
||||
$field = new xmldb_field('onenumber');
|
||||
$field->set_attributes(XMLDB_TYPE_NUMBER, '6,3', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 2.55);
|
||||
$dbman->add_field($table, $field);
|
||||
@@ -703,7 +702,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
$this->assertEquals($columns['onenumber']->meta_type ,'N');
|
||||
$this->assertEquals($DB->get_field('test_table1', 'onenumber', array(), IGNORE_MULTIPLE), 2.550); //check default has been applied
|
||||
|
||||
/// add one float field and check it (not official type - must work as number)
|
||||
// add one float field and check it (not official type - must work as number)
|
||||
$field = new xmldb_field('onefloat');
|
||||
$field->set_attributes(XMLDB_TYPE_FLOAT, '6,3', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 3.550);
|
||||
$dbman->add_field($table, $field);
|
||||
@@ -723,7 +722,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
// this isn't a real problem at all.
|
||||
$this->assertEquals(round($DB->get_field('test_table1', 'onefloat', array(), IGNORE_MULTIPLE), 7), 3.550); //check default has been applied
|
||||
|
||||
/// add one char field and check it
|
||||
// add one char field and check it
|
||||
$field = new xmldb_field('onechar');
|
||||
$field->set_attributes(XMLDB_TYPE_CHAR, '25', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 'Nice dflt!');
|
||||
$dbman->add_field($table, $field);
|
||||
@@ -740,7 +739,7 @@ class ddl_testcase extends database_driver_testcase {
|
||||
$this->assertEquals($columns['onechar']->meta_type ,'C');
|
||||
$this->assertEquals($DB->get_field('test_table1', 'onechar', array(), IGNORE_MULTIPLE), 'Nice dflt!'); //check default has been applied
|
||||
|
||||
/// add one big text field and check it
|
||||
// add one big text field and check it
|
||||
$field = new xmldb_field('onetext');
|
||||
$field->set_attributes(XMLDB_TYPE_TEXT, 'big');
|
||||
$dbman->add_field($table, $field);
|
||||
@@ -756,21 +755,21 @@ class ddl_testcase extends database_driver_testcase {
|
||||
$this->assertEquals($columns['onetext']->default_value, null);
|
||||
$this->assertEquals($columns['onetext']->meta_type ,'X');
|
||||
|
||||
/// add one medium text field and check it
|
||||
// add one medium text field and check it
|
||||
$field = new xmldb_field('mediumtext');
|
||||
$field->set_attributes(XMLDB_TYPE_TEXT, 'medium');
|
||||
$dbman->add_field($table, $field);
|
||||
$columns = $DB->get_columns('test_table1');
|
||||
$this->assertTrue(($columns['mediumtext']->max_length == -1) or ($columns['mediumtext']->max_length >= 16777215)); // -1 means unknown or big
|
||||
|
||||
/// add one small text field and check it
|
||||
// add one small text field and check it
|
||||
$field = new xmldb_field('smalltext');
|
||||
$field->set_attributes(XMLDB_TYPE_TEXT, 'small');
|
||||
$dbman->add_field($table, $field);
|
||||
$columns = $DB->get_columns('test_table1');
|
||||
$this->assertTrue(($columns['smalltext']->max_length == -1) or ($columns['smalltext']->max_length >= 65535)); // -1 means unknown or big
|
||||
|
||||
/// add one binary field and check it
|
||||
// add one binary field and check it
|
||||
$field = new xmldb_field('onebinary');
|
||||
$field->set_attributes(XMLDB_TYPE_BINARY);
|
||||
$dbman->add_field($table, $field);
|
||||
|
||||
Reference in New Issue
Block a user