public function test_reserved_words() { $reserved = sql_generator::getAllReservedWords(); $this->assertTrue(count($reserved) > 1); }
/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; /// Set own core attributes $this->does_generate = ACTION_GENERATE_HTML; /// These are always here global $CFG, $XMLDB, $DB; /// Calculate list of available SQL generators require_once "{$CFG->libdir}/ddl/sql_generator.php"; $reserved_words = sql_generator::getAllReservedWords(); /// Now, calculate, looking into current DB (with AdoDB Metadata), which fields are /// in the list of reserved words $wronguses = array(); $dbtables = $DB->get_tables(); if ($dbtables) { foreach ($dbtables as $table) { if (array_key_exists($table, $reserved_words)) { $wronguses[] = $this->str['table'] . ' - ' . $table . ' (' . implode(', ', $reserved_words[$table]) . ')'; } $dbfields = $DB->get_columns($table); if ($dbfields) { foreach ($dbfields as $dbfield) { if (array_key_exists($dbfield->name, $reserved_words)) { $wronguses[] = $this->str['field'] . ' - ' . $table . '->' . $dbfield->name . ' (' . implode(', ', $reserved_words[$dbfield->name]) . ')'; } } } } } /// Sort the wrong uses sort($wronguses); /// The back to edit table button $b = ' <p class="centerpara buttons">'; $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>'; $b .= '</p>'; $o = $b; /// The list of currently wrong field names if ($wronguses) { $o .= ' <table id="formelements" class="boxaligncenter" cellpadding="5">'; $o .= ' <tr><td align="center"><font color="red">' . $this->str['wrongreservedwords'] . '</font></td></tr>'; $o .= ' <tr><td>'; $o .= ' <ul><li>' . implode('</li><li>', $wronguses) . '</li></ul>'; $o .= ' </td></tr>'; $o .= ' </table>'; } /// The textarea showing all the reserved words $o .= ' <table id="formelements" class="boxaligncenter" cellpadding="5">'; $o .= ' <tr><td align="center">' . $this->str['listreservedwords'] . '</td></tr>'; $o .= ' <tr><td><textarea cols="80" rows="32">'; $o .= s(implode(', ', array_keys($reserved_words))); $o .= '</textarea></td></tr>'; $o .= ' </table>'; $this->output = $o; /// Launch postaction if exists (leave this here!) if ($this->getPostAction() && $result) { return $this->launch($this->getPostAction()); } /// Return ok if arrived here return $result; }
/** * 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 */ public function getAlterFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause = NULL, $skip_default_clause = NULL, $skip_notnull_clause = NULL) { $skip_type_clause = is_null($skip_type_clause) ? $this->alter_column_skip_type : $skip_type_clause; $skip_default_clause = is_null($skip_default_clause) ? $this->alter_column_skip_default : $skip_default_clause; $skip_notnull_clause = is_null($skip_notnull_clause) ? $this->alter_column_skip_notnull : $skip_notnull_clause; $results = array(); /// To store all the needed SQL commands /// Get the quoted name of the table and field $tablename = $this->getTableName($xmldb_table); $fieldname = $xmldb_field->getName(); /// Take a look to field metadata $meta = $this->mdb->get_columns($xmldb_table->getName()); $metac = $meta[$fieldname]; $oldmetatype = $metac->meta_type; $oldlength = $metac->max_length; /// To calculate the oldlength if the field is numeric, we need to perform one extra query /// because ADOdb has one bug here. http://phplens.com/lens/lensforum/msgs.php?id=15883 if ($oldmetatype == 'N') { $uppertablename = strtoupper($tablename); $upperfieldname = strtoupper($fieldname); if ($col = $this->mdb->get_record_sql("SELECT cname, precision\n FROM col\n WHERE tname = ? AND cname = ?", array($uppertablename, $upperfieldname))) { $oldlength = $col->precision; } } $olddecimals = empty($metac->scale) ? null : $metac->scale; $oldnotnull = empty($metac->not_null) ? false : $metac->not_null; $olddefault = empty($metac->default_value) || strtoupper($metac->default_value) == 'NULL' ? null : $metac->default_value; $typechanged = true; //By default, assume that the column type has changed $precisionchanged = true; //By default, assume that the column precision has changed $decimalchanged = true; //By default, assume that the column decimal has changed $defaultchanged = true; //By default, assume that the column default has changed $notnullchanged = true; //By default, assume that the column notnull has changed $from_temp_fields = false; //By default don't assume we are going to use temporal fields /// Detect if we are changing the type of the column if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I' || $xmldb_field->getType() == XMLDB_TYPE_NUMBER && $oldmetatype == 'N' || $xmldb_field->getType() == XMLDB_TYPE_FLOAT && $oldmetatype == 'F' || $xmldb_field->getType() == XMLDB_TYPE_CHAR && $oldmetatype == 'C' || $xmldb_field->getType() == XMLDB_TYPE_TEXT && $oldmetatype == 'X' || $xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B') { $typechanged = false; } /// Detect if precision has changed if ($xmldb_field->getType() == XMLDB_TYPE_TEXT || $xmldb_field->getType() == XMLDB_TYPE_BINARY || $oldlength == -1 || $xmldb_field->getLength() == $oldlength) { $precisionchanged = false; } /// Detect if decimal has changed if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER || $xmldb_field->getType() == XMLDB_TYPE_CHAR || $xmldb_field->getType() == XMLDB_TYPE_TEXT || $xmldb_field->getType() == XMLDB_TYPE_BINARY || !$xmldb_field->getDecimals() || !$olddecimals || $xmldb_field->getDecimals() == $olddecimals) { $decimalchanged = false; } /// Detect if we are changing the default if ($xmldb_field->getDefault() === null && $olddefault === null || $xmldb_field->getDefault() === $olddefault || "'" . $xmldb_field->getDefault() . "'" === $olddefault) { //Equality with quotes because ADOdb returns the default with quotes $defaultchanged = false; } /// Detect if we are changing the nullability if ($xmldb_field->getNotnull() === $oldnotnull) { $notnullchanged = false; } /// If type has changed or precision or decimal has changed and we are in one numeric field /// - create one temp column with the new specs /// - fill the new column with the values from the old one /// - drop the old column /// - rename the temp column to the original name if ($typechanged || ($oldmetatype == 'N' || $oldmetatype == 'I') && ($precisionchanged || $decimalchanged)) { $tempcolname = $xmldb_field->getName() . '_alter_column_tmp'; /// Prevent temp field to have both NULL/NOT NULL and DEFAULT constraints $skip_notnull_clause = true; $skip_default_clause = true; $xmldb_field->setName($tempcolname); // Drop the temp column, in case it exists (due to one previous failure in conversion) // really ugly but we cannot enclose DDL into transaction :-( if (isset($meta[$tempcolname])) { $results = array_merge($results, $this->getDropFieldSQL($xmldb_table, $xmldb_field)); } /// Create the temporal column $results = array_merge($results, $this->getAddFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause, $skip_type_clause, $skip_notnull_clause)); /// Copy contents from original col to the temporal one // From TEXT to integer/number we need explicit conversion if ($oldmetatype == 'X' && $xmldb_field->GetType() == XMLDB_TYPE_INTEGER) { $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = CAST(' . $this->mdb->sql_compare_text($fieldname) . ' AS INT)'; } else { if ($oldmetatype == 'X' && $xmldb_field->GetType() == XMLDB_TYPE_NUMBER) { $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = CAST(' . $this->mdb->sql_compare_text($fieldname) . ' AS NUMBER)'; // Normal cases, implicit conversion } else { $results[] = 'UPDATE ' . $tablename . ' SET ' . $tempcolname . ' = ' . $fieldname; } } /// Drop the old column $xmldb_field->setName($fieldname); //Set back the original field name $results = array_merge($results, $this->getDropFieldSQL($xmldb_table, $xmldb_field)); /// Rename the temp column to the original one $results[] = 'ALTER TABLE ' . $tablename . ' RENAME COLUMN ' . $tempcolname . ' TO ' . $fieldname; /// Mark we have performed one change based in temp fields $from_temp_fields = true; /// Re-enable the notnull and default sections so the general AlterFieldSQL can use it $skip_notnull_clause = false; $skip_default_clause = false; /// Dissable the type section because we have done it with the temp field $skip_type_clause = true; /// If new field is nullable, nullability hasn't changed if (!$xmldb_field->getNotnull()) { $notnullchanged = false; } /// If new field hasn't default, default hasn't changed if ($xmldb_field->getDefault() === null) { $defaultchanged = false; } } /// If type and precision and decimals hasn't changed, prevent the type clause if (!$typechanged && !$precisionchanged && !$decimalchanged) { $skip_type_clause = true; } /// If NULL/NOT NULL hasn't changed /// prevent null clause to be specified if (!$notnullchanged) { $skip_notnull_clause = true; /// Initially, prevent the notnull clause /// But, if we have used the temp field and the new field is not null, then enforce the not null clause if ($from_temp_fields && $xmldb_field->getNotnull()) { $skip_notnull_clause = false; } } /// If default hasn't changed /// prevent default clause to be specified if (!$defaultchanged) { $skip_default_clause = true; /// Initially, prevent the default clause /// But, if we have used the temp field and the new field has default clause, then enforce the default clause if ($from_temp_fields) { $default_clause = $this->getDefaultClause($xmldb_field); if ($default_clause) { $skip_notnull_clause = false; } } } /// If arriving here, something is not being skipped (type, notnull, default), calculate the standard AlterFieldSQL if (!$skip_type_clause || !$skip_notnull_clause || !$skip_default_clause) { $results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause, $skip_default_clause, $skip_notnull_clause)); return $results; } /// Finally return results return $results; }
/** * Given three strings (table name, list of fields (comma separated) and suffix), * create the proper object name quoting it if necessary. * * IMPORTANT: This function must be used to CALCULATE NAMES of objects TO BE CREATED, * NEVER TO GUESS NAMES of EXISTING objects!!! * * IMPORTANT: We are overriding this function for the MSSQL generator because objects * belonging to temporary tables aren't searchable in the catalog neither in information * schema tables. So, for temporary tables, we are going to add 4 randomly named "virtual" * fields, so the generated names won't cause concurrency problems. Really nasty hack, * 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. * */ public function getNameForObject($tablename, $fields, $suffix = '') { if ($this->temptables->is_temptable($tablename)) { // Is temp table, inject random field names $random = strtolower(random_string(12)); // 12cc to be split in 4 parts $fields = $fields . ', ' . implode(', ', str_split($random, 3)); } return parent::getNameForObject($tablename, $fields, $suffix); // Delegate to parent (common) algorithm }
/** * Creates one new XMLDBmysql */ public function __construct($mdb) { parent::__construct($mdb); }
/** * Given one correct xmldb_table, returns the SQL statements * to create temporary table (inside one array) */ public function getCreateTempTableSQL($xmldb_table) { $this->temptables->add_temptable($xmldb_table->getName()); $sqlarr = parent::getCreateTableSQL($xmldb_table); // we do not want the engine hack included in create table SQL $sqlarr = preg_replace('/^CREATE TABLE (.*)/s', 'CREATE TEMPORARY TABLE $1', $sqlarr); return $sqlarr; }
/** * Given one correct xmldb_index, returns the SQL statements * needed to create it (in array). * * @param xmldb_table $xmldb_table The xmldb_table instance to create the index on. * @param xmldb_index $xmldb_index The xmldb_index to create. * @return array An array of SQL statements to create the index. * @throws coding_exception Thrown if the xmldb_index does not validate with the xmldb_table. */ public function getCreateIndexSQL($xmldb_table, $xmldb_index) { $sqls = parent::getCreateIndexSQL($xmldb_table, $xmldb_index); $hints = $xmldb_index->getHints(); $fields = $xmldb_index->getFields(); if (in_array('varchar_pattern_ops', $hints) and count($fields) == 1) { // Add the pattern index and keep the normal one, keep unique only the standard index to improve perf. foreach ($sqls as $sql) { $field = reset($fields); $count = 0; $newindex = preg_replace("/^CREATE( UNIQUE)? INDEX ([a-z0-9_]+) ON ([a-z0-9_]+) \\({$field}\\)\$/", "CREATE INDEX \\2_pattern ON \\3 USING btree ({$field} varchar_pattern_ops)", $sql, -1, $count); if ($count != 1) { debugging('Unexpected getCreateIndexSQL() structure.'); continue; } $sqls[] = $newindex; } } return $sqls; }
/** * Given one correct xmldb_table, returns the SQL statements * to drop it (inside one array). * * @param xmldb_table $xmldb_table The table to drop. * @return array SQL statement(s) for dropping the specified table. */ public function getDropTableSQL($xmldb_table) { $sqlarr = parent::getDropTableSQL($xmldb_table); if ($this->temptables->is_temptable($xmldb_table->getName())) { $sqlarr = preg_replace('/^DROP TABLE/', "DROP TEMPORARY TABLE", $sqlarr); $this->temptables->delete_temptable($xmldb_table->getName()); } return $sqlarr; }
/** * Given one correct xmldb_table, returns the SQL statements * to drop it (inside one array). * * @param xmldb_table $xmldb_table The table to drop. * @return array SQL statement(s) for dropping the specified table. */ public function getDropTableSQL($xmldb_table) { $sqlarr = parent::getDropTableSQL($xmldb_table); if ($this->temptables->is_temptable($xmldb_table->getName())) { $this->temptables->delete_temptable($xmldb_table->getName()); } return $sqlarr; }
/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; // Set own core attributes $this->does_generate = ACTION_GENERATE_HTML; // These are always here global $CFG, $XMLDB, $DB; // Do the job, setting $result as needed // Get the dir containing the file $dirpath = required_param('dir', PARAM_PATH); $dirpath = $CFG->dirroot . $dirpath; // Get the correct dir if (!empty($XMLDB->dbdirs)) { $dbdir =& $XMLDB->dbdirs[$dirpath]; if ($dbdir) { // Only if the directory exists and it has been loaded if (!$dbdir->path_exists || !$dbdir->xml_loaded) { return false; } // Check if the in-memory object exists and create it if (empty($XMLDB->editeddirs)) { $XMLDB->editeddirs = array(); } // Check if the dir exists and copy it from dbdirs if (!isset($XMLDB->editeddirs[$dirpath])) { $XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir)); } // Get it $editeddir =& $XMLDB->editeddirs[$dirpath]; $structure =& $editeddir->xml_file->getStructure(); // Add the main form $o = '<form id="form" action="index.php" method="post">'; $o .= '<div>'; $o .= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />'; $o .= ' <input type="hidden" name ="action" value="edit_xml_file_save" />'; $o .= ' <input type="hidden" name ="postaction" value="edit_xml_file" />'; $o .= ' <input type="hidden" name ="path" value="' . s($structure->getPath()) . '" />'; $o .= ' <input type="hidden" name ="version" value="' . s($structure->getVersion()) . '" />'; $o .= ' <input type="hidden" name ="sesskey" value="' . sesskey() . '" />'; $o .= ' <table id="formelements" class="boxaligncenter">'; $o .= ' <tr valign="top"><td>Path:</td><td>' . s($structure->getPath()) . '</td></tr>'; $o .= ' <tr valign="top"><td>Version:</td><td>' . s($structure->getVersion()) . '</td></tr>'; $o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td><textarea name="comment" rows="3" cols="80" id="comment">' . $structure->getComment() . '</textarea></td></tr>'; $o .= ' <tr><td> </td><td><input type="submit" value="' . $this->str['change'] . '" /></td></tr>'; $o .= ' </table>'; $o .= '</div></form>'; // Calculate the pending changes / save message $e = ''; $cansavenow = false; if ($structure->hasChanged()) { if (!is_writeable($dirpath . '/install.xml') || !is_writeable($dirpath)) { $e .= '<p class="centerpara error">' . $this->str['pendingchangescannotbesaved'] . '</p>'; } else { $e .= '<p class="centerpara warning">' . $this->str['pendingchanges'] . '</p>'; $cansavenow = true; } } // Calculate the buttons $b = ' <p class="centerpara buttons">'; // The view original XML button $b .= ' <a href="index.php?action=view_structure_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&select=original">[' . $this->str['vieworiginal'] . ']</a>'; // The view edited XML button if ($structure->hasChanged()) { $b .= ' <a href="index.php?action=view_structure_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&select=edited">[' . $this->str['viewedited'] . ']</a>'; } else { $b .= ' [' . $this->str['viewedited'] . ']'; } // The new table button $b .= ' <a href="index.php?action=new_table&sesskey=' . sesskey() . '&postaction=edit_table&table=changeme&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtable'] . ']</a>'; // The new from MySQL button if ($DB->get_dbfamily() == 'mysql') { $b .= ' <a href="index.php?action=new_table_from_mysql&sesskey=' . sesskey() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtablefrommysql'] . ']</a>'; } else { $b .= ' [' . $this->str['newtablefrommysql'] . ']'; } // The view sql code button $b .= '<a href="index.php?action=view_structure_sql&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewsqlcode'] . ']</a>'; // The view php code button $b .= ' <a href="index.php?action=view_structure_php&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>'; // The save button (if possible) if ($cansavenow) { $b .= ' <a href="index.php?action=save_xml_file&sesskey=' . sesskey() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&time=' . time() . '&unload=false&postaction=edit_xml_file&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['save'] . ']</a>'; } // The back to main menu button $b .= ' <a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>'; $b .= '</p>'; $o .= $e . $b; // Join all the reserved words into one big array // Calculate list of available SQL generators require_once "{$CFG->libdir}/ddl/sql_generator.php"; $reserved_words = sql_generator::getAllReservedWords(); // Add the tables list $tables = $structure->getTables(); if ($tables) { $o .= '<h3 class="main">' . $this->str['tables'] . '</h3>'; $o .= '<table id="listtables" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">'; $row = 0; foreach ($tables as $table) { // The table name (link to edit table) $t = '<a href="index.php?action=edit_table&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $table->getName() . '</a>'; // Calculate buttons $b = '</td><td class="button cell">'; // The edit button $b .= '<a href="index.php?action=edit_table&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>'; $b .= '</td><td class="button cell">'; // The up button if ($table->getPrevious()) { $b .= '<a href="index.php?action=move_updown_table&direction=up&sesskey=' . sesskey() . '&table=' . $table->getName() . '&postaction=edit_xml_file' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>'; } else { $b .= '[' . $this->str['up'] . ']'; } $b .= '</td><td class="button cell">'; // The down button if ($table->getNext()) { $b .= '<a href="index.php?action=move_updown_table&direction=down&sesskey=' . sesskey() . '&table=' . $table->getName() . '&postaction=edit_xml_file' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>'; } else { $b .= '[' . $this->str['down'] . ']'; } $b .= '</td><td class="button cell">'; // The delete button (if we have more than one and it isn't used) if (count($tables) > 1 && !$structure->getTableUses($table->getName())) { // !$structure->getTableUses($table->getName())) { $b .= '<a href="index.php?action=delete_table&sesskey=' . sesskey() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>'; } else { $b .= '[' . $this->str['delete'] . ']'; } $b .= '</td><td class="button cell">'; // The view xml button $b .= '<a href="index.php?action=view_table_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&table=' . $table->getName() . '&select=edited">[' . $this->str['viewxml'] . ']</a>'; // Detect if the table name is a reserved word if (array_key_exists($table->getName(), $reserved_words)) { $b .= ' <a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>'; } $b .= '</td>'; // Print table row $o .= '<tr class="r' . $row . '"><td class="table cell">' . $t . $b . '</tr>'; $row = ($row + 1) % 2; } $o .= '</table>'; } // Add the back to main $this->output = $o; } } // Launch postaction if exists (leave this unmodified) if ($this->getPostAction() && $result) { return $this->launch($this->getPostAction()); } return $result; }
/** * Given one correct xmldb_table and the new name, returns the SQL statements * to drop it (inside one array) */ public function getDropTempTableSQL($xmldb_table) { $sqlarr = parent::getDropTableSQL($xmldb_table); $sqlarr = preg_replace('/^DROP TABLE/', "DROP TEMPORARY TABLE", $sqlarr); return $sqlarr; }
/** * Given one xmldb_table and one xmldb_field, return the SQL statements needded to add the field to the table * PostgreSQL is pretty standard but with one severe restriction under 7.4 that forces us to overload * this function: Default clause is not allowed when adding fields. * * This function can be safely removed once min req. for PG will be 8.0 */ public function getAddFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause = NULL, $skip_default_clause = NULL, $skip_notnull_clause = NULL) { $skip_type_clause = is_null($skip_type_clause) ? $this->alter_column_skip_type : $skip_type_clause; $skip_default_clause = is_null($skip_default_clause) ? $this->alter_column_skip_default : $skip_default_clause; $skip_notnull_clause = is_null($skip_notnull_clause) ? $this->alter_column_skip_notnull : $skip_notnull_clause; $results = array(); $tablename = $this->getTableName($xmldb_table); $fieldname = $this->getEncQuoted($xmldb_field->getName()); $defaultvalue = $xmldb_field->getDefault(); $results = parent::getAddFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause, $skip_default_clause, $skip_notnull_clause); /// Add default (only if not skip_default) if (!$skip_default_clause) { $default_clause = $this->getDefaultClause($xmldb_field); if ($default_clause) { $sql = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $default_clause; /// Add default clause $results[] = $sql; } /// Update default value (if exists) to all the records if ($defaultvalue !== null) { if (!is_numeric($defaultvalue)) { $defaultvalue = "'" . $this->addslashes($defaultvalue) . "'"; } $sql = 'UPDATE ' . $tablename . ' SET ' . $fieldname . '=' . $defaultvalue; $results[] = $sql; } } /// Add not null (only if no skip_notnull) if (!$skip_notnull_clause) { if ($xmldb_field->getNotnull()) { $results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET NOT NULL'; /// Add not null } } return $results; }
/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; /// Set own core attributes $this->does_generate = ACTION_GENERATE_HTML; /// These are always here global $CFG, $XMLDB; /// Do the job, setting result as needed /// Get the dir containing the file $dirpath = required_param('dir', PARAM_PATH); $dirpath = $CFG->dirroot . $dirpath; /// Get the correct dirs if (!empty($XMLDB->dbdirs)) { $dbdir =& $XMLDB->dbdirs[$dirpath]; } else { return false; } /// Check if the dir exists and copy it from dbdirs /// (because we need straight load in case of saving from here) if (!isset($XMLDB->editeddirs[$dirpath])) { $XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir)); } if (!empty($XMLDB->editeddirs)) { $editeddir =& $XMLDB->editeddirs[$dirpath]; $structure =& $editeddir->xml_file->getStructure(); } /// ADD YOUR CODE HERE $tableparam = required_param('table', PARAM_CLEAN); if (!($table =& $structure->getTable($tableparam))) { /// Arriving here from a name change, looking for the new table name $tableparam = required_param('name', PARAM_CLEAN); $table =& $structure->getTable($tableparam); } $dbdir =& $XMLDB->dbdirs[$dirpath]; $origstructure =& $dbdir->xml_file->getStructure(); /// Add the main form $o = '<form id="form" action="index.php" method="post">'; $o .= '<div>'; $o .= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />'; $o .= ' <input type="hidden" name ="table" value="' . $tableparam . '" />'; $o .= ' <input type="hidden" name ="action" value="edit_table_save" />'; $o .= ' <input type="hidden" name ="sesskey" value="' . sesskey() . '" />'; $o .= ' <input type="hidden" name ="postaction" value="edit_table" />'; $o .= ' <table id="formelements" class="boxaligncenter">'; /// If the table is being used, we cannot rename it if ($structure->getTableUses($table->getName())) { $o .= ' <tr valign="top"><td>Name:</td><td><input type="hidden" name ="name" value="' . s($table->getName()) . '" />' . s($table->getName()) . '</td></tr>'; } else { $o .= ' <tr valign="top"><td><label for="name" accesskey="p">Name:</label></td><td><input name="name" type="text" size="28" maxlength="28" id="name" value="' . s($table->getName()) . '" /></td></tr>'; } $o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td><textarea name="comment" rows="3" cols="80" id="comment">' . s($table->getComment()) . '</textarea></td></tr>'; $o .= ' <tr valign="top"><td> </td><td><input type="submit" value="' . $this->str['change'] . '" /></td></tr>'; $o .= ' </table>'; $o .= '</div></form>'; /// Calculate the pending changes / save message $e = ''; $cansavenow = false; if ($structure->hasChanged()) { if (!is_writeable($dirpath . '/install.xml') || !is_writeable($dirpath)) { $e .= '<p class="centerpara error">' . $this->str['pendingchangescannotbesaved'] . '</p>'; } else { $e .= '<p class="centerpara warning">' . $this->str['pendingchanges'] . '</p>'; $cansavenow = true; } } /// Calculate the buttons $b = ' <p class="centerpara buttons">'; /// The view original XML button if ($origstructure->getTable($tableparam)) { $b .= ' <a href="index.php?action=view_table_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&select=original&table=' . $tableparam . '">[' . $this->str['vieworiginal'] . ']</a>'; } else { $b .= ' [' . $this->str['vieworiginal'] . ']'; } /// The view edited XML button if ($table->hasChanged()) { $b .= ' <a href="index.php?action=view_table_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&select=edited&table=' . $tableparam . '">[' . $this->str['viewedited'] . ']</a>'; } else { $b .= ' [' . $this->str['viewedited'] . ']'; } /// The new field button $b .= ' <a href="index.php?action=new_field&sesskey=' . sesskey() . '&postaction=edit_field&table=' . $tableparam . '&field=changeme&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newfield'] . ']</a>'; /// The new key button $b .= ' <a href="index.php?action=new_key&sesskey=' . sesskey() . '&postaction=edit_key&table=' . $tableparam . '&key=changeme&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newkey'] . ']</a>'; /// The new index button $b .= ' <a href="index.php?action=new_index&sesskey=' . sesskey() . '&postaction=edit_index&table=' . $tableparam . '&index=changeme&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newindex'] . ']</a>'; $b .= '</p>'; $b .= ' <p class="centerpara buttons">'; /// The view sql code button $b .= '<a href="index.php?action=view_table_sql&table=' . $tableparam . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewsqlcode'] . ']</a>'; /// The view php code button $b .= ' <a href="index.php?action=view_table_php&table=' . $tableparam . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>'; /// The save button (if possible) if ($cansavenow) { $b .= ' <a href="index.php?action=save_xml_file&sesskey=' . sesskey() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&time=' . time() . '&unload=false&postaction=edit_table&table=' . $tableparam . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['save'] . ']</a>'; } /// The back to edit xml file button $b .= ' <a href="index.php?action=edit_xml_file&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>'; $b .= '</p>'; $o .= $e . $b; require_once "{$CFG->libdir}/ddl/sql_generator.php"; $reserved_words = sql_generator::getAllReservedWords(); /// Delete any 'changeme' field/key/index $table->deleteField('changeme'); $table->deleteKey('changeme'); $table->deleteIndex('changeme'); /// Add the fields list $fields =& $table->getFields(); if (!empty($fields)) { $o .= '<h3 class="main">' . $this->str['fields'] . '</h3>'; $o .= '<table id="listfields" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">'; $row = 0; foreach ($fields as $field) { /// The field name (link to edit - if the field has no uses) if (!$structure->getFieldUses($table->getName(), $field->getName())) { $f = '<a href="index.php?action=edit_field&field=' . $field->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $field->getName() . '</a>'; } else { $f = $field->getName(); } /// Calculate buttons $b = '</td><td class="button cell">'; /// The edit button (if the field has no uses) if (!$structure->getFieldUses($table->getName(), $field->getName())) { $b .= '<a href="index.php?action=edit_field&field=' . $field->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>'; } else { $b .= '[' . $this->str['edit'] . ']'; } $b .= '</td><td class="button cell">'; /// The up button if ($field->getPrevious()) { $b .= '<a href="index.php?action=move_updown_field&direction=up&sesskey=' . sesskey() . '&field=' . $field->getName() . '&table=' . $table->getName() . '&postaction=edit_table' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>'; } else { $b .= '[' . $this->str['up'] . ']'; } $b .= '</td><td class="button cell">'; /// The down button if ($field->getNext()) { $b .= '<a href="index.php?action=move_updown_field&direction=down&sesskey=' . sesskey() . '&field=' . $field->getName() . '&table=' . $table->getName() . '&postaction=edit_table' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>'; } else { $b .= '[' . $this->str['down'] . ']'; } $b .= '</td><td class="button cell">'; /// The delete button (if we have more than one and it isn't used if (count($fields) > 1 && !$structure->getFieldUses($table->getName(), $field->getName())) { $b .= '<a href="index.php?action=delete_field&sesskey=' . sesskey() . '&field=' . $field->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>'; } else { $b .= '[' . $this->str['delete'] . ']'; } $b .= '</td><td class="button cell">'; /// The view xml button $b .= '<a href="index.php?action=view_field_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&field=' . $field->getName() . '&table=' . $table->getName() . '&select=edited">[' . $this->str['viewxml'] . ']</a>'; /// Detect if the table name is a reserved word if (array_key_exists($field->getName(), $reserved_words)) { $b .= ' <a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>'; } /// The readable info $r = '</td><td class="readableinfo cell">' . $field->readableInfo() . '</td>'; /// Print table row $o .= '<tr class="r' . $row . '"><td class="table cell">' . $f . $b . $r . '</tr>'; $row = ($row + 1) % 2; } $o .= '</table>'; } /// Add the keys list $keys =& $table->getKeys(); if (!empty($keys)) { $o .= '<h3 class="main">' . $this->str['keys'] . '</h3>'; $o .= '<table id="listkeys" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">'; $row = 0; foreach ($keys as $key) { /// The key name (link to edit - if the key has no uses) if (!$structure->getKeyUses($table->getName(), $key->getName())) { $k = '<a href="index.php?action=edit_key&key=' . $key->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $key->getName() . '</a>'; } else { $k = $key->getName(); } /// Calculate buttons $b = '</td><td class="button cell">'; /// The edit button (if the key hasn't uses) if (!$structure->getKeyUses($table->getName(), $key->getName())) { $b .= '<a href="index.php?action=edit_key&key=' . $key->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>'; } else { $b .= '[' . $this->str['edit'] . ']'; } $b .= '</td><td class="button cell">'; /// The up button if ($key->getPrevious()) { $b .= '<a href="index.php?action=move_updown_key&direction=up&sesskey=' . sesskey() . '&key=' . $key->getName() . '&table=' . $table->getName() . '&postaction=edit_table' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>'; } else { $b .= '[' . $this->str['up'] . ']'; } $b .= '</td><td class="button cell">'; /// The down button if ($key->getNext()) { $b .= '<a href="index.php?action=move_updown_key&direction=down&sesskey=' . sesskey() . '&key=' . $key->getName() . '&table=' . $table->getName() . '&postaction=edit_table' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>'; } else { $b .= '[' . $this->str['down'] . ']'; } $b .= '</td><td class="button cell">'; /// The delete button (if the key hasn't uses) if (!$structure->getKeyUses($table->getName(), $key->getName())) { $b .= '<a href="index.php?action=delete_key&sesskey=' . sesskey() . '&key=' . $key->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>'; } else { $b .= '[' . $this->str['delete'] . ']'; } $b .= '</td><td class="button cell">'; /// The view xml button $b .= '<a href="index.php?action=view_key_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&key=' . $key->getName() . '&table=' . $table->getName() . '&select=edited">[' . $this->str['viewxml'] . ']</a>'; /// The readable info $r = '</td><td class="readableinfo cell">' . $key->readableInfo() . '</td>'; /// Print table row $o .= '<tr class="r' . $row . '"><td class="table cell">' . $k . $b . $r . '</tr>'; $row = ($row + 1) % 2; } $o .= '</table>'; } /// Add the indexes list $indexes =& $table->getIndexes(); if (!empty($indexes)) { $o .= '<h3 class="main">' . $this->str['indexes'] . '</h3>'; $o .= '<table id="listindexes" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">'; $row = 0; foreach ($indexes as $index) { /// The index name (link to edit) $i = '<a href="index.php?action=edit_index&index=' . $index->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $index->getName() . '</a>'; /// Calculate buttons $b = '</td><td class="button cell">'; /// The edit button $b .= '<a href="index.php?action=edit_index&index=' . $index->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>'; $b .= '</td><td class="button cell">'; /// The up button if ($index->getPrevious()) { $b .= '<a href="index.php?action=move_updown_index&direction=up&sesskey=' . sesskey() . '&index=' . $index->getName() . '&table=' . $table->getName() . '&postaction=edit_table' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['up'] . ']</a>'; } else { $b .= '[' . $this->str['up'] . ']'; } $b .= '</td><td class="button cell">'; /// The down button if ($index->getNext()) { $b .= '<a href="index.php?action=move_updown_index&direction=down&sesskey=' . sesskey() . '&index=' . $index->getName() . '&table=' . $table->getName() . '&postaction=edit_table' . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['down'] . ']</a>'; } else { $b .= '[' . $this->str['down'] . ']'; } $b .= '</td><td class="button cell">'; /// The delete button $b .= '<a href="index.php?action=delete_index&sesskey=' . sesskey() . '&index=' . $index->getName() . '&table=' . $table->getName() . '&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>'; $b .= '</td><td class="button cell">'; /// The view xml button $b .= '<a href="index.php?action=view_index_xml&dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&index=' . $index->getName() . '&table=' . $table->getName() . '&select=edited">[' . $this->str['viewxml'] . ']</a>'; /// The readable info $r = '</td><td class="readableinfo cell">' . $index->readableInfo() . '</td>'; /// Print table row $o .= '<tr class="r' . $row . '"><td class="table cell">' . $i . $b . $r . '</tr>'; $row = ($row + 1) % 2; } $o .= '</table>'; } $this->output = $o; /// Launch postaction if exists (leave this here!) if ($this->getPostAction() && $result) { return $this->launch($this->getPostAction()); } /// Return ok if arrived here return $result; }
/** * Given one xmldb_table and one xmldb_field, return the SQL statements needded to alter the field in the table */ public function getAlterFieldSQL($xmldb_table, $xmldb_field) { $results = array(); /// To store all the needed SQL commands /// Get the quoted name of the table and field $tablename = $xmldb_table->getName(); $fieldname = $xmldb_field->getName(); /// Take a look to field metadata $meta = $this->mdb->get_columns($tablename, false); $metac = $meta[$fieldname]; $oldmetatype = $metac->meta_type; $oldlength = $metac->max_length; $olddecimals = empty($metac->scale) ? null : $metac->scale; $oldnotnull = empty($metac->not_null) ? false : $metac->not_null; $olddefault = empty($metac->has_default) ? null : strtok($metac->default_value, ':'); $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 if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I' || $xmldb_field->getType() == XMLDB_TYPE_NUMBER && $oldmetatype == 'N' || $xmldb_field->getType() == XMLDB_TYPE_FLOAT && $oldmetatype == 'F' || $xmldb_field->getType() == XMLDB_TYPE_CHAR && $oldmetatype == 'C' || $xmldb_field->getType() == XMLDB_TYPE_TEXT && $oldmetatype == 'X' || $xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B') { $typechanged = false; } /// Detect if we are changing the 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 ($typechanged || $lengthchanged) { $results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); } /// Just prevent default clauses in this type of sentences for mssql and launch the parent one $results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, NULL, true, NULL)); // Call parent /// 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; }
$internal = array('change_db_encoding', 'configure_dbconnection', 'db_(detect_lobs|update_lobs)', 'execute_sql(_arr)?', 'onespace2empty', 'oracle_dirty_hack', 'rcache_(get|getforfill|releaseforfill|set|unset|unset_table)', 'where_clause'); $unsupported = array('column_type', 'table_column', 'modify_database', '(Execute|Connect|PConnect|ErrorMsg)', '(MetaTables|MetaColumns|MetaColumnNames|MetaPrimaryKeys|MetaIndexes)'); $other = array('\\$db[,; -]', "[^\$_'\"\\.-]dbfamily", "[^\$_'\"\\.-]dblibrary", "[^\$_'\"\\.-]dbtype[^s]", 'sql_substr\\(\\)', '\\$CFG->prefix', 'NEWNAMEGOESHERE', 'new\\s(XMLDBTable|XMLDBField|XMLDBIndex|XMLDBKey)', '>(addFieldInfo|addIndexInfo|addKeyInfo|setAttributes)', '>(begin|commit|rollback)_sql', '(if|while|for|return).*>get_recordset(_list|_select|_sql)?', 'SELECT DISTINCT.*\\.\\*', "get_in_or_equal\\(.*SQL_PARAMS_NAMED\\s*,\\s*'.*\\d'"); /// List of reserved words /// 1. default (common) ones $reservedlist = array('user', 'group', 'order', 'select', 'from', 'where', 'role', 'null', 'start', 'end', 'date', 'match', 'mod', 'new', 'old'); /// 2. from sql_generators if possible if ($is_moodle_root) { define('MOODLE_INTERNAL', true); // cheat, so sql_generator think we are one standard moodle script global $CFG; // cheat, again, to define some stuff needed by generators $CFG = new stdclass(); $CFG->libdir = dirname(__FILE__) . '/lib'; require_once $CFG->libdir . '/ddl/sql_generator.php'; $reservedlist = array_keys(sql_generator::getAllReservedWords()); } foreach ($reservedlist as $key => $word) { $reservedlist[$key] = '(?: AS\\s+|:)' . trim($word); } /// Define some known false positives to take them out from errors report (nested array of => file => regular expressions considered false positives) $fp = array('install.php' => array('empty\\(\\$distro-\\>dbtype\\)', '= trim\\(\\$_POST\\[\'dbtype\'\\]', 'get_driver_instance\\(\\$config-|>dbtype'), 'admin/blocks.php' => array('drop_plugin_tables.*\\/blocks'), 'admin/health.php' => array('\\. \\$CFG-\\>prefix \\.'), 'admin/modules.php' => array('drop_plugin_tables.*\\/mod'), 'admin/qtypes.php' => array('drop_plugin_tables.*\\$QTYPES\\[\\$delete\\]-\\>'), 'admin/xmldb/actions/check_bigints/check_bigints.class.php' => array('this->dbfamily'), 'auth/cas/CAS/CAS/client.php' => array('this->setAttributes'), 'backup/util/dbops/backup_structure_dbops.class.php' => array('element->get_source_.*convert_params_to_values'), 'backup/util/helper/restore_decode_content.class.php' => array('return.*get_recordset_sql'), 'blocks/html/backup/moodle2/restore_html_block_task.class.php' => array('return.*get_recordset_sql'), 'lib/adminlib.php' => array('drop_plugin_tables\\(\\$pluginname', 'used_tables = get_used_table_names', 'dbdirs = get_db_directories'), 'lib/ddl/database_manager.php' => array('dbdirs = get_db_directories'), 'lib/ddl/simpletest/testddl.php' => array('DB2 = moodle_database::get_driver_instance'), 'lib/dml/moodle_database.php' => array('cfg-\\>dbtype = \\$this-\\>get_dbtype', 'cfg-\\>dblibrary = \\$this-\\>get_dblibrary', 'return \\$this-\\>get_recordset_select\\(\\$table, \\$select, \\$params', 'return \\$this-\\>get_recordset_sql\\(\\$sql, \\$params, \\$limitfrom'), 'lib/dml/simpletest/testdml.php' => array('DB2 = moodle_database::get_driver_instance'), 'lib/form/recaptcha.php' => array('this->setAttributes'), 'mod/assignment/lib.php' => array('mform->setAttributes'), 'mod/scorm/datamodels/scorm_13.js.php' => array('max.*delimiter.*(unique|duplicate).*(:true|:false)', 'cmi\\.objectives\\.n\\..*defaultvalue.*:null'), 'mod/workshop/form/accumulative/lib.php' => array('return \\$DB-\\>get_recordset_sql\\('), 'mod/workshop/form/comments/lib.php' => array('return \\$DB-\\>get_recordset_sql\\('), 'mod/workshop/form/numerrors/lib.php' => array('return \\$DB-\\>get_recordset_sql\\('), 'mod/workshop/form/rubric/lib.php' => array('return \\$DB-\\>get_recordset_sql\\('), 'admin/xmldb/actions/generate_all_documentation/generate_all_documentation.class.php' => array('dbdirs = get_db_directories'), 'admin/xmldb/actions/get_db_directories/get_db_directories.class.php' => array('db_directories = get_db_directories')); /// List of exceptions that aren't errors (function declarations, comments, adodb usage from adodb drivers and harcoded strings). Non reportable false positives $excludes = '/(function |^\\s*\\*|^\\s*\\/\\/|\\$this-\\>adodb-\\>(Execute|Connect|PConnect|ErrorMsg|MetaTables|MetaIndexes|MetaColumns|MetaColumnNames|MetaPrimaryKeys|)|protected \\$[a-zA-Z]*db|Incorrect |check find_index_name|not available anymore|output|Replace it with the correct use of|where order of parameters is|_moodle_database|invaliddbtype|has been deprecated in Moodle 2\\.0\\. Will be out in Moodle 2\\.1|Potential SQL injection detected|requires at least two parameters|hint_database = install_db_val|Current database \\(|admin_setting_configselect|(if|while|for|return).*\\>get_recordset(_list|_select|_sql)?.*\\>valid\\(\\)|NEWNAMEGOESHERE.*XMLDB_LINEFEED|has_capability\\(.*:view.*context)|die(.*result.*:null.*errstr)|CAST\\(.+AS\\s+(INT|FLOAT|DECIMAL|NUM|REAL)/'; /// Calculating megarules $dml_megarule = calculate_megarule($dml, array('[ =@.]'), array('( )?\\('), 'i'); $helper_megarule = calculate_megarule($helper, array('[ =@.]'), array('( )?\\('), 'i'); $ddl_megarule = calculate_megarule($ddl, array('[ =@.]'), array('( )?\\('), 'i'); $coreonly_megarule = calculate_megarule($coreonly, array('[ =@.]'), array('( )?\\('), 'i'); $enum_megarule = calculate_megarule($enum); $internal_megarule = calculate_megarule($internal, array('[ =@.]'), array('( )?\\('), 'i');