From 5a070f0477c40fdb79da4b1307fc47dd9a96eb6b Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Tue, 5 Jun 2012 12:14:02 +0200 Subject: [PATCH] MDL-32003 fix phpdocs in DDL layer --- lib/ddl/database_manager.php | 127 ++++++----- lib/ddl/mssql_sql_generator.php | 261 +++++++++++++++-------- lib/ddl/mysql_sql_generator.php | 165 ++++++++++----- lib/ddl/oracle_sql_generator.php | 267 ++++++++++++++++-------- lib/ddl/postgres_sql_generator.php | 218 ++++++++++++------- lib/ddl/sql_generator.php | 324 ++++++++++++++--------------- lib/ddl/sqlite_sql_generator.php | 126 +++++++---- lib/ddl/tests/ddl_test.php | 23 +- 8 files changed, 924 insertions(+), 587 deletions(-) diff --git a/lib/ddl/database_manager.php b/lib/ddl/database_manager.php index ee6f9bd9dc0..aba9282770c 100644 --- a/lib/ddl/database_manager.php +++ b/lib/ddl/database_manager.php @@ -14,13 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . - /** * 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() . diff --git a/lib/ddl/mssql_sql_generator.php b/lib/ddl/mssql_sql_generator.php index ed9942e17a9..bbf769ded3d 100644 --- a/lib/ddl/mssql_sql_generator.php +++ b/lib/ddl/mssql_sql_generator.php @@ -1,5 +1,4 @@ . - /** * 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', diff --git a/lib/ddl/mysql_sql_generator.php b/lib/ddl/mysql_sql_generator.php index 801d7401e0f..6ae310f6411 100644 --- a/lib/ddl/mysql_sql_generator.php +++ b/lib/ddl/mysql_sql_generator.php @@ -1,5 +1,4 @@ . - /** * 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', diff --git a/lib/ddl/oracle_sql_generator.php b/lib/ddl/oracle_sql_generator.php index 312c97d4e03..e096c871ec2 100644 --- a/lib/ddl/oracle_sql_generator.php +++ b/lib/ddl/oracle_sql_generator.php @@ -1,5 +1,4 @@ . - /** * 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', diff --git a/lib/ddl/postgres_sql_generator.php b/lib/ddl/postgres_sql_generator.php index 46436fc8156..8d410868e01 100644 --- a/lib/ddl/postgres_sql_generator.php +++ b/lib/ddl/postgres_sql_generator.php @@ -1,5 +1,4 @@ . - /** * 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', diff --git a/lib/ddl/sql_generator.php b/lib/ddl/sql_generator.php index 4cc1eedb8b3..805189a3419 100644 --- a/lib/ddl/sql_generator.php +++ b/lib/ddl/sql_generator.php @@ -14,16 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . - /** * 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() */ diff --git a/lib/ddl/sqlite_sql_generator.php b/lib/ddl/sqlite_sql_generator.php index e10b24a869b..c0b088cfbbd 100644 --- a/lib/ddl/sqlite_sql_generator.php +++ b/lib/ddl/sqlite_sql_generator.php @@ -1,5 +1,4 @@ . - /** * 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); diff --git a/lib/ddl/tests/ddl_test.php b/lib/ddl/tests/ddl_test.php index 352202f4190..64f7d6ddc02 100644 --- a/lib/ddl/tests/ddl_test.php +++ b/lib/ddl/tests/ddl_test.php @@ -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);