MDL-14679 ok, here is the big patch with new dmllib and ddlib API, some code is already converted, XML db editor works; see tracker for details of regressions and TODOs

This commit is contained in:
skodak
2008-05-15 21:40:00 +00:00
parent 469dcbcc8b
commit f33e1ed4ae
112 changed files with 8225 additions and 6596 deletions
+6 -6
View File
@@ -860,16 +860,16 @@ if ( file_exists(dirname(dirname(__FILE__)) . '/config.php')) {
/// Both old .sql files and new install.xml are supported
/// But we prioritise install.xml (XMLDB) if present
change_db_encoding(); // first try to change db encoding to utf8
if (!setup_is_unicodedb()) {
// If could not convert successfully, throw error, and prevent installation
console_write(STDERR,'unicoderequired', 'admin');
if (!$DB->setup_is_unicodedb()) {
if (!$DB->change_db_encoding()) {
// If could not convert successfully, throw error, and prevent installation
console_write(STDERR,'unicoderequired', 'admin');
}
}
$status = false;
if (file_exists("$CFG->libdir/db/install.xml")) {
$status = install_from_xmldb_file("$CFG->libdir/db/install.xml"); //New method
$status = $DB->get_manager()->install_from_xmldb_file("$CFG->libdir/db/install.xml"); //New method
} else {
console_write(STDERR,"Error: Your database ($CFG->dbtype) is not yet fully supported by Moodle or install.xml is not present. See the lib/db directory.",'',false);
}
+1 -1
View File
@@ -36,7 +36,7 @@
/// Extra debugging (set in config.php)
if (!empty($CFG->showcronsql)) {
$db->debug = true;
$DB->set_debug(true);
}
if (!empty($CFG->showcrondebugging)) {
$CFG->debug = DEBUG_DEVELOPER;
+17 -25
View File
@@ -61,14 +61,6 @@
print_error('phpvaron', 'debug', '', array('file_uploads', $documentationlink));
}
if (empty($CFG->prefix) && $CFG->dbfamily != 'mysql') { //Enforce prefixes for everybody but mysql
print_error('prefixcannotbeempty', 'debug', '', array($CFG->prefix, $CFG->dbtype));
}
if ($CFG->dbfamily == 'oracle' && strlen($CFG->prefix) > 2) { //Max prefix length for Oracle is 2cc
print_error('prefixlimit', 'debug', '', $CFG->prefix);
}
/// Check that config.php has been edited
if ($CFG->wwwroot == "http://example.com/moodle") {
@@ -103,8 +95,7 @@
}
/// Check if the main tables have been installed yet or not.
if (! $tables = $db->Metatables() ) { // No tables yet at all.
if (!$tables = $DB->get_tables() ) { // No tables yet at all.
$maintables = false;
} else { // Check for missing main tables
@@ -113,7 +104,7 @@
"course_sections", "log", "log_display", "modules",
"user");
foreach ($mtables as $mtable) {
if (!in_array($CFG->prefix.$mtable, $tables)) {
if (!in_array($mtable, $tables)) {
$maintables = false;
break;
}
@@ -164,20 +155,21 @@
$CFG->debug = $origdebug;
error_reporting($CFG->debug);
upgrade_log_start();
$db->debug = true;
$DB->set_debug(true);
/// Both old .sql files and new install.xml are supported
/// But we prioritise install.xml (XMLDB) if present
change_db_encoding(); // first try to change db encoding to utf8
if (!setup_is_unicodedb()) {
// If could not convert successfully, throw error, and prevent installation
print_error('unicoderequired', 'admin');
if (!$DB->setup_is_unicodedb()) {
if (!$DB->change_db_encoding()) {
// If could not convert successfully, throw error, and prevent installation
print_error('unicoderequired', 'admin');
}
}
$status = false;
if (file_exists("$CFG->libdir/db/install.xml")) {
$status = install_from_xmldb_file("$CFG->libdir/db/install.xml"); //New method
$status = $DB->get_manager()->install_from_xmldb_file("$CFG->libdir/db/install.xml"); //New method
} else {
print_error('dbnotsupport', 'debug', '', $CFG->dbtype);
}
@@ -186,7 +178,7 @@
set_config('unicodedb', 1);
/// Continue with the instalation
$db->debug = false;
$DB->set_debug(false);
if ($status) {
/// Groups install is now in core above.
@@ -335,7 +327,7 @@
upgrade_language_pack();
print_heading($strdatabasechecking);
$db->debug=true;
$DB->set_debug(true);
/// Launch the old main upgrade (if exists)
$status = true;
if (function_exists('main_upgrade')) {
@@ -345,7 +337,7 @@
if ($status && function_exists('xmldb_main_upgrade')) {
$status = xmldb_main_upgrade($CFG->version);
}
$db->debug=false;
$DB->set_debug(false);
/// If successful, continue upgrading roles and setting everything properly
if ($status) {
if (!update_capabilities()) {
@@ -473,7 +465,7 @@
$newsite->students = get_string("defaultcoursestudents");
$newsite->timemodified = time();
if (!$newid = insert_record('course', $newsite)) {
if (!$newid = $DB->insert_record('course', $newsite)) {
print_error('cannotsetupsite', 'error');
}
// make sure course context exists
@@ -486,7 +478,7 @@
$cat = new object();
$cat->name = get_string('miscellaneous');
$cat->depth = 1;
if (!$catid = insert_record('course_categories', $cat)) {
if (!$catid = $DB->insert_record('course_categories', $cat)) {
print_error('cannotsetupcategory', 'error');
}
// make sure category context exists
@@ -505,10 +497,10 @@
blocks_repopulate_page($page);
//add admin_tree block to site if not already present
if ($admintree = get_record('block', 'name', 'admin_tree')) {
if ($admintree = $DB->get_record('block', array('name'=>'admin_tree'))) {
$page = page_create_object(PAGE_COURSE_VIEW, SITEID);
blocks_execute_action($page, blocks_get_by_page($page), 'add', (int)$admintree->id, false, false);
if ($admintreeinstance = get_record('block_instance', 'pagetype', $page->type, 'pageid', SITEID, 'blockid', $admintree->id)) {
if ($admintreeinstance = $DB->get_record('block_instance', array('pagetype'=>$page->type, 'pageid'=>SITEID, 'blockid'=>$admintree->id))) {
blocks_execute_action($page, blocks_get_by_page($page), 'moveleft', $admintreeinstance, false, false);
}
}
@@ -522,7 +514,7 @@
}
/// Check if the guest user exists. If not, create one.
if (! record_exists("user", "username", "guest")) {
if (!$DB->record_exists('user', array('username'=>'guest'))) {
if (! $guest = create_guest_record()) {
notify("Could not create guest user record !!!");
}
+29 -28
View File
@@ -1,43 +1,44 @@
<?php
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('toinodb');
admin_externalpage_setup('toinodb');
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
require_login();
require_login();
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
admin_externalpage_print_header();
print_heading('Convert all MySQL tables from MYISAM to InnoDB');
admin_externalpage_print_header();
print_heading('Convert all MySQL tables from MYISAM to InnoDB');
if ($CFG->dbfamily != 'mysql') {
if ($CFG->dbfamily != 'mysql') {
notice('This function is for MySQL databases only!', 'index.php');
}
}
if (data_submitted() and $confirm and confirm_sesskey()) {
if (data_submitted() and $confirm and confirm_sesskey()) {
notify('Please be patient and wait for this to complete...', 'notifysuccess');
notify('Please be patient and wait for this to complete...', 'notifysuccess');
if ($tables = $db->MetaTables()) {
$db->debug = true;
foreach ($tables as $table) {
execute_sql("ALTER TABLE $table TYPE=INNODB; ");
}
$db->debug = false;
}
notify('... done.', 'notifysuccess');
print_continue('index.php');
admin_externalpage_print_footer();
if ($tables = $DB->get_tables()) {
$DB->set_debug(true);
foreach ($tables as $table) {
$fulltable = $DB->get_prefix().$table;
$DB->change_database_structure("ALTER TABLE $fulltable TYPE=INNODB");
}
$DB->set_debug(false);
}
notify('... done.', 'notifysuccess');
print_continue('index.php');
admin_externalpage_print_footer();
} else {
$optionsyes = array('confirm'=>'1', 'sesskey'=>sesskey());
notice_yesno('Are you sure you want convert all your tables to the InnoDB format?',
'innodb.php', 'index.php', $optionsyes, NULL, 'post', 'get');
admin_externalpage_print_footer();
}
} else {
$optionsyes = array('confirm'=>'1', 'sesskey'=>sesskey());
notice_yesno('Are you sure you want convert all your tables to the InnoDB format?',
'innodb.php', 'index.php', $optionsyes, NULL, 'post', 'get');
admin_externalpage_print_footer();
}
?>
+6 -6
View File
@@ -19,7 +19,7 @@ admin_externalpage_setup('ssoaccesscontrol');
admin_externalpage_print_header();
if (!extension_loaded('openssl')) {
print_error('requiresopenssl', 'mnet', '', NULL, true);
print_error('requiresopenssl', 'mnet');
}
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
@@ -27,7 +27,7 @@ $sesskey = sesskey();
$formerror = array();
// grab the mnet hosts and remove the localhost
$mnethosts = get_records_menu('mnet_host', '', '', 'name', 'id, name');
$mnethosts = $DB->get_records_menu('mnet_host', array(), 'name', 'id, name');
if (array_key_exists($CFG->mnet_localhost_id, $mnethosts)) {
unset($mnethosts[$CFG->mnet_localhost_id]);
}
@@ -39,13 +39,13 @@ if (!empty($action) and confirm_sesskey()) {
// boot if insufficient permission
if (!has_capability('moodle/user:delete', $sitecontext)) {
error(get_string('nomodifyacl','mnet'));
print_error('nomodifyacl','mnet');
}
// fetch the record in question
$id = required_param('id', PARAM_INT);
if (!$idrec = get_record('mnet_sso_access_control', 'id', $id)) {
error(get_string('recordnoexists','mnet'), "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('recordnoexists','mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
switch ($action) {
@@ -60,7 +60,7 @@ if (!empty($action) and confirm_sesskey()) {
// require the access parameter, and it must be 'allow' or 'deny'
$accessctrl = trim(strtolower(required_param('accessctrl', PARAM_ALPHA)));
if ($accessctrl != 'allow' and $accessctrl != 'deny') {
error(get_string('invalidaccessparam', 'mnet') , "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('invalidaccessparam', 'mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
if (mnet_update_sso_access_control($idrec->username, $idrec->mnet_host_id, $accessctrl)) {
@@ -84,7 +84,7 @@ if ($form = data_submitted() and confirm_sesskey()) {
// check permissions and verify form input
if (!has_capability('moodle/user:delete', $sitecontext)) {
error(get_string('nomodifyacl','mnet'), "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
print_error('nomodifyacl','mnet', "$CFG->wwwroot/$CFG->admin/mnet/access_control.php");
}
if (empty($form->username)) {
$formerror['username'] = get_string('enterausername','mnet');
+12 -15
View File
@@ -24,7 +24,7 @@ if (!$go or !data_submitted() or !confirm_sesskey()) { /// Print a form
}
if (!$tables = $db->Metatables() ) { // No tables yet at all.
if (!$tables = $DB->get_tables() ) { // No tables yet at all.
print_error('notables', 'debug');
}
@@ -38,29 +38,28 @@ while(@ob_end_flush());
echo '<strong>Progress:</strong>';
$i = 0;
$skiptables = array($CFG->prefix.'config', $CFG->prefix.'user_students', $CFG->prefix.'user_teachers');//, $CFG->prefix.'sessions2');
$skiptables = array('config', 'user_students', 'user_teachers');//, 'sessions2');
foreach ($tables as $table) {
if (($CFG->prefix && strpos($table, $CFG->prefix) !== 0)
or strpos($table, $CFG->prefix.'pma') === 0) { // Not our tables
if (strpos($table,'pma') === 0) { // Not our tables
continue;
}
if (in_array($table, $skiptables)) { // Don't process these
continue;
}
if ($columns = $db->MetaColumns($table, false)) {
$fulltable = $DB->get_prefix().$table;
if ($columns = $DB->get_columns($table)) {
if (!array_key_exists('id', $columns) and !array_key_exists('ID', $columns)) {
continue; // moodle tables have id
}
foreach ($columns as $column => $data) {
if (in_array($data->type, array('text','mediumtext','longtext','varchar'))) { // Text stuff only
// first find candidate records
$rs = get_recordset_sql("SELECT id, $column FROM $table WHERE $column LIKE '%</lang>%' OR $column LIKE '%<span lang=%'");
if ($rs) {
while (!$rs->EOF) {
$text = $rs->fields[$column];
$id = $rs->fields['id'];
$sql = "SELECT id, $column FROM $fulltable WHERE $column LIKE '%</lang>%' OR $column LIKE '%<span lang=%'";
if ($rs = $DB->get_recordset_sql($sql)) {
foreach ($rs as $data) {
$text = $data->$column;
$id = $data->id;
if ($i % 600 == 0) {
echo '<br />';
}
@@ -68,7 +67,6 @@ foreach ($tables as $table) {
echo '.';
}
$i++;
$rs->MoveNext();
if (empty($text) or is_numeric($text)) {
continue; // nothing to do
@@ -82,11 +80,10 @@ foreach ($tables as $table) {
}
if ($newtext != $text) {
$newtext = addslashes($newtext);
execute_sql("UPDATE $table SET $column='$newtext' WHERE id=$id", false);
$DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
}
}
rs_close($rs);
$rs->close();
}
}
}
+3 -3
View File
@@ -34,16 +34,16 @@ if (!data_submitted() or !$search or !$replace or !confirm_sesskey()) { /// Pr
print_simple_box_start('center');
if (!db_replace($search, $replace)) {
if (!db_replace(stripslashes($search), stripslashes($replace))) {
print_error('erroroccur', debug);
}
print_simple_box_end();
/// Rebuild course cache which might be incorrect now
notify('Rebuilding course cache...');
notify('Rebuilding course cache...', 'notifysuccess');
rebuild_course_cache();
notify('...finished');
notify('...finished', 'notifysuccess');
print_continue('index.php');
+22 -17
View File
@@ -14,6 +14,9 @@
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$cancel = optional_param('cancel', 0, PARAM_BOOL);
$name = stripslashes($name);
$description = stripslashes($description);
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
require_capability('moodle/role:manage', $sitecontext);
@@ -65,13 +68,13 @@
if (empty($name)) {
$errors['name'] = get_string('errorbadrolename', 'role');
} else if (count_records('role', 'name', $name)) {
} else if ($DB->count_records('role', array('name'=>$name))) {
$errors['name'] = get_string('errorexistsrolename', 'role');
}
if (empty($shortname)) {
$errors['shortname'] = get_string('errorbadroleshortname', 'role');
} else if (count_records('role', 'shortname', $shortname)) {
} else if ($DB->count_records('role', array('shortname'=>$shortname))) {
$errors['shortname'] = get_string('errorexistsroleshortname', 'role');
}
@@ -142,7 +145,7 @@
if (empty($name)) {
$errors['name'] = get_string('errorbadrolename', 'role');
} else if ($rs = get_records('role', 'name', $name)) {
} else if ($rs = $DB->get_records('role', array('name'=>$name))) {
unset($rs[$roleid]);
if (!empty($rs)) {
$errors['name'] = get_string('errorexistsrolename', 'role');
@@ -151,7 +154,7 @@
if (empty($shortname)) {
$errors['shortname'] = get_string('errorbadroleshortname', 'role');
} else if ($rs = get_records('role', 'shortname', $shortname)) {
} else if ($rs = $DB->get_records('role', array('shortname'=>$shortname))) {
unset($rs[$roleid]);
if (!empty($rs)) {
$errors['shortname'] = get_string('errorexistsroleshortname', 'role');
@@ -190,11 +193,13 @@
}
// edit default caps
$SQL = "SELECT * FROM {$CFG->prefix}role_capabilities
WHERE roleid = $roleid AND capability = '$capname'
AND contextid = $sitecontext->id";
$SQL = "SELECT *
FROM {role_capabilities}
WHERE roleid = ? AND capability = ?
AND contextid = ?";
$params = array($roleid, $capname, $sitecontext->id);
$localoverride = get_record_sql($SQL);
$localoverride = $DB->get_record_sql($SQL, $params);
if ($localoverride) { // update current overrides
if ($value == CAP_INHERIT) { // inherit = delete
@@ -204,7 +209,7 @@
$localoverride->permission = $value;
$localoverride->timemodified = time();
$localoverride->modifierid = $USER->id;
update_record('role_capabilities', $localoverride);
$DB->update_record('role_capabilities', $localoverride);
}
} else { // insert a record
if ($value != CAP_INHERIT) {
@@ -221,7 +226,7 @@
$role->shortname = $shortname;
$role->description = $description;
if (!update_record('role', $role)) {
if (!$DB->update_record('role', $role)) {
print_error('cannotupdaterole', 'error');
}
@@ -331,7 +336,7 @@
}
// duplicate current role
$sourcerole = get_record('role','id',$roleid);
$sourcerole = $DB->get_record('role', array('id'=>$roleid));
$fullname = $sourcerole->name;
$shortname = $sourcerole->shortname;
@@ -351,8 +356,8 @@
$currentfullname = $fullname.$suffixfull;
// Limit the size of shortname - database column accepts <= 100 chars
$currentshortname = substr($shortname, 0, 100 - strlen($suffixshort)).$suffixshort;
$coursefull = get_record("role","name",addslashes($currentfullname));
$courseshort = get_record("role","shortname",addslashes($currentshortname));
$coursefull = $DB->get_record("role", array("name"=>$currentfullname));
$courseshort = $DB->get_record("role", array("shortname"=>$currentshortname));
$counter++;
} while ($coursefull || $courseshort);
@@ -365,7 +370,7 @@
mark_context_dirty($sitecontext->path);
}
$rolename = get_field('role', 'name', 'id', $newrole);
$rolename = $DB->get_field('role', 'name', array('id'=>$newrole));
add_to_log(SITEID, 'role', 'duplicate', 'admin/roles/manage.php?roleid='.$newrole.'&action=duplicate', $rolename, '', $USER->id);
redirect('manage.php');
break;
@@ -430,12 +435,12 @@
$role->description = '';
$role->legacytype = '';
} else {
$role = stripslashes_safe($newrole);
$role = $newrole;
}
} else if ($action == 'edit' and !empty($errors) and !empty($newrole)) {
$role = stripslashes_safe($newrole);
$role = $newrole;
} else {
if(!$role = get_record('role', 'id', $roleid)) {
if(!$role = $DB->get_record('role', array('id'=>$roleid))) {
print_error('wrongroleid', 'error');
}
$role->legacytype = get_legacy_type($role->id);
+15 -8
View File
@@ -2,7 +2,12 @@
require_once('../config.php');
$zone = optional_param('zone', '', PARAM_PATH); //not a path, but it looks like it anyway
$zone = optional_param('zone', '', PARAM_RAW);
if (!is_numeric($zone)) {
//not a path, but it looks like it anyway
$zone = clean_param($zone, PARAM_PATH);
}
require_login();
@@ -17,24 +22,26 @@
print_heading("");
if (!empty($zone) and confirm_sesskey()) {
$db->debug = true;
if (data_submitted() and !empty($zone) and confirm_sesskey()) {
echo "<center>";
execute_sql("UPDATE {$CFG->prefix}user SET timezone = '$zone'");
$db->debug = false;
$DB->execute("UPDATE {user} SET timezone = ?", array($zone));
echo "</center>";
$USER->timezone = $zone;
$current = $zone;
notify('Timezone of all users changed', 'notifysuccess');
} else {
$current = 99;
}
require_once($CFG->dirroot.'/calendar/lib.php');
$timezones = get_list_of_timezones();
echo '<center><form action="timezone.php" method="get">';
echo '<center><form action="timezone.php" method="post">';
echo "$strusers ($strall): ";
choose_from_menu ($timezones, "zone", 99, get_string("serverlocaltime"), "", "99");
choose_from_menu ($timezones, "zone", $current, get_string("serverlocaltime"), "", "99");
echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
echo "<input type=\"submit\" value=\"$strsavechanges\" />";
echo '<input type="submit" value="'.s($strsavechanges).'" />';
echo "</form></center>";
print_footer();
@@ -76,7 +76,10 @@ class check_bigints extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $db;
global $CFG, $XMLDB, $db, $DB;
$dbman = $DB->get_manager();
$dbfamily = $DB->get_dbfamily();
/// And we nedd some ddl suff
require_once ($CFG->libdir . '/ddllib.php');
@@ -85,7 +88,7 @@ class check_bigints extends XMLDBAction {
$wrong_fields = array();
/// Correct fields must be type bigint for MySQL and int8 for PostgreSQL
switch ($CFG->dbfamily) {
switch ($dbfamily) {
case 'mysql':
$correct_type = 'bigint';
break;
@@ -106,7 +109,7 @@ class check_bigints extends XMLDBAction {
$o = '<table class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmcheckbigints'] . '</p>';
if ($CFG->dbfamily == 'mysql') {
if ($dbfamily == 'mysql') {
$o.= ' <p class="centerpara">' . $this->str['mysqlextracheckbigints'] . '</p>';
}
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
@@ -140,10 +143,6 @@ class check_bigints extends XMLDBAction {
}
/// Load the XML file
$xmldb_file = new XMLDBFile($dbdir->path . '/install.xml');
/// Load the needed XMLDB generator
$classname = 'XMLDB' . $CFG->dbtype;
$generator = new $classname();
$generator->setPrefix($CFG->prefix);
/// Only if the file exists
if (!$xmldb_file->fileExists()) {
@@ -164,13 +163,11 @@ class check_bigints extends XMLDBAction {
/// Foreach table, process its fields
foreach ($xmldb_tables as $xmldb_table) {
/// Skip table if not exists
if (!table_exists($xmldb_table)) {
if (!$dbman->table_exists($xmldb_table)) {
continue;
}
/// Fetch metadata from phisical DB. All the columns info.
if ($metacolumns = $db->MetaColumns($CFG->prefix . $xmldb_table->getName())) {
$metacolumns = array_change_key_case($metacolumns, CASE_LOWER);
} else {
if (!$metacolumns = $DB->get_columns($xmldb_table->getName())) {
//// Skip table if no metacolumns is available for it
continue;
}
@@ -193,7 +190,7 @@ class check_bigints extends XMLDBAction {
/// Going to check this field in DB
$o.=' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' ';
/// Detect if the phisical field is wrong and, under mysql, check for incorrect signed fields too
if ($metacolumn->type != $correct_type || ($CFG->dbfamily == 'mysql' && $xmldb_field->getUnsigned() && !$metacolumn->unsigned)) {
if ($metacolumn->type != $correct_type || ($dbfamily == 'mysql' && $xmldb_field->getUnsigned() && !$metacolumn->unsigned)) {
$o.='<font color="red">' . $this->str['wrong'] . '</font>';
/// Add the wrong field to the list
$obj = new object;
@@ -233,18 +230,22 @@ class check_bigints extends XMLDBAction {
$xmldb_table = $obj->table;
$xmldb_field = $obj->field;
/// MySQL directly supports this
if ($CFG->dbfamily == 'mysql') {
$sqlarr = $xmldb_table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $xmldb_field, true);
// TODO: move this hack to generators!!
if ($dbfamily == 'mysql') {
$sqlarr = $dbman->generator->getAlterFieldSQL($xmldb_table, $xmldb_field);
/// PostgreSQL (XMLDB implementation) is a bit, er... imperfect.
} else if ($CFG->dbfamily == 'postgres') {
$sqlarr = array('ALTER TABLE ' . $CFG->prefix . $xmldb_table->getName() .
} else if ($dbfamily == 'postgres') {
$sqlarr = array('ALTER TABLE ' . $DB->get_prefix() . $xmldb_table->getName() .
' ALTER COLUMN ' . $xmldb_field->getName() . ' TYPE BIGINT;');
}
$r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
$this->str['field'] . ': ' . $xmldb_field->getName() . '</li>';
/// Add to output if we have sentences
if ($sqlarr) {
$s.= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />';
$sqlarr = $dbman->generator->getEndedStatements($sqlarr);
$s.= '<code>' . str_replace("\n", implode('<br />', $sqlarr)). '</code><br />';
}
}
$r.= ' </ul>';
@@ -26,7 +26,7 @@
/// This class will check all the default values existing in the DB
/// match those specified in the xml specs
/// and providing one SQL script to fix all them.
/// and providing one SQL script to fix all them.
class check_defaults extends XMLDBAction {
@@ -76,10 +76,11 @@ class check_defaults extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $db;
global $CFG, $XMLDB, $DB;
/// And we nedd some ddl suff
require_once ($CFG->libdir . '/ddllib.php');
$dbman = $DB->get_manager();
/// Here we'll acummulate all the wrong fields found
$wrong_fields = array();
@@ -125,10 +126,6 @@ class check_defaults extends XMLDBAction {
}
/// Load the XML file
$xmldb_file = new XMLDBFile($dbdir->path . '/install.xml');
/// Load the needed XMLDB generator
$classname = 'XMLDB' . $CFG->dbtype;
$generator = new $classname();
$generator->setPrefix($CFG->prefix);
/// Only if the file exists
if (!$xmldb_file->fileExists()) {
@@ -142,7 +139,7 @@ class check_defaults extends XMLDBAction {
}
/// Arriving here, everything is ok, get the XMLDB structure
$structure = $xmldb_file->getStructure();
//echo "<pre>"; print_r( $structure ); die;
$o.=' <li>' . str_replace($CFG->dirroot . '/', '', $dbdir->path . '/install.xml');
/// Getting tables
if ($xmldb_tables = $structure->getTables()) {
@@ -150,14 +147,11 @@ class check_defaults extends XMLDBAction {
/// Foreach table, process its fields
foreach ($xmldb_tables as $xmldb_table) {
/// Skip table if not exists
if (!table_exists($xmldb_table)) {
if (!$dbman->table_exists($xmldb_table)) {
continue;
}
/// Fetch metadata from phisical DB. All the columns info.
if ($metacolumns = $db->MetaColumns($CFG->prefix . $xmldb_table->getName())) {
$metacolumns = array_change_key_case($metacolumns, CASE_LOWER);
// echo "<pre>".$xmldb_table->getName(); print_r( $metacolumns ); die;
} else {
if (!$metacolumns = $DB->get_columns($xmldb_table->getName())) {
//// Skip table if no metacolumns is available for it
continue;
}
@@ -167,33 +161,32 @@ class check_defaults extends XMLDBAction {
if ($xmldb_fields = $xmldb_table->getFields()) {
$o.=' <ul>';
foreach ($xmldb_fields as $xmldb_field) {
//echo "<pre>"; print_r( $xmldb_field ); die;
// Get the default value for the field
$xmldbdefault = $xmldb_field->getDefault();
/// If the metadata for that column doesn't exist, skip
if (!isset($metacolumns[$xmldb_field->getName()])) {
continue;
}
// Get the default value for the field
$xmldbdefault = $xmldb_field->getDefault();
/// To variable for better handling
$metacolumn = $metacolumns[$xmldb_field->getName()];
/// If the metadata for that column doesn't exist or 'id' field found, skip
if (!isset($metacolumns[$xmldb_field->getName()]) or $xmldb_field->getName() == 'id') {
continue;
}
/// Going to check this field in DB
$o.=' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' ';
/// To variable for better handling
$metacolumn = $metacolumns[$xmldb_field->getName()];
// get the value of the physical default (or blank if there isn't one)
if ($metacolumn->has_default==1) {
$physicaldefault = $metacolumn->default_value;
}
else {
$physicaldefault = '';
}
/// Going to check this field in DB
$o.=' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' ';
// there *is* a default and it's wrong
if ($physicaldefault != $xmldbdefault) {
$info = '['.$this->str['shouldbe']." '$xmldbdefault' ".$this->str['butis'].
// get the value of the physical default (or blank if there isn't one)
if ($metacolumn->has_default==1) {
$physicaldefault = $metacolumn->default_value;
}
else {
$physicaldefault = '';
}
// there *is* a default and it's wrong
if ($physicaldefault != $xmldbdefault) {
$info = '['.$this->str['shouldbe']." '$xmldbdefault' ".$this->str['butis'].
" '$physicaldefault']";
$o.='<font color="red">' . $this->str['wrong'] . " $info</font>";
/// Add the wrong field to the list
@@ -237,9 +230,9 @@ class check_defaults extends XMLDBAction {
$xmldb_field = $obj->field;
$physicaldefault = $obj->physicaldefault;
$xmldbdefault = $obj->xmldbdefault;
// get the alter table command
$sqlarr = $xmldb_table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $xmldb_field, true);
$sqlarr = $dbman->generator->getAlterFieldSQL($xmldb_table, $xmldb_field);
$r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
$this->str['field'] . ': ' . $xmldb_field->getName() . ', ' .
@@ -247,6 +240,7 @@ class check_defaults extends XMLDBAction {
$this->str['butis'] . ' ' . "'$physicaldefault'" . '</li>';
/// Add to output if we have sentences
if ($sqlarr) {
$sqlarr = $dbman->generator->getEndedStatements($sqlarr);
$s.= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />';
}
}
@@ -74,7 +74,9 @@ class check_indexes extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB;
global $CFG, $XMLDB, $DB;
$dbman = $DB->get_manager();
/// And we nedd some ddl suff
require_once ($CFG->libdir . '/ddllib.php');
@@ -123,10 +125,6 @@ class check_indexes extends XMLDBAction {
}
/// Load the XML file
$xmldb_file = new XMLDBFile($dbdir->path . '/install.xml');
/// Load the needed XMLDB generator
$classname = 'XMLDB' . $CFG->dbtype;
$generator = new $classname();
$generator->setPrefix($CFG->prefix);
/// Only if the file exists
if (!$xmldb_file->fileExists()) {
@@ -147,7 +145,7 @@ class check_indexes extends XMLDBAction {
/// Foreach table, process its indexes and keys
foreach ($xmldb_tables as $xmldb_table) {
/// Skip table if not exists
if (!table_exists($xmldb_table)) {
if (!$dbman->table_exists($xmldb_table)) {
continue;
}
$o.=' <li>' . $xmldb_table->getName();
@@ -163,7 +161,7 @@ class check_indexes extends XMLDBAction {
}
/// If we aren't creating the keys or the key is a XMLDB_KEY_FOREIGN (not underlying index generated
/// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists)
if (!$generator->getKeySQL($xmldb_table, $xmldb_key) || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) {
if (!$dbman->generator->getKeySQL($xmldb_table, $xmldb_key) || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) {
/// Create the interim index
$xmldb_index = new XMLDBIndex('anyname');
$xmldb_index->setFields($xmldb_key->getFields());
@@ -177,7 +175,7 @@ class check_indexes extends XMLDBAction {
break;
}
/// Check if the index exists in DB
if (index_exists($xmldb_table, $xmldb_index)) {
if ($dbman->index_exists($xmldb_table, $xmldb_index)) {
$o.='<font color="green">' . $this->str['ok'] . '</font>';
} else {
$o.='<font color="red">' . $this->str['missing'] . '</font>';
@@ -198,7 +196,7 @@ class check_indexes extends XMLDBAction {
foreach ($xmldb_indexes as $xmldb_index) {
$o.=' <li>' . $this->str['index'] . ': ' . $xmldb_index->readableInfo() . ' ';
/// Check if the index exists in DB
if (index_exists($xmldb_table, $xmldb_index)) {
if ($dbman->index_exists($xmldb_table, $xmldb_index)) {
$o.='<font color="green">' . $this->str['ok'] . '</font>';
} else {
$o.='<font color="red">' . $this->str['missing'] . '</font>';
@@ -237,11 +235,12 @@ class check_indexes extends XMLDBAction {
foreach ($missing_indexes as $obj) {
$xmldb_table = $obj->table;
$xmldb_index = $obj->index;
$sqlarr = $xmldb_table->getAddIndexSQL($CFG->dbtype, $CFG->prefix, $xmldb_index, true);
$sqlarr = $dbman->generator->getAddIndexSQL($xmldb_table, $xmldb_index);
$r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
$this->str['index'] . ': ' . $xmldb_index->readableInfo() . '</li>';
$sqlarr = $dbman->generator->getEndedStatements($sqlarr);
$s.= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />';
}
$r.= ' </ul>';
/// Add the SQL statements (all together)
@@ -103,7 +103,7 @@ class edit_statement extends XMLDBAction {
/// Add the main form
$o = '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$o.= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="statement" value="' . $statementparam .'" />';
$o.= ' <input type="hidden" name ="action" value="edit_statement_save" />';
@@ -103,7 +103,7 @@ class edit_table extends XMLDBAction {
/// Add the main form
$o = '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$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" />';
@@ -150,17 +150,8 @@ class edit_table extends XMLDBAction {
$b .= '</p>';
$o .= $b;
/// Join all the reserved words into one big array
/// Calculate list of available SQL generators
$plugins = get_list_of_plugins('lib/xmldb/classes/generators');
$reserved_words = array();
foreach($plugins as $plugin) {
$classname = 'XMLDB' . $plugin;
$generator = new $classname();
$reserved_words = array_merge($reserved_words, $generator->getReservedWords());
}
sort($reserved_words);
$reserved_words = array_unique($reserved_words);
require("$CFG->libdir/ddl/sql_generator.php");
$reserved_words = sql_generator::getAllReservedWords();
/// Delete any 'changeme' field/key/index
$table->deleteField('changeme');
@@ -205,7 +196,7 @@ class edit_table extends XMLDBAction {
$b .= '[' . $this->str['delete'] . ']';
}
/// Detect if the table name is a reserved word
if (in_array($field->getName(), $reserved_words)) {
if (array_key_exists($field->getName(), $reserved_words)) {
$b .= '&nbsp;<a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>';
}
/// The readable info
@@ -72,7 +72,7 @@ class edit_xml_file extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB;
global $CFG, $XMLDB, $DB;
/// Do the job, setting $result as needed
@@ -127,7 +127,7 @@ class edit_xml_file extends XMLDBAction {
/// The new table button
$b .= '&nbsp;<a href="index.php?action=new_table&amp;postaction=edit_table&amp;table=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtable'] . ']</a>';
/// The new from MySQL button
if ($CFG->dbfamily == 'mysql') {
if ($DB->get_dbfamily() == 'mysql') {
$b .= '&nbsp;<a href="index.php?action=new_table_from_mysql&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtablefrommysql'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['newtablefrommysql'] . ']';
@@ -146,17 +146,12 @@ class edit_xml_file extends XMLDBAction {
$o .= $b;
/// Join all the reserved words into one big array
/// Calculate list of available SQL generators
$plugins = get_list_of_plugins('lib/xmldb/classes/generators');
$reserved_words = array();
foreach($plugins as $plugin) {
$classname = 'XMLDB' . $plugin;
$generator = new $classname();
$reserved_words = array_merge($reserved_words, $generator->getReservedWords());
}
sort($reserved_words);
$reserved_words = array_unique($reserved_words);
require("$CFG->libdir/ddl/sql_generator.php");
$reserved_words = sql_generator::getAllReservedWords();
/// Add the tables list
$tables =& $structure->getTables();
$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">';
@@ -190,7 +185,7 @@ class edit_xml_file extends XMLDBAction {
$b .= '[' . $this->str['delete'] . ']';
}
/// Detect if the table name is a reserved word
if (in_array($table->getName(), $reserved_words)) {
if (array_key_exists($table->getName(), $reserved_words)) {
$b .= '&nbsp;<a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>';
}
$b .= '</td>';
@@ -95,7 +95,7 @@ class load_xml_file extends XMLDBAction {
$loaded = $xmldb_file->loadXMLStructure();
if ($loaded && $xmldb_file->isLoaded()) {
$dbdir->xml_loaded = true;
$dbdir->filemtime = filemtime($dbdir->path . '/install.xml');
$dbdir->filemtime = filemtime($dbdir->path . '/install.xml');
}
$dbdir->xml_file = $xmldb_file;
} else {
@@ -68,7 +68,7 @@ class main_view extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $SESSION;
global $CFG, $XMLDB, $SESSION, $DB;
/// Get lastused
$o = '';
@@ -92,7 +92,7 @@ class main_view extends XMLDBAction {
/// The check defaults button
$b .= '&nbsp;<a href="index.php?action=check_defaults">[' . $this->str['checkdefaults'] . ']</a>';
/// The check bigints button (only for MySQL and PostgreSQL) MDL-11038a
if ($CFG->dbfamily == 'mysql' || $CFG->dbfamily == 'postgres') {
if ($DB->get_dbfamily() == 'mysql' || $DB->get_dbfamily() == 'postgres') {
$b .= '&nbsp;<a href="index.php?action=check_bigints">[' . $this->str['checkbigints'] . ']</a>';
}
$b .= '</p>';
@@ -60,7 +60,7 @@ class new_statement extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $db;
global $CFG, $XMLDB, $DB;
/// Do the job, setting result as needed
/// Get the dir containing the file
@@ -86,12 +86,7 @@ class new_statement extends XMLDBAction {
/// No postaction here
$this->postaction = NULL;
/// Get list of tables
$dbtables = $db->MetaTables('TABLES');
$selecttables = array();
foreach ($dbtables as $dbtable) {
$dbtable = str_replace($CFG->prefix, '', $dbtable);
$selecttables[$dbtable] = $dbtable;
}
$selecttables = $DB->get_tables();
/// Get list of statement types
$typeoptions = array (XMLDB_STATEMENT_INSERT => XMLDBStatement::getXMLDBStatementName(XMLDB_STATEMENT_INSERT),
XMLDB_STATEMENT_UPDATE => XMLDBStatement::getXMLDBStatementName(XMLDB_STATEMENT_UPDATE),
@@ -60,7 +60,7 @@ class new_table_from_mysql extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $db;
global $CFG, $XMLDB, $DB;
/// Do the job, setting result as needed
/// Get the dir containing the file
@@ -85,10 +85,9 @@ class new_table_from_mysql extends XMLDBAction {
/// No postaction here
$this->postaction = NULL;
/// Get list of tables
$dbtables = $db->MetaTables('TABLES');
$dbtables = $DB->get_tables();
$selecttables = array();
foreach ($dbtables as $dbtable) {
$dbtable = strtolower(str_replace($CFG->prefix, '', $dbtable));
$i = $structure->findTableInArray($dbtable);
if ($i === NULL) {
$selecttables[$dbtable] = $dbtable;
@@ -132,14 +131,11 @@ class new_table_from_mysql extends XMLDBAction {
$table = new XMLDBTable(strtolower(trim($tableparam)));
$table->setComment($table->getName() . ' table retrofitted from MySQL');
/// Get fields info from ADODb
if(!$dbfields = $db->MetaColumns($CFG->prefix . $tableparam)) {
///Try it without prefix if doesn't exist
$dbfields = $db->MetaColumns($tableparam);
}
$dbfields = $DB->get_columns($tableparam);
if ($dbfields) {
foreach ($dbfields as $dbfield) {
/// Create new XMLDB field
$field = new XMLDBField(strtolower($dbfield->name));
$field = new XMLDBField($dbfield->name);
/// Set field with info retrofitted
$field->setFromADOField($dbfield);
/// Add field to the table
@@ -147,7 +143,7 @@ class new_table_from_mysql extends XMLDBAction {
}
}
/// Get PK, UK and indexes info from ADODb
$dbindexes = $db->MetaIndexes($CFG->prefix . $tableparam, true);
$dbindexes = $DB->get_indexes($tableparam);
if ($dbindexes) {
$lastkey = NULL; //To temp store the last key processed
foreach ($dbindexes as $indexname => $dbindex) {
+194 -187
View File
@@ -58,10 +58,10 @@ class test extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $db;
/// ADD YOUR CODE HERE
require_once ($CFG->libdir . '/ddllib.php');
global $XMLDB, $DB, $CFG;
$dbman = $DB->get_manager();
$gen = $dbman->generator;
$dbfamily = $DB->get_dbfamily();
/// Where all the tests will be stored
$tests = array();
@@ -74,16 +74,16 @@ class test extends XMLDBAction {
/// Silenty drop any previous test tables
$table = new XMLDBTable('testtable');
if (table_exists($table)) {
$status = drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$status = $dbman->drop_table($table, true, false);
}
$table = new XMLDBTable ('anothertest');
if (table_exists($table)) {
$status = drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$status = $dbman->drop_table($table, true, false);
}
$table = new XMLDBTable ('newnameforthetable');
if (table_exists($table)) {
$status = drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$status = $dbman->drop_table($table, true, false);
}
/// 1st test. Complete table creation.
@@ -118,10 +118,10 @@ class test extends XMLDBAction {
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getCreateTableSQL($CFG->dbtype, $CFG->prefix, true);
$test->status = create_table($table, false, false);
$test->sql = $gen->getCreateTableSQL($table);
$test->status = $dbman->create_table($table, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['create table'] = $test;
@@ -129,10 +129,10 @@ class test extends XMLDBAction {
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getDropTableSQL($CFG->dbtype, $CFG->prefix, true);
$test->status = drop_table($table, false, false);
$test->sql = $gen->getDropTableSQL($table);
$test->status = $dbman->drop_table($table, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop table'] = $test;
}
@@ -150,10 +150,10 @@ class test extends XMLDBAction {
$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getCreateTableSQL($CFG->dbtype, $CFG->prefix, true);
$test->status = create_table($table, false, false);
$test->sql = $gen->getCreateTableSQL($table);
$test->status = $dbman->create_table($table, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['create table - 2'] = $test;
}
@@ -164,13 +164,13 @@ class test extends XMLDBAction {
$rec->secondname = 'Dougiamas';
$rec->intro = 'The creator of Moodle';
$rec->grade = 10.0001;
insert_record('anothertest', $rec);
$DB->insert_record('anothertest', $rec);
$rec->course = 2;
$rec->name = 'Eloy';
$rec->secondname = 'Lafuente';
$rec->intro = 'One poor developer';
$rec->grade = 9.99;
insert_record('anothertest', $rec);
$DB->insert_record('anothertest', $rec);
/// 4th test. Adding one complex enum field
if ($test->status) {
@@ -179,10 +179,10 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getAddFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = add_field($table, $field, false, false);
$test->sql = $gen->getAddFieldSQL($table, $field);
$test->status = $dbman->add_field($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add enum field'] = $test;
}
@@ -191,10 +191,10 @@ class test extends XMLDBAction {
if ($test->status) {
/// Create a new field with complex specs (enums are good candidates)
$test = new stdClass;
$test->sql = $table->getDropFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = drop_field($table, $field, false, false);
$test->sql = $gen->getDropFieldSQL($table, $field);
$test->status = $dbman->drop_field($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop enum field'] = $test;
}
@@ -206,10 +206,10 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getAddFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = add_field($table, $field, false, false);
$test->sql = $gen->getAddFieldSQL($table, $field);
$test->status = $dbman->add_field($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add enum field again'] = $test;
}
@@ -221,10 +221,10 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'type');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getAddFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = add_field($table, $field, false, false);
$test->sql = $gen->getAddFieldSQL($table, $field);
$test->status = $dbman->add_field($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add numeric field'] = $test;
}
@@ -234,10 +234,10 @@ class test extends XMLDBAction {
/// Create a new field with complex specs (enums are good candidates)
$field = new XMLDBField('type');
$test = new stdClass;
$test->sql = $table->getDropFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = drop_field($table, $field, false, false);
$test->sql = $gen->getDropFieldSQL($table, $field);
$test->status = $dbman->drop_field($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop enum field again'] = $test;
}
@@ -249,10 +249,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('course');
$field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, '0');
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_type($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_type($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field type (int2char)'] = $test;
}
@@ -264,10 +264,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('course');
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_type($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_type($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field type (char2int)'] = $test;
}
@@ -279,10 +279,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, "test'n drop");
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_type($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_type($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field type (number2char)'] = $test;
}
@@ -294,10 +294,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_FLOAT, '20,10', XMLDB_UNSIGNED, null, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_type($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_type($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field type (char2float)'] = $test;
}
@@ -309,10 +309,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'test');
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_type($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_type($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field type (float2char)'] = $test;
}
@@ -324,10 +324,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_NUMBER, '20,10', XMLDB_UNSIGNED, null, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_type($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_type($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field type (char2number)'] = $test;
}
@@ -340,10 +340,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('intro');
$field->setAttributes(XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_precision($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_precision($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field precision (text)'] = $test;
}
@@ -355,10 +355,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('secondname');
$field->setAttributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_precision($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_precision($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field precision (char)'] = $test;
}
@@ -370,10 +370,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_precision($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_precision($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field precision (number)'] = $test;
}
@@ -385,10 +385,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('course');
$field->setAttributes(XMLDB_TYPE_INTEGER, '5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_precision($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_precision($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field precision (integer) to smaller one'] = $test;
}
@@ -400,10 +400,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_NUMBER, '10,2', XMLDB_UNSIGNED, null, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_unsigned($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_unsigned($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field sign (unsigned)'] = $test;
}
@@ -415,10 +415,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('grade');
$field->setAttributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null, null, null);
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_unsigned($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_unsigned($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field sign (signed)'] = $test;
}
@@ -430,10 +430,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('name');
$field->setAttributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'Moodle');
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_notnull($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_notnull($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field nullability (not null)'] = $test;
}
@@ -445,10 +445,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('name');
$field->setAttributes(XMLDB_TYPE_CHAR, '30', null, null, null, null, null, 'Moodle');
$test->sql = $table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_notnull($table, $field, false, false);
$test->sql = $gen->getAlterFieldSQL($table, $field);
$test->status = $dbman->change_field_notnull($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['change field nullability (null)'] = $test;
}
@@ -460,10 +460,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('name');
$field->setAttributes(XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
$test->sql = $table->getModifyDefaultSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_default($table, $field, false, false);
$test->sql = $gen->getModifyDefaultSQL($table, $field);
$test->status = $dbman->change_field_default($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop field default of NULL field'] = $test;
}
@@ -475,10 +475,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('name');
$field->setAttributes(XMLDB_TYPE_CHAR, '30', null, null, null, null, null, 'Moodle');
$test->sql = $table->getModifyDefaultSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_default($table, $field, false, false);
$test->sql = $gen->getModifyDefaultSQL($table, $field);
$test->status = $dbman->change_field_default($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add field default of NULL field'] = $test;
}
@@ -490,10 +490,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('secondname');
$field->setAttributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null, null, 'Moodle2');
$test->sql = $table->getModifyDefaultSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_default($table, $field, false, false);
$test->sql = $gen->getModifyDefaultSQL($table, $field);
$test->status = $dbman->change_field_default($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add field default of NOT NULL field'] = $test;
}
@@ -506,10 +506,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('secondname');
$field->setAttributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null, null, null);
$test->sql = $table->getModifyDefaultSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_default($table, $field, false, false);
$test->sql = $gen->getModifyDefaultSQL($table, $field);
$test->status = $dbman->change_field_default($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop field default of NOT NULL field'] = $test;
}
@@ -521,10 +521,10 @@ class test extends XMLDBAction {
$index = new XMLDBIndex('secondname');
$index->setAttributes(XMLDB_INDEX_UNIQUE, array('name', 'secondname', 'grade'));
$test->sql = $table->getAddIndexSQL($CFG->dbtype, $CFG->prefix, $index, true);
$test->status = add_index($table, $index, false, false);
$test->sql = $gen->getAddIndexSQL($table, $index);
$test->status = $dbman->add_index($table, $index, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add unique index'] = $test;
}
@@ -536,10 +536,10 @@ class test extends XMLDBAction {
$index = new XMLDBIndex('secondname');
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'name'));
$test->sql = $table->getAddIndexSQL($CFG->dbtype, $CFG->prefix, $index, true);
$test->status = add_index($table, $index, false, false);
$test->sql = $gen->getAddIndexSQL($table, $index);
$test->status = $dbman->add_index($table, $index, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add not unique index'] = $test;
}
@@ -551,7 +551,7 @@ class test extends XMLDBAction {
$index = new XMLDBIndex('secondname');
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('name', 'course'));
if ($indexfound = find_index_name($table, $index)) {
if ($indexfound = $dbman->find_index_name($table, $index)) {
$test->status = true;
$test->sql = array();
} else {
@@ -570,10 +570,10 @@ class test extends XMLDBAction {
$index = new XMLDBIndex('name');
$index->setAttributes(XMLDB_INDEX_UNIQUE, array('name', 'grade', 'secondname'));
$test->sql = $table->getDropIndexSQL($CFG->dbtype, $CFG->prefix, $index, true);
$test->status = drop_index($table, $index, false, false);
$test->sql = $gen->getDropIndexSQL($table, $index);
$test->status = $dbman->drop_index($table, $index, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop index'] = $test;
}
@@ -585,10 +585,10 @@ class test extends XMLDBAction {
$key = new XMLDBKey('id-course-grade');
$key->setAttributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
$test->sql = $table->getAddKeySQL($CFG->dbtype, $CFG->prefix, $key, true);
$test->status = add_key($table, $key, false, false);
$test->sql = $gen->getAddKeySQL($table, $key);
$test->status = $dbman->add_key($table, $key, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add unique key'] = $test;
}
@@ -600,10 +600,10 @@ class test extends XMLDBAction {
$key = new XMLDBKey('course');
$key->setAttributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'anothertest', array('id'));
$test->sql = $table->getAddKeySQL($CFG->dbtype, $CFG->prefix, $key, true);
$test->status = add_key($table, $key, false, false);
$test->sql = $gen->getAddKeySQL($table, $key);
$test->status = $dbman->add_key($table, $key, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add foreign+unique key'] = $test;
}
@@ -615,10 +615,10 @@ class test extends XMLDBAction {
$key = new XMLDBKey('course');
$key->setAttributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'anothertest', array('id'));
$test->sql = $table->getDropKeySQL($CFG->dbtype, $CFG->prefix, $key, true);
$test->status = drop_key($table, $key, false, false);
$test->sql = $gen->getDropKeySQL($table, $key);
$test->status = $dbman->drop_key($table, $key, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop foreign+unique key'] = $test;
}
@@ -630,10 +630,10 @@ class test extends XMLDBAction {
$key = new XMLDBKey('course');
$key->setAttributes(XMLDB_KEY_FOREIGN, array('course'), 'anothertest', array('id'));
$test->sql = $table->getAddKeySQL($CFG->dbtype, $CFG->prefix, $key, true);
$test->status = add_key($table, $key, false, false);
$test->sql = $gen->getAddKeySQL($table, $key);
$test->status = $dbman->add_key($table, $key, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add foreign key'] = $test;
}
@@ -645,10 +645,10 @@ class test extends XMLDBAction {
$key = new XMLDBKey('course');
$key->setAttributes(XMLDB_KEY_FOREIGN, array('course'), 'anothertest', array('id'));
$test->sql = $table->getDropKeySQL($CFG->dbtype, $CFG->prefix, $key, true);
$test->status = drop_key($table, $key, false, false);
$test->sql = $gen->getDropKeySQL($table, $key);
$test->status = $dbman->drop_key($table, $key, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop foreign key'] = $test;
}
@@ -660,11 +660,12 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getAddFieldSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = add_field($table, $field, false, false);
$test->sql = $gen->getAddFieldSQL($table, $field);
$test->status = $dbman->add_field($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add field with enum'] = $test;
}
@@ -674,11 +675,10 @@ class test extends XMLDBAction {
$test = new stdClass;
$field = new XMLDBField('type');
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'general', 'course');
$test->sql = $table->getModifyEnumSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_enum($table, $field, false, false);
$test->sql = $gen->getModifyEnumSQL($table, $field);
$test->status = $dbman->change_field_enum($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['delete enumlist from one field'] = $test;
}
@@ -689,10 +689,10 @@ class test extends XMLDBAction {
$test = new stdClass;
$field = new XMLDBField('type');
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
$test->sql = $table->getModifyEnumSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_enum($table, $field, false, false);
$test->sql = $gen->getModifyEnumSQL($table, $field);
$test->status = $dbman->change_field_enum($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add enumlist to one field'] = $test;
}
@@ -703,13 +703,14 @@ class test extends XMLDBAction {
$test = new stdClass;
$index = new XMLDBIndex('anyname');
$index->setAttributes(XMLDB_INDEX_UNIQUE, array('name', 'course'));
$test->sql = $table->getRenameIndexSQL($CFG->dbtype, $CFG->prefix, $index, 'newnamefortheindex', true);
$test->status = rename_index($table, $index, 'newnamefortheindex', false, false);
$test->sql = $gen->getRenameIndexSQL($table, $index, 'newnamefortheindex');
$test->status = $dbman->rename_index($table, $index, 'newnamefortheindex', false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['rename index (experimental. DO NOT USE IT)'] = $test;
$test = new stdClass;
$test->status = true; // ignore errors here
}
/// 40th test. Renaming one key
@@ -719,12 +720,19 @@ class test extends XMLDBAction {
$key = new XMLDBKey('anyname');
$key->setAttributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
$test->sql = $table->getRenameKeySQL($CFG->dbtype, $CFG->prefix, $key, 'newnameforthekey', true);
$test->status = rename_key($table, $key, 'newnameforthekey', false, false);
$test->sql = $gen->getRenameKeySQL($table, $key, 'newnameforthekey', true);
$olddebug = $CFG->debug;
if ($olddebug > DEBUG_ALL) {
$CFG->debug = DEBUG_ALL; // do not show experimental debug warning
}
$test->status = $dbman->rename_key($table, $key, 'newnameforthekey', false, false);
$CFG->debug = $olddebug;
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['rename key (experimental. DO NOT USE IT)'] = $test;
$test = new stdClass;
$test->status = true; // ignore errors here
}
/// 41th test. Renaming one field
@@ -734,10 +742,10 @@ class test extends XMLDBAction {
$field = new XMLDBField('type');
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
$test->sql = $table->getRenameFieldSQL($CFG->dbtype, $CFG->prefix, $field, 'newnameforthefield', true);
$test->status = rename_field($table, $field, 'newnameforthefield', false, false);
$test->sql = $gen->getRenameFieldSQL($table, $field, 'newnameforthefield', true);
$test->status = $dbman->rename_field($table, $field, 'newnameforthefield', false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['rename field'] = $test;
}
@@ -747,10 +755,10 @@ class test extends XMLDBAction {
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getRenameTableSQL($CFG->dbtype, $CFG->prefix, 'newnameforthetable', true);
$test->status = rename_table($table, 'newnameforthetable', false, false);
$test->sql = $gen->getRenameTableSQL($table, 'newnameforthetable', true);
$test->status = $dbman->rename_table($table, 'newnameforthetable', false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['rename table'] = $test;
}
@@ -763,16 +771,16 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getModifyEnumSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_enum($table, $field, false, false);
$test->sql = $gen->getModifyEnumSQL($table, $field);
$test->status = $dbman->change_field_enum($table, $field, false, false);
/// Let's see if the constraint exists to alter results
if (check_constraint_exists($table, $field)) {
if ($dbman->check_constraint_exists($table, $field)) {
$test->sql = array('Nothing executed. Enum already exists. Correct.');
} else {
$test->status = false;
}
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['add enum to field containing enum'] = $test;
}
@@ -785,10 +793,10 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getModifyEnumSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_enum($table, $field, false, false);
$test->sql = $gen->getModifyEnumSQL($table, $field);
$test->status = $dbman->change_field_enum($table, $field, false, false);
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop enum from field containing enum'] = $test;
}
@@ -801,16 +809,16 @@ class test extends XMLDBAction {
$field->setAttributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $table->getModifyEnumSQL($CFG->dbtype, $CFG->prefix, $field, true);
$test->status = change_field_enum($table, $field, false, false);
$test->sql = $gen->getModifyEnumSQL($table, $field);
$test->status = $dbman->change_field_enum($table, $field, false, false);
/// Let's see if the constraint exists to alter results
if (!check_constraint_exists($table, $field)) {
if (!$dbman->check_constraint_exists($table, $field)) {
$test->sql = array('Nothing executed. Enum does not exists. Correct.');
} else {
$test->status = false;
}
if (!$test->status) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['drop enum from field not containing enum'] = $test;
}
@@ -818,10 +826,10 @@ class test extends XMLDBAction {
/// 46th test. Getting the PK sequence name for one table
if ($test->status) {
$test = new stdClass;
$test->sql = array(find_sequence_name($table));
$test->status = find_sequence_name($table);
$test->sql = array($dbman->find_sequence_name($table));
$test->status = $dbman->find_sequence_name($table);
if (!$test->status) {
if (!$test->error = $db->ErrorMsg()) { //If no db errors, result is ok. Just the driver doesn't support this
if (!$test->error = $DB->get_last_error()) { //If no db errors, result is ok. Just the driver doesn't support this
$test->sql = array('Not needed for this DB. Correct.');
$test->status = true;
}
@@ -843,30 +851,29 @@ class test extends XMLDBAction {
}
/// Build the record to insert
$rec->intro = addslashes($fulltext);
$rec->intro = $fulltext;
$rec->name = 'texttest';
/// Calculate its length
$textlen = $textlib->strlen($fulltext);
if ($rec->id = insert_record('newnameforthetable', $rec)) {
if ($new = get_record('newnameforthetable', 'id', $rec->id)) {
delete_records('newnameforthetable', 'id', $new->id);
if ($rec->id = $DB->insert_record('newnameforthetable', $rec)) {
if ($new = $DB->get_record('newnameforthetable', array('id'=>$rec->id))) {
$DB->delete_records('newnameforthetable', array('id'=>$new->id));
$newtextlen = $textlib->strlen($new->intro);
if ($fulltext === $new->intro) {
$test->sql = array($newtextlen . ' cc. (text) sent and received ok');
$test->status = true;
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
print_object($new);
$test->status = false;
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error().'xx';
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error().'yy'.var_export($rec->id, true);
}
$tests['insert record '. $textlen . ' cc. (text)'] = $test;
}
/// 48th test. Inserting BINARY contents
@@ -874,26 +881,26 @@ class test extends XMLDBAction {
$test = new stdClass;
$test->status = false;
/// Build the record to insert
$rec->avatar = addslashes($fulltext);
$rec->avatar = $fulltext;
$rec->name = 'binarytest';
/// Calculate its length
$textlen = strlen($fulltext);
if ($rec->id = insert_record('newnameforthetable', $rec)) {
if ($new = get_record('newnameforthetable', 'id', $rec->id)) {
if ($rec->id = $DB->insert_record('newnameforthetable', $rec)) {
if ($new = $DB->get_record('newnameforthetable', array('id'=>$rec->id))) {
$newtextlen = strlen($new->avatar);
if ($fulltext === $new->avatar) {
$test->sql = array($newtextlen . ' bytes (binary) sent and received ok');
$test->status = true;
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' bytes (binary) transfer failed. Data changed!');
$test->status = false;
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['insert record '. $textlen . ' bytes (binary)'] = $test;
}
@@ -904,14 +911,14 @@ class test extends XMLDBAction {
$test->status = false;
$test->sql = array();
/// Build the record to insert
$rec->intro = addslashes($basetext);
$rec->avatar = addslashes($basetext);
$rec->intro = $basetext;
$rec->avatar = $basetext;
$rec->name = 'updatelobs';
/// Calculate its length
$textlen = $textlib->strlen($basetext);
$imglen = strlen($basetext);
if (update_record('newnameforthetable', $rec)) {
if ($new = get_record('newnameforthetable', 'id', $rec->id)) {
if ($DB->update_record('newnameforthetable', $rec)) {
if ($new = $DB->get_record('newnameforthetable', array('id'=>$rec->id))) {
$newtextlen = $textlib->strlen($new->intro);
$newimglen = strlen($new->avatar);
if ($basetext === $new->avatar && $basetext === $new->intro) {
@@ -920,20 +927,20 @@ class test extends XMLDBAction {
$test->status = true;
} else {
if ($rec->avatar !== $new->avatar) {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
$test->sql = array($newimglen . ' bytes (binary) transfer failed. Data changed!');
$test->status = false;
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
$test->status = false;
}
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['update record '. $textlen . ' cc. (text) and ' . $imglen . ' bytes (binary)'] = $test;
}
@@ -944,26 +951,26 @@ class test extends XMLDBAction {
$test->status = false;
$test->sql = array();
/// Build the record to insert
$rec->intro = addslashes($fulltext);
$rec->intro = $fulltext;
$rec->name = 'updatelobs';
/// Calculate its length
$textlen = $textlib->strlen($fulltext);
if (set_field('newnameforthetable', 'intro', $rec->intro, 'name', $rec->name)) {
if ($new = get_record('newnameforthetable', 'id', $rec->id)) {
if ($DB->set_field('newnameforthetable', 'intro', $rec->intro, array('name'=>$rec->name))) {
if ($new = $DB->get_record('newnameforthetable', array('id'=>$rec->id))) {
$newtextlen = $textlib->strlen($new->intro);
if ($fulltext === $new->intro) {
$test->sql = array($newtextlen . ' cc. (text) sent and received ok');
$test->status = true;
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
$test->status = false;
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['set field '. $textlen . ' cc. (text)'] = $test;
}
@@ -974,31 +981,31 @@ class test extends XMLDBAction {
$test->status = false;
$test->sql = array();
/// Build the record to insert
$rec->avatar = addslashes($fulltext);
$rec->avatar = $fulltext;
$rec->name = 'updatelobs';
/// Calculate its length
$textlen = strlen($fulltext);
if (set_field('newnameforthetable', 'avatar', $rec->avatar, 'name', $rec->name)) {
if ($new = get_record('newnameforthetable', 'id', $rec->id)) {
if ($DB->set_field('newnameforthetable', 'avatar', $rec->avatar, array('name'=>$rec->name))) {
if ($new = $DB->get_record('newnameforthetable', array('id'=>$rec->id))) {
$newtextlen = strlen($new->avatar);
if ($fulltext === $new->avatar) {
$test->sql = array($newtextlen . ' bytes (binary) sent and received ok');
$test->status = true;
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' bytes (binary) transfer failed. Data changed!');
$test->status = false;
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
} else {
$test->error = $db->ErrorMsg();
$test->error = $DB->get_last_error();
}
$tests['set field '. $textlen . ' bytes (binary)'] = $test;
}
/// TODO: Check here values of the inserted records to see that everything ha the correct value
/// TODO: Check here values of the inserted records to see that everything has the correct value
/// Iterate over tests, showing information as needed
@@ -63,49 +63,27 @@ class view_reserved_words extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB, $db;
global $CFG, $XMLDB, $DB;
/// Calculate list of available SQL generators
$plugins = get_list_of_plugins('lib/xmldb/classes/generators');
$reserved_words = array();
$reserved_words_bydb = array();
foreach($plugins as $plugin) {
$classname = 'XMLDB' . $plugin;
$generator = new $classname();
$reserved_words = array_merge($reserved_words, $generator->getReservedWords());
$reserved_words_bydb[$plugin] = $generator->getReservedWords();
}
sort($reserved_words);
$reserved_words = array_unique($reserved_words);
require("$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->MetaTables('TABLES');
$dbtables = $DB->get_tables();
if ($dbtables) {
foreach ($dbtables as $dbtable) {
$table = str_replace($CFG->prefix, '', $dbtable);
if (in_array($table, $reserved_words)) {
$list_of_db = array();
foreach ($reserved_words_bydb as $key=>$words) {
if (in_array($table, $words)) {
$list_of_db[] = $key;
}
}
$wronguses[] = $this->str['table'] . ' - ' . $table . ' (' . implode(', ',$list_of_db) . ')';
foreach ($dbtables as $table) {
if (array_key_exists($table, $reserved_words)) {
$wronguses[] = $this->str['table'] . ' - ' . $table . ' (' . implode(', ',$reserved_words[$table]) . ')';
}
$dbfields = $db->MetaColumns($dbtable);
$dbfields = $DB->get_columns($table);
if ($dbfields) {
foreach ($dbfields as $dbfield) {
if (in_array($dbfield->name, $reserved_words)) {
$list_of_db = array();
foreach ($reserved_words_bydb as $key=>$words) {
if (in_array($dbfield->name, $words)) {
$list_of_db[] = $key;
}
}
$wronguses[] = $this->str['field'] . ' - ' . $table . '->' . $dbfield->name . ' (' . implode(', ',$list_of_db) . ')';
if (array_key_exists($dbfield->name, $reserved_words)) {
$wronguses[] = $this->str['field'] . ' - ' . $table . '->' . $dbfield->name . ' (' . implode(', ',$reserved_words[$dbfield->name]) . ')';
}
}
}
@@ -135,7 +113,7 @@ class view_reserved_words extends XMLDBAction {
$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(', ', $reserved_words));
$o.= s(implode(', ', array_keys($reserved_words)));
$o.= '</textarea></td></tr>';
$o.= ' </table>';
@@ -58,7 +58,8 @@ class view_structure_sql extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB;
global $CFG, $XMLDB, $DB;
$dbman = $DB->get_manager();
/// Do the job, setting result as needed
/// Get the dir containing the file
@@ -77,23 +78,6 @@ class view_structure_sql extends XMLDBAction {
}
/// ADD YOUR CODE HERE
/// Get parameters
$generatorparam = optional_param('generator', null, PARAM_ALPHANUM);
if (empty($generatorparam)) {
$generatorparam = $CFG->dbtype;
}
/// Calculate list of available SQL generators
$plugins = get_list_of_plugins('lib/xmldb/classes/generators');
$generators = array();
foreach($plugins as $plugin) {
$generators[$plugin] = $plugin;
}
/// Check we have the selected generator
if (!in_array($generatorparam, $generators)) {
$generatorparam = reset($generators);
}
/// The back to edit table button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
@@ -101,15 +85,10 @@ class view_structure_sql extends XMLDBAction {
$o = $b;
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$o.= ' <tr><td align="center">' . $this->str['selectdb'];
/// Show the popup of generators
$url = 'index.php?action=view_structure_sql&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;generator=';
$o.= popup_form($url, $generators, 'selectgenerator', $generatorparam, '', '', '' , true);
$o.= ' </td></tr>';
$o.= ' <tr><td><textarea cols="80" rows="32">';
/// Get an array of statements
if ($starr = $structure->getCreateStructureSQL($generatorparam, $CFG->prefix)) {
if ($starr = $DB->get_manager()->generator->getCreateStructureSQL($structure)) {
$starr = $dbman->generator->getEndedStatements($starr);
$sqltext = '';
foreach ($starr as $st) {
$sqltext .= s($st) . "\n\n";
@@ -650,7 +650,7 @@ class view_table_php extends XMLDBAction {
/**
* This function will generate all the PHP code needed to
* change the enum values (check constraint) of one field
* change the enum values (check constraint) of one field
* using XMLDB objects and functions
*
* @param XMLDBStructure structure object containing all the info
@@ -58,7 +58,8 @@ class view_table_sql extends XMLDBAction {
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $CFG, $XMLDB;
global $CFG, $XMLDB, $DB;
$dbman = $DB->get_manager();
/// Do the job, setting result as needed
/// Get the dir containing the file
@@ -79,25 +80,10 @@ class view_table_sql extends XMLDBAction {
/// Get parameters
$tableparam = required_param('table', PARAM_PATH);
if (!$table =& $structure->getTable($tableparam)) {
$this->errormsg = 'Wrong table specified: ' . $tableparm;
if (!$table = $structure->getTable($tableparam)) {
$this->errormsg = 'Wrong table specified: ' . $tableparam;
return false;
}
$generatorparam = optional_param('generator', null, PARAM_ALPHANUM);
if (empty($generatorparam)) {
$generatorparam = $CFG->dbtype;
}
/// Calculate list of available SQL generators
$plugins = get_list_of_plugins('lib/xmldb/classes/generators');
$generators = array();
foreach($plugins as $plugin) {
$generators[$plugin] = $plugin;
}
/// Check we have the selected generator
if (!in_array($generatorparam, $generators)) {
$generatorparam = reset($generators);
}
/// The back to edit table button
$b = ' <p class="centerpara buttons">';
@@ -106,15 +92,11 @@ class view_table_sql extends XMLDBAction {
$o = $b;
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$o.= ' <tr><td align="center">' . $this->str['selectdb'];
/// Show the popup of generators
$url = 'index.php?action=view_table_sql&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;generator=';
$o.= popup_form($url, $generators, 'selectgenerator', $generatorparam, '', '', '' , true);
$o.= ' </td></tr>';
$o.= ' <tr><td><textarea cols="80" rows="32">';
/// Get an array of statements
if ($starr = $table->getCreateTableSQL($generatorparam, $CFG->prefix)) {
if ($starr = $DB->get_manager()->generator->getCreateTableSQL($table)) {
$starr = $dbman->generator->getEndedStatements($starr);
$sqltext = '';
foreach ($starr as $st) {
$sqltext .= s($st) . "\n\n";
+9 -17
View File
@@ -28,23 +28,21 @@
/// all the actions supported will be launched.
/// Add required XMLDB constants
require_once('../../lib/xmldb/classes/XMLDBConstants.php');
require_once('../../lib/xmldb/XMLDBConstants.php');
/// Add required XMLDB action classes
require_once('actions/XMLDBAction.class.php');
/// Add main XMLDB Generator
require_once('../../lib/xmldb/classes/generators/XMLDBGenerator.class.php');
/// Add required XMLDB DB classes
require_once('../../lib/xmldb/classes/XMLDBObject.class.php');
require_once('../../lib/xmldb/classes/XMLDBFile.class.php');
require_once('../../lib/xmldb/classes/XMLDBStructure.class.php');
require_once('../../lib/xmldb/classes/XMLDBTable.class.php');
require_once('../../lib/xmldb/classes/XMLDBField.class.php');
require_once('../../lib/xmldb/classes/XMLDBKey.class.php');
require_once('../../lib/xmldb/classes/XMLDBIndex.class.php');
require_once('../../lib/xmldb/classes/XMLDBStatement.class.php');
require_once('../../lib/xmldb/XMLDBObject.class.php');
require_once('../../lib/xmldb/XMLDBFile.class.php');
require_once('../../lib/xmldb/XMLDBStructure.class.php');
require_once('../../lib/xmldb/XMLDBTable.class.php');
require_once('../../lib/xmldb/XMLDBField.class.php');
require_once('../../lib/xmldb/XMLDBKey.class.php');
require_once('../../lib/xmldb/XMLDBIndex.class.php');
require_once('../../lib/xmldb/XMLDBStatement.class.php');
/// Add Moodle config script (this is loaded AFTER all the rest
/// of classes because it starts the SESSION and classes to be
@@ -59,12 +57,6 @@
/// Add other used libraries
require_once($CFG->libdir . '/xmlize.php');
/// Add all the available SQL generators
$generators = get_list_of_plugins('lib/xmldb/classes/generators');
foreach($generators as $generator) {
require_once ('../../lib/xmldb/classes/generators/' . $generator . '/' . $generator . '.class.php');
}
/// Handle session data
global $XMLDB;
/// The global SESSION object where everything will happen
+4
View File
@@ -592,6 +592,10 @@ if ( !is_object($PHPCAS_CLIENT) ) {
/// some persistent drivers like ODBTP (mssql) or if this function is invoked
/// from within a PHP application using persistent connections
// configure a temp table
/// TODO: move this to sql generators
error('fix temporary table code in CAS');
print "Configuring temp table\n";
switch (strtolower($CFG->dbfamily)) {
case 'mysql':
+3
View File
@@ -532,6 +532,7 @@ class auth_plugin_ldap extends auth_plugin_base {
// configure a temp table
print "Configuring temp table\n";
error('fix temporary table code in CAS'); // use sql generator
switch (strtolower($CFG->dbfamily)) {
case 'mysql':
$droptablesql[] = 'DROP TEMPORARY TABLE ' . $temptable; // sql command to drop the table (because session scope could be a problem)
@@ -556,6 +557,8 @@ class auth_plugin_ldap extends auth_plugin_base {
break;
}
/// TODO: remove these ugly hacks
error('fix temporary table code in CAS');
execute_sql_arr($droptablesql, true, false); /// Drop temp table to avoid persistence problems later
echo "Creating temp table $temptable\n";
+8 -8
View File
@@ -326,7 +326,7 @@
/// This function upgrades the backup tables, if necessary
/// It's called from admin/index.php, also backup.php and restore.php
global $CFG, $db, $interactive;
global $CFG, $DB, $interactive, $DB;
require_once ("$CFG->dirroot/backup/version.php"); // Get code versions
@@ -344,17 +344,17 @@
upgrade_log_start();
print_heading('backup');
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=true;
$DB->set_debug(true);
}
/// Both old .sql files and new install.xml are supported
/// but we priorize install.xml (XMLDB) if present
$status = false;
if (file_exists($CFG->dirroot . '/backup/db/install.xml')) {
$status = install_from_xmldb_file($CFG->dirroot . '/backup/db/install.xml'); //New method
$status = $DB->get_manager()->install_from_xmldb_file($CFG->dirroot . '/backup/db/install.xml'); //New method
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = false;
$DB->set_debug(false);
}
if ($status) {
if (set_config("backup_version", $backup_version) and set_config("backup_release", $backup_release)) {
@@ -402,16 +402,16 @@
$newupgrade_status = true;
if ($newupgrade && function_exists($newupgrade_function)) {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE) {
$db->debug = true;
$DB->set_debug(true);
}
$newupgrade_status = $newupgrade_function($CFG->backup_version);
} else if ($newupgrade) {
notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
'/backup/db/upgrade.php');
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE) {
$db->debug=false;
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE) {
$DB->set_debug(false);
}
/// Now analyze upgrade results
if ($newupgrade_status) { // No upgrading failed
if (set_config("backup_version", $backup_version) and set_config("backup_release", $backup_release)) {
+2 -2
View File
@@ -8,7 +8,7 @@ class block_admin extends block_list {
function get_content() {
global $CFG, $USER, $SITE, $COURSE;
global $CFG, $USER, $SITE, $COURSE, $DB;
if ($this->content !== NULL) {
return $this->content;
@@ -30,7 +30,7 @@ class block_admin extends block_list {
if ($COURSE->id == $this->instance->pageid) {
$course = $COURSE;
} else {
$course = get_record('course', 'id', $this->instance->pageid);
$course = $DB->get_record('course', array('id'=>$this->instance->pageid));
}
} else {
$context = get_context_instance(CONTEXT_SYSTEM);
-2
View File
@@ -612,9 +612,7 @@
$orderby = ' ORDER BY '. $sort .' ';
//global $db; $db->debug = true;
$records = get_records_sql($SQL . $orderby, $limitfrom, $limitnum);
//$db->debug = false;
if (empty($records)) {
return array();
+2 -2
View File
@@ -158,8 +158,8 @@
}
execute_sql('UPDATE '.$CFG->prefix.'event SET '.
'name = '.$db->qstr($form->name).','.
'description = '.$db->qstr($form->description).','.
'name = '.addslashes($form->name).','.
'description = '.addslashes($form->description).','.
'timestart = '.$timestartoffset.','.
'timeduration = '.$form->timeduration.','.
'timemodified = '.time().' WHERE repeatid = '.$event->repeatid);
+2 -2
View File
@@ -5,7 +5,7 @@ require_once($CFG->libdir.'/formslib.php');
class course_edit_form extends moodleform {
function definition() {
global $USER, $CFG;
global $USER, $CFG, $DB;
$mform =& $this->_form;
@@ -350,7 +350,7 @@ class course_edit_form extends moodleform {
$options['1'] = get_string('yes');
$mform->addElement('select', 'restrictmodules', get_string('restrictmodules'), $options);
$mods = array(0=>get_string('allownone'));
$mods += get_records_menu('modules', '','','','id, name');
$mods += get_records_menu('modules', array() ,'name','id, name');
$mform->addElement('select', 'allowedmods', get_string('to'), $mods,
+3 -3
View File
@@ -1535,7 +1535,7 @@ function print_section_add_menus($course, $section, $modnames, $vertical=false,
* @param boolean $clearonly - only clear the modinfo fields, gets rebuild automatically on the fly
*/
function rebuild_course_cache($courseid=0, $clearonly=false) {
global $COURSE;
global $COURSE, $DB;
if ($clearonly) {
$courseselect = empty($courseid) ? "" : "id = $courseid";
@@ -2581,6 +2581,7 @@ function print_groupmode_setting($form, $course=NULL) {
* Print groupmode form element on module setup forms in mod/.../mod.html
*/
function print_grouping_settings($form, $course=NULL) {
global $DB;
if (empty($course)) {
if (! $course = get_record('course', 'id', $form->course)) {
@@ -2595,13 +2596,12 @@ function print_grouping_settings($form, $course=NULL) {
$cm = null;
}
$groupings = get_records_menu('groupings', 'courseid', $course->id, 'name', 'id, name');
$groupings = $DB->get_records_menu('groupings', array('courseid'=>$course->id), 'name', 'id, name');
if (!empty($groupings)) {
echo '<tr valign="top">';
echo '<td align="right"><b>'.get_string('grouping', 'group').':</b></td>';
echo '<td align="left">';
$groupings;
$groupingid = isset($cm->groupingid) ? $cm->groupingid : 0;
choose_from_menu($groupings, 'groupingid', $groupingid, get_string('none'), '', 0, false);
+1 -1
View File
@@ -19,7 +19,7 @@
function xmldb_enrol_authorize_upgrade($oldversion=0) {
global $CFG, $THEME, $db;
global $CFG, $THEME, $DB;
$result = true;
+13 -13
View File
@@ -42,7 +42,7 @@
}
// security: limit access to existing course subdirectories
if (($args[0]!='blog') and (!$course = get_record_sql("SELECT * FROM {$CFG->prefix}course WHERE id='".(int)$args[0]."'"))) {
if (($args[0]!='blog') and (!$course = $DB->get_record_sql("SELECT * FROM {course} WHERE id=?", array((int)$args[0])))) {
print_error('invalidcourseid');
}
@@ -140,18 +140,18 @@
array_shift($rargs);
$reference = implode('/', $rargs);
$sql = "SELECT COUNT(r.id) " .
"FROM {$CFG->prefix}resource r, " .
"{$CFG->prefix}course_modules cm, " .
"{$CFG->prefix}modules m " .
"WHERE r.course = '{$course->id}' " .
"AND m.name = 'resource' " .
"AND cm.module = m.id " .
"AND cm.instance = r.id " .
"AND cm.visible = 0 " .
"AND r.type = 'file' " .
"AND r.reference = '{$reference}'";
if (count_records_sql($sql)) {
$sql = "SELECT COUNT(r.id)
FROM {resource} r, {course_modules} cm, {modules} m
WHERE r.course = ?
AND m.name = 'resource'
AND cm.module = m.id
AND cm.instance = r.id
AND cm.visible = 0
AND r.type = 'file'
AND r.reference = ?";
$params = array($course->id, $reference);
if ($DB->count_records_sql($sql, $params)) {
print_error('nopermissions');
}
}
-1
View File
@@ -175,7 +175,6 @@ if ($handle = fopen($imported_file['userfile']['tmp_name'], 'r')) {
}
//var_dump($csv_data);
//$db->debug = 3498723498237; // .. very large randomly-typed random value
if ($local_scope) {
$outcome = get_records_select('grade_outcomes', 'shortname = "'. $csv_data[$imported_headers['outcome_shortname']] .'" and courseid = '. $courseid );
+2 -3
View File
@@ -28,7 +28,7 @@ $returnurl = $CFG->wwwroot.'/group/index.php?id='.$courseid;
// Get the course information so we can print the header and
// check the course id is valid
if (!$course = get_record('course', 'id',$courseid)) {
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
$success = false;
print_error('invalidcourse'); //'The course ID is invalid'
}
@@ -141,7 +141,6 @@ echo '<tr>'."\n";
echo "<td>\n";
// NO GROUPINGS YET!
echo '<p><label for="groups"><span id="groupslabel">'.get_string('groups').':</span><span id="thegrouping">&nbsp;</span></label></p>'."\n";
if (ajaxenabled()) {
@@ -166,7 +165,7 @@ if ($groups) {
$select = ' selected="selected"';
$sel_groupid = $group->id;
}
$usercount = (int)count_records('groups_members', 'groupid', $group->id);
$usercount = $DB->count_records('groups_members', array('groupid'=>$group->id));
$groupname = format_string($group->name).' ('.$usercount.')';
echo "<option value=\"{$group->id}\"$select title=\"$groupname\">$groupname</option>\n";
+27 -16
View File
@@ -43,7 +43,7 @@ if (empty($CFG->enablegroupings)) {
$members = array(-1 => array()); //groups not in a grouping
$groupingid = 0;
} else {
if (!$groupings = get_records('groupings', 'courseid', $courseid, 'name')) {
if (!$groupings = $DB->get_records('groupings', array('courseid'=>$courseid), 'name')) {
$groupings = array();
}
$members = array();
@@ -54,32 +54,43 @@ if (empty($CFG->enablegroupings)) {
}
// Get all groups
if (!$groups = get_records('groups', 'courseid', $courseid, 'name')) {
if (!$groups = $DB->get_records('groups', array('courseid'=>$courseid), 'name')) {
$groups = array();
}
$params = array($courseid);
if ($groupid) {
$groupwhere = "AND g.id = ?";
$params[] = $groupid;
} else {
$groupwhere = "";
}
if (empty($CFG->enablegroupings)) {
$groupwhere = $groupid ? "AND g.id = $groupid" : "";
$sql = "SELECT g.id AS groupid, NULL AS groupingid, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username
FROM {$CFG->prefix}groups g
LEFT JOIN {$CFG->prefix}groups_members gm ON g.id = gm.groupid
LEFT JOIN {$CFG->prefix}user u ON gm.userid = u.id
WHERE g.courseid = {$course->id} $groupwhere
FROM {groups} g
LEFT JOIN {groups_members} gm ON g.id = gm.groupid
LEFT JOIN {user} u ON gm.userid = u.id
WHERE g.courseid = ? $groupwhere
ORDER BY g.name, u.lastname, u.firstname";
} else {
$groupingwhere = $groupingid ? "AND gg.groupingid = $groupingid" : "";
$groupwhere = $groupid ? "AND g.id = $groupid" : "";
if ($groupingid) {
$groupingwhere = "AND gg.groupingid = ";
$params[] = $groupingid;
} else {
$groupingwhere = "";
}
$sql = "SELECT g.id AS groupid, gg.groupingid, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username
FROM {$CFG->prefix}groups g
LEFT JOIN {$CFG->prefix}groupings_groups gg ON g.id = gg.groupid
LEFT JOIN {$CFG->prefix}groups_members gm ON g.id = gm.groupid
LEFT JOIN {$CFG->prefix}user u ON gm.userid = u.id
WHERE g.courseid = {$course->id} $groupingwhere $groupwhere
FROM {groups} g
LEFT JOIN {groupings_groups} gg ON g.id = gg.groupid
LEFT JOIN {groups_members} gm ON g.id = gm.groupid
LEFT JOIN {user} u ON gm.userid = u.id
WHERE g.courseid = ? $groupwhere $groupingwhere
ORDER BY g.name, u.lastname, u.firstname";
}
if ($rs = get_recordset_sql($sql)) {
while ($row = rs_fetch_next_record($rs)) {
if ($rs = $DB->get_recordset_sql($sql, $params)) {
foreach ($rs as $row) {
$user = new object();
$user->id = $row->userid;
$user->firstname = $row->firstname;
+2 -2
View File
@@ -193,9 +193,9 @@ function file_exists_and_readable($filepath) {
// Some functions for handling special cases ========================================
function include_help_for_each_module($file, $langs, $helpdir) {
global $CFG;
global $CFG, $DB;
if (!$modules = get_records('modules', 'visible', 1)) {
if (!$modules = $DB->get_records('modules', array('visible'=>1))) {
print_error('nomodules', 'debug'); // Should never happen
}
+2 -2
View File
@@ -139,14 +139,14 @@
/// Print Section
if ($SITE->numsections > 0) {
if (!$section = get_record('course_sections', 'course', $SITE->id, 'section', 1)) {
if (!$section = $DB->get_record('course_sections', array('course'=>$SITE->id, 'section'=>1))) {
delete_records('course_sections', 'course', $SITE->id, 'section', 1); // Just in case
$section->course = $SITE->id;
$section->section = 1;
$section->summary = '';
$section->sequence = '';
$section->visible = 1;
$section->id = insert_record('course_sections', $section);
$section->id = $DB->insert_record('course_sections', $section);
}
if (!empty($section->sequence) or !empty($section->summary) or $editing) {
+252 -351
View File
File diff suppressed because it is too large Load Diff
+56 -50
View File
@@ -42,14 +42,13 @@ function upgrade_blocks_savepoint($result, $version, $type) {
/**
* Upgrade plugins
*
* @uses $db
* @uses $CFG
* @param string $type The type of plugins that should be updated (e.g. 'enrol', 'qtype')
* @param string $dir The directory where the plugins are located (e.g. 'question/questiontypes')
* @param string $return The url to prompt the user to continue to
*/
function upgrade_plugins($type, $dir, $return) {
global $CFG, $db, $interactive;
global $CFG, $interactive, $DB;
/// Let's know if the header has been printed, so the funcion is being called embedded in an outer page
$embedded = defined('HEADER_PRINTED');
@@ -119,7 +118,7 @@ function upgrade_plugins($type, $dir, $return) {
upgrade_log_start();
print_heading($dir.'/'. $plugin->name .' plugin needs upgrading');
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = true;
$DB->set_debug(true);
}
@set_time_limit(0); // To allow slow databases to complete the long SQL
@@ -128,12 +127,12 @@ function upgrade_plugins($type, $dir, $return) {
/// but we priorize install.xml (XMLDB) if present
$status = false;
if (file_exists($fullplug . '/db/install.xml')) {
$status = install_from_xmldb_file($fullplug . '/db/install.xml'); //New method
$status = $DB->get_manager()->install_from_xmldb_file($fullplug . '/db/install.xml'); //New method
} else {
$status = true;
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = false;
$DB->set_debug(false);
}
/// Continue with the instalation, roles and other stuff
if ($status) {
@@ -170,7 +169,7 @@ function upgrade_plugins($type, $dir, $return) {
$newupgrade_status = true;
if ($newupgrade && function_exists($newupgrade_function)) {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = true;
$DB->set_debug(true);
}
$newupgrade_status = $newupgrade_function($CFG->$pluginversion);
} else if ($newupgrade) {
@@ -178,7 +177,7 @@ function upgrade_plugins($type, $dir, $return) {
$fullplug . '/db/upgrade.php');
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=false;
$DB->set_debug(false);
}
/// Now analyze upgrade results
if ($newupgrade_status) { // No upgrading failed
@@ -223,14 +222,13 @@ function upgrade_plugins($type, $dir, $return) {
/**
* Find and check all modules and load them up or upgrade them if necessary
*
* @uses $db
* @uses $CFG
* @param string $return The url to prompt the user to continue to
* @todo Finish documenting this function
*/
function upgrade_activity_modules($return) {
global $CFG, $db, $interactive;
global $CFG, $interactive, $DB;
if (!$mods = get_list_of_plugins('mod') ) {
print_error('No modules installed!');
@@ -289,7 +287,7 @@ function upgrade_activity_modules($return) {
include_once($fullmod.'/lib.php'); // defines upgrading and/or installing functions
if ($currmodule = get_record('modules', 'name', $module->name)) {
if ($currmodule = $DB->get_record('modules', array('name'=>$module->name))) {
if ($currmodule->version == $module->version) {
// do nothing
} else if ($currmodule->version < $module->version) {
@@ -314,7 +312,7 @@ function upgrade_activity_modules($return) {
$newupgrade_status = true;
if ($newupgrade && function_exists($newupgrade_function)) {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = true;
$DB->set_debug(true);
}
$newupgrade_status = $newupgrade_function($currmodule->version, $module);
} else if ($newupgrade) {
@@ -322,13 +320,13 @@ function upgrade_activity_modules($return) {
$mod . ': ' . $fullmod . '/db/upgrade.php');
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=false;
$DB->set_debug(false);
}
/// Now analyze upgrade results
if ($newupgrade_status) { // No upgrading failed
// OK so far, now update the modules record
$module->id = $currmodule->id;
if (! update_record('modules', $module)) {
if (!$DB->update_record('modules', $module)) {
print_error('Could not update '. $module->name .' record in modules table!');
}
remove_dir($CFG->dataroot . '/cache', true); // flush cache
@@ -366,22 +364,22 @@ function upgrade_activity_modules($return) {
$updated_modules = true;
// To avoid unnecessary output from the SQL queries in the CLI version
if (!defined('CLI_UPGRADE')|| !CLI_UPGRADE ) {
$db->debug = true;
$DB->set_debug(true);
}
@set_time_limit(0); // To allow slow databases to complete the long SQL
/// Both old .sql files and new install.xml are supported
/// but we priorize install.xml (XMLDB) if present
if (file_exists($fullmod . '/db/install.xml')) {
$status = install_from_xmldb_file($fullmod . '/db/install.xml'); //New method
$status = $DB->get_manager()->install_from_xmldb_file($fullmod . '/db/install.xml'); //New method
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = false;
$DB->set_debug(false);
}
/// Continue with the installation, roles and other stuff
if ($status) {
if ($module->id = insert_record('modules', $module)) {
if ($module->id = $DB->insert_record('modules', $module)) {
/// Capabilities
if (!update_capabilities('mod/'.$module->name)) {
@@ -461,6 +459,7 @@ function upgrade_activity_modules($return) {
* @return bool true if lock obtained
*/
function set_cron_lock($name, $until, $ignorecurrent=false) {
global $DB;
if (empty($name)) {
debugging("Tried to get a cron lock for a null fieldname");
return false;
@@ -474,7 +473,7 @@ function set_cron_lock($name, $until, $ignorecurrent=false) {
if (!$ignorecurrent) {
// read value from db - other processes might have changed it
$value = get_field('config', 'value', 'name', $name);
$value = $DB->get_field('config', 'value', array('name'=>$name));
if ($value and $value > time()) {
//lock active
@@ -521,7 +520,7 @@ function print_progress($done, $total, $updatetime=5, $sleeptime=1, $donetext=''
}
echo '<script>';
echo 'document.getElementById("text'.$total.'").innerHTML = "'.addslashes($donetext).' ('.$done.'/'.$total.') '.$projectedtext.'";'."\n";
echo 'document.getElementById("text'.$total.'").innerHTML = "'.addslashes_js($donetext).' ('.$done.'/'.$total.') '.$projectedtext.'";'."\n";
echo 'document.getElementById("slider'.$total.'").style.width = \''.$width.'px\';'."\n";
echo '</script>';
@@ -544,7 +543,7 @@ function upgrade_get_javascript() {
}
function create_admin_user($user_input=NULL) {
global $CFG, $USER;
global $CFG, $USER, $DB;
if (empty($CFG->rolesactive)) { // No admin user yet.
@@ -564,11 +563,11 @@ function create_admin_user($user_input=NULL) {
if ($user_input) {
$user = $user_input;
}
if (!$user->id = insert_record('user', $user)) {
if (!$user->id = $DB->insert_record('user', $user)) {
print_error('SERIOUS ERROR: Could not create admin user record !!!');
}
if (!$user = get_record('user', 'id', $user->id)) { // Double check.
if (!$user = $DB->get_record('user', array('id'=>$user->id))) { // Double check.
print_error('User ID was incorrect (can\'t find it)');
}
@@ -2431,6 +2430,7 @@ class admin_setting_sitesetselect extends admin_setting_configselect {
}
function write_setting($data) {
global $DB;
if (!in_array($data, array_keys($this->choices))) {
return get_string('errorsetting', 'admin');
}
@@ -2439,7 +2439,7 @@ class admin_setting_sitesetselect extends admin_setting_configselect {
$temp = $this->name;
$record->$temp = $data;
$record->timemodified = time();
return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin'));
return ($DB->update_record('course', $record) ? '' : get_string('errorsetting', 'admin'));
}
}
@@ -2538,11 +2538,12 @@ class admin_setting_sitesetcheckbox extends admin_setting_configcheckbox {
}
function write_setting($data) {
global $DB;
$record = new object();
$record->id = SITEID;
$record->{$this->name} = ($data == '1' ? 1 : 0);
$record->timemodified = time();
return (update_record('course', $record) ? '' : get_string('errorsetting', 'admin'));
return ($DB->update_record('course', $record) ? '' : get_string('errorsetting', 'admin'));
}
}
@@ -2569,6 +2570,7 @@ class admin_setting_sitesettext extends admin_setting_configtext {
}
function write_setting($data) {
global $DB;
$data = trim($data);
$validated = $this->validate($data);
if ($validated !== true) {
@@ -2577,9 +2579,9 @@ class admin_setting_sitesettext extends admin_setting_configtext {
$record = new object();
$record->id = SITEID;
$record->{$this->name} = addslashes($data);
$record->{$this->name} = $data;
$record->timemodified = time();
return (update_record('course', $record) ? '' : get_string('dbupdatefailed', 'error'));
return ($DB->update_record('course', $record) ? '' : get_string('dbupdatefailed', 'error'));
}
}
@@ -2597,11 +2599,12 @@ class admin_setting_special_frontpagedesc extends admin_setting {
}
function write_setting($data) {
global $DB;
$record = new object();
$record->id = SITEID;
$record->{$this->name} = addslashes($data);
$record->{$this->name} = $data;
$record->timemodified = time();
return(update_record('course', $record) ? '' : get_string('errorsetting', 'admin'));
return($DB->update_record('course', $record) ? '' : get_string('errorsetting', 'admin'));
}
function output_html($data, $query='') {
@@ -3166,14 +3169,14 @@ class admin_setting_special_gradebookroles extends admin_setting_configmultichec
}
function load_choices() {
global $CFG;
global $CFG, $DB;
if (empty($CFG->rolesactive)) {
return false;
}
if (is_array($this->choices)) {
return true;
}
if ($roles = get_records('role')) {
if ($roles = $DB->get_records('role')) {
$this->choices = array();
foreach($roles as $role) {
$this->choices[$role->id] = format_string($role->name);
@@ -3201,7 +3204,7 @@ class admin_setting_special_gradebookroles extends admin_setting_configmultichec
class admin_setting_regradingcheckbox extends admin_setting_configcheckbox {
function write_setting($data) {
global $CFG;
global $CFG, $DB;
$oldvalue = $this->config_read($this->name);
$return = parent::write_setting($data);
@@ -3209,7 +3212,7 @@ class admin_setting_regradingcheckbox extends admin_setting_configcheckbox {
if ($oldvalue !== $newvalue) {
// force full regrading
set_field('grade_items', 'needsupdate', 1, 'needsupdate', 0);
$DB->set_field('grade_items', 'needsupdate', 1, array('needsupdate'=>0));
}
return $return;
@@ -3226,10 +3229,11 @@ class admin_setting_special_coursemanager extends admin_setting_configmulticheck
}
function load_choices() {
global $DB;
if (is_array($this->choices)) {
return true;
}
if ($roles = get_records('role')) {
if ($roles = $DB->get_records('role')) {
$this->choices = array();
foreach($roles as $role) {
$this->choices[$role->id] = format_string($role->name);
@@ -3462,12 +3466,13 @@ class admin_page_managemods extends admin_externalpage {
}
function search($query) {
global $DB;
if ($result = parent::search($query)) {
return $result;
}
$found = false;
if ($modules = get_records('modules')) {
if ($modules = $DB->get_records('modules')) {
$textlib = textlib_get_instance();
foreach ($modules as $module) {
if (strpos($module->name, $query) !== false) {
@@ -3502,13 +3507,13 @@ class admin_page_manageblocks extends admin_externalpage {
}
function search($query) {
global $CFG;
global $CFG, $DB;
if ($result = parent::search($query)) {
return $result;
}
$found = false;
if (!empty($CFG->blocks_version) and $blocks = get_records('block')) {
if (!empty($CFG->blocks_version) and $blocks = $DB->get_records('block')) {
$textlib = textlib_get_instance();
foreach ($blocks as $block) {
if (strpos($block->name, $query) !== false) {
@@ -4151,7 +4156,7 @@ function admin_apply_default_settings($node=NULL, $unconditional=true) {
* @return int number of changed settings
*/
function admin_write_settings($formdata) {
global $CFG, $SITE, $COURSE;
global $CFG, $SITE, $COURSE, $DB;
$olddbsessions = !empty($CFG->dbsessions);
$formdata = (array)stripslashes_recursive($formdata);
@@ -4191,7 +4196,7 @@ function admin_write_settings($formdata) {
}
// now update $SITE - it might have been changed
$SITE = get_record('course', 'id', $SITE->id);
$SITE = $DB->get_record('course', array('id'=>$SITE->id));
$COURSE = clone($SITE);
// now reload all settings - some of them might depend on the changed
@@ -4469,36 +4474,36 @@ function any_new_admin_settings($node) {
/**
* Moved from admin/replace.php so that we can use this in cron
* @param string $search - string to look for (with magic quotes)
* @param string $replace - string to replace (with magic quotes)
* @param string $search - string to look for
* @param string $replace - string to replace
* @return bool - success or fail
*/
function db_replace($search, $replace) {
global $db, $CFG;
global $DB, $CFG;
/// Turn off time limits, sometimes upgrades can be slow.
@set_time_limit(0);
@ob_implicit_flush(true);
while(@ob_end_flush());
if (!$tables = $db->Metatables() ) { // No tables yet at all.
if (!$tables = $DB->get_tables() ) { // No tables yet at all.
return false;
}
foreach ($tables as $table) {
if (in_array($table, array($CFG->prefix.'config'))) { // Don't process these
if (in_array($table, array('config'))) { // Don't process these
continue;
}
if ($columns = $db->MetaColumns($table, false)) {
if ($columns = $DB->get_columns($table)) {
$DB->set_debug(true);
foreach ($columns as $column => $data) {
if (in_array($data->type, array('text','mediumtext','longtext','varchar'))) { // Text stuff only
$db->debug = true;
execute_sql("UPDATE $table SET $column = REPLACE($column, '$search', '$replace');");
$db->debug = false;
if (in_array($data->meta_type, array('C', 'X'))) { // Text stuff only
$DB->execute("UPDATE {$CFG->prefix}$table SET $column = REPLACE($column, ?, ?)", array($search, $replace));
}
}
$DB->set_debug(false);
}
}
@@ -4511,6 +4516,7 @@ function db_replace($search, $replace) {
* distribution or not.
*/
function print_plugin_tables() {
global $DB;
$plugins_standard = array();
$plugins_standard['mod'] = array('assignment',
'chat',
@@ -4571,8 +4577,8 @@ function print_plugin_tables() {
'tidy');
$plugins_installed = array();
$installed_mods = get_records_list('modules', '', '', '', 'name');
$installed_blocks = get_records_list('block', '', '', '', 'name');
$installed_mods = $DB->get_records_list('modules', '', null, '', 'name');
$installed_blocks = $DB->get_records_list('block', '', null, '', 'name');
foreach($installed_mods as $mod) {
$plugins_installed['mod'][] = $mod->name;
+12 -12
View File
@@ -1036,7 +1036,7 @@ function upgrade_blocks_db($continueto) {
/// This function upgrades the blocks tables, if necessary
/// It's called from admin/index.php
global $CFG, $db, $interactive;
global $CFG, $interactive, $DB;
require_once ($CFG->dirroot .'/blocks/version.php'); // Get code versions
@@ -1050,16 +1050,16 @@ function upgrade_blocks_db($continueto) {
upgrade_log_start();
print_heading('blocks');
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=true;
$DB->set_debug(true);
}
/// Both old .sql files and new install.xml are supported
/// but we priorize install.xml (XMLDB) if present
$status = false;
if (file_exists($CFG->dirroot . '/blocks/db/install.xml')) {
$status = install_from_xmldb_file($CFG->dirroot . '/blocks/db/install.xml'); //New method
$status = $DB->get_manager()->install_from_xmldb_file($CFG->dirroot . '/blocks/db/install.xml'); //New method
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = false;
$DB->set_debug(false);
}
if ($status) {
if (set_config('blocks_version', $blocks_version)) {
@@ -1109,7 +1109,7 @@ function upgrade_blocks_db($continueto) {
$newupgrade_status = true;
if ($newupgrade && function_exists($newupgrade_function)) {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = true;
$DB->set_debug(true);
}
$newupgrade_status = $newupgrade_function($CFG->blocks_version);
} else if ($newupgrade) {
@@ -1117,7 +1117,7 @@ function upgrade_blocks_db($continueto) {
'/blocks/db/upgrade.php');
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=false;
$DB->set_debug(false);
}
/// Now analyze upgrade results
if ($newupgrade_status) { // No upgrading failed
@@ -1147,7 +1147,7 @@ function upgrade_blocks_db($continueto) {
//into blocks table or do all the upgrade process if newer
function upgrade_blocks_plugins($continueto) {
global $CFG, $db, $interactive;
global $CFG, $interactive, $DB;
$blocktitles = array();
$invalidblocks = array();
@@ -1270,7 +1270,7 @@ function upgrade_blocks_plugins($continueto) {
$newupgrade_status = true;
if ($newupgrade && function_exists($newupgrade_function)) {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = true;
$DB->set_debug(true);
}
$newupgrade_status = $newupgrade_function($currblock->version, $block);
} else if ($newupgrade) {
@@ -1278,7 +1278,7 @@ function upgrade_blocks_plugins($continueto) {
$fullblock . '/db/upgrade.php');
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=false;
$DB->set_debug(false);
}
/// Now analyze upgrade results
if ($newupgrade_status) { // No upgrading failed
@@ -1343,7 +1343,7 @@ function upgrade_blocks_plugins($continueto) {
upgrade_log_start();
print_heading($block->name);
if (!defined('CLI_UPGRADE')||!CLI_UPGRADE) {
$db->debug = true;
$DB->set_debug(true);
}
@set_time_limit(0); // To allow slow databases to complete the long SQL
@@ -1351,12 +1351,12 @@ function upgrade_blocks_plugins($continueto) {
/// but we priorize install.xml (XMLDB) if present
$status = false;
if (file_exists($fullblock . '/db/install.xml')) {
$status = install_from_xmldb_file($fullblock . '/db/install.xml'); //New method
$status = $DB->get_manager()->install_from_xmldb_file($fullblock . '/db/install.xml'); //New method
} else {
$status = true;
}
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug = false;
$DB->set_debug(false);
}
if ($status) {
if ($block->id = insert_record('block', $block)) {
+41 -60
View File
@@ -1865,7 +1865,7 @@ function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user
// Note that this function intentionally does not follow the normal Moodle DB access idioms.
// This is for a good reason: it is the most frequently used DB update function,
// so it has been optimised for speed.
global $db, $CFG, $USER;
global $DB, $CFG, $USER;
if ($cm === '' || is_null($cm)) { // postgres won't translate empty string to its default
$cm = 0;
@@ -1908,33 +1908,30 @@ function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user
}
$url=addslashes($url);
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; $PERF->logwrites++;};
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->logwrites++;};
if ($CFG->type = 'oci8po') {
if (empty($info)) {
if ($info == '') {
$info = ' ';
}
}
$sql ='INSERT INTO '. $CFG->prefix .'log (time, userid, course, ip, module, cmid, action, url, info)
VALUES (' . "'$timenow', '$userid', '$courseid', '$REMOTE_ADDR', '$module', '$cm', '$action', '$url', '$info')";
$result = $db->Execute($sql);
$log = array('time'=>$timenow, 'userid'=>$userid, 'course'=>$courseid, 'ip'=>$REMOTE_ADDR, 'module'=>$module,
'cmid'=>$cm, 'action'=>$action, 'url'=>$url, 'info'=>$info);
$result = $DB->insert_record_raw('log', $log, false);
// MDL-11893, alert $CFG->supportemail if insert into log failed
if (!$result && $CFG->supportemail) {
if (!$result and $CFG->supportemail and empty($CFG->noemailever)) {
// email_to_user is not usable because email_to_user tries to write to the logs table,
// and this will get caught in an infinite loop, if disk is full
$site = get_site();
$subject = 'Insert into log failed at your moodle site '.$site->fullname;
$message = "Insert into log table failed at ". date('l dS \of F Y h:i:s A') .".\n It is possible that your disk is full.\n\n";
$message .= "The failed SQL is:\n\n" . $sql;
$message .= "The failed query parameters are:\n\n" . var_export($log, true);
// email_to_user is not usable because email_to_user tries to write to the logs table,
// and this will get caught in an infinite loop, if disk is full
if (empty($CFG->noemailever)) {
$lasttime = get_config('admin', 'lastloginserterrormail');
if(empty($lasttime) || time() - $lasttime > 60*60*24) { // limit to 1 email per day
mail($CFG->supportemail, $subject, $message);
set_config('lastloginserterrormail', time(), 'admin');
}
$lasttime = get_config('admin', 'lastloginserterrormail');
if(empty($lasttime) || time() - $lasttime > 60*60*24) { // limit to 1 email per day
mail($CFG->supportemail, $subject, $message);
set_config('lastloginserterrormail', time(), 'admin');
}
}
@@ -1956,7 +1953,7 @@ function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user
*/
function user_accesstime_log($courseid=0) {
global $USER, $CFG, $PERF, $db;
global $USER, $CFG, $DB;
if (!isloggedin() or !empty($USER->realuser)) {
// no access tracking
@@ -1973,18 +1970,14 @@ function user_accesstime_log($courseid=0) {
if ($timenow - $USER->lastaccess > LASTACCESS_UPDATE_SECS) {
/// Update $USER->lastaccess for next checks
$USER->lastaccess = $timenow;
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++;};
$remoteaddr = getremoteaddr();
if ($db->Execute("UPDATE {$CFG->prefix}user
SET lastip = '$remoteaddr', lastaccess = $timenow
WHERE id = $USER->id")) {
} else {
debugging('Error: Could not update global user lastaccess information'); // Don't throw an error
}
/// Remove this record from record cache since it will change
if (!empty($CFG->rcache)) {
rcache_unset('user', $USER->id);
$last = new object();
$last->id = $USER->id;
$last->lastip = getremoteaddr();
$last->lastaccess = $timenow;
if (!$DB->update_record_raw('user', $last)) {
debugging('Error: Could not update global user lastaccess information', DEBUG_ALL); // Don't throw an error
}
}
@@ -1995,43 +1988,31 @@ function user_accesstime_log($courseid=0) {
/// Store course lastaccess times for the current user
if (empty($USER->currentcourseaccess[$courseid]) or ($timenow - $USER->currentcourseaccess[$courseid] > LASTACCESS_UPDATE_SECS)) {
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
$exists = false; // To detect if the user_lastaccess record exists or no
if ($rs = $db->Execute("SELECT timeaccess
FROM {$CFG->prefix}user_lastaccess
WHERE userid = $USER->id AND courseid = $courseid")) {
if (!$rs->EOF) {
$exists = true;
$lastaccess = reset($rs->fields);
if ($timenow - $lastaccess < LASTACCESS_UPDATE_SECS) {
/// no need to update now, it was updated recently in concurrent login ;-)
$rs->Close();
return;
}
$lastaccess = $DB->get_field('user_lastaccess', 'timeaccess', array('userid'=>$USER->id, 'courseid'=>$courseid));
if ($lastaccess === false) {
// Update course lastaccess for next checks
$USER->currentcourseaccess[$courseid] = $timenow;
$last = new object();
$last->userid = $USER->id;
$last->courseid = $courseid;
$last->timeaccess = $timenow;
if (!$DB->insert_record_raw('user_lastaccess', $last, false)) {
debugging('Error: Could not insert course user lastaccess information', DEBUG_ALL); // Don't throw an error
}
$rs->Close();
}
} else if ($timenow - $lastaccess < LASTACCESS_UPDATE_SECS) {
// no need to update now, it was updated recently in concurrent login ;-)
/// Update course lastaccess for next checks
$USER->currentcourseaccess[$courseid] = $timenow;
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
} else {
// Update course lastaccess for next checks
$USER->currentcourseaccess[$courseid] = $timenow;
if ($exists) { // user_lastaccess record exists, update it
if ($db->Execute("UPDATE {$CFG->prefix}user_lastaccess
SET timeaccess = $timenow
WHERE userid = $USER->id AND courseid = $courseid")) {
} else {
if (!$DB->set_field('user_lastaccess', 'timeaccess', $timenow, array('userid'=>$USER->id, 'courseid'=>$courseid))) {
debugging('Error: Could not update course user lastacess information'); // Don't throw an error
}
} else { // user lastaccess record doesn't exist, insert it
if ($db->Execute("INSERT INTO {$CFG->prefix}user_lastaccess
(userid, courseid, timeaccess)
VALUES ($USER->id, $courseid, $timenow)")) {
} else {
debugging('Error: Could not insert course user lastaccess information'); // Don't throw an error
}
}
}
}
+3 -17
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20080307" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20080514" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
@@ -377,7 +377,7 @@
<INDEX NAME="name" UNIQUE="false" FIELDS="name"/>
</INDEXES>
</TABLE>
<TABLE NAME="sessions2" COMMENT="Optional database session storage in new format, not used by default" PREVIOUS="modules" NEXT="adodb_logsql">
<TABLE NAME="sessions2" COMMENT="Optional database session storage in new format, not used by default" PREVIOUS="modules" NEXT="timezone">
<FIELDS>
<FIELD NAME="sesskey" TYPE="char" LENGTH="64" NOTNULL="true" SEQUENCE="false" ENUM="false" NEXT="expiry"/>
<FIELD NAME="expiry" TYPE="datetime" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="sesskey" NEXT="expireref"/>
@@ -394,21 +394,7 @@
<INDEX NAME="expireref" UNIQUE="false" FIELDS="expireref" PREVIOUS="expiry"/>
</INDEXES>
</TABLE>
<TABLE NAME="adodb_logsql" COMMENT="to save some logs from ADOdb" PREVIOUS="sessions2" NEXT="timezone">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="created"/>
<FIELD NAME="created" TYPE="datetime" LENGTH="2" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="sql0"/>
<FIELD NAME="sql0" TYPE="char" LENGTH="250" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="created" NEXT="sql1"/>
<FIELD NAME="sql1" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="sql0" NEXT="params"/>
<FIELD NAME="params" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="sql1" NEXT="tracer"/>
<FIELD NAME="tracer" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" PREVIOUS="params" NEXT="timer"/>
<FIELD NAME="timer" TYPE="number" LENGTH="16" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" DECIMALS="6" PREVIOUS="tracer"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="timezone" COMMENT="Rules for calculating local wall clock time for users" PREVIOUS="adodb_logsql" NEXT="user">
<TABLE NAME="timezone" COMMENT="Rules for calculating local wall clock time for users" PREVIOUS="sessions2" NEXT="user">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="year"/>
+16 -8
View File
@@ -19,10 +19,12 @@
function xmldb_main_upgrade($oldversion=0) {
global $CFG, $THEME, $USER, $db;
global $CFG, $THEME, $USER, $DB;
$result = true;
$dbman = $DB->get_manager(); // loads XSMLDB classes too
////////////////////////////////////////
///upgrade supported only from 1.9.x ///
////////////////////////////////////////
@@ -35,7 +37,7 @@ function xmldb_main_upgrade($oldversion=0) {
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('contextid', 'lowerboundary'));
/// Launch drop index contextid-lowerboundary
$result = $result && drop_index($table, $index);
$result = $result && $dbman->drop_index($table, $index);
/// Define index contextid-lowerboundary-letter (unique) to be added to grade_letters
$table = new XMLDBTable('grade_letters');
@@ -43,7 +45,7 @@ function xmldb_main_upgrade($oldversion=0) {
$index->setAttributes(XMLDB_INDEX_UNIQUE, array('contextid', 'lowerboundary', 'letter'));
/// Launch add index contextid-lowerboundary-letter
$result = $result && add_index($table, $index);
$result = $result && $dbman->add_index($table, $index);
/// Main savepoint reached
upgrade_main_savepoint($result, 2008030700);
@@ -51,7 +53,7 @@ function xmldb_main_upgrade($oldversion=0) {
if ($result && $oldversion < 2008050100) {
// Update courses that used weekscss to weeks
$result = set_field('course', 'format', 'weeks', 'format', 'weekscss');
$result = $DB->set_field('course', 'format', 'weeks', 'format', 'weekscss');
upgrade_main_savepoint($result, 2008050100);
}
@@ -98,8 +100,8 @@ function xmldb_main_upgrade($oldversion=0) {
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
/// Launch drop index idnumber
if (index_exists($table, $index)) {
$result = $result && drop_index($table, $index);
if ($dbman->index_exists($table, $index)) {
$result = $result && $dbman->drop_index($table, $index);
}
/// Changing precision of field idnumber on table user to (255)
@@ -108,17 +110,23 @@ function xmldb_main_upgrade($oldversion=0) {
$field->setAttributes(XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null, 'password');
/// Launch change of precision for field idnumber
$result = $result && change_field_precision($table, $field);
$result = $result && $dbman->change_field_precision($table, $field);
/// Launch add index idnumber again
$index = new XMLDBIndex('idnumber');
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
$result = $result && add_index($table, $index);
$result = $result && $dbman->add_index($table, $index);
/// Main savepoint reached
upgrade_main_savepoint($result, 2008051201);
}
/*
* TODO:
* drop adodb_logsql table and create a ner general sql log table
*
*/
return $result;
}
+18 -18
View File
@@ -8,42 +8,43 @@
*/
function upgrade_fix_category_depths() {
global $CFG, $db;
global $CFG, $DB;
// first fix incorrect parents
$sql = "SELECT c.id
FROM {$CFG->prefix}course_categories c
WHERE c.parent > 0 AND c.parent NOT IN (SELECT pc.id FROM {$CFG->prefix}course_categories pc)";
if ($rs = get_recordset_sql($sql)) {
while ($cat = rs_fetch_next_record($rs)) {
FROM {course_categories} c
WHERE c.parent > 0 AND c.parent NOT IN (SELECT pc.id FROM {course_categories} pc)";
if ($rs = $DB->get_recordset_sql($sql)) {
foreach ($rs as $cat) {
$cat->depth = 1;
$cat->path = '/'.$cat->id;
$cat->parent = 0;
update_record('course_categories', $cat);
$DB->update_record('course_categories', $cat);
}
rs_close($rs);
$rs->close();
}
// now add path and depth to top level categories
$sql = "UPDATE {$CFG->prefix}course_categories
$sql = "UPDATE {course_categories}
SET depth = 1, path = ".sql_concat("'/'", "id")."
WHERE parent = 0";
execute_sql($sql);
$DB->execute($sql);
// now fix all other levels - slow but works in all supported dbs
$parentdepth = 1;
$db->debug = true;
while (record_exists('course_categories', 'depth', 0)) {
while ($DB->record_exists('course_categories', array('depth'=>0))) {
$sql = "SELECT c.id, pc.path
FROM {$CFG->prefix}course_categories c, {$CFG->prefix}course_categories pc
WHERE c.parent=pc.id AND c.depth=0 AND pc.depth=$parentdepth";
if ($rs = get_recordset_sql($sql)) {
while ($cat = rs_fetch_next_record($rs)) {
FROM {course_categories} c, {course_categories} pc
WHERE c.parent=pc.id AND c.depth=0 AND pc.depth=?";
if ($rs = $DB->get_recordset_sql($sql, array($parentdepth))) {
$DB->set_debug(false);
foreach ($rs as $cat) {
$cat->depth = $parentdepth+1;
$cat->path = $cat->path.'/'.$cat->id;
update_record('course_categories', $cat);
$DB->update_record('course_categories', $cat);
}
rs_close($rs);
$rs->close();
$DB->set_debug(false);
}
$parentdepth++;
if ($parentdepth > 100) {
@@ -52,7 +53,6 @@ function upgrade_fix_category_depths() {
break;
}
}
$db->debug = true;
}
?>
File diff suppressed because it is too large Load Diff
@@ -24,67 +24,112 @@
// //
///////////////////////////////////////////////////////////////////////////
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
/// overriden as needed to generate correct SQL.
class XMLDBmssql extends XMLDBgenerator {
class mssql_sql_generator extends sql_generator {
/// Only set values that are different from the defaults present in XMLDBgenerator
var $statement_end = "\ngo"; // String to be automatically added at the end of each statement
public $statement_end = "\ngo"; // String to be automatically added at the end of each statement
var $number_type = 'DECIMAL'; // Proper type for NUMBER(x) in this DB
public $number_type = 'DECIMAL'; // Proper type for NUMBER(x) in this DB
var $unsigned_allowed = false; // To define in the generator must handle unsigned information
var $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
public $unsigned_allowed = false; // To define in the generator must handle unsigned information
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
var $specify_nulls = true; //To force the generator if NULL clauses must be specified. It shouldn't be necessary
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 $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
var $sequence_name = 'IDENTITY(1,1)'; //Particular name for inline sequences in this generator
var $sequence_only = false; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable
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 $enum_inline_code = false; //Does the generator need to add inline code in the column definition
public $enum_inline_code = false; //Does the generator need to add inline code in the column definition
var $add_table_comments = false; // Does the generator need to add code for table comments
public $add_table_comments = false; // Does the generator need to add code for table comments
var $concat_character = '+'; //Characters to be used as concatenation operator. If not defined
public $concat_character = '+'; //Characters to be used as concatenation operator. If not defined
//MySQL CONCAT function will be use
var $rename_table_sql = "sp_rename 'OLDNAME', 'NEWNAME'"; //SQL sentence to rename one table, both
public $rename_table_sql = "sp_rename 'OLDNAME', 'NEWNAME'"; //SQL sentence to rename one table, both
//OLDNAME and NEWNAME are dinamically replaced
var $rename_table_extra_code = true; //Does the generator need to add code after table rename
var $rename_column_extra_code = true; //Does the generator need to add code after field rename
var $rename_column_sql = "sp_rename 'TABLENAME.OLDFIELDNAME', 'NEWFIELDNAME', 'COLUMN'";
public $rename_column_sql = "sp_rename 'TABLENAME.OLDFIELDNAME', 'NEWFIELDNAME', 'COLUMN'";
///TABLENAME, OLDFIELDNAME and NEWFIELDNAME are dianmically replaced
var $drop_index_sql = 'DROP INDEX TABLENAME.INDEXNAME'; //SQL sentence to drop one index
public $drop_index_sql = 'DROP INDEX TABLENAME.INDEXNAME'; //SQL sentence to drop one index
//TABLENAME, INDEXNAME are dinamically replaced
var $rename_index_sql = "sp_rename 'TABLENAME.OLDINDEXNAME', 'NEWINDEXNAME', 'INDEX'"; //SQL sentence to rename one index
public $rename_index_sql = "sp_rename 'TABLENAME.OLDINDEXNAME', 'NEWINDEXNAME', 'INDEX'"; //SQL sentence to rename one index
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dinamically replaced
var $rename_key_sql = null; //SQL sentence to rename one key
public $rename_key_sql = null; //SQL sentence to rename one key
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dinamically replaced
/**
* Creates one new XMLDBmssql
*/
function XMLDBmssql() {
parent::XMLDBgenerator();
$this->prefix = '';
$this->reserved_words = $this->getReservedWords();
public function __construct($mdb) {
parent::__construct($mdb);
}
/**
* This function will create the temporary table passed as argument with all its
* fields/keys/indexes/sequences, everything based in the XMLDB object
*
* TRUNCATE the table immediately after creation. A previous process using
* the same persistent connection may have created the temp table and failed to
* drop it. In that case, the table will exist, and create_temp_table() will
* will succeed.
*
* NOTE: The return value is the tablename - some DBs (MSSQL at least) use special
* names for temp tables.
*
* @uses $CFG, $db
* @param XMLDBTable table object (full specs are required)
* @param boolean continue to specify if must continue on error (true) or stop (false)
* @param boolean feedback to specify to show status info (true) or not (false)
* @return string tablename on success, false on error
*/
function create_temp_table($xmldb_table, $continue=true, $feedback=true) {
if (!($xmldb_table instanceof XMLDBTable)) {
debugging('Incorrect create_table() $xmldb_table parameter');
return false;
}
/// Check table doesn't exist
if ($this->table_exists($xmldb_table)) {
debugging('Table ' . $xmldb_table->getName() .
' already exists. Create skipped', DEBUG_DEVELOPER);
return $xmldb_table->getName(); //Table exists, nothing to do
}
if (!$sqlarr = $this->getCreateTableSQL($xmldb_table)) {
return $xmldb_table->getName(); //Empty array = nothing to do = no error
}
// TODO: somehow change the name to have a #
/*$temporary = '';
if (!empty($temporary)) {
$sqlarr = preg_replace('/^CREATE/', "CREATE $temporary", $sqlarr);
}*/
if (execute_sql_arr($sqlarr, $continue, $feedback)) {
return $xmldb_table->getName();
} else {
return false;
}
}
/**
* Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type
*/
function getTypeSQL ($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
switch ($xmldb_type) {
case XMLDB_TYPE_INTEGER: // From http://msdn.microsoft.com/library/en-us/tsqlref/ts_da-db_7msw.asp?frame=true
@@ -144,7 +189,7 @@ class XMLDBmssql extends XMLDBgenerator {
/**
* Returns the code needed to create one enum for the xmldb_table and xmldb_field passes
*/
function getEnumExtraSQL ($xmldb_table, $xmldb_field) {
public function getEnumExtraSQL($xmldb_table, $xmldb_field) {
$sql = 'CONSTRAINT ' . $this->getNameForObject($xmldb_table->getName(), $xmldb_field->getName(), 'ck');
$sql.= ' CHECK (' . $this->getEncQuoted($xmldb_field->getName()) . ' IN (' . implode(', ', $xmldb_field->getEnumValues()) . '))';
@@ -157,7 +202,7 @@ class XMLDBmssql extends XMLDBgenerator {
* MSSQL overwrites the standard sentence because it needs to do some extra work dropping the default and
* check constraints
*/
function getDropFieldSQL($xmldb_table, $xmldb_field) {
public function getDropFieldSQL($xmldb_table, $xmldb_field) {
global $db;
@@ -189,7 +234,7 @@ class XMLDBmssql extends XMLDBgenerator {
* MSSQL is special, so we overload the function here. It needs to
* drop the constraints BEFORE renaming the field
*/
function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
public function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
$results = array(); //Array where all the sentences will be stored
@@ -218,7 +263,7 @@ class XMLDBmssql extends XMLDBgenerator {
/**
* Returns the code (array of statements) needed to execute extra statements on field rename
*/
function getRenameFieldExtraSQL ($xmldb_table, $xmldb_field, $newname) {
public function getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname) {
$results = array();
@@ -240,7 +285,7 @@ class XMLDBmssql extends XMLDBgenerator {
/**
* Returns the code (array of statements) needed to execute extra statements on table rename
*/
function getRenameTableExtraSQL ($xmldb_table, $newname) {
public function getRenameTableExtraSQL($xmldb_table, $newname) {
$results = array();
@@ -271,21 +316,21 @@ class XMLDBmssql extends XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to alter the field in the table
*/
function getAlterFieldSQL($xmldb_table, $xmldb_field) {
global $db;
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 = $this->getTableName($xmldb_table);
$fieldname = $this->getEncQuoted($xmldb_field->getName());
$tablename = $xmldb_table->getName();
$fieldname = $xmldb_field->getName();
/// Take a look to field metadata
$meta = array_change_key_case($db->MetaColumns($tablename));
$this->mdb->reset_columns($tablename);
$meta = $this->mdb->get_columns($tablename);
$metac = $meta[$fieldname];
$oldtype = strtolower($metac->type);
$oldmetatype = column_type($xmldb_table->getName(), $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;
@@ -295,11 +340,11 @@ class XMLDBmssql extends XMLDBgenerator {
$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 && substr($oldmetatype, 0, 1) == 'I') ||
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 && substr($oldmetatype, 0, 1) == 'C') ||
($xmldb_field->getType() == XMLDB_TYPE_TEXT && substr($oldmetatype, 0, 1) == 'X') ||
($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;
}
@@ -331,20 +376,17 @@ class XMLDBmssql extends XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to modify the default of the field in the table
*/
function getModifyDefaultSQL($xmldb_table, $xmldb_field) {
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
$results = array();
/// 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
if ($xmldb_field->getDefault() === null) {
$results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); //Drop but, under some circumptances, re-enable
if ($this->getDefaultClause($xmldb_field)) { //If getDefaultClause() it must have one default, create it
$default_clause = $this->getDefaultClause($xmldb_field);
if ($default_clause) { //If getDefaultClause() it must have one default, create it
$results = array_merge($results, $this->getCreateDefaultSQL($xmldb_table, $xmldb_field)); //Create/modify
}
} else {
@@ -356,10 +398,10 @@ class XMLDBmssql extends XMLDBgenerator {
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* (usually invoked from getModifyEnumSQL()
*/
function getCreateEnumSQL($xmldb_table, $xmldb_field) {
public function getCreateEnumSQL($xmldb_table, $xmldb_field) {
/// All we have to do is to create the check constraint
return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
' ADD ' . $this->getEnumExtraSQL($xmldb_table, $xmldb_field));
@@ -369,7 +411,7 @@ class XMLDBmssql extends XMLDBgenerator {
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* (usually invoked from getModifyEnumSQL()
*/
function getDropEnumSQL($xmldb_table, $xmldb_field) {
public function getDropEnumSQL($xmldb_table, $xmldb_field) {
/// Let's introspect to know the real name of the check constraint
if ($check_constraints = $this->getCheckConstraintsFromDB($xmldb_table, $xmldb_field)) {
$check_constraint = array_shift($check_constraints); /// Get the 1st (should be only one)
@@ -383,10 +425,10 @@ class XMLDBmssql extends XMLDBgenerator {
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* (usually invoked from getModifyDefaultSQL()
*/
function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
/// MSSQL is a bit special and it requires the corresponding DEFAULT CONSTRAINT to be dropped
$results = array();
@@ -396,19 +438,21 @@ class XMLDBmssql extends XMLDBgenerator {
$fieldname = $this->getEncQuoted($xmldb_field->getName());
/// Now, check if, with the current field attributes, we have to build one default
if ($default_clause = $this->getDefaultClause($xmldb_field)) {
$default_clause = $this->getDefaultClause($xmldb_field);
if ($default_clause) {
/// We need to build the default (Moodle) default, so do it
$results[] = 'ALTER TABLE ' . $tablename . ' ADD' . $default_clause . ' FOR ' . $fieldname;
$sql = 'ALTER TABLE ' . $tablename . ' ADD' . $default_clause . ' FOR ' . $fieldname;
$results[] = $sql;
}
return $results;
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* (usually invoked from getModifyDefaultSQL()
*/
function getDropDefaultSQL($xmldb_table, $xmldb_field) {
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
/// MSSQL is a bit special and it requires the corresponding DEFAULT CONSTRAINT to be dropped
$results = array();
@@ -420,7 +464,7 @@ class XMLDBmssql extends XMLDBgenerator {
/// 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;
}
}
return $results;
}
@@ -430,7 +474,7 @@ class XMLDBmssql extends XMLDBgenerator {
* or false if not found
* This function should be considered internal and never used outside from generator
*/
function getDefaultConstraintName($xmldb_table, $xmldb_field) {
public function getDefaultConstraintName($xmldb_table, $xmldb_field) {
/// Get the quoted name of the table and field
$tablename = $this->getTableName($xmldb_table);
@@ -455,7 +499,7 @@ class XMLDBmssql extends XMLDBgenerator {
* Each element contains the name of the constraint and its description
* If no check constraints are found, returns an empty array
*/
function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
public function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
$results = array();
@@ -498,7 +542,7 @@ class XMLDBmssql extends XMLDBgenerator {
* return if such name is currently in use (true) or no (false)
* (invoked from getNameForObject()
*/
function isNameInUse($object_name, $type, $table_name) {
public function isNameInUse($object_name, $type, $table_name) {
switch($type) {
case 'seq':
case 'trg':
@@ -506,15 +550,15 @@ class XMLDBmssql extends XMLDBgenerator {
case 'uk':
case 'fk':
case 'ck':
if ($check = get_records_sql("SELECT name
FROM sysobjects
if ($check = get_records_sql("SELECT name
FROM sysobjects
WHERE lower(name) = '" . strtolower($object_name) . "'")) {
return true;
}
break;
case 'ix':
case 'uix':
if ($check = get_records_sql("SELECT name
if ($check = get_records_sql("SELECT name
FROM sysindexes
WHERE lower(name) = '" . strtolower($object_name) . "'")) {
return true;
@@ -524,10 +568,23 @@ class XMLDBmssql extends XMLDBgenerator {
return false; //No name in use found
}
/**
* Returns the code (in array) needed to add one comment to the table
*/
public function getCommentSQL($xmldb_table) {
return array();
}
public function addslashes($s) {
// do not use php addslashes() because it depends on PHP quote settings!
$s = str_replace("'", "''", $s);
return $s;
}
/**
* Returns an array of reserved words (lowercase) for this DB
*/
function getReservedWords() {
public static function getReservedWords() {
/// This file contains the reserved words for MSSQL databases
/// from http://msdn2.microsoft.com/en-us/library/ms189822.aspx
$reserved_words = array (
@@ -24,67 +24,66 @@
// //
///////////////////////////////////////////////////////////////////////////
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
/// overriden as needed to generate correct SQL.
class XMLDBmysql extends XMLDBGenerator {
class mysql_sql_generator extends sql_generator {
/// Only set values that are different from the defaults present in XMLDBgenerator
var $quote_string = '`'; // String used to quote names
public $quote_string = '`'; // String used to quote names
var $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
var $drop_default_clause_required = true; //To specify if the generator must use some DEFAULT clause to drop defaults
var $drop_default_clause = 'NULL'; //The DEFAULT clause required to drop defaults
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 $primary_key_name = ''; //To force primary key names to one string (null=no force)
public $primary_key_name = ''; //To force primary key names to one string (null=no force)
var $drop_primary_key = 'ALTER TABLE TABLENAME DROP PRIMARY KEY'; // Template to drop PKs
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP PRIMARY KEY'; // Template to drop PKs
// with automatic replace for TABLENAME and KEYNAME
var $drop_unique_key = 'ALTER TABLE TABLENAME DROP KEY KEYNAME'; // Template to drop UKs
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP KEY KEYNAME'; // Template to drop UKs
// with automatic replace for TABLENAME and KEYNAME
var $drop_foreign_key = 'ALTER TABLE TABLENAME DROP FOREIGN KEY KEYNAME'; // Template to drop FKs
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP FOREIGN KEY KEYNAME'; // Template to drop FKs
// with automatic replace for TABLENAME and KEYNAME
var $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
var $sequence_name = 'auto_increment'; //Particular name for inline sequences in this generator
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 $enum_extra_code = false; //Does the generator need to add extra code to generate code for the enums in the table
public $enum_extra_code = false; //Does the generator need to add extra code to generate code for the enums in the table
var $add_after_clause = true; // Does the generator need to add the after clause for fields
public $add_after_clause = true; // Does the generator need to add the after clause for fields
var $concat_character = null; //Characters to be used as concatenation operator. If not defined
public $concat_character = null; //Characters to be used as concatenation operator. If not defined
//MySQL CONCAT function will be use
var $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY COLUMN COLUMNSPECS'; //The SQL template to alter columns
public $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY COLUMN COLUMNSPECS'; //The SQL template to alter columns
var $drop_index_sql = 'ALTER TABLE TABLENAME DROP INDEX INDEXNAME'; //SQL sentence to drop one index
public $drop_index_sql = 'ALTER TABLE TABLENAME DROP INDEX INDEXNAME'; //SQL sentence to drop one index
//TABLENAME, INDEXNAME are dinamically replaced
var $rename_index_sql = null; //SQL sentence to rename one index (MySQL doesn't support this!)
public $rename_index_sql = null; //SQL sentence to rename one index (MySQL doesn't support this!)
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dinamically replaced
var $rename_key_sql = null; //SQL sentence to rename one key (MySQL doesn't support this!)
public $rename_key_sql = null; //SQL sentence to rename one key (MySQL doesn't support this!)
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dinamically replaced
/**
* Creates one new XMLDBmysql
*/
function XMLDBmysql() {
parent::XMLDBGenerator();
global $CFG;
$this->prefix = '';
$this->reserved_words = $this->getReservedWords();
public function __construct($mdb) {
parent::__construct($mdb);
}
/**
* Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type
*/
function getTypeSQL ($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
switch ($xmldb_type) {
case XMLDB_TYPE_INTEGER: // From http://mysql.com/doc/refman/5.0/en/numeric-types.html!
@@ -167,28 +166,28 @@ class XMLDBmysql extends XMLDBGenerator {
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* (usually invoked from getModifyEnumSQL()
*/
function getCreateEnumSQL($xmldb_table, $xmldb_field) {
/// For MySQL, just alter the field
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* (usually invoked from getModifyEnumSQL()
*/
function getDropEnumSQL($xmldb_table, $xmldb_field) {
public function getCreateEnumSQL($xmldb_table, $xmldb_field) {
/// For MySQL, just alter the field
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* (usually invoked from getModifyEnumSQL()
*/
public function getDropEnumSQL($xmldb_table, $xmldb_field) {
/// For MySQL, just alter the field
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* (usually invoked from getModifyDefaultSQL()
*/
function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
/// Just a wrapper over the getAlterFieldSQL() function for MySQL that
/// is capable of handling defaults
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
@@ -199,9 +198,7 @@ class XMLDBmysql extends XMLDBGenerator {
* to rename it (inside one array)
* MySQL is pretty diferent from the standard to justify this oveloading
*/
function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
$results = array(); //Array where all the sentences will be stored
public function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
/// Need a clone of xmldb_field to perform the change leaving original unmodified
$xmldb_field_clone = clone($xmldb_field);
@@ -209,17 +206,18 @@ class XMLDBmysql extends XMLDBGenerator {
/// Change the name of the field to perform the change
$xmldb_field_clone->setName($xmldb_field_clone->getName() . ' ' . $newname);
$results[] = 'ALTER TABLE ' . $this->getTableName($xmldb_table) . ' CHANGE ' .
$this->getFieldSQL($xmldb_field_clone);
$fieldsql = $this->getFieldSQL($xmldb_field_clone);
return $results;
$sql = 'ALTER TABLE ' . $this->getTableName($xmldb_table) . ' CHANGE ' . $fieldsql;
return array($sql);
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* (usually invoked from getModifyDefaultSQL()
*/
function getDropDefaultSQL($xmldb_table, $xmldb_field) {
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
/// Just a wrapper over the getAlterFieldSQL() function for MySQL that
/// is capable of handling defaults
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
@@ -228,7 +226,7 @@ class XMLDBmysql extends XMLDBGenerator {
/**
* Given one XMLDB Field, return its enum SQL
*/
function getEnumSQL ($xmldb_field) {
public function getEnumSQL($xmldb_field) {
return 'enum(' . implode(', ', $xmldb_field->getEnumValues()) . ')';
}
@@ -236,12 +234,11 @@ class XMLDBmysql extends XMLDBGenerator {
* Returns the code (in array) needed to add one comment to the table
*/
function getCommentSQL ($xmldb_table) {
$comment = '';
if ($xmldb_table->getComment()) {
$comment .= 'ALTER TABLE ' . $this->getTableName($xmldb_table);
$comment .= " COMMENT='" . addslashes(substr($xmldb_table->getComment(), 0, 60)) . "'";
$comment .= " COMMENT='" . $this->addslashes(substr($xmldb_table->getComment(), 0, 60)) . "'";
}
return array($comment);
}
@@ -256,18 +253,37 @@ class XMLDBmysql extends XMLDBGenerator {
* MySQL doesn't have check constraints in this implementation, but
* we return them based on the enum fields in the table
*/
function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
public function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
global $db;
$results = array();
$tablename = $xmldb_table->getName($xmldb_table);
$tablename = $this->getTableName($xmldb_table);
$this->mdb->reset_columns($tablename);
/// Fetch all the columns in the table
if ($columns = $db->MetaColumns($tablename)) {
/// Normalize array keys
$columns = array_change_key_case($columns, CASE_LOWER);
if (!$columns = $this->mdb->get_columns($tablename)) {
return array();
}
/// Filter by the required field if specified
if ($xmldb_field) {
$filter = $xmldb_field->getName();
if (!isset($columns[$filter])) {
return array();
}
$column = ($columns[$filter]);
if (!empty($column->enums)) {
$result = new object;
$result->name = $filter;
$result->description = implode(', ', $column->enums);
return array($result);
} else {
return array();
}
} else {
$results = array();
/// Iterate over columns searching for enums
foreach ($columns as $key => $column) {
/// Enum found, let's add it to the constraints list
@@ -278,20 +294,8 @@ class XMLDBmysql extends XMLDBGenerator {
$results[$key] = $result;
}
}
return $results;
}
/// Filter by the required field if specified
if ($xmldb_field) {
$filter = $xmldb_field->getName();
/// Check if some of the checks belong to the field (easy under MySQL)
if (array_key_exists($filter, $results)) {
$results = array($filter => $results[$filter]);
} else {
$results = array();
}
}
return $results;
}
/**
@@ -299,28 +303,22 @@ class XMLDBmysql extends XMLDBGenerator {
* return if such name is currently in use (true) or no (false)
* (invoked from getNameForObject()
*/
function isNameInUse($object_name, $type, $table_name) {
global $db;
public function isNameInUse($object_name, $type, $table_name) {
/// Calculate the real table name
$xmldb_table = new XMLDBTable($table_name);
$tname = $this->getTableName($xmldb_table);
switch($type) {
case 'ix':
case 'uix':
/// First of all, check table exists
$metatables = $db->MetaTables();
$metatables = array_flip($metatables);
$metatables = array_change_key_case($metatables, CASE_LOWER);
if (array_key_exists($tname, $metatables)) {
$metatables = $this->mdb->get_tables();
if (isset($metatables[$tname])) {
/// Fetch all the indexes in the table
if ($indexes = $db->MetaIndexes($tname)) {
/// Normalize array keys
$indexes = array_change_key_case($indexes, CASE_LOWER);
if ($indexes = $this->mdb->get_indexes($tname)) {
/// Look for existing index in array
if (array_key_exists(strtolower($object_name), $indexes)) {
if (isset($indexes[$object_name])) {
return true;
}
}
@@ -334,7 +332,7 @@ class XMLDBmysql extends XMLDBGenerator {
/**
* Returns an array of reserved words (lowercase) for this DB
*/
function getReservedWords() {
public static function getReservedWords() {
/// This file contains the reserved words for MySQL databases
/// from http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html
$reserved_words = array (
@@ -24,54 +24,48 @@
// //
///////////////////////////////////////////////////////////////////////////
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
/// overriden as needed to generate correct SQL.
class XMLDBoci8po extends XMLDBgenerator {
class oracle_sql_generator extends sql_generator {
/// Only set values that are different from the defaults present in XMLDBgenerator
var $statement_end = "\n/"; // String to be automatically added at the end of each statement
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 $number_type = 'NUMBER'; // Proper type for NUMBER(x) in this DB
public $number_type = 'NUMBER'; // Proper type for NUMBER(x) in this DB
var $unsigned_allowed = false; // To define in the generator must handle unsigned information
var $default_for_char = ' '; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
public $unsigned_allowed = false; // To define in the generator must handle unsigned information
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 $drop_default_clause_required = true; //To specify if the generator must use some DEFAULT clause to drop defaults
var $drop_default_clause = 'NULL'; //The DEFAULT clause required to drop defaults
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 $default_after_null = false; //To decide if the default clause of each field must go after the null clause
public $default_after_null = false; //To decide if the default clause of each field must go after the null clause
var $sequence_extra_code = true; //Does the generator need to add extra code to generate the sequence fields
var $sequence_name = ''; //Particular name for inline sequences in this generator
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
var $drop_table_extra_code = true; //Does the generator need to add code after table drop
public $enum_inline_code = false; //Does the generator need to add inline code in the column definition
var $rename_table_extra_code = true; //Does the generator need to add code after table rename
var $rename_column_extra_code = true; //Does the generator need to add code after field rename
var $enum_inline_code = false; //Does the generator need to add inline code in the column definition
var $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY (COLUMNSPECS)'; //The SQL template to alter columns
public $alter_column_sql = 'ALTER TABLE TABLENAME MODIFY (COLUMNSPECS)'; //The SQL template to alter columns
/**
* Creates one new XMLDBoci8po
*/
function XMLDBoci8po() {
parent::XMLDBgenerator();
$this->prefix = '';
$this->reserved_words = $this->getReservedWords();
public function __construct($mdb) {
parent::__construct($mdb);
}
/**
* Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type
*/
function getTypeSQL ($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
switch ($xmldb_type) {
case XMLDB_TYPE_INTEGER: // From http://www.postgresql.org/docs/7.4/interactive/datatype.html
@@ -117,10 +111,54 @@ class XMLDBoci8po extends XMLDBgenerator {
return $dbtype;
}
/**
* This function will create the temporary table passed as argument with all its
* fields/keys/indexes/sequences, everything based in the XMLDB object
*
* TRUNCATE the table immediately after creation. A previous process using
* the same persistent connection may have created the temp table and failed to
* drop it. In that case, the table will exist, and create_temp_table() will
* will succeed.
*
* NOTE: The return value is the tablename - some DBs (MSSQL at least) use special
* names for temp tables.
*
* @uses $CFG, $db
* @param XMLDBTable table object (full specs are required)
* @param boolean continue to specify if must continue on error (true) or stop (false)
* @param boolean feedback to specify to show status info (true) or not (false)
* @return string tablename on success, false on error
*/
function create_temp_table($xmldb_table, $continue=true, $feedback=true) {
if (!($xmldb_table instanceof XMLDBTable)) {
debugging('Incorrect create_table() $xmldb_table parameter');
return false;
}
/// Check table doesn't exist
if ($this->table_exists($xmldb_table)) {
debugging('Table ' . $xmldb_table->getName() .
' already exists. Create skipped', DEBUG_DEVELOPER);
return $xmldb_table->getName(); //Table exists, nothing to do
}
if (!$sqlarr = $this->getCreateTableSQL($xmldb_table)) {
return $xmldb_table->getName(); //Empty array = nothing to do = no error
}
$sqlarr = preg_replace('/^CREATE/', "CREATE GLOBAL TEMPORARY", $sqlarr);
if (execute_sql_arr($sqlarr, $continue, $feedback)) {
return $xmldb_table->getName();
} else {
return false;
}
}
/**
* Returns the code needed to create one enum for the xmldb_table and xmldb_field passes
*/
function getEnumExtraSQL ($xmldb_table, $xmldb_field) {
public function getEnumExtraSQL($xmldb_table, $xmldb_field) {
$sql = 'CONSTRAINT ' . $this->getNameForObject($xmldb_table->getName(), $xmldb_field->getName(), 'ck');
$sql.= ' CHECK (' . $this->getEncQuoted($xmldb_field->getName()) . ' IN (' . implode(', ', $xmldb_field->getEnumValues()) . '))';
@@ -131,7 +169,7 @@ class XMLDBoci8po extends XMLDBgenerator {
/**
* Returns the code needed to create one sequence for the xmldb_table and xmldb_field passes
*/
function getCreateSequenceSQL ($xmldb_table, $xmldb_field) {
public function getCreateSequenceSQL($xmldb_table, $xmldb_field) {
$results = array();
@@ -152,7 +190,7 @@ class XMLDBoci8po extends XMLDBgenerator {
/**
* Returns the code needed to create one trigger for the xmldb_table and xmldb_field passed
*/
function getCreateTriggerSQL ($xmldb_table, $xmldb_field) {
public function getCreateTriggerSQL($xmldb_table, $xmldb_field) {
$trigger_name = $this->getNameForObject($xmldb_table->getName(), $xmldb_field->getName(), 'trg');
$sequence_name = $this->getNameForObject($xmldb_table->getName(), $xmldb_field->getName(), 'seq');
@@ -174,7 +212,7 @@ class XMLDBoci8po extends XMLDBgenerator {
* 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
*/
function getDropSequenceSQL ($xmldb_table, $xmldb_field, $include_trigger=false) {
public function getDropSequenceSQL($xmldb_table, $xmldb_field, $include_trigger=false) {
$sequence_name = $this->getSequenceFromDB($xmldb_table);
@@ -198,7 +236,7 @@ class XMLDBoci8po extends XMLDBgenerator {
function getCommentSQL ($xmldb_table) {
$comment = "COMMENT ON TABLE " . $this->getTableName($xmldb_table);
$comment.= " IS '" . addslashes(substr($xmldb_table->getComment(), 0, 250)) . "'";
$comment.= " IS '" . $this->addslashes(substr($xmldb_table->getComment(), 0, 250)) . "'";
return array($comment);
}
@@ -206,7 +244,7 @@ class XMLDBoci8po extends XMLDBgenerator {
/**
* Returns the code (array of statements) needed to execute extra statements on field rename
*/
function getRenameFieldExtraSQL ($xmldb_table, $xmldb_field, $newname) {
public function getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname) {
$results = array();
@@ -227,7 +265,7 @@ class XMLDBoci8po extends XMLDBgenerator {
/**
* Returns the code (array of statements) needed to execute extra statements on table drop
*/
function getDropTableExtraSQL ($xmldb_table) {
public function getDropTableExtraSQL($xmldb_table) {
$xmldb_field = new XMLDBField('id'); // Fields having sequences should be exclusively, id.
return $this->getDropSequenceSQL($xmldb_table, $xmldb_field, false);
}
@@ -235,7 +273,7 @@ class XMLDBoci8po extends XMLDBgenerator {
/**
* Returns the code (array of statements) needed to execute extra statements on table rename
*/
function getRenameTableExtraSQL ($xmldb_table, $newname) {
public function getRenameTableExtraSQL($xmldb_table, $newname) {
$results = array();
@@ -287,7 +325,7 @@ class XMLDBoci8po extends XMLDBgenerator {
* - 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
*/
function getAlterFieldSQL($xmldb_table, $xmldb_field) {
public function getAlterFieldSQL($xmldb_table, $xmldb_field) {
global $db;
@@ -298,10 +336,10 @@ class XMLDBoci8po extends XMLDBgenerator {
$fieldname = $this->getEncQuoted($xmldb_field->getName());
/// Take a look to field metadata
$meta = array_change_key_case($db->MetaColumns($tablename));
$meta = $this->mdb->get_columns($tablename);
$metac = $meta[$fieldname];
$oldtype = strtolower($metac->type);
$oldmetatype = column_type($xmldb_table->getName(), $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
@@ -328,14 +366,14 @@ class XMLDBoci8po extends XMLDBgenerator {
$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 && substr($oldmetatype, 0, 1) == 'I') ||
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 && substr($oldmetatype, 0, 1) == 'C') ||
($xmldb_field->getType() == XMLDB_TYPE_TEXT && substr($oldmetatype, 0, 1) == 'X') ||
($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) ||
@@ -421,8 +459,11 @@ class XMLDBoci8po extends XMLDBgenerator {
if (!$defaultchanged) {
$this->alter_column_skip_default = 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)) {
$this->alter_column_skip_default = false;
if ($from_temp_fields) {
$default_clause = $this->getDefaultClause($xmldb_field);
if ($default_clause) {
$this->alter_column_skip_default = false;
}
}
}
@@ -437,51 +478,51 @@ class XMLDBoci8po extends XMLDBgenerator {
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* (usually invoked from getModifyEnumSQL()
*/
function getCreateEnumSQL($xmldb_table, $xmldb_field) {
public function getCreateEnumSQL($xmldb_table, $xmldb_field) {
/// All we have to do is to create the check constraint
return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
' ADD ' . $this->getEnumExtraSQL($xmldb_table, $xmldb_field));
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* (usually invoked from getModifyEnumSQL()
*/
function getDropEnumSQL($xmldb_table, $xmldb_field) {
*/
public function getDropEnumSQL($xmldb_table, $xmldb_field) {
/// Let's introspect to know the real name of the check constraint
if ($check_constraints = $this->getCheckConstraintsFromDB($xmldb_table, $xmldb_field)) {
$check_constraint = array_shift($check_constraints); /// Get the 1st (should be only one)
$constraint_name = strtolower($check_constraint->name); /// Extract the REAL name
/// All we have to do is to drop the check constraint
return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
' DROP CONSTRAINT ' . $constraint_name);
} else { /// Constraint not found. Nothing to do
return array();
}
}
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* (usually invoked from getModifyDefaultSQL()
*/
function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
/// Just a wrapper over the getAlterFieldSQL() function for Oracle that
/// is capable of handling defaults
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* (usually invoked from getModifyDefaultSQL()
*/
function getDropDefaultSQL($xmldb_table, $xmldb_field) {
*/
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
/// Just a wrapper over the getAlterFieldSQL() function for Oracle that
/// is capable of handling defaults
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
}
}
/**
* Given one XMLDBTable returns one array with all the check constrainsts
@@ -491,7 +532,7 @@ class XMLDBoci8po extends XMLDBgenerator {
* Each element contains the name of the constraint and its description
* If no check constraints are found, returns an empty array
*/
function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
public function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
$results = array();
@@ -533,7 +574,7 @@ class XMLDBoci8po extends XMLDBgenerator {
* independent elements)
* If no sequence is found, returns false
*/
function getSequenceFromDB($xmldb_table) {
public function getSequenceFromDB($xmldb_table) {
$tablename = strtoupper($this->getTableName($xmldb_table));
$prefixupper = strtoupper($this->prefix);
@@ -558,7 +599,7 @@ class XMLDBoci8po extends XMLDBgenerator {
* in the table (fetched from DB)
* If no trigger is found, returns false
*/
function getTriggerFromDB($xmldb_table) {
public function getTriggerFromDB($xmldb_table) {
$tablename = strtoupper($this->getTableName($xmldb_table));
$prefixupper = strtoupper($this->prefix);
@@ -579,14 +620,14 @@ class XMLDBoci8po extends XMLDBgenerator {
* return if such name is currently in use (true) or no (false)
* (invoked from getNameForObject()
*/
function isNameInUse($object_name, $type, $table_name) {
public function isNameInUse($object_name, $type, $table_name) {
switch($type) {
case 'ix':
case 'uix':
case 'seq':
case 'trg':
if ($check = get_records_sql("SELECT object_name
FROM user_objects
if ($check = get_records_sql("SELECT object_name
FROM user_objects
WHERE lower(object_name) = '" . strtolower($object_name) . "'")) {
return true;
}
@@ -595,7 +636,7 @@ class XMLDBoci8po extends XMLDBgenerator {
case 'uk':
case 'fk':
case 'ck':
if ($check = get_records_sql("SELECT constraint_name
if ($check = get_records_sql("SELECT constraint_name
FROM user_constraints
WHERE lower(constraint_name) = '" . strtolower($object_name) . "'")) {
return true;
@@ -605,10 +646,16 @@ class XMLDBoci8po extends XMLDBgenerator {
return false; //No name in use found
}
public function addslashes($s) {
// do not use php addslashes() because it depends on PHP quote settings!
$s = str_replace("'", "''", $s);
return $s;
}
/**
* Returns an array of reserved words (lowercase) for this DB
*/
function getReservedWords() {
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
$reserved_words = array (
@@ -24,49 +24,45 @@
// //
///////////////////////////////////////////////////////////////////////////
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
/// overriden as needed to generate correct SQL.
class XMLDBpostgres7 extends XMLDBgenerator {
class postgres_sql_generator extends sql_generator {
/// Only set values that are different from the defaults present in XMLDBgenerator
var $number_type = 'NUMERIC'; // Proper type for NUMBER(x) in this DB
public $number_type = 'NUMERIC'; // Proper type for NUMBER(x) in this DB
var $unsigned_allowed = false; // To define in the generator must handle unsigned information
var $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
public $unsigned_allowed = false; // To define in the generator must handle unsigned information
public $default_for_char = ''; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
var $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
var $sequence_name = 'BIGSERIAL'; //Particular name for inline sequences in this generator
var $sequence_name_small = 'SERIAL'; //Particular name for inline sequences in this generator
var $sequence_only = true; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable
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 $rename_table_extra_code = true; //Does the generator need to add code after table rename
public $enum_inline_code = false; //Does the generator need to add inline code in the column definition
var $rename_column_extra_code = true; //Does the generator need to add code after column rename
var $enum_inline_code = false; //Does the generator need to add inline code in the column definition
var $rename_index_sql = 'ALTER TABLE OLDINDEXNAME RENAME TO NEWINDEXNAME'; //SQL sentence to rename one index
public $rename_index_sql = 'ALTER TABLE OLDINDEXNAME RENAME TO NEWINDEXNAME'; //SQL sentence to rename one index
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dinamically replaced
var $rename_key_sql = null; //SQL sentence to rename one key (PostgreSQL doesn't support this!)
public $rename_key_sql = null; //SQL sentence to rename one key (PostgreSQL doesn't support this!)
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dinamically replaced
/**
* Creates one new XMLDBpostgres7
*/
function XMLDBpostgres7() {
parent::XMLDBgenerator();
$this->prefix = '';
$this->reserved_words = $this->getReservedWords();
public function __construct($mdb) {
parent::__construct($mdb);
}
/**
* Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type
*/
function getTypeSQL ($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
switch ($xmldb_type) {
case XMLDB_TYPE_INTEGER: // From http://www.postgresql.org/docs/7.4/interactive/datatype.html
@@ -122,7 +118,7 @@ class XMLDBpostgres7 extends XMLDBgenerator {
/**
* Returns the code needed to create one enum for the xmldb_table and xmldb_field passes
*/
function getEnumExtraSQL ($xmldb_table, $xmldb_field) {
public function getEnumExtraSQL($xmldb_table, $xmldb_field) {
$sql = 'CONSTRAINT ' . $this->getNameForObject($xmldb_table->getName(), $xmldb_field->getName(), 'ck');
$sql.= ' CHECK (' . $this->getEncQuoted($xmldb_field->getName()) . ' IN (' . implode(', ', $xmldb_field->getEnumValues()) . '))';
@@ -136,7 +132,7 @@ class XMLDBpostgres7 extends XMLDBgenerator {
function getCommentSQL ($xmldb_table) {
$comment = "COMMENT ON TABLE " . $this->getTableName($xmldb_table);
$comment.= " IS '" . addslashes(substr($xmldb_table->getComment(), 0, 250)) . "'";
$comment.= " IS '" . $this->addslashes(substr($xmldb_table->getComment(), 0, 250)) . "'";
return array($comment);
}
@@ -144,7 +140,7 @@ class XMLDBpostgres7 extends XMLDBgenerator {
/**
* Returns the code (array of statements) needed to execute extra statements on table rename
*/
function getRenameTableExtraSQL ($xmldb_table, $newname) {
public function getRenameTableExtraSQL($xmldb_table, $newname) {
$results = array();
@@ -184,17 +180,17 @@ class XMLDBpostgres7 extends XMLDBgenerator {
* Given one XMLDBTable and one XMLDBField, 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
*/
function getAddFieldSQL($xmldb_table, $xmldb_field) {
public function getAddFieldSQL($xmldb_table, $xmldb_field) {
$results = array();
$tablename = $this->getTableName($xmldb_table);
$fieldname = $this->getEncQuoted($xmldb_field->getName());
$defaultvalue = null;
$defaultvalue = $xmldb_field->getDefault();
/// Save old flags
$old_skip_default = $this->alter_column_skip_default;
@@ -211,13 +207,19 @@ class XMLDBpostgres7 extends XMLDBgenerator {
/// Add default (only if not skip_default)
if (!$this->alter_column_skip_default) {
if ($defaultclause = $this->getDefaultClause($xmldb_field)) {
$defaultvalue = $this->getDefaultValue($xmldb_field);
$results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $defaultclause; /// Add 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) {
$results[] = 'UPDATE ' . $tablename . ' SET ' . $fieldname . '=' . $defaultvalue;
if (!is_numeric($defaultvalue)) {
$defaultvalue = "'".$this->addslashes($defaultvalue)."'";
}
$sql = 'UPDATE ' . $tablename . ' SET ' . $fieldname . '=' . $defaultvalue;
$results[] = $sql;
}
}
@@ -235,30 +237,29 @@ class XMLDBpostgres7 extends XMLDBgenerator {
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded 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
* 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
*/
function getAlterFieldSQL($xmldb_table, $xmldb_field) {
public function getAlterFieldSQL($xmldb_table, $xmldb_field) {
global $db;
$results = array(); /// To store all the needed SQL commands
/// Get the quoted name of the table and field
$tablename = $this->getTableName($xmldb_table);
$fieldname = $this->getEncQuoted($xmldb_field->getName());
/// Get the normla names of the table and field
$tablename = $xmldb_table->getName();
$fieldname = $xmldb_field->getName();
/// Take a look to field metadata
$meta = array_change_key_case($db->MetaColumns($tablename));
$metac = $meta[$fieldname];
$oldtype = strtolower($metac->type);
$oldmetatype = column_type($xmldb_table->getName(), $fieldname);
$meta = $this->mdb->get_columns($xmldb_table->getName());
$metac = $meta[$xmldb_field->getName()];
$oldmetatype = $metac->meta_type;
$oldlength = $metac->max_length;
$olddecimals = empty($metac->scale) ? null : $metac->scale;
$oldnotnull = empty($metac->not_null) ? false : $metac->not_null;
$olddefault = empty($metac->has_default) ? null : strtok($metac->default_value, ':');
$olddefault = empty($metac->has_default) ? null : $metac->default_value;
$typechanged = true; //By default, assume that the column type has changed
$precisionchanged = true; //By default, assume that the column precision has changed
@@ -269,15 +270,15 @@ class XMLDBpostgres7 extends XMLDBgenerator {
$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 && substr($oldmetatype, 0, 1) == 'I') ||
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 && substr($oldmetatype, 0, 1) == 'C') ||
($xmldb_field->getType() == XMLDB_TYPE_TEXT && substr($oldmetatype, 0, 1) == 'X') ||
($xmldb_field->getType() == XMLDB_TYPE_CHAR && $oldmetatype == 'C') ||
($xmldb_field->getType() == XMLDB_TYPE_TEXT && $oldmetatype == 'X') ||
($xmldb_field->getType() == XMLDB_TYPE_BINARY && $oldmetatype == 'B')) {
$typechanged = false;
}
/// Detect if we are changing the precision
/// Detect if we are changing the precision
if (($xmldb_field->getType() == XMLDB_TYPE_TEXT) ||
($xmldb_field->getType() == XMLDB_TYPE_BINARY) ||
($oldlength == -1) ||
@@ -296,8 +297,7 @@ class XMLDBpostgres7 extends XMLDBgenerator {
}
/// 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
($xmldb_field->getDefault() === $olddefault)) {
$defaultchanged = false;
}
/// Detect if we are changing the nullability
@@ -305,6 +305,10 @@ class XMLDBpostgres7 extends XMLDBgenerator {
$notnullchanged = false;
}
/// Get the quoted name of the table and field
$tablename = $this->getTableName($xmldb_table);
$fieldname = $this->getEncQuoted($xmldb_field->getName());
/// TODO: Some combinations like
/// TODO: integer->integer
/// TODO: integer->text
@@ -348,8 +352,10 @@ class XMLDBpostgres7 extends XMLDBgenerator {
}
/// If the default has changed or we have used one temp field
if ($defaultchanged || $from_temp_fields) {
if ($default_clause = $this->getDefaultClause($xmldb_field)) {
$results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $default_clause; /// Add default clause
$default_clause = $this->getDefaultClause($xmldb_field);
if ($default_clause) {
$sql = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' SET' . $default_clause; /// Add default clause
$results[] = $sql;
} else {
if (!$from_temp_fields) { /// Only drop default if we haven't used the temp field, i.e. old column
$results[] = 'ALTER TABLE ' . $tablename . ' ALTER COLUMN ' . $fieldname . ' DROP DEFAULT'; /// Drop default clause
@@ -365,14 +371,14 @@ class XMLDBpostgres7 extends XMLDBgenerator {
}
}
/// Return the results
/// Return the results
return $results;
}
/**
* Returns the code (array of statements) needed to execute extra statements on field rename
*/
function getRenameFieldExtraSQL ($xmldb_table, $xmldb_field, $newname) {
public function getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname) {
$results = array();
@@ -391,20 +397,20 @@ class XMLDBpostgres7 extends XMLDBgenerator {
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its enum
* (usually invoked from getModifyEnumSQL()
*/
function getCreateEnumSQL($xmldb_table, $xmldb_field) {
public function getCreateEnumSQL($xmldb_table, $xmldb_field) {
/// All we have to do is to create the check constraint
return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
' ADD ' . $this->getEnumExtraSQL($xmldb_table, $xmldb_field));
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* (usually invoked from getModifyEnumSQL()
*/
function getDropEnumSQL($xmldb_table, $xmldb_field) {
public function getDropEnumSQL($xmldb_table, $xmldb_field) {
/// Let's introspect to know the real name of the check constraint
if ($check_constraints = $this->getCheckConstraintsFromDB($xmldb_table, $xmldb_field)) {
$check_constraint = array_shift($check_constraints); /// Get the 1st (should be only one)
@@ -418,20 +424,20 @@ class XMLDBpostgres7 extends XMLDBgenerator {
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to create its default
* (usually invoked from getModifyDefaultSQL()
*/
function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
/// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
/// is capable of handling defaults
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* (usually invoked from getModifyDefaultSQL()
*/
function getDropDefaultSQL($xmldb_table, $xmldb_field) {
public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
/// Just a wrapper over the getAlterFieldSQL() function for PostgreSQL that
/// is capable of handling defaults
return $this->getAlterFieldSQL($xmldb_table, $xmldb_field);
@@ -445,7 +451,7 @@ class XMLDBpostgres7 extends XMLDBgenerator {
* Each element contains the name of the constraint and its description
* If no check constraints are found, returns an empty array
*/
function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
public function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
$results = array();
@@ -488,7 +494,7 @@ class XMLDBpostgres7 extends XMLDBgenerator {
/**
* Given one XMLDBTable returns one string with the sequence of the table
* in the table (fetched from DB)
* The sequence name for Postgres has one standard name convention:
* 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
@@ -513,13 +519,13 @@ function getSequenceFromDB($xmldb_table) {
* return if such name is currently in use (true) or no (false)
* (invoked from getNameForObject()
*/
function isNameInUse($object_name, $type, $table_name) {
public function isNameInUse($object_name, $type, $table_name) {
switch($type) {
case 'ix':
case 'uix':
case 'seq':
if ($check = get_records_sql("SELECT relname
FROM pg_class
if ($check = get_records_sql("SELECT relname
FROM pg_class
WHERE lower(relname) = '" . strtolower($object_name) . "'")) {
return true;
}
@@ -528,14 +534,14 @@ function getSequenceFromDB($xmldb_table) {
case 'uk':
case 'fk':
case 'ck':
if ($check = get_records_sql("SELECT conname
if ($check = get_records_sql("SELECT conname
FROM pg_constraint
WHERE lower(conname) = '" . strtolower($object_name) . "'")) {
return true;
}
break;
case 'trg':
if ($check = get_records_sql("SELECT tgname
if ($check = get_records_sql("SELECT tgname
FROM pg_trigger
WHERE lower(tgname) = '" . strtolower($object_name) . "'")) {
return true;
@@ -548,7 +554,7 @@ function getSequenceFromDB($xmldb_table) {
/**
* Returns an array of reserved words (lowercase) for this DB
*/
function getReservedWords() {
public static function getReservedWords() {
/// This file contains the reserved words for PostgreSQL databases
/// http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
$reserved_words = array (
@@ -7,7 +7,7 @@
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
// //
// This program is free software; you can redistribute it and/or modify //
@@ -30,123 +30,171 @@
/// The rest of classes will inherit, by default, the same logic.
/// Functions will be overriden as needed to generate correct SQL.
class XMLDBgenerator {
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.
var $quote_string = '"'; // String used to quote names
public $quote_string = '"'; // String used to quote names
var $quote_all = false; // To decide if we want to quote all the names or only the reserved ones
public $statement_end = ';'; // String to be automatically added at the end of each statement
var $statement_end = ';'; // String to be automatically added at the end of each statement
public $quote_all = false; // To decide if we want to quote all the names or only the reserved ones
var $integer_to_number = false; // To create all the integers as NUMBER(x) (also called DECIMAL, NUMERIC...)
var $float_to_number = false; // To create all the floats as NUMBER(x) (also called DECIMAL, NUMERIC...)
public $integer_to_number = false; // To create all the integers as NUMBER(x) (also called DECIMAL, NUMERIC...)
public $float_to_number = false; // To create all the floats as NUMBER(x) (also called DECIMAL, NUMERIC...)
var $number_type = 'NUMERIC'; // Proper type for NUMBER(x) in this DB
public $number_type = 'NUMERIC'; // Proper type for NUMBER(x) in this DB
var $unsigned_allowed = true; // To define in the generator must handle unsigned information
var $default_for_char = null; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
public $unsigned_allowed = true; // To define in the generator must handle unsigned information
public $default_for_char = null; // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
var $drop_default_clause_required = false; //To specify if the generator must use some DEFAULT clause to drop defaults
var $drop_default_clause = ''; //The DEFAULT clause required to drop defaults
public $drop_default_value_required = false; //To specify if the generator must use some DEFAULT clause to drop defaults
public $drop_default_value = ''; //The DEFAULT clause required to drop defaults
var $default_after_null = true; //To decide if the default clause of each field must go after the null clause
public $default_after_null = true; //To decide if the default clause of each field must go after the null clause
var $specify_nulls = false; //To force the generator if NULL clauses must be specified. It shouldn't be necessary
public $specify_nulls = false; //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 $primary_key_name = null; //To force primary key names to one string (null=no force)
public $primary_key_name = null; //To force primary key names to one string (null=no force)
var $primary_keys = true; // Does the generator build primary keys
var $unique_keys = false; // Does the generator build unique keys
var $foreign_keys = false; // Does the generator build foreign keys
public $primary_keys = true; // Does the generator build primary keys
public $unique_keys = false; // Does the generator build unique keys
public $foreign_keys = false; // Does the generator build foreign keys
var $drop_primary_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop PKs
public $drop_primary_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop PKs
// with automatic replace for TABLENAME and KEYNAME
var $drop_unique_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop UKs
public $drop_unique_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop UKs
// with automatic replace for TABLENAME and KEYNAME
var $drop_foreign_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop FKs
public $drop_foreign_key = 'ALTER TABLE TABLENAME DROP CONSTRAINT KEYNAME'; // Template to drop FKs
// with automatic replace for TABLENAME and KEYNAME
var $sequence_extra_code = true; //Does the generator need to add extra code to generate the sequence fields
var $sequence_name = 'auto_increment'; //Particular name for inline sequences in this generator
var $sequence_name_small = false; //Different name for small (4byte) sequences or false if same
var $sequence_only = false; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable
public $sequence_extra_code = true; //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
public $sequence_name_small = false; //Different name for small (4byte) sequences or false if same
public $sequence_only = false; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name publiciable
var $enum_inline_code = true; //Does the generator need to add inline code in the column definition
var $enum_extra_code = true; //Does the generator need to add extra code to generate code for the enums in the table
public $enum_inline_code = true; //Does the generator need to add inline code in the column definition
public $enum_extra_code = true; //Does the generator need to add extra code to generate code for the enums in the table
var $add_table_comments = true; // Does the generator need to add code for table comments
public $add_table_comments = true; // Does the generator need to add code for table comments
var $add_after_clause = false; // Does the generator need to add the after clause for fields
public $add_after_clause = false; // Does the generator need to add the after clause for fields
var $prefix_on_names = true; //Does the generator need to prepend the prefix to all the key/index/sequence/trigger/check names
public $prefix_on_names = true; //Does the generator need to prepend the prefix to all the key/index/sequence/trigger/check names
var $names_max_length = 30; //Max length for key/index/sequence/trigger/check names (keep 30 for all!)
public $names_max_length = 30; //Max length for key/index/sequence/trigger/check names (keep 30 for all!)
var $concat_character = '||'; //Characters to be used as concatenation operator. If not defined
public $concat_character = '||'; //Characters to be used as concatenation operator. If not defined
//MySQL CONCAT function will be used
var $rename_table_sql = 'ALTER TABLE OLDNAME RENAME TO NEWNAME'; //SQL sentence to rename one table, both
public $rename_table_sql = 'ALTER TABLE OLDNAME RENAME TO NEWNAME'; //SQL sentence to rename one table, both
//OLDNAME and NEWNAME are dinamically replaced
var $rename_table_extra_code = false; //Does the generator need to add code after table rename
var $drop_table_sql = 'DROP TABLE TABLENAME'; //SQL sentence to drop one table
public $drop_table_sql = 'DROP TABLE TABLENAME'; //SQL sentence to drop one table
//TABLENAME is dinamically replaced
var $drop_table_extra_code = false; //Does the generator need to add code after table drop
public $alter_column_sql = 'ALTER TABLE TABLENAME ALTER COLUMN COLUMNSPECS'; //The SQL template to alter columns
var $alter_column_sql = 'ALTER TABLE TABLENAME ALTER COLUMN COLUMNSPECS'; //The SQL template to alter columns
public $alter_column_skip_default = false; //The generator will skip the default clause on alter columns
var $alter_column_skip_default = false; //The generator will skip the default clause on alter columns
public $alter_column_skip_type = false; //The generator will skip the type clause on alter columns
var $alter_column_skip_type = false; //The generator will skip the type clause on alter columns
public $alter_column_skip_notnull = false; //The generator will skip the null/notnull clause on alter columns
var $alter_column_skip_notnull = false; //The generator will skip the null/notnull clause on alter columns
var $rename_column_sql = 'ALTER TABLE TABLENAME RENAME COLUMN OLDFIELDNAME TO NEWFIELDNAME';
public $rename_column_sql = 'ALTER TABLE TABLENAME RENAME COLUMN OLDFIELDNAME TO NEWFIELDNAME';
///TABLENAME, OLDFIELDNAME and NEWFIELDNAME are dianmically replaced
var $rename_column_extra_code = false; //Does the generator need to add code after column rename
var $drop_index_sql = 'DROP INDEX INDEXNAME'; //SQL sentence to drop one index
public $drop_index_sql = 'DROP INDEX INDEXNAME'; //SQL sentence to drop one index
//TABLENAME, INDEXNAME are dinamically replaced
var $rename_index_sql = 'ALTER INDEX OLDINDEXNAME RENAME TO NEWINDEXNAME'; //SQL sentence to rename one index
public $rename_index_sql = 'ALTER INDEX OLDINDEXNAME RENAME TO NEWINDEXNAME'; //SQL sentence to rename one index
//TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dinamically replaced
var $rename_key_sql = 'ALTER TABLE TABLENAME CONSTRAINT OLDKEYNAME RENAME TO NEWKEYNAME'; //SQL sentence to rename one key
public $rename_key_sql = 'ALTER TABLE TABLENAME CONSTRAINT OLDKEYNAME RENAME TO NEWKEYNAME'; //SQL sentence to rename one key
//TABLENAME, OLDKEYNAME, NEWKEYNAME are dinamically replaced
var $prefix; // Prefix to be used for all the DB objects
public $prefix; // Prefix to be used for all the DB objects
var $reserved_words; // List of reserved words (in order to quote them properly)
public $reserved_words; // List of reserved words (in order to quote them properly)
public $mdb;
/**
* Creates one new XMLDBGenerator
* Creates new sql_generator
* @param object moodle_database instance
*/
function XMLDBgenerator() {
global $CFG;
$this->prefix = '';
public function __construct($mdb) {
$this->prefix = $mdb->get_prefix();
$this->reserved_words = $this->getReservedWords();
$this->mdb = $mdb; // this creates circular reference - the other link must be unset when closing db
}
/// ALL THESE FUNCTION ARE SHARED BY ALL THE XMLDGenerator classes
/**
* Given one string (or one array), ends it with statement_end
*/
public function getEndedStatements($input) {
if (is_array($input)) {
foreach ($input as $key=>$content) {
$input[$key] = $this->getEndedStatements($content);
}
return $input;
} else {
$input = trim($input).$this->statement_end;
return $input;
}
}
/**
* Set the prefix
* This function will return the SQL code needed to create db tables and statements
*/
function setPrefix($prefix) {
if ($this->prefix_on_names) { // Only if we want prefix on names
$this->prefix = $prefix;
public function getCreateStructureSQL($xmldb_structure) {
$results = array();
if ($tables = $xmldb_structure->getTables()) {
foreach ($tables as $table) {
$results = array_merge($results, $this->getCreateTableSQL($table));
}
}
if ($statements = $xmldb_structure->getStatements()) {
foreach ($statements as $statement) {
$results = array_merge($results, $this->getExecuteStatementSQL($statement));
}
}
return $results;
}
/**
* This function will return the code needed to execute a collection
* of sentences present inside one statement for the specified BD
* and prefix.
* For now it only supports INSERT statements
*/
public function getExecuteStatementSQL($xmldb_statement) {
$results = array();
/// Based on statement type
switch ($xmldb_statement->type) {
case XMLDB_STATEMENT_INSERT:
$results = $this->getExecuteInsertSQL($xmldb_statement);
break;
case XMLDB_STATEMENT_UPDATE:
break;
case XMLDB_STATEMENT_DELETE:
break;
case XMLDB_STATEMENT_CUSTOM:
break;
}
return $results;
}
/**
@@ -156,16 +204,11 @@ class XMLDBgenerator {
* @param boolean to specify if the name must be quoted (if reserved word, only!)
* @return string the correct name of the table
*/
function getTableName($xmldb_table, $quoted = true) {
$prefixtouse = $this->prefix;
/// Determinate if this table must have prefix or no
if (in_array($xmldb_table->getName(), $this->getTablesWithoutPrefix())) {
$prefixtouse = '';
}
public function getTableName($xmldb_table, $quoted=true) {
/// Get the name
$tablename = $prefixtouse . $xmldb_table->getName();
/// Apply quotes conditionally
$tablename = $this->prefix.$xmldb_table->getName();
/// Apply quotes optionally
if ($quoted) {
$tablename = $this->getEncQuoted($tablename);
}
@@ -177,7 +220,7 @@ class XMLDBgenerator {
* Given one correct XMLDBTable, returns the SQL statements
* to create it (inside one array)
*/
function getCreateTableSQL($xmldb_table) {
public function getCreateTableSQL($xmldb_table) {
$results = array(); //Array where all the sentences will be stored
@@ -188,12 +231,6 @@ class XMLDBgenerator {
return $results;
}
/// Prevent tables without prefix to be duplicated (part of MDL-6614)
if (in_array($xmldb_table->getName(), $this->getTablesWithoutPrefix()) &&
table_exists($xmldb_table)) {
return $results; // false here would break the install, empty array is better ;-)
}
/// Add the fields, separated by commas
foreach ($xmldb_fields as $xmldb_field) {
$table .= "\n " . $this->getFieldSQL($xmldb_field);
@@ -233,7 +270,7 @@ class XMLDBgenerator {
/// Add comments if specified and it exists
if ($this->add_table_comments && $xmldb_table->getComment()) {
$comment = $this->getCommentSQL ($xmldb_table);
$comment = $this->getCommentSQL($xmldb_table);
/// Add the COMMENT to results
$results = array_merge($results, $comment);
}
@@ -242,7 +279,7 @@ class XMLDBgenerator {
if ($xmldb_indexes = $xmldb_table->getIndexes()) {
foreach ($xmldb_indexes as $xmldb_index) {
///Only process all this if the index doesn't exist in DB
if (!index_exists($xmldb_table, $xmldb_index)) {
if (!$this->mdb->get_manager()->index_exists($xmldb_table, $xmldb_index)) {
if ($indextext = $this->getCreateIndexSQL($xmldb_table, $xmldb_index)) {
$results = array_merge($results, $indextext);
}
@@ -253,14 +290,14 @@ class XMLDBgenerator {
/// 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
/// 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 XMLDBIndex('anyname');
$index->setFields($xmldb_key->getFields());
///Only process all this if the index doesn't exist in DB
if (!index_exists($xmldb_table, $index)) {
if (!$this->mdb->get_manager()->index_exists($xmldb_table, $index)) {
$createindex = false; //By default
switch ($xmldb_key->getType()) {
case XMLDB_KEY_UNIQUE:
@@ -304,7 +341,7 @@ class XMLDBgenerator {
* Given one correct XMLDBIndex, returns the SQL statements
* needed to create it (in array)
*/
function getCreateIndexSQL ($xmldb_table, $xmldb_index) {
public function getCreateIndexSQL($xmldb_table, $xmldb_index) {
$unique = '';
$suffix = 'ix';
@@ -324,7 +361,7 @@ class XMLDBgenerator {
/**
* Given one correct XMLDBField, returns the complete SQL line to create it
*/
function getFieldSQL($xmldb_field, $skip_type_clause = false, $skip_default_clause = false, $skip_notnull_clause = false) {
public function getFieldSQL($xmldb_field, $skip_type_clause = false, $skip_default_clause = false, $skip_notnull_clause = false) {
/// First of all, convert integers to numbers if defined
if ($this->integer_to_number) {
@@ -372,16 +409,15 @@ class XMLDBgenerator {
}
}
/// Calculate the default clause
$default_clause = '';
if (!$skip_default_clause) { //Only if we don't want to skip it
$default = $this->getDefaultClause($xmldb_field);
} else {
$default = '';
$default_clause = $this->getDefaultClause($xmldb_field);
}
/// Based on default_after_null, set both clauses properly
if ($this->default_after_null) {
$field .= $notnull . $default;
$field .= $notnull . $default_clause;
} else {
$field .= $default . $notnull;
$field .= $default_clause . $notnull;
}
/// The sequence
if ($xmldb_field->getSequence()) {
@@ -394,7 +430,8 @@ class XMLDBgenerator {
if ($this->sequence_only) {
/// We only want the field name and sequence name to be printed
/// so, calculate it and return
return $this->getEncQuoted($xmldb_field->getName()) . ' ' . $sequencename;
$sql = $this->getEncQuoted($xmldb_field->getName()) . ' ' . $sequencename;
return $sql;
}
}
return $field;
@@ -403,7 +440,7 @@ class XMLDBgenerator {
/**
* Given one correct XMLDBKey, returns its specs
*/
function getKeySQL ($xmldb_table, $xmldb_key) {
public function getKeySQL($xmldb_table, $xmldb_key) {
$key = '';
@@ -441,14 +478,14 @@ class XMLDBgenerator {
/**
* Give one XMLDBField, returns the correct "default value" for the current configuration
*/
function getDefaultValue ($xmldb_field) {
public function getDefaultValue($xmldb_field) {
$default = null;
if ($xmldb_field->getDefault() !== NULL) {
if ($xmldb_field->getType() == XMLDB_TYPE_CHAR ||
$xmldb_field->getType() == XMLDB_TYPE_TEXT) {
$default = "'" . addslashes($xmldb_field->getDefault()) . "'";
$default = "'" . $this->addslashes($xmldb_field->getDefault()) . "'";
} else {
$default = $xmldb_field->getDefault();
}
@@ -462,10 +499,10 @@ class XMLDBgenerator {
} 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 ($this->drop_default_clause_required &&
if ($this->drop_default_value_required &&
$xmldb_field->getType() != XMLDB_TYPE_TEXT &&
$xmldb_field->getType() != XMLDB_TYPE_BINARY && !$xmldb_field->getNotNull()) {
$default = $this->drop_default_clause;
$default = $this->drop_default_value;
}
}
}
@@ -475,7 +512,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBField, returns the correct "default clause" for the current configuration
*/
function getDefaultClause ($xmldb_field) {
public function getDefaultClause($xmldb_field) {
$defaultvalue = $this->getDefaultValue ($xmldb_field);
@@ -490,7 +527,7 @@ class XMLDBgenerator {
* Given one correct XMLDBTable and the new name, returns the SQL statements
* to rename it (inside one array)
*/
function getRenameTableSQL($xmldb_table, $newname) {
public function getRenameTableSQL($xmldb_table, $newname) {
$results = array(); //Array where all the sentences will be stored
@@ -501,11 +538,9 @@ class XMLDBgenerator {
$results[] = $rename;
/// Call to getRenameTableExtraSQL() if $rename_table_extra_code is enabled. It will add sequence regeneration code.
if ($this->rename_table_extra_code) {
$extra_sentences = $this->getRenameTableExtraSQL($xmldb_table, $newname);
$results = array_merge($results, $extra_sentences);
}
/// Call to getRenameTableExtraSQL() override if needed
$extra_sentences = $this->getRenameTableExtraSQL($xmldb_table, $newname);
$results = array_merge($results, $extra_sentences);
return $results;
}
@@ -514,7 +549,7 @@ class XMLDBgenerator {
* Given one correct XMLDBTable and the new name, returns the SQL statements
* to drop it (inside one array)
*/
function getDropTableSQL($xmldb_table) {
public function getDropTableSQL($xmldb_table) {
$results = array(); //Array where all the sentences will be stored
@@ -522,11 +557,9 @@ class XMLDBgenerator {
$results[] = $drop;
/// call to getDropTableExtraSQL() if $drop_table_extra_code is enabled. It will add sequence/trigger drop code.
if ($this->drop_table_extra_code) {
$extra_sentences = $this->getDropTableExtraSQL($xmldb_table);
$results = array_merge($results, $extra_sentences);
}
/// call to getDropTableExtraSQL(), override if needed
$extra_sentences = $this->getDropTableExtraSQL($xmldb_table);
$results = array_merge($results, $extra_sentences);
return $results;
}
@@ -534,7 +567,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add the field to the table
*/
function getAddFieldSQL($xmldb_table, $xmldb_field) {
public function getAddFieldSQL($xmldb_table, $xmldb_field) {
$results = array();
@@ -542,13 +575,13 @@ class XMLDBgenerator {
$tablename = $this->getTableName($xmldb_table);
/// Build the standard alter table add
$altertable = 'ALTER TABLE ' . $tablename . ' ADD ' .
$this->getFieldSQL($xmldb_field, $this->alter_column_skip_type,
$this->alter_column_skip_default,
$this->alter_column_skip_notnull);
$sql = $this->getFieldSQL($xmldb_field, $this->alter_column_skip_type,
$this->alter_column_skip_default,
$this->alter_column_skip_notnull);
$altertable = 'ALTER TABLE ' . $tablename . ' ADD ' . $sql;
/// Add the after clause if necesary
if ($this->add_after_clause && $xmldb_field->getPrevious()) {
$altertable .= ' after ' . $this->getEncQuoted($xmldb_field->getPrevious());
$altertable .= ' AFTER ' . $this->getEncQuoted($xmldb_field->getPrevious());
}
$results[] = $altertable;
@@ -566,7 +599,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop the field from the table
*/
function getDropFieldSQL($xmldb_table, $xmldb_field) {
public function getDropFieldSQL($xmldb_table, $xmldb_field) {
$results = array();
@@ -583,7 +616,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to alter the field in the table
*/
function getAlterFieldSQL($xmldb_table, $xmldb_field) {
public function getAlterFieldSQL($xmldb_table, $xmldb_field) {
$results = array();
@@ -596,9 +629,10 @@ class XMLDBgenerator {
/// Build de alter sentence using the alter_column_sql template
$alter = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->alter_column_sql);
$alter = str_replace('COLUMNSPECS', $this->getFieldSQL($xmldb_field, $this->alter_column_skip_type,
$this->alter_column_skip_default,
$this->alter_column_skip_notnull), $alter);
$colspec = $this->getFieldSQL($xmldb_field, $this->alter_column_skip_type,
$this->alter_column_skip_default,
$this->alter_column_skip_notnull);
$alter = str_replace('COLUMNSPECS', $colspec, $alter);
/// Add the after clause if necesary
if ($this->add_after_clause && $xmldb_field->getPrevious()) {
@@ -614,7 +648,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to modify the enum of the field in the table
*/
function getModifyEnumSQL($xmldb_table, $xmldb_field) {
public function getModifyEnumSQL($xmldb_table, $xmldb_field) {
$results = array();
@@ -635,7 +669,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to modify the default of the field in the table
*/
function getModifyDefaultSQL($xmldb_table, $xmldb_field) {
public function getModifyDefaultSQL($xmldb_table, $xmldb_field) {
$results = array();
@@ -657,7 +691,7 @@ class XMLDBgenerator {
* Given one correct XMLDBField and the new name, returns the SQL statements
* to rename it (inside one array)
*/
function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
public function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
$results = array(); //Array where all the sentences will be stored
@@ -678,11 +712,9 @@ class XMLDBgenerator {
$results[] = $rename;
/// Call to getRenameFieldExtraSQL() if $rename_column_extra_code is enabled (will add some required sentences)
if ($this->rename_column_extra_code) {
$extra_sentences = $this->getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname);
$results = array_merge($results, $extra_sentences);
}
/// Call to getRenameFieldExtraSQL(), override if needed
$extra_sentences = $this->getRenameFieldExtraSQL($xmldb_table, $xmldb_field, $newname);
$results = array_merge($results, $extra_sentences);
return $results;
}
@@ -691,7 +723,7 @@ class XMLDBgenerator {
* Given one XMLDBTable and one XMLDBKey, return the SQL statements needded to add the key to the table
* note that undelying indexes will be added as parametrised by $xxxx_keys and $xxxx_index parameters
*/
function getAddKeySQL($xmldb_table, $xmldb_key) {
public function getAddKeySQL($xmldb_table, $xmldb_key) {
$results = array();
@@ -702,7 +734,7 @@ class XMLDBgenerator {
$results[] = $key;
}
/// If we aren't creating the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
/// 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
@@ -713,7 +745,7 @@ class XMLDBgenerator {
}
$xmldb_index = new XMLDBIndex('anyname');
$xmldb_index->setAttributes($indextype, $xmldb_key->getFields());
if (!index_exists($xmldb_table, $xmldb_index)) {
if (!$this->mdb->get_manager()->index_exists($xmldb_table, $xmldb_index)) {
$results = array_merge($results, $this->getAddIndexSQL($xmldb_table, $xmldb_index));
}
}
@@ -724,7 +756,7 @@ class XMLDBgenerator {
$xmldb_key->setType(XMLDB_KEY_UNIQUE);
$results = array_merge($results, $this->getAddKeySQL($xmldb_table, $xmldb_key));
}
/// Return results
return $results;
}
@@ -732,7 +764,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to drop the index from the table
*/
function getDropKeySQL($xmldb_table, $xmldb_key) {
public function getDropKeySQL($xmldb_table, $xmldb_key) {
$results = array();
@@ -741,7 +773,7 @@ class XMLDBgenerator {
/// 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 = find_key_name($xmldb_table, $xmldb_key);
$dbkeyname = $this->mdb->get_manager()->find_key_name($xmldb_table, $xmldb_key);
/// Only if such type of key generation is enabled
$dropkey = false;
@@ -775,13 +807,13 @@ class XMLDBgenerator {
$results[] = $dropsql;
}
/// If we aren't dropping the keys OR if the key is XMLDB_KEY_FOREIGN (not underlying index generated
/// 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
$xmldb_index = new XMLDBIndex('anyname');
$xmldb_index->setAttributes(XMLDB_INDEX_UNIQUE, $xmldb_key->getFields());
if (index_exists($xmldb_table, $xmldb_index)) {
if ($this->mdb->get_manager()->index_exists($xmldb_table, $xmldb_index)) {
$results = array_merge($results, $this->getDropIndexSQL($xmldb_table, $xmldb_index));
}
}
@@ -792,7 +824,7 @@ class XMLDBgenerator {
$xmldb_key->setType(XMLDB_KEY_UNIQUE);
$results = array_merge($results, $this->getDropKeySQL($xmldb_table, $xmldb_key));
}
/// Return results
return $results;
}
@@ -802,12 +834,12 @@ class XMLDBgenerator {
* Experimental! Shouldn't be used at all!
*/
function getRenameKeySQL($xmldb_table, $xmldb_key, $newname) {
public function getRenameKeySQL($xmldb_table, $xmldb_key, $newname) {
$results = array();
/// Get the real key name
$dbkeyname = find_key_name($xmldb_table, $xmldb_key);
$dbkeyname = $this->mdb->get_manager()->find_key_name($xmldb_table, $xmldb_key);
/// Check we are really generating this type of keys
if (($xmldb_key->getType() == XMLDB_KEY_PRIMARY && !$this->primary_keys) ||
@@ -837,7 +869,7 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to add the index to the table
*/
function getAddIndexSQL($xmldb_table, $xmldb_index) {
public function getAddIndexSQL($xmldb_table, $xmldb_index) {
/// Just use the CreateIndexSQL function
return $this->getCreateIndexSQL($xmldb_table, $xmldb_index);
@@ -846,12 +878,12 @@ class XMLDBgenerator {
/**
* Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to drop the index from the table
*/
function getDropIndexSQL($xmldb_table, $xmldb_index) {
public function getDropIndexSQL($xmldb_table, $xmldb_index) {
$results = array();
/// Get the real index name
$dbindexname = find_index_name($xmldb_table, $xmldb_index);
$dbindexname = $this->mdb->get_manager()->find_index_name($xmldb_table, $xmldb_index);
/// Replace TABLENAME and INDEXNAME as needed
$dropsql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->drop_index_sql);
@@ -866,25 +898,20 @@ class XMLDBgenerator {
* Given one XMLDBTable and one XMLDBIndex, return the SQL statements needded to rename the index in the table
* Experimental! Shouldn't be used at all!
*/
function getRenameIndexSQL($xmldb_table, $xmldb_index, $newname) {
$results = array();
/// 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
$dbindexname = find_index_name($xmldb_table, $xmldb_index);
$dbindexname = $this->mdb->get_manager()->find_index_name($xmldb_table, $xmldb_index);
/// Replace TABLENAME and INDEXNAME as needed
$renamesql = str_replace('TABLENAME', $this->getTableName($xmldb_table), $this->rename_index_sql);
$renamesql = str_replace('OLDINDEXNAME', $dbindexname, $renamesql);
$renamesql = str_replace('NEWINDEXNAME', $newname, $renamesql);
/// Some DB doesn't support index renaming (MySQL) so this can be empty
if ($renamesql) {
$results[] = $renamesql;
}
return $results;
return array($renamesql);
}
/**
@@ -894,7 +921,7 @@ class XMLDBgenerator {
* IMPORTANT: This function must be used to CALCULATE NAMES of objects TO BE CREATED,
* NEVER TO GUESS NAMES of EXISTING objects!!!
*/
function getNameForObject($tablename, $fields, $suffix='') {
public function getNameForObject($tablename, $fields, $suffix='') {
$name = '';
@@ -969,7 +996,7 @@ class XMLDBgenerator {
* Given any string (or one array), enclose it by the proper quotes
* if it's a reserved word
*/
function getEncQuoted($input) {
public function getEncQuoted($input) {
if (is_array($input)) {
foreach ($input as $key=>$content) {
@@ -1017,7 +1044,7 @@ class XMLDBgenerator {
}
}
/// Values to be sent to DB must be properly escaped
$value = addslashes($value);
$value = $this->addslashes($value);
/// Back trimmed quotes
$value = "'" . $value . "'";
/// Back to the array
@@ -1044,7 +1071,7 @@ class XMLDBgenerator {
* in the $concat_character setting. If such setting is empty, then
* MySQL's CONCAT function will be used instead
*/
function getConcatSQL($elements) {
public function getConcatSQL($elements) {
/// Replace double quoted elements by single quotes
foreach($elements as $key => $element) {
@@ -1056,30 +1083,14 @@ class XMLDBgenerator {
}
/// Now call the standard sql_concat() DML function
return call_user_func_array('sql_concat', $elements);
}
/**
* Given one string (or one array), ends it with statement_end
*/
function getEndedStatements ($input) {
if (is_array($input)) {
foreach ($input as $key=>$content) {
$input[$key] = $this->getEndedStatements($content);
}
return $input;
} else {
$input = trim($input) . $this->statement_end;
return $input;
}
return call_user_func_array(array($this->mdb, 'sql_concat'), $elements);
}
/**
* Returns the name (string) of the sequence used in the table for the autonumeric pk
* Only some DB have this implemented
*/
function getSequenceFromDB($xmldb_table) {
public function getSequenceFromDB($xmldb_table) {
return false;
}
@@ -1090,8 +1101,8 @@ class XMLDBgenerator {
* (invoked from getNameForObject()
* Only some DB have this implemented
*/
function isNameInUse($object_name, $type, $table_name) {
return false; //For generators not implementing introspecion,
public function isNameInUse($object_name, $type, $table_name) {
return false; //For generators not implementing introspecion,
//we always return with the name being free to be used
}
@@ -1101,123 +1112,141 @@ class XMLDBgenerator {
/**
* Given one XMLDB Type, lenght and decimals, returns the DB proper SQL type
*/
function getTypeSQL ($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
return 'code for type(precision) goes to function getTypeSQL()';
}
public abstract function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null);
/**
* Given one XMLDB Field, return its enum SQL to be added inline with the column definition
*/
function getEnumSQL ($xmldb_field) {
return 'code for inline enum declaration goes to function getEnumSQL(). Can be disabled with enum_inline_code=false';
public function getEnumSQL($xmldb_field) {
return '';
}
/**
* Returns the code needed to create one enum for the xmldb_table and xmldb_field passes
*/
function getEnumExtraSQL ($xmldb_table, $xmldb_field) {
return 'Code for extra enum SQL goes to getEnumExtraSQL(). Can be disabled with enum_extra_code=false';
public function getEnumExtraSQL($xmldb_table, $xmldb_field) {
return '';
}
/**
* Returns the code (array of statements) needed to execute extra statements on field rename
*/
function getRenameFieldExtraSQL ($xmldb_table, $xmldb_field) {
return array('Code for field rename goes to getRenameFieldExtraSQL(). Can be disabled with rename_column_extra_code=false;');
public function getRenameFieldExtraSQL($xmldb_table, $xmldb_field) {
return array();
}
/**
* Returns the code (array of statements) needed
* to create one sequence for the xmldb_table and xmldb_field passes
*/
function getCreateSequenceSQL ($xmldb_table, $xmldb_field) {
return array('Code for extra sequence SQL goes to getCreateSequenceSQL(). Can be disabled with sequence_extra_code=false');
public function getCreateSequenceSQL($xmldb_table, $xmldb_field) {
return array();
}
/**
* Returns the code (array of statements) needed to add one comment to the table
*/
function getCommentSQL ($xmldb_table) {
return array('Code for table comment goes to getCommentSQL(). Can be disabled with add_table_comments=false;');
}
public abstract function getCommentSQL($xmldb_table);
/**
* Returns the code (array of statements) needed to execute extra statements on table rename
*/
function getRenameTableExtraSQL ($xmldb_table) {
return array('Code for table rename goes to getRenameTableExtraSQL(). Can be disabled with rename_table_extra_code=false;');
public function getRenameTableExtraSQL($xmldb_table) {
return array();
}
/**
* Returns the code (array of statements) needed to execute extra statements on table drop
*/
function getDropTableExtraSQL ($xmldb_table) {
return array('Code for table drop goes to getDropTableExtraSQL(). Can be disabled with drop_table_extra_code=false;');
public function getDropTableExtraSQL($xmldb_table) {
return array();
}
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its enum
* (usually invoked from getModifyEnumSQL()
*/
function getDropEnumSQL($xmldb_table, $xmldb_field) {
return array('Code to drop one enum goes to getDropEnumSQL()');
}
public abstract function getDropEnumSQL($xmldb_table, $xmldb_field);
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add its enum
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add its enum
* (usually invoked from getModifyEnumSQL()
*/
function getCreateEnumSQL($xmldb_table, $xmldb_field) {
return array('Code to create one enum goes to getCreateEnumSQL()');
}
public abstract function getCreateEnumSQL($xmldb_table, $xmldb_field);
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to drop its default
* (usually invoked from getModifyDefaultSQL()
*/
function getDropDefaultSQL($xmldb_table, $xmldb_field) {
return array('Code to drop one default goes to getDropDefaultSQL()');
}
public abstract function getDropDefaultSQL($xmldb_table, $xmldb_field);
/**
* Given one XMLDBTable and one optional XMLDBField, return one array with all the check
* constrainst found for that table (or field). Must exist for each DB supported.
* (usually invoked from find_check_constraint_name)
*/
function getCheckConstraintsFromDB($xmldb_table, $xmldb_field=null) {
return array('Code to fetch check constraints goes to getCheckConstraintsFromDB()');
}
public abstract function getCheckConstraintsFromDB($xmldb_table, $xmldb_field=null);
/**
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add its default
* Given one XMLDBTable and one XMLDBField, return the SQL statements needded to add its default
* (usually invoked from getModifyDefaultSQL()
*/
function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
return array('Code to create one default goes to getCreateDefaultSQL()');
}
public abstract function getCreateDefaultSQL($xmldb_table, $xmldb_field);
/**
* Returns an array of reserved words (lowercase) for this DB
* You MUST provide the real list for each DB inside every XMLDB class
*/
function getReservedWords() {
/// Some well-know reserved words
$reserved_words = array (
'user', 'scale', 'type', 'comment', 'view', 'value', 'table', 'index', 'key', 'sequence', 'trigger'
);
public static abstract function getReservedWords();
/**
* Returns all reserved works in supported databases.
* @return array ('word'=>array(databases))
*/
public static function getAllReservedWords() {
global $CFG;
$reserved_words = array();
require("$CFG->libdir/ddl/mysql_sql_generator.php");
require("$CFG->libdir/ddl/postgres_sql_generator.php");
require("$CFG->libdir/ddl/oracle_sql_generator.php");
require("$CFG->libdir/ddl/mssql_sql_generator.php");
foreach (mysql_sql_generator::getReservedWords() as $word) {
if (!isset($reserved_words[$word])) {
$reserved_words[$word] = array();
}
$reserved_words[$word][] = 'mysql';
}
foreach (postgres_sql_generator::getReservedWords() as $word) {
if (!isset($reserved_words[$word])) {
$reserved_words[$word] = array();
}
$reserved_words[$word][] = 'postgres';
}
foreach (oracle_sql_generator::getReservedWords() as $word) {
if (!isset($reserved_words[$word])) {
$reserved_words[$word] = array();
}
$reserved_words[$word][] = 'oracle';
}
foreach (mssql_sql_generator::getReservedWords() as $word) {
if (!isset($reserved_words[$word])) {
$reserved_words[$word] = array();
}
$reserved_words[$word][] = 'mssql';
}
ksort($reserved_words);
return $reserved_words;
}
/**
* Returns an array of tables to be built without prefix (lowercase)
* It's enough to keep updated here this function.
*/
function getTablesWithoutPrefix() {
/// Some well-known tables to be created without prefix
$tables = array (
'adodb_logsql'
);
return $tables;
public function addslashes($s) {
// do not use php addslashes() because it depends on PHP quote settings!
$s = str_replace('\\','\\\\',$s);
$s = str_replace("\0","\\\0", $s);
$s = str_replace("'", "\\'", $s);
return $s;
}
}
+134 -1321
View File
File diff suppressed because it is too large Load Diff
+454
View File
@@ -0,0 +1,454 @@
<?php //$Id$
require_once($CFG->libdir.'/adodb/adodb.inc.php');
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_recordset.php');
/**
* Abstract moodle database class
* @package dmlib
*/
abstract class adodb_moodle_database extends moodle_database {
protected $db;
protected $columns = array(); // I wish we had a shared memory cache for this :-(
public function __construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix);
}
public function connect() {
$this->db = ADONewConnection($this->get_dbtype());
global $db; $db = $this->db; // TODO: BC only for now
// See MDL-6760 for why this is necessary. In Moodle 1.8, once we start using NULLs properly,
// we probably want to change this value to ''.
$this->db->null2null = 'A long random string that will never, ever match something we want to insert into the database, I hope. \'';
if (!isset($this->dbpersist) or !empty($this->dbpersist)) { // Use persistent connection (default)
if (!$this->db->PConnect($this->dbhost, $this->dbuser, $this->dbpass, $this->dbname)) {
return false;
}
} else { // Use single connection
if (!$this->db->Connect($this->dbhost, $this->dbuser, $this->dbpass, $this->dbname)) {
return false;
}
}
$this->configure_dbconnection();
return true;
}
protected function configure_dbconnection() {
// empty
}
/**
* Returns database server info array
* @return array
*/
public function get_server_info() {
return $this->db->ServerInfo();
}
/**
* Return tables in database with WITHOUT current prefix
* @return array of table names in lowercase and without prefix
*/
public function get_tables() {
$metatables = $this->db->MetaTables();
$tables = array();
foreach ($metatables as $table) {
$table = strtolower($table);
if (strpos($table, $this->prefix) === 0) {
$tablename = substr($table, strlen($this->prefix));
$tables[$tablename] = $tablename;
}
}
return $tables;
}
/**
* Return table indexes
* @return array of arrays
*/
public function get_indexes($table) {
if (!$indexes = $this->db->MetaIndexes($this->prefix.$table)) {
return array();
}
$indexes = array_change_key_case($indexes, CASE_LOWER);
foreach ($indexes as $indexname => $index) {
$columns = $index['columns'];
/// column names always lowercase
$columns = array_map('strtolower', $columns);
$indexes[$indexname]['columns'] = $columns;
}
return $indexes;
}
public function get_columns($table) {
if (isset($this->columns[$table])) {
return $this->columns[$table];
}
if (!$columns = $this->db->MetaColumns($this->prefix.$table)) {
return array();
}
$this->columns[$table] = array();
foreach ($columns as $column) {
// colum names must be lowercase
$column->meta_type = substr($this->db->MetaType($column), 0 ,1); // only 1 character
$this->columns[$table][$column->name] = new database_column_info($column);
}
return $this->columns[$table];
}
public function reset_columns($table=null) {
if ($table) {
unset($this->columns[$table]);
} else {
$this->columns[$table] = array();
}
}
public function get_last_error() {
return $this->db->ErrorMsg();
}
/**
* Enable/disable very detailed debugging
* @param bool $state
*/
public function set_debug($state) {
$this->db->debug = $state;
}
/**
* Returns debug status
* @return bool $state
*/
public function get_debug() {
return $this->db->debug;
}
/**
* Enable/disable detailed sql logging
* @param bool $state
*/
public function set_logging($state) {
// TODO: adodb sql logging shares one table without prefix per db - this is no longer acceptable :-(
// we must create one table shared by all drivers
}
/**
* Do NOT use in code, to be used by database_manager only!
* @param string $sql query
* @return bool success
*/
public function change_database_structure($sql) {
if ($rs = $this->db->Execute($sql)) {
$result = true;
} else {
$result = false;
$this->report_error($sql);
}
return $result;
}
/**
* Execute general sql query. Should be used only when no other method suitable.
* Do NOT use this to make changes in db structure, use database_manager::execute_sql() instead!
* @param string $sql query
* @param array $params query parameters
* @return bool success
*/
public function execute($sql, array $params=null) {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
if (strpos($sql, ';') !== false) {
debugging('Error: Multiple sql statements found or bound parameters not used properly in query!');
return false;
}
if ($rs = $this->db->Execute($sql, $params)) {
$result = true;
$rs->Close();
} else {
$result = false;
$this->report_error($sql, $params);
}
return $result;
}
/**
* Insert new record into database, as fast as possible, no safety checks, lobs not supported.
* @param string $table name
* @param mixed $params data record as object or array
* @param bool $returnit return it of inserted record
* @param bool $bulk true means repeated inserts expected
* @return mixed success or new id
*/
public function insert_record_raw($table, $params, $returnid=true, $bulk=false) {
if (!is_array($params)) {
$params = (array)$params;
}
unset($params['id']);
if (empty($params)) {
return false;
}
$fields = implode(',', array_keys($params));
$qms = array_fill(0, count($params), '?');
$qms = implode(',', $qms);
$sql = "INSERT INTO {$this->prefix}$table ($fields) VALUES($qms)";
if (!$rs = $this->db->Execute($sql, $params)) {
$this->report_error($sql, $params);
return false;
}
if (!$returnid) {
return true;
}
if ($id = $this->db->Insert_ID()) {
return (int)$id;
}
return false;
}
/**
* Update record in database, as fast as possible, no safety checks, lobs not supported.
* @param string $table name
* @param mixed $params data record as object or array
* @param bool true means repeated updates expected
* @return bool success
*/
public function update_record_raw($table, $params, $bulk=false) {
if (!is_array($params)) {
$params = (array)$params;
}
if (!isset($params['id'])) {
return false;
}
$id = $params['id'];
unset($params['id']);
if (empty($params)) {
return false;
}
$sets = array();
foreach ($params as $field=>$value) {
$sets[] = "$field = ?";
}
$params[] = $id; // last ? in WHERE condition
$sets = implode(',', $sets);
$sql = "UPDATE {$this->prefix}$table SET $sets WHERE id=?";
if (!$rs = $this->db->Execute($sql, $params)) {
$this->report_error($sql, $params);
return false;
}
return true;
}
/**
* Delete one or more records from a table
*
* @param string $table The database table to be checked against.
* @param string $select A fragment of SQL to be used in a where clause in the SQL call (used to define the selection criteria).
* @param array $params array of sql parameters
* @return returns success.
*/
public function delete_records_select($table, $select, array $params=null) {
if ($select) {
$select = "WHERE $select";
}
$sql = "DELETE FROM {$this->prefix}$table $select";
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
$result = false;
if ($rs = $this->db->Execute($sql, $params)) {
$result = true;
$rs->Close();
} else {
$this-report_error($sql, $params);
}
return $result;
}
/**
* Get a number of records as an moodle_recordset. $sql must be a complete SQL query.
* Since this method is a little less readable, use of it should be restricted to
* code where it's possible there might be large datasets being returned. For known
* small datasets use get_records_sql - it leads to simpler code.
*
* The return type is as for @see function get_recordset.
*
* @param string $sql the SQL select query to execute.
* @param array $params array of sql parameters
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
* @return mixed an moodle_recorset object, or false if an error occured.
*/
public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
if ($limitfrom || $limitnum) {
///Special case, 0 must be -1 for ADOdb
$limitfrom = empty($limitfrom) ? -1 : $limitfrom;
$limitnum = empty($limitnum) ? -1 : $limitnum;
$rs = $this->db->SelectLimit($sql, $limitnum, $limitfrom, $params);
} else {
$rs = $this->db->Execute($sql, $params);
}
if (!$rs) {
$this->report_error($sql, $params);
return false;
}
return $this->create_recordset($rs);
}
protected function create_recordset($rs) {
return new adodb_moodle_recordset($rs);
}
/**
* Get a number of records as an array of objects.
*
* Return value as for @see function get_records.
*
* @param string $sql the SQL select query to execute. The first column of this SELECT statement
* must be a unique value (usually the 'id' field), as it will be used as the key of the
* returned array.
* @param array $params array of sql parameters
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
* @return mixed an array of objects, or empty array if no records were found, or false if an error occured.
*/
public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
if ($limitfrom || $limitnum) {
///Special case, 0 must be -1 for ADOdb
$limitfrom = empty($limitfrom) ? -1 : $limitfrom;
$limitnum = empty($limitnum) ? -1 : $limitnum;
$rs = $this->db->SelectLimit($sql, $limitnum, $limitfrom, $params);
} else {
$rs = $this->db->Execute($sql, $params);
}
if (!$rs) {
$this->report_error($sql, $params);
return false;
}
$return = $this->adodb_recordset_to_array($rs);
$rs->close();
return $return;
}
/**
* Selects rows and return values of first column as array.
*
* @param string $sql The SQL query
* @param array $params array of sql parameters
* @return mixed array of values or false if an error occured
*/
public function get_fieldset_sql($sql, array $params=null) {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
if (!$rs = $this->db->Execute($sql, $params)) {
$this->report_error($sql, $params);
return false;
}
$results = array();
while (!$rs->EOF) {
$res = reset($rs->fields);
$results[] = $res;
$rs->MoveNext();
}
$rs->Close();
return $results;
}
protected function adodb_recordset_to_array($rs) {
$debugging = debugging('', DEBUG_DEVELOPER);
if ($rs->EOF) {
// BIIIG change here - return empty array() if nothing found (2.0)
return array();
}
$objects = array();
/// First of all, we are going to get the name of the first column
/// to introduce it back after transforming the recordset to assoc array
/// See http://docs.moodle.org/en/XMLDB_Problems, fetch mode problem.
$firstcolumn = $rs->FetchField(0);
/// Get the whole associative array
if ($records = $rs->GetAssoc(true)) {
foreach ($records as $key => $record) {
$record = array($firstcolumn->name=>$key) + $record; /// Re-add the assoc field (as FIRST element since 2.0)
if ($debugging && array_key_exists($key, $objects)) {
debugging("Did you remember to make the first column something unique in your call to get_records? Duplicate value '$key' found in column '".$firstcolumn->name."'.", DEBUG_DEVELOPER);
}
$objects[$key] = (object) $record; /// To object
}
return $objects;
/// Fallback in case we only have 1 field in the recordset. MDL-5877
} else if ($rs->_numOfFields == 1 and $records = $rs->GetRows()) {
foreach ($records as $key => $record) {
if ($debugging && array_key_exists($record[$firstcolumn->name], $objects)) {
debugging("Did you remember to make the first column something unique in your call to get_records? Duplicate value '".$record[$firstcolumn->name]."' found in column '".$firstcolumn->name."'.", DEBUG_DEVELOPER);
}
$objects[$record[$firstcolumn->name]] = (object) $record; /// The key is the first column value (like Assoc)
}
return $objects;
} else {
// weird error?
return false;
}
}
public function sql_substr() {
return $this->db->substr;
}
public function sql_concat() {
$args = func_get_args();
return call_user_func_array(array($this->db, 'Concat'), $args);
}
public function sql_concat_join($separator="' '", $elements=array()) {
// Intersperse $elements in the array.
// Add items to the array on the fly, walking it
// _backwards_ splicing the elements in. The loop definition
// should skip first and last positions.
for ($n=count($elements)-1; $n > 0 ; $n--) {
array_splice($elements, $n, 0, $separator);
}
return call_user_func_array(array($this->db, 'Concat'), $elements);
}
public function begin_sql() {
$this->db->BeginTrans();
return true;
}
public function commit_sql() {
$this->db->CommitTrans();
return true;
}
public function rollback_sql() {
$this->db->RollbackTrans();
return true;
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* Adodb basic moodle recordset class
* @package dmlib
*/
class adodb_moodle_recordset implements moodle_recordset {
private $rs;
public function __construct($rs) {
$this->rs = $rs;
}
public function current() {
return (object)$this->rs->fields;
}
public function key() {
return $this->rs->_currentRow;
}
public function next() {
$this->rs->MoveNext();
}
public function rewind() {
$this->rs->MoveFirst();
}
public function valid() {
return !$this->rs->EOF;
}
public function close() {
$this->rs->Close();
$this->rs = null;
}
}
File diff suppressed because it is too large Load Diff
+385
View File
@@ -0,0 +1,385 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
/**
* MSSQL database class using adodb backend
* @package dmlib
*/
class mssql_adodb_moodle_database extends adodb_moodle_database {
function __construct ($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
if ($prefix=='') {
print_error('prefixcannotbeempty', 'debug', '', array($prefix, $this->get_dbfamily()));
}
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, false, $prefix);
}
protected function configure_dbconnection() {
if (!defined('ADODB_ASSOC_CASE')) {
define ('ADODB_ASSOC_CASE', 2);
}
$this->db->SetFetchMode(ADODB_ASSOC_CASE);
/// No need to set charset. It must be specified in the driver conf
/// Allow quoted identifiers
$this->db->Execute('SET QUOTED_IDENTIFIER ON');
/// Force ANSI nulls so the NULL check was done by IS NULL and NOT IS NULL
/// instead of equal(=) and distinct(<>) simbols
$this->db->Execute('SET ANSI_NULLS ON');
/// Enable sybase quotes, so addslashes and stripslashes will use "'"
ini_set('magic_quotes_sybase', '1');
/// NOTE: Not 100% useful because GPC has been addslashed with the setting off
/// so IT'S MANDATORY TO CHANGE THIS UNDER php.ini or .htaccess for this DB
/// or to turn off magic_quotes to allow Moodle to do it properly
return true;
}
/**
* Returns database family type
* @return string db family name (mysql, postgres, mssql, oracle, etc.)
*/
public function get_dbfamily() {
return 'mssql';
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'mssql';
}
/**
* Returns supported query parameter types
* @return bitmask
*/
protected function allowed_param_types() {
return SQL_PARAMS_QM;
}
public function sql_cast_char2int($fieldname, $text=false) {
if (!$text) {
return ' CAST(' . $fieldname . ' AS INT) ';
} else {
return ' CAST(' . sql_compare_text($fieldname) . ' AS INT) ';
}
}
public function sql_order_by_text($fieldname, $numchars=32) {
return 'CONVERT(varchar, ' . $fieldname . ', ' . $numchars . ')';
}
public function sql_isempty($tablename, $fieldname, $nullablefield, $textfield) {
if ($textfield) {
return " ".sql_compare_text($fieldname)." = '' ";
} else {
return " $fieldname = '' ";
}
}
/**
* Update a record in a table
*
* $dataobject is an object containing needed data
* Relies on $dataobject having a variable "id" to
* specify the record to update
*
* @param string $table The database table to be checked against.
* @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified.
* @param bool true means repeated updates expected
* @return bool success
*/
public function update_record($table, $dataobject, $bulk=false) {
error('todo');
global $db, $CFG;
if (! isset($dataobject->id) ) {
return false;
}
/// Check we are handling a proper $dataobject
if (is_array($dataobject)) {
debugging('Warning. Wrong call to update_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER);
$dataobject = (object)$dataobject;
}
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
if (!empty($CFG->rolesactive)) {
if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) {
if (debugging()) { var_dump(debug_backtrace()); }
print_error('This SQL relies on obsolete tables ('.$table.')! Your code must be fixed by a developer.');
}
}
/// Begin DIRTY HACK
if ($CFG->dbfamily == 'oracle') {
oracle_dirty_hack($table, $dataobject); // Convert object to the correct "empty" values for Oracle DB
}
/// End DIRTY HACK
/// Under Oracle, MSSQL and PostgreSQL we have our own update record process
/// detect all the clob/blob fields and delete them from the record being updated
/// saving them into $foundclobs and $foundblobs [$fieldname]->contents
/// They will be updated later
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres')
&& !empty($dataobject->id)) {
/// Detect lobs
$foundclobs = array();
$foundblobs = array();
db_detect_lobs($table, $dataobject, $foundclobs, $foundblobs, true);
}
// Determine all the fields in the table
if (!$columns = $db->MetaColumns($CFG->prefix . $table)) {
return false;
}
$data = (array)$dataobject;
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
// Pull out data matching these fields
$update = array();
foreach ($columns as $column) {
if ($column->name == 'id') {
continue;
}
if (array_key_exists($column->name, $data)) {
$key = $column->name;
$value = $data[$key];
if (is_null($value)) {
$update[] = "$key = NULL"; // previously NULLs were not updated
} else if (is_bool($value)) {
$value = (int)$value;
$update[] = "$key = $value"; // lets keep pg happy, '' is not correct smallint MDL-13038
} else {
$update[] = "$key = '$value'"; // All incoming data is already quoted
}
}
}
/// Only if we have fields to be updated (this will prevent both wrong updates +
/// updates of only LOBs in Oracle
if ($update) {
$query = "UPDATE {$CFG->prefix}{$table} SET ".implode(',', $update)." WHERE id = {$dataobject->id}";
if (!$rs = $db->Execute($query)) {
debugging($db->ErrorMsg() .'<br /><br />'.s($query));
if (!empty($CFG->dblogerror)) {
$debug=array_shift(debug_backtrace());
error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $query");
}
return false;
}
}
/// Under Oracle, MSSQL and PostgreSQL, finally, update all the Clobs and Blobs present in the record
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') &&
!empty($dataobject->id) &&
(!empty($foundclobs) || !empty($foundblobs))) {
if (!db_update_lobs($table, $dataobject->id, $foundclobs, $foundblobs)) {
return false; //Some error happened while updating LOBs
}
}
return true;
}
/**
* Insert a record into a table and return the "id" field if required,
* Some conversions and safety checks are carried out. Lobs are supported.
* If the return ID isn't required, then this just reports success as true/false.
* $data is an object containing needed data
* @param string $table The database table to be inserted into
* @param object $data A data object with values for one or more fields in the record
* @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned.
* @param bool $bulk true means repeated inserts expected
* @return mixed success or new ID
*/
public function insert_record($table, $dataobject, $returnid=true, $bulk=false) {
error('todo');
///////////////////////////////////////////////////////////////
/// TODO: keeping this for now - only mysql implemented ;-) ///
///////////////////////////////////////////////////////////////
global $db, $CFG, $empty_rs_cache;
if (empty($db)) {
return false;
}
/// Check we are handling a proper $dataobject
if (is_array($dataobject)) {
debugging('Warning. Wrong call to insert_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER);
$dataobject = (object)$dataobject;
}
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
if (!empty($CFG->rolesactive)) {
if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) {
if (debugging()) { var_dump(debug_backtrace()); }
print_error('This SQL relies on obsolete tables ('.$table.')! Your code must be fixed by a developer.');
}
}
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
/// In Moodle we always use auto-numbering fields for the primary key
/// so let's unset it now before it causes any trouble later
unset($dataobject->{$primarykey});
/// Get an empty recordset. Cache for multiple inserts.
if (empty($empty_rs_cache[$table])) {
/// Execute a dummy query to get an empty recordset
if (!$empty_rs_cache[$table] = $db->Execute('SELECT * FROM '. $CFG->prefix . $table .' WHERE '. $primarykey .' = \'-1\'')) {
return false;
}
}
$rs = $empty_rs_cache[$table];
/// Postgres doesn't have the concept of primary key built in
/// and will return the OID which isn't what we want.
/// The efficient and transaction-safe strategy is to
/// move the sequence forward first, and make the insert
/// with an explicit id.
if ( $CFG->dbfamily === 'postgres' && $returnid == true ) {
if ($nextval = (int)get_field_sql("SELECT NEXTVAL('{$CFG->prefix}{$table}_{$primarykey}_seq')")) {
$dataobject->{$primarykey} = $nextval;
}
}
/// Begin DIRTY HACK
if ($CFG->dbfamily == 'oracle') {
oracle_dirty_hack($table, $dataobject); // Convert object to the correct "empty" values for Oracle DB
}
/// End DIRTY HACK
/// Under Oracle, MSSQL and PostgreSQL we have our own insert record process
/// detect all the clob/blob fields and change their contents to @#CLOB#@ and @#BLOB#@
/// saving them into $foundclobs and $foundblobs [$fieldname]->contents
/// Same for mssql (only processing blobs - image fields)
if ($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') {
$foundclobs = array();
$foundblobs = array();
db_detect_lobs($table, $dataobject, $foundclobs, $foundblobs);
}
/// Under Oracle, if the primary key inserted has been requested OR
/// if there are LOBs to insert, we calculate the next value via
/// explicit query to the sequence.
/// Else, the pre-insert trigger will do the job, because the primary
/// key isn't needed at all by the rest of PHP code
if ($CFG->dbfamily === 'oracle' && ($returnid == true || !empty($foundclobs) || !empty($foundblobs))) {
/// We need this here (move this function to dmlib?)
include_once($CFG->libdir . '/ddllib.php');
$xmldb_table = new XMLDBTable($table);
$seqname = find_sequence_name($xmldb_table);
if (!$seqname) {
/// Fallback, seqname not found, something is wrong. Inform and use the alternative getNameForObject() method
debugging('Sequence name for table ' . $table->getName() . ' not found', DEBUG_DEVELOPER);
$generator = new XMLDBoci8po();
$generator->setPrefix($CFG->prefix);
$seqname = $generator->getNameForObject($table, $primarykey, 'seq');
}
if ($nextval = (int)$db->GenID($seqname)) {
$dataobject->{$primarykey} = $nextval;
} else {
debugging('Not able to get value from sequence ' . $seqname, DEBUG_DEVELOPER);
}
}
/// Get the correct SQL from adoDB
if (!$insertSQL = $db->GetInsertSQL($rs, (array)$dataobject, true)) {
return false;
}
/// Under Oracle, MSSQL and PostgreSQL, replace all the '@#CLOB#@' and '@#BLOB#@' ocurrences to proper default values
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') &&
(!empty($foundclobs) || !empty($foundblobs))) {
/// Initial configuration, based on DB
switch ($CFG->dbfamily) {
case 'oracle':
$clobdefault = 'empty_clob()'; //Value of empty default clobs for this DB
$blobdefault = 'empty_blob()'; //Value of empty default blobs for this DB
break;
case 'mssql':
case 'postgres':
$clobdefault = 'null'; //Value of empty default clobs for this DB (under mssql this won't be executed
$blobdefault = 'null'; //Value of empty default blobs for this DB
break;
}
$insertSQL = str_replace("'@#CLOB#@'", $clobdefault, $insertSQL);
$insertSQL = str_replace("'@#BLOB#@'", $blobdefault, $insertSQL);
}
/// Run the SQL statement
if (!$rs = $db->Execute($insertSQL)) {
debugging($db->ErrorMsg() .'<br /><br />'.s($insertSQL));
if (!empty($CFG->dblogerror)) {
$debug=array_shift(debug_backtrace());
error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $insertSQL");
}
return false;
}
/// Under Oracle and PostgreSQL, finally, update all the Clobs and Blobs present in the record
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'postgres') &&
!empty($dataobject->{$primarykey}) &&
(!empty($foundclobs) || !empty($foundblobs))) {
if (!db_update_lobs($table, $dataobject->{$primarykey}, $foundclobs, $foundblobs)) {
return false; //Some error happened while updating LOBs
}
}
/// If a return ID is not needed then just return true now (but not in MSSQL DBs, where we may have some pending tasks)
if (!$returnid && $CFG->dbfamily != 'mssql') {
return true;
}
/// We already know the record PK if it's been passed explicitly,
/// or if we've retrieved it from a sequence (Postgres and Oracle).
if (!empty($dataobject->{$primarykey})) {
return $dataobject->{$primarykey};
}
/// This only gets triggered with MySQL and MSQL databases
/// however we have some postgres fallback in case we failed
/// to find the sequence.
$id = $db->Insert_ID();
/// Under MSSQL all the Clobs and Blobs (IMAGE) present in the record
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'mssql') &&
!empty($id) &&
(!empty($foundclobs) || !empty($foundblobs))) {
if (!db_update_lobs($table, $id, $foundclobs, $foundblobs)) {
return false; //Some error happened while updating LOBs
}
}
if ($CFG->dbfamily === 'postgres') {
// try to get the primary key based on id
if ( ($rs = $db->Execute('SELECT '. $primarykey .' FROM '. $CFG->prefix . $table .' WHERE oid = '. $id))
&& ($rs->RecordCount() == 1) ) {
trigger_error("Retrieved $primarykey from oid on table $table because we could not find the sequence.");
return (integer)reset($rs->fields);
}
trigger_error('Failed to retrieve primary key after insert: SELECT '. $primarykey .
' FROM '. $CFG->prefix . $table .' WHERE oid = '. $id);
return false;
}
return (integer)$id;
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
require_once($CFG->libdir.'/dml/mssql_adodb_moodle_database.php');
/**
* MSSQL database class using adodb backend
* @package dmlib
*/
class mssql_n_adodb_moodle_database extends mssql_adodb_moodle_database {
function __construct ($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, false, $prefix);
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'mssql_n';
}
protected function configure_dbconnection() {
if (!defined('ADODB_ASSOC_CASE')) {
define ('ADODB_ASSOC_CASE', 0);
}
$this->db->SetFetchMode(ADODB_ASSOC_CASE);
/// No need to set charset. It must be specified in the driver conf
/// Allow quoted identifiers
$this->db->Execute('SET QUOTED_IDENTIFIER ON');
/// Force ANSI nulls so the NULL check was done by IS NULL and NOT IS NULL
/// instead of equal(=) and distinct(<>) simbols
$this->db->Execute('SET ANSI_NULLS ON');
/// Enable sybase quotes, so addslashes and stripslashes will use "'"
ini_set('magic_quotes_sybase', '1');
/// NOTE: Not 100% useful because GPC has been addslashed with the setting off
/// so IT'S MANDATORY TO CHANGE THIS UNDER php.ini or .htaccess for this DB
/// or to turn off magic_quotes to allow Moodle to do it properly
return true;
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
require_once($CFG->libdir.'/dml/mysqli_adodb_moodle_database.php');
/**
* Legacy MySQL database class using adodb backend
* @package dmlib
*/
class mysql_adodb_moodle_database extends mysqli_adodb_moodle_database {
protected $columns = array();
function __construct ($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix);
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'mysql';
}
}
+203
View File
@@ -0,0 +1,203 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
/**
* Recommended MySQL database class using adodb backend
* @package dmlib
*/
class mysqli_adodb_moodle_database extends adodb_moodle_database {
function __construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix);
}
protected function configure_dbconnection() {
if (!defined('ADODB_ASSOC_CASE')) {
define ('ADODB_ASSOC_CASE', 2);
}
$this->db->SetFetchMode(ADODB_ASSOC_CASE);
$this->db->Execute("SET NAMES 'utf8'");
return true;
}
/**
* Returns database family type
* @return string db family name (mysql, postgres, mssql, oracle, etc.)
*/
public function get_dbfamily() {
return 'mysql';
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'mysqli';
}
/**
* Returns supported query parameter types
* @return bitmask
*/
protected function allowed_param_types() {
return SQL_PARAMS_QM;
}
/**
* This method will introspect inside DB to detect it it's a UTF-8 DB or no
* Used from setup.php to set correctly "set names" when the installation
* process is performed without the initial and beautiful installer
* @return bool true if db in unicode mode
*/
function setup_is_unicodedb() {
$rs = $this->db->Execute("SHOW LOCAL VARIABLES LIKE 'character_set_database'");
if ($rs && !$rs->EOF) {
$records = $rs->GetAssoc(true);
$encoding = $records['character_set_database']['Value'];
if (strtoupper($encoding) == 'UTF8') {
return true;
}
}
return false;
}
/**
/* Tries to change default db encoding to utf8, if empty db
* @return bool sucecss
*/
public function change_db_encoding() {
// try forcing utf8 collation, if mysql db and no tables present
if (!$this->db->Metatables()) {
$SQL = 'ALTER DATABASE '.$this->dbname.' CHARACTER SET utf8';
$this->db->Execute($SQL);
if ($this->setup_is_unicodedb()) {
$this->configure_dbconnection();
return true;
} else {
return false;
}
} else {
return false;
}
}
/**
* Insert a record into a table and return the "id" field if required,
* Some conversions and safety checks are carried out. Lobs are supported.
* If the return ID isn't required, then this just reports success as true/false.
* $data is an object containing needed data
* @param string $table The database table to be inserted into
* @param object $data A data object with values for one or more fields in the record
* @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned.
* @param bool $bulk true means repeated inserts expected
* @return mixed success or new ID
*/
public function insert_record($table, $dataobject, $returnid=true, $bulk=false) {
if (!is_object($dataobject)) {
$dataobject = (object)$dataobject;
}
$columns = $this->get_columns($table);
unset($dataobject->id);
$cleaned = array();
foreach ($dataobject as $field=>$value) {
if (!isset($columns[$field])) {
continue;
}
if (is_bool($value)) {
$value = (int)$value; // prevent "false" problems
}
$cleaned[$field] = $value;
}
if (empty($cleaned)) {
return false;
}
return $this->insert_record_raw($table, $cleaned, $returnid, $bulk);
}
/**
* Update a record in a table
*
* $dataobject is an object containing needed data
* Relies on $dataobject having a variable "id" to
* specify the record to update
*
* @param string $table The database table to be checked against.
* @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified.
* @param bool true means repeated updates expected
* @return bool success
*/
public function update_record($table, $dataobject, $bulk=false) {
if (!is_object($dataobject)) {
$dataobject = (object)$dataobject;
}
if (!isset($dataobject->id) ) {
return false;
}
$columns = $this->get_columns($table);
$cleaned = array();
foreach ($dataobject as $field=>$value) {
if (!isset($columns[$field])) {
continue;
}
if (is_bool($value)) {
$value = (int)$value; // prevent "false" problems
}
$cleaned[$field] = $value;
}
return $this->update_record_raw($table, $cleaned, $bulk);
}
/**
* Set a single field in every table row where the select statement evaluates to true.
*
* @param string $table The database table to be checked against.
* @param string $newfield the field to set.
* @param string $newvalue the value to set the field to.
* @param string $select A fragment of SQL to be used in a where clause in the SQL call.
* @param array $params array of sql parameters
* @return bool success
*/
public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) {
if ($select) {
$select = "WHERE $select";
}
if (is_null($params)) {
$params = array();
}
list($select, $params, $type) = $this->fix_sql_params($select, $params);
if (is_bool($newvalue)) {
$newvalue = (int)$newvalue; // prevent "false" problems
}
if (is_null($newvalue)) {
$newfield = "$newfield = NULL";
} else {
$newfield = "$newfield = ?";
array_unshift($params, $newvalue);
}
$sql = "UPDATE {$this->prefix}$table SET $newfield $select";
if (!$rs = $this->db->Execute($sql, $params)) {
$this->report_error($sql, $params);
return false;
}
return true;
}
public function sql_cast_char2int($fieldname, $text=false) {
return ' CAST(' . $fieldname . ' AS SIGNED) ';
}
}
+483
View File
@@ -0,0 +1,483 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
require_once($CFG->libdir.'/dml/oci8po_adodb_moodle_recordset.php');
/**
* Oracle database class using adodb backend
* @package dmlib
*/
class oci8_adodb_moodle_database extends adodb_moodle_database {
function __construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
if ($prefix=='') {
print_error('prefixcannotbeempty', 'debug', '', array($prefix, $this->get_dbfamily()));
}
if (strlen($prefix) > 2) { //Max prefix length for Oracle is 2cc
print_error('prefixlimit', 'debug', '', $prefix);
}
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix);
}
protected function configure_dbconnection() {
if (!defined('ADODB_ASSOC_CASE')) {
define ('ADODB_ASSOC_CASE', 0); /// Use lowercase fieldnames for ADODB_FETCH_ASSOC
/// (only meaningful for oci8po, it's the default
/// for other DB drivers so this won't affect them)
}
/// Row prefetching uses a bit of memory but saves a ton
/// of network latency. With current AdoDB and PHP, only
/// Oracle uses this setting.
if (!defined('ADODB_PREFETCH_ROWS')) {
define ('ADODB_PREFETCH_ROWS', 1000);
}
$this->db->SetFetchMode(ADODB_ASSOC_CASE);
/// No need to set charset. It must be specified by the NLS_LANG env. variable
/// Enable sybase quotes, so addslashes and stripslashes will use "'"
ini_set('magic_quotes_sybase', '1');
/// NOTE: Not 100% useful because GPC has been addslashed with the setting off
/// so IT'S MANDATORY TO ENABLE THIS UNDER php.ini or .htaccess for this DB
/// or to turn off magic_quotes to allow Moodle to do it properly
/// Now set the decimal separator to DOT, Moodle & PHP will always send floats to
/// DB using DOTS. Manually introduced floats (if using other characters) must be
/// converted back to DOTs (like gradebook does)
$this->db->Execute("ALTER SESSION SET NLS_NUMERIC_CHARACTERS='.,'");
return true;
}
/**
* Returns database family type
* @return string db family name (mysql, postgres, mssql, oracle, etc.)
*/
public function get_dbfamily() {
return 'oracle';
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'oci8po';
}
/**
* Returns supported query parameter types
* @return bitmask
*/
protected function allowed_param_types() {
return SQL_PARAMS_NAMED;
}
/**
* This method will introspect inside DB to detect it it's a UTF-8 DB or no
* Used from setup.php to set correctly "set names" when the installation
* process is performed without the initial and beautiful installer
* @return bool true if db in unicode mode
*/
function setup_is_unicodedb() {
$rs = $this->db->Execute("SELECT parameter, value FROM nls_database_parameters where parameter = 'NLS_CHARACTERSET'");
if ($rs && !$rs->EOF) {
$encoding = $rs->fields['value'];
if (strtoupper($encoding) == 'AL32UTF8') {
return true;
}
}
return false;
}
/**
* Selects rows and return values of first column as array.
*
* @param string $sql The SQL query
* @param array $params array of sql parameters
* @return mixed array of values or false if an error occured
*/
public function get_fieldset_sql($sql, array $params=null) {
if ($result = parent::get_fieldset_sql($sql, $params)) {
array_walk($result, 'onespace2empty');
}
return $result;
}
protected function create_recordset($rs) {
return new oci8po_adodb_moodle_recordset($rs);
}
protected function adodb_recordset_to_array($rs) {
/// Really DIRTY HACK for Oracle - needed because it can not see difference from NULL and ''
/// this can not be removed even if we chane db defaults :-(
if ($result = parent::adodb_recordset_to_array($rs)) {
foreach ($result as $key=>$row) {
$row = (array)$row;
array_walk($row, 'onespace2empty');
$result[$key] = (object)$row;
}
}
return $result;
}
public function sql_bitand($int1, $int2) {
return 'bitand((' . $int1 . '), (' . $int2 . '))';
}
public function sql_bitnot($int1) {
return '((0 - (' . $int1 . ')) - 1)';
}
public function sql_bitor($int1, $int2) {
return '((' . $int1 . ') + (' . $int2 . ') - ' . sql_bitand($int1, $int2) . ')';
}
public function sql_bitxor($int1, $int2) {
return '((' . $int1 . ') # (' . $int2 . '))';
}
public function sql_cast_char2int($fieldname, $text=false) {
if (!$text) {
return ' CAST(' . $fieldname . ' AS INT) ';
} else {
return ' CAST(' . sql_compare_text($fieldname) . ' AS INT) ';
}
}
public function sql_order_by_text($fieldname, $numchars=32) {
return 'dbms_lob.substr(' . $fieldname . ', ' . $numchars . ',1)';
}
public function sql_isempty($tablename, $fieldname, $nullablefield, $textfield) {
if ($nullablefield) {
return " $fieldname IS NULL "; /// empties in nullable fields are stored as
} else { /// NULLs
if ($textfield) {
return " ".sql_compare_text($fieldname)." = ' ' "; /// oracle_dirty_hack inserts 1-whitespace
} else { /// in NOT NULL varchar and text columns so
return " $fieldname = ' ' "; /// we need to look for that in any situation
}
}
}
function sql_empty() {
return ' ';
}
/**
* Update a record in a table
*
* $dataobject is an object containing needed data
* Relies on $dataobject having a variable "id" to
* specify the record to update
*
* @param string $table The database table to be checked against.
* @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified.
* @param bool true means repeated updates expected
* @return bool success
*/
public function update_record($table, $dataobject, $bulk=false) {
error('todo');
global $db, $CFG;
if (! isset($dataobject->id) ) {
return false;
}
/// Check we are handling a proper $dataobject
if (is_array($dataobject)) {
debugging('Warning. Wrong call to update_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER);
$dataobject = (object)$dataobject;
}
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
if (!empty($CFG->rolesactive)) {
if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) {
if (debugging()) { var_dump(debug_backtrace()); }
print_error('This SQL relies on obsolete tables ('.$table.')! Your code must be fixed by a developer.');
}
}
/// Begin DIRTY HACK
if ($CFG->dbfamily == 'oracle') {
oracle_dirty_hack($table, $dataobject); // Convert object to the correct "empty" values for Oracle DB
}
/// End DIRTY HACK
/// Under Oracle, MSSQL and PostgreSQL we have our own update record process
/// detect all the clob/blob fields and delete them from the record being updated
/// saving them into $foundclobs and $foundblobs [$fieldname]->contents
/// They will be updated later
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres')
&& !empty($dataobject->id)) {
/// Detect lobs
$foundclobs = array();
$foundblobs = array();
db_detect_lobs($table, $dataobject, $foundclobs, $foundblobs, true);
}
// Determine all the fields in the table
if (!$columns = $db->MetaColumns($CFG->prefix . $table)) {
return false;
}
$data = (array)$dataobject;
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
// Pull out data matching these fields
$update = array();
foreach ($columns as $column) {
if ($column->name == 'id') {
continue;
}
if (array_key_exists($column->name, $data)) {
$key = $column->name;
$value = $data[$key];
if (is_null($value)) {
$update[] = "$key = NULL"; // previously NULLs were not updated
} else if (is_bool($value)) {
$value = (int)$value;
$update[] = "$key = $value"; // lets keep pg happy, '' is not correct smallint MDL-13038
} else {
$update[] = "$key = '$value'"; // All incoming data is already quoted
}
}
}
/// Only if we have fields to be updated (this will prevent both wrong updates +
/// updates of only LOBs in Oracle
if ($update) {
$query = "UPDATE {$CFG->prefix}{$table} SET ".implode(',', $update)." WHERE id = {$dataobject->id}";
if (!$rs = $db->Execute($query)) {
debugging($db->ErrorMsg() .'<br /><br />'.s($query));
if (!empty($CFG->dblogerror)) {
$debug=array_shift(debug_backtrace());
error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $query");
}
return false;
}
}
/// Under Oracle, MSSQL and PostgreSQL, finally, update all the Clobs and Blobs present in the record
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') &&
!empty($dataobject->id) &&
(!empty($foundclobs) || !empty($foundblobs))) {
if (!db_update_lobs($table, $dataobject->id, $foundclobs, $foundblobs)) {
return false; //Some error happened while updating LOBs
}
}
return true;
}
/**
* Insert a record into a table and return the "id" field if required,
* Some conversions and safety checks are carried out. Lobs are supported.
* If the return ID isn't required, then this just reports success as true/false.
* $data is an object containing needed data
* @param string $table The database table to be inserted into
* @param object $data A data object with values for one or more fields in the record
* @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned.
* @param bool $bulk true means repeated inserts expected
* @return mixed success or new ID
*/
public function insert_record($table, $dataobject, $returnid=true, $bulk=false) {
error('todo');
///////////////////////////////////////////////////////////////
/// TODO: keeping this for now - only mysql implemented ;-) ///
///////////////////////////////////////////////////////////////
global $db, $CFG, $empty_rs_cache;
if (empty($db)) {
return false;
}
/// Check we are handling a proper $dataobject
if (is_array($dataobject)) {
debugging('Warning. Wrong call to insert_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER);
$dataobject = (object)$dataobject;
}
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
if (!empty($CFG->rolesactive)) {
if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) {
if (debugging()) { var_dump(debug_backtrace()); }
print_error('This SQL relies on obsolete tables ('.$table.')! Your code must be fixed by a developer.');
}
}
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
/// In Moodle we always use auto-numbering fields for the primary key
/// so let's unset it now before it causes any trouble later
unset($dataobject->{$primarykey});
/// Get an empty recordset. Cache for multiple inserts.
if (empty($empty_rs_cache[$table])) {
/// Execute a dummy query to get an empty recordset
if (!$empty_rs_cache[$table] = $db->Execute('SELECT * FROM '. $CFG->prefix . $table .' WHERE '. $primarykey .' = \'-1\'')) {
return false;
}
}
$rs = $empty_rs_cache[$table];
/// Postgres doesn't have the concept of primary key built in
/// and will return the OID which isn't what we want.
/// The efficient and transaction-safe strategy is to
/// move the sequence forward first, and make the insert
/// with an explicit id.
if ( $CFG->dbfamily === 'postgres' && $returnid == true ) {
if ($nextval = (int)get_field_sql("SELECT NEXTVAL('{$CFG->prefix}{$table}_{$primarykey}_seq')")) {
$dataobject->{$primarykey} = $nextval;
}
}
/// Begin DIRTY HACK
if ($CFG->dbfamily == 'oracle') {
oracle_dirty_hack($table, $dataobject); // Convert object to the correct "empty" values for Oracle DB
}
/// End DIRTY HACK
/// Under Oracle, MSSQL and PostgreSQL we have our own insert record process
/// detect all the clob/blob fields and change their contents to @#CLOB#@ and @#BLOB#@
/// saving them into $foundclobs and $foundblobs [$fieldname]->contents
/// Same for mssql (only processing blobs - image fields)
if ($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') {
$foundclobs = array();
$foundblobs = array();
db_detect_lobs($table, $dataobject, $foundclobs, $foundblobs);
}
/// Under Oracle, if the primary key inserted has been requested OR
/// if there are LOBs to insert, we calculate the next value via
/// explicit query to the sequence.
/// Else, the pre-insert trigger will do the job, because the primary
/// key isn't needed at all by the rest of PHP code
if ($CFG->dbfamily === 'oracle' && ($returnid == true || !empty($foundclobs) || !empty($foundblobs))) {
/// We need this here (move this function to dmlib?)
include_once($CFG->libdir . '/ddllib.php');
$xmldb_table = new XMLDBTable($table);
$seqname = find_sequence_name($xmldb_table);
if (!$seqname) {
/// Fallback, seqname not found, something is wrong. Inform and use the alternative getNameForObject() method
debugging('Sequence name for table ' . $table->getName() . ' not found', DEBUG_DEVELOPER);
$generator = new XMLDBoci8po();
$generator->setPrefix($CFG->prefix);
$seqname = $generator->getNameForObject($table, $primarykey, 'seq');
}
if ($nextval = (int)$db->GenID($seqname)) {
$dataobject->{$primarykey} = $nextval;
} else {
debugging('Not able to get value from sequence ' . $seqname, DEBUG_DEVELOPER);
}
}
/// Get the correct SQL from adoDB
if (!$insertSQL = $db->GetInsertSQL($rs, (array)$dataobject, true)) {
return false;
}
/// Under Oracle, MSSQL and PostgreSQL, replace all the '@#CLOB#@' and '@#BLOB#@' ocurrences to proper default values
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql' || $CFG->dbfamily == 'postgres') &&
(!empty($foundclobs) || !empty($foundblobs))) {
/// Initial configuration, based on DB
switch ($CFG->dbfamily) {
case 'oracle':
$clobdefault = 'empty_clob()'; //Value of empty default clobs for this DB
$blobdefault = 'empty_blob()'; //Value of empty default blobs for this DB
break;
case 'mssql':
case 'postgres':
$clobdefault = 'null'; //Value of empty default clobs for this DB (under mssql this won't be executed
$blobdefault = 'null'; //Value of empty default blobs for this DB
break;
}
$insertSQL = str_replace("'@#CLOB#@'", $clobdefault, $insertSQL);
$insertSQL = str_replace("'@#BLOB#@'", $blobdefault, $insertSQL);
}
/// Run the SQL statement
if (!$rs = $db->Execute($insertSQL)) {
debugging($db->ErrorMsg() .'<br /><br />'.s($insertSQL));
if (!empty($CFG->dblogerror)) {
$debug=array_shift(debug_backtrace());
error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $insertSQL");
}
return false;
}
/// Under Oracle and PostgreSQL, finally, update all the Clobs and Blobs present in the record
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'postgres') &&
!empty($dataobject->{$primarykey}) &&
(!empty($foundclobs) || !empty($foundblobs))) {
if (!db_update_lobs($table, $dataobject->{$primarykey}, $foundclobs, $foundblobs)) {
return false; //Some error happened while updating LOBs
}
}
/// If a return ID is not needed then just return true now (but not in MSSQL DBs, where we may have some pending tasks)
if (!$returnid && $CFG->dbfamily != 'mssql') {
return true;
}
/// We already know the record PK if it's been passed explicitly,
/// or if we've retrieved it from a sequence (Postgres and Oracle).
if (!empty($dataobject->{$primarykey})) {
return $dataobject->{$primarykey};
}
/// This only gets triggered with MySQL and MSQL databases
/// however we have some postgres fallback in case we failed
/// to find the sequence.
$id = $db->Insert_ID();
/// Under MSSQL all the Clobs and Blobs (IMAGE) present in the record
/// if we know we have some of them in the query
if (($CFG->dbfamily == 'mssql') &&
!empty($id) &&
(!empty($foundclobs) || !empty($foundblobs))) {
if (!db_update_lobs($table, $id, $foundclobs, $foundblobs)) {
return false; //Some error happened while updating LOBs
}
}
if ($CFG->dbfamily === 'postgres') {
// try to get the primary key based on id
if ( ($rs = $db->Execute('SELECT '. $primarykey .' FROM '. $CFG->prefix . $table .' WHERE oid = '. $id))
&& ($rs->RecordCount() == 1) ) {
trigger_error("Retrieved $primarykey from oid on table $table because we could not find the sequence.");
return (integer)reset($rs->fields);
}
trigger_error('Failed to retrieve primary key after insert: SELECT '. $primarykey .
' FROM '. $CFG->prefix . $table .' WHERE oid = '. $id);
return false;
}
return (integer)$id;
}
}
/**
* This function is used to convert all the Oracle 1-space defaults to the empty string
* like a really DIRTY HACK to allow it to work better until all those NOT NULL DEFAULT ''
* fields will be out from Moodle.
* @param string the string to be converted to '' (empty string) if it's ' ' (one space)
* @param mixed the key of the array in case we are using this function from array_walk,
* defaults to null for other (direct) uses
* @return boolean always true (the converted variable is returned by reference)
*/
function onespace2empty(&$item, $key=null) {
$item = $item == ' ' ? '' : $item;
return true;
}
+41
View File
@@ -0,0 +1,41 @@
<?php
/**
* Oracle moodle recordest with special hacks
* @package dmlib
*/
class oci8po_adodb_moodle_recordset implements adodb_moodle_recordset {
private $rs;
public function __construct($rs) {
$this->rs = $rs;
}
public function current() {
/// Really DIRTY HACK for Oracle - needed because it can not see difference from NULL and ''
/// this can not be removed even if we chane db defaults :-(
$fields = $this->rs->fields;
array_walk($fields, 'onespace2empty');
return (object)$fields;
}
public function key() {
return $this->rs->_currentRow;
}
public function next() {
$this->rs->MoveNext();
}
public function rewind() {
$this->rs->MoveFirst();
}
public function valid() {
return !$this->rs->EOF;
}
public function close() {
$this->rs->Close();
}
}
@@ -0,0 +1,45 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
require_once($CFG->libdir.'/dml/mssql_adodb_moodle_database.php');
/**
* Experimenta mssql odbc database class using adodb backend
* @package dmlib
*/
class odbc_mssql_adodb_moodle_database extends mssql_adodb_moodle_database {
function __construct ($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, false, $prefix);
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'odbc_mssql';
}
protected function configure_dbconnection() {
if (!defined('ADODB_ASSOC_CASE')) {
define ('ADODB_ASSOC_CASE', 0);
}
$this->db->SetFetchMode(ADODB_ASSOC_CASE);
/// No need to set charset. It must be specified in the driver conf
/// Allow quoted identifiers
$this->db->Execute('SET QUOTED_IDENTIFIER ON');
/// Force ANSI nulls so the NULL check was done by IS NULL and NOT IS NULL
/// instead of equal(=) and distinct(<>) simbols
$this->db->Execute('SET ANSI_NULLS ON');
/// Enable sybase quotes, so addslashes and stripslashes will use "'"
ini_set('magic_quotes_sybase', '1');
/// NOTE: Not 100% useful because GPC has been addslashed with the setting off
/// so IT'S MANDATORY TO CHANGE THIS UNDER php.ini or .htaccess for this DB
/// or to turn off magic_quotes to allow Moodle to do it properly
return true;
}
}
+156
View File
@@ -0,0 +1,156 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/pdo_moodle_recordset.php');
/**
* Experimental pdo database class
* @package dmlib
*/
abstract class pdo_moodle_database extends moodle_database {
protected $pdb;
protected $columns = array(); // I wish we had a shared memory cache for this :-(
public function __construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix);
}
public function connect() {
try {
$this->pdb = new PDO('mysql:host='.$this->dbhost.';dbname='.$this->dbname, $this->dbuser, $this->pass, array(PDO::ATTR_PERSISTENT => $this->dbpresist));
$this->configure_dbconnection();
return true;
} catch (PDOException $ex) {
return false;
}
}
protected function configure_dbconnection() {
}
public function get_columns($table) {
if (isset($this->columns[$table])) {
return $this->columns[$table];
}
if (!$this->columns[$table] = array_change_key_case($this->db->MetaColumns($this->prefix.$table), CASE_LOWER)) {
$this->columns[$table] = array();
}
return $this->columns[$table];
}
public function reset_columns($table=null) {
if ($table) {
unset($this->columns[$table]);
} else {
$this->columns[$table] = array();
}
}
protected function report_error($sql, $params, $obj) {
debugging($e->getMessage() .'<br /><br />'. s($sql));
}
public function set_debug($state) {
//TODO
}
public function set_logging($state) {
//TODO
}
public function execute($sql, array $params=null) {
try {
//$this->reset_columns(); // TODO: do we need to clean the cache here??
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
$sth = $this->dbh->prepare($sql);
return $sth->execute($params);
} catch (PDOException $ex) {
$this->report_error($sql, $params, $ex);
return false;
}
}
public function delete_records_select($table, $select, array $params=null) {
try {
if ($select) {
$select = "WHERE $select";
}
$sql = "DELETE FROM {$this->prefix}$table $select";
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
$sth = $this->dbh->prepare($sql);
return $sth->execute($params);
} catch (PDOException $ex) {
$this->report_error($sql, $params, $ex);
return false;
}
}
public function get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
try {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
$sth = $this->dbh->prepare($sql);
error('TODO');
return $this->create_recordset($sth);
} catch (PDOException $ex) {
$this->report_error($sql, $params, $ex);
return false;
}
}
protected function create_recordset($sth) {
return new pdo_moodle_recordset($sth);
}
public function get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0) {
try {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
error('TODO');
} catch (PDOException $ex) {
$this->report_error($sql, $params, $ex);
return false;
}
}
public function get_fieldset_sql($sql, array $params=null) {
try {
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
error('TODO');
} catch (PDOException $ex) {
$this->report_error($sql, $params, $ex);
return false;
}
}
public function sql_substr() {
error('TODO');
}
public function sql_concat() {
error('TODO');
}
public function sql_concat_join($separator="' '", $elements=array()) {
error('TODO');
}
public function begin_sql() {
$this->pdb->beginTransaction();
return true;
}
public function commit_sql() {
$this->pdb->commit();
return true;
}
public function rollback_sql() {
$this->pdb->rollBack();
return true;
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* Experimental pdo recordset
* @package dmlib
*/
class adodb_moodle_recordset implements moodle_recordset {
private $sht;
public function __construct($sth) {
$this->sth = $sth;
}
public function current() {
error('TODO');
}
public function key() {
error('TODO');
}
public function next() {
error('TODO');
}
public function rewind() {
error('TODO');
}
public function valid() {
error('TODO');
}
public function close() {
$this->sth->closeCursor();
$this->sth = null;
}
}
+401
View File
@@ -0,0 +1,401 @@
<?php //$Id$
require_once($CFG->libdir.'/dml/moodle_database.php');
require_once($CFG->libdir.'/dml/adodb_moodle_database.php');
/**
* Postgresql database class using adodb backend
* @package dmlib
*/
class postgres7_adodb_moodle_database extends adodb_moodle_database {
function __construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix) {
if ($prefix=='') {
print_error('prefixcannotbeempty', 'debug', '', array($prefix, $this->get_dbfamily()));
}
parent::__construct($dbhost, $dbuser, $dbpass, $dbname, $dbpersist, $prefix);
}
/**
* Returns database family type
* @return string db family name (mysql, postgres, mssql, oracle, etc.)
*/
public function get_dbfamily() {
return 'postgres';
}
/**
* Returns database type
* @return string db type mysql, mysqli, postgres7
*/
protected function get_dbtype() {
return 'postgres7';
}
/**
* Returns supported query parameter types
* @return bitmask
*/
protected function allowed_param_types() {
return SQL_PARAMS_QM;
}
public function get_columns($table) {
if (isset($this->columns[$table])) {
return $this->columns[$table];
}
if (!$columns = $this->db->MetaColumns($this->prefix.$table)) {
return array();
}
$this->columns[$table] = array();
foreach ($columns as $column) {
// colum names must be lowercase
$column->meta_type = substr($this->db->MetaType($column), 0 ,1); // only 1 character
if ($column->has_default) {
if ($pos = strpos($column->default_value, '::')) {
if (strpos($column->default_value, "'") === 0) {
$column->default_value = substr($column->default_value, 1, $pos-2);
} else {
$column->default_value = substr($column->default_value, 0, $pos);
}
}
} else {
$column->default_value = null;
}
$this->columns[$table][$column->name] = new database_column_info($column);
}
return $this->columns[$table];
}
protected function configure_dbconnection() {
if (!defined('ADODB_ASSOC_CASE')) {
define ('ADODB_ASSOC_CASE', 2);
}
$this->db->SetFetchMode(ADODB_ASSOC_CASE);
$this->db->Execute("SET NAMES 'utf8'");
return true;
}
/**
* This method will introspect inside DB to detect it it's a UTF-8 DB or no
* Used from setup.php to set correctly "set names" when the installation
* process is performed without the initial and beautiful installer
* @return bool true if db in unicode mode
*/
function setup_is_unicodedb() {
/// Get PostgreSQL server_encoding value
$rs = $this->db->Execute("SHOW server_encoding");
if ($rs && !$rs->EOF) {
$encoding = $rs->fields['server_encoding'];
if (strtoupper($encoding) == 'UNICODE' || strtoupper($encoding) == 'UTF8') {
return true;
}
}
return false;
}
/**
* Insert new record into database, as fast as possible, no safety checks, lobs not supported.
* @param string $table name
* @param mixed $params data record as object or array
* @param bool $returnit return it of inserted record
* @param bool $bulk true means repeated inserts expected
* @return mixed success or new id
*/
public function insert_record_raw($table, $params, $returnid=true, $bulk=false) {
/// Postgres doesn't have the concept of primary key built in
/// and will return the OID which isn't what we want.
/// The efficient and transaction-safe strategy is to
/// move the sequence forward first, and make the insert
/// with an explicit id.
if (!is_array($params)) {
$params = (array)$params;
}
unset($params['id']);
if ($returnid) {
if ($nextval = $this->get_field_sql("SELECT NEXTVAL('{$this->prefix}{$table}_id_seq')")) {
$params['id'] = (int)$nextval;
}
}
if (empty($params)) {
return false;
}
$fields = implode(',', array_keys($params));
$qms = array_fill(0, count($params), '?');
$qms = implode(',', $qms);
$sql = "INSERT INTO {$this->prefix}$table ($fields) VALUES($qms)";
if (!$rs = $this->db->Execute($sql, $params)) {
$this->report_error($sql, $params);
return false;
}
if (!$returnid) {
return true;
}
if (!empty($params['id'])) {
return (int)$params['id'];
}
$oid = $this->db->Insert_ID();
// try to get the primary key based on id
$sql = "SELECT id FROM {$this->prefix}$table WHERE oid = $oid";
if ( ($rs = $this->db->Execute($sql))
&& ($rs->RecordCount() == 1) ) {
trigger_error("Retrieved id using oid on table $table because we could not find the sequence.");
return (integer)reset($rs->fields);
}
trigger_error("Failed to retrieve primary key after insert: $sql");
return false;
}
/**
* Insert a record into a table and return the "id" field if required,
* Some conversions and safety checks are carried out. Lobs are supported.
* If the return ID isn't required, then this just reports success as true/false.
* $data is an object containing needed data
* @param string $table The database table to be inserted into
* @param object $data A data object with values for one or more fields in the record
* @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned.
* @param bool $bulk true means repeated inserts expected
* @return mixed success or new ID
*/
public function insert_record($table, $dataobject, $returnid=true, $bulk=false) {
//TODO: add support for blobs BYTEA
if (!is_object($dataobject)) {
$dataobject = (object)$dataobject;
}
$columns = $this->get_columns($table);
unset($dataobject->id);
$cleaned = array();
$blobs = array();
foreach ($dataobject as $field=>$value) {
if (!isset($columns[$field])) {
continue;
}
$column = $columns[$field];
if ($column->meta_type == 'B') {
if (is_null($value)) {
$cleaned[$field] = null;
} else {
$blobs[$field] = $value;
$cleaned[$field] = '@#BLOB#@';
}
continue;
} else if (is_bool($value)) {
$value = (int)$value; // prevent false '' problems
} else if ($value === '') {
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
$value = 0; // prevent '' problems in numeric fields
}
}
$cleaned[$field] = $value;
}
if (empty($cleaned)) {
return false;
}
if (empty($blobs)) {
return $this->insert_record_raw($table, $cleaned, $returnid, $bulk);
}
if (!$id = $this->insert_record_raw($table, $cleaned, true, $bulk)) {
return false;
}
foreach ($blobs as $key=>$value) {
if (!$this->db->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB')) { // adodb does not use bound parameters for blob updates :-(
return false;
}
}
return ($returnid ? $id : true);
}
/**
* Update a record in a table
*
* $dataobject is an object containing needed data
* Relies on $dataobject having a variable "id" to
* specify the record to update
*
* @param string $table The database table to be checked against.
* @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified.
* @param bool true means repeated updates expected
* @return bool success
*/
public function update_record($table, $dataobject, $bulk=false) {
//TODO: add support for blobs BYTEA
if (!is_object($dataobject)) {
$dataobject = (object)$dataobject;
}
if (!isset($dataobject->id) ) {
return false;
}
$id = $dataobject->id;
$columns = $this->get_columns($table);
$cleaned = array();
$blobs = array();
foreach ($dataobject as $field=>$value) {
if (!isset($columns[$field])) {
continue;
}
$column = $columns[$field];
if ($column->meta_type == 'B') {
if (is_null($value)) {
$cleaned[$field] = null;
} else {
$blobs[$field] = $value;
$cleaned[$field] = '@#BLOB#@';
}
continue;
} else if (is_bool($value)) {
$value = (int)$value; // prevent "false" problems
} else if ($value === '') {
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
$value = 0; // prevent '' problems in numeric fields
}
}
$cleaned[$field] = $value;
}
if (!$this->update_record_raw($table, $cleaned, $bulk)) {
return false;
}
if (empty($blobs)) {
return true;
}
foreach ($blobs as $key=>$value) {
if (!$this->db->UpdateBlob($this->prefix.$table, $key, $value, "id = $id", 'BLOB')) { // adodb does not use bound parameters for blob updates :-(
return false;
}
}
return true;
}
/**
* Set a single field in every table row where the select statement evaluates to true.
*
* @param string $table The database table to be checked against.
* @param string $newfield the field to set.
* @param string $newvalue the value to set the field to.
* @param string $select A fragment of SQL to be used in a where clause in the SQL call.
* @param array $params array of sql parameters
* @return bool success
*/
public function set_field_select($table, $newfield, $newvalue, $select, array $params=null) {
$params = (array)$params;
list($select, $params, $type) = $this->fix_sql_params($select, $params);
$columns = $this->get_columns($table);
$column = $columns[$newfield];
if ($column->meta_type == 'B') {
/// update blobs and return
$select = $this->emulate_bound_params($select, $params); // adodb does not use bound parameters for blob updates :-(
if (!$this->db->UpdateBlob($this->prefix.$table, $newfield, $newvalue, $select, 'BLOB')) {
return false;
}
return true;
}
if ($select) {
$select = "WHERE $select";
}
/// normal field update
if (is_null($newvalue)) {
$newfield = "$newfield = NULL";
} else {
if (is_bool($newvalue)) {
$newvalue = (int)$newvalue; // prevent "false" problems
} else if ($newvalue === '') {
if ($column->meta_type == 'I' or $column->meta_type == 'F' or $column->meta_type == 'N') {
$newvalue = 0; // prevent '' problems in numeric fields
}
}
$newfield = "$newfield = ?";
array_unshift($params, $newvalue); // add as first param
}
$sql = "UPDATE {$this->prefix}$table SET $newfield $select";
if (!$rs = $this->db->Execute($sql, $params)) {
$this->report_error($sql, $params);
return false;
}
return true;
}
public function sql_ilike() {
return 'ILIKE';
}
public function sql_concat() {
$args = func_get_args();
/// PostgreSQL requires at least one char element in the concat, let's add it
/// here (at the beginning of the array) until ADOdb fixes it
if (is_array($args)) {
array_unshift($args , "''");
}
return call_user_func_array(array($this->db, 'Concat'), $args);
}
public function sql_bitxor($int1, $int2) {
return '(' . sql_bitor($int1, $int2) . ' - ' . sql_bitand($int1, $int2) . ')';
}
public function sql_cast_char2int($fieldname, $text=false) {
return ' CAST(' . $fieldname . ' AS INT) ';
}
/**
* Very ugly hack which emulates bound parameters in pg queries
* where params not supported :-(
*/
private function emulate_bound_params($sql, array $params=null) {
if (empty($params)) {
return $sql;
}
// ok, we have verified sql statement with ? and correct number of params
$return = strtok($sql, '?');
foreach ($params as $param) {
if (is_bool($param)) {
$return .= (int)$param;
} else if (is_null($param)) {
$return .= 'NULL';
} else if (is_numeric($param)) {
$return .= $param;
} else {
$param = $this->db->qstr($param);
$return .= "$param";
}
$return .= strtok('?');
}
return $return;
}
}
+312 -2620
View File
File diff suppressed because it is too large Load Diff
+1298
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -680,7 +680,7 @@ function environment_check_php($version) {
* @return object results encapsulated in one environment_result object
*/
function environment_check_unicode($version) {
global $db;
global $db, $DB;
$result = new environment_results('unicode');
@@ -704,7 +704,7 @@ function environment_check_unicode($version) {
$level = get_level($data['#']['UNICODE']['0']);
}
if (!$unicodedb = setup_is_unicodedb()) {
if (!$unicodedb = $DB->setup_is_unicodedb()) {
$result->setStatus(false);
} else {
$result->setStatus(true);
@@ -725,7 +725,7 @@ function environment_check_unicode($version) {
*/
function environment_check_database($version) {
global $db;
global $DB;
$result = new environment_results('database');
@@ -779,9 +779,9 @@ function environment_check_database($version) {
}
/// Now search the version we are using (depending of vendor)
$current_vendor = set_dbfamily();
$current_vendor = $DB->get_dbfamily();
$dbinfo = $db->ServerInfo();
$dbinfo = $DB->get_server_info();
$current_version = normalize_version($dbinfo['version']);
$needed_version = $vendors[$current_vendor];
+4 -4
View File
@@ -733,9 +733,9 @@ function send_file($path, $filename, $lifetime=86400 , $filter=0, $pathisstring=
}
function get_records_csv($file, $table) {
global $CFG, $db;
global $CFG, $DB;
if (!$metacolumns = $db->MetaColumns($CFG->prefix . $table)) {
if (!$metacolumns = $DB->get_columns($table)) {
return false;
}
@@ -773,14 +773,14 @@ function get_records_csv($file, $table) {
}
function put_records_csv($file, $records, $table = NULL) {
global $CFG, $db;
global $CFG, $DB;
if (empty($records)) {
return true;
}
$metacolumns = NULL;
if ($table !== NULL && !$metacolumns = $db->MetaColumns($CFG->prefix . $table)) {
if ($table !== NULL && !$metacolumns = $DB->get_columns($table)) {
return false;
}
+4 -2
View File
@@ -774,10 +774,12 @@ class grade_item extends grade_object {
* @return void
*/
function force_regrading() {
global $DB;
$this->needsupdate = 1;
//mark this item and course item only - categories and calculated items are always regraded
$wheresql = "(itemtype='course' OR id={$this->id}) AND courseid={$this->courseid}";
set_field_select('grade_items', 'needsupdate', 1, $wheresql);
$wheresql = "(itemtype='course' OR id=?) AND courseid=?";
$params = array($this->id, $this->courseid);
$DB->set_field_select('grade_items', 'needsupdate', 1, $wheresql, $params);
}
/**
+2 -1
View File
@@ -24,6 +24,7 @@
///////////////////////////////////////////////////////////////////////////
class grade_lib_wrapper {
/*
function get_records_sql($sql, $limitfrom='', $limitnum='') {
return get_records_sql($sql, $limitfrom, $limitnum);
}
@@ -107,7 +108,7 @@ class grade_lib_wrapper {
function rs_close(&$rs) {
return;
}
*/
function get_coursemodule_from_instance($modulename, $instance, $courseid=0) {
return get_coursemodule_from_instance($modulename, $instance, $courseid);
}
+69 -56
View File
@@ -23,7 +23,8 @@ define('VISIBLEGROUPS', 2);
* occurred.
*/
function groups_group_exists($groupid) {
return record_exists('groups', 'id', $groupid);
global $DB;
return $DB->record_exists('groups', array('id'=>$groupid));
}
/**
@@ -32,7 +33,8 @@ function groups_group_exists($groupid) {
* @return string The name of the group
*/
function groups_get_group_name($groupid) {
return get_field('groups', 'name', 'id', $groupid);
global $DB;
return $DB->get_field('groups', 'name', array('id'=>$groupid));
}
/**
@@ -41,7 +43,8 @@ function groups_get_group_name($groupid) {
* @return string The name of the grouping
*/
function groups_get_grouping_name($groupingid) {
return get_field('groupings', 'name', 'id', $groupingid);
global $DB;
return $DB->get_field('groupings', 'name', array('id'=>$groupingid));
}
/**
@@ -52,7 +55,8 @@ function groups_get_grouping_name($groupingid) {
* @return int $groupid
*/
function groups_get_group_by_name($courseid, $name) {
if ($groups = get_records_select('groups', "courseid=$courseid AND name='".addslashes($name)."'")) {
global $DB;
if ($groups = $DB->get_records('groups', array('courseid'=>$courseid, 'name'=>$name))) {
return key($groups);
}
return false;
@@ -66,7 +70,8 @@ function groups_get_group_by_name($courseid, $name) {
* @return int $groupid
*/
function groups_get_grouping_by_name($courseid, $name) {
if ($groupings = get_records_select('groupings', "courseid=$courseid AND name='".addslashes($name)."'")) {
global $DB;
if ($groupings = $DB->get_records_select('groupings', array('courseid'=>$courseid, 'name'=>$name))) {
return key($groupings);
}
return false;
@@ -78,7 +83,8 @@ function groups_get_grouping_by_name($courseid, $name) {
* @return group object
*/
function groups_get_group($groupid) {
return get_record('groups', 'id', $groupid);
global $DB;
return $DB->get_record('groups', array('id'=>$groupid));
}
/**
@@ -87,7 +93,8 @@ function groups_get_group($groupid) {
* @return group object
*/
function groups_get_grouping($groupingid) {
return get_record('groupings', 'id', $groupingid);
global $DB;
return $DB->get_record('groupings', array('id'=>$groupingid));
}
/**
@@ -99,39 +106,40 @@ function groups_get_grouping($groupingid) {
* or an error occurred. (userid field returned if array in $userid)
*/
function groups_get_all_groups($courseid, $userid=0, $groupingid=0, $fields='g.*') {
global $CFG;
global $CFG, $DB;
// groupings are ignored when not enabled
if (empty($CFG->enablegroupings)) {
$groupingid = 0;
}
if (empty($userid)) {
$userfrom = "";
$userwhere = "";
} else if (is_array($userid)) {
$userids = implode(',', $userid);
$userfrom = ", {$CFG->prefix}groups_members gm";
$userwhere = "AND g.id = gm.groupid AND gm.userid IN ($userids)";
$params = array();
} else {
$userfrom = ", {$CFG->prefix}groups_members gm";
$userwhere = "AND g.id = gm.groupid AND gm.userid = '$userid'";
list($usql, $params) = $DB->get_in_or_equal($userid);
$userfrom = ", {groups_members} gm";
$userwhere = "AND g.id = gm.groupid AND gm.userid $usql";
}
if (!empty($groupingid)) {
$groupingfrom = ", {$CFG->prefix}groupings_groups gg";
$groupingwhere = "AND g.id = gg.groupid AND gg.groupingid = '$groupingid'";
$groupingfrom = ", {groupings_groups} gg";
$groupingwhere = "AND g.id = gg.groupid AND gg.groupingid = ?";
$params[] = $groupingid;
} else {
$groupingfrom = "";
$groupingwhere = "";
}
return get_records_sql("SELECT $fields
FROM {$CFG->prefix}groups g $userfrom $groupingfrom
WHERE g.courseid = $courseid $userwhere $groupingwhere
ORDER BY name ASC");
array_unshift($params, $courseid);
return $DB->get_records_sql("SELECT $fields
FROM {groups} g $userfrom $groupingfrom
WHERE g.courseid = ? $userwhere $groupingwhere
ORDER BY name ASC", $params);
}
/**
@@ -141,24 +149,27 @@ function groups_get_all_groups($courseid, $userid=0, $groupingid=0, $fields='g.*
* @return array[groupingid][groupid] including grouping id 0 which means all groups
*/
function groups_get_user_groups($courseid, $userid=0) {
global $CFG, $USER;
global $CFG, $USER, $DB;
if (empty($userid)) {
$userid = $USER->id;
}
if (!$rs = get_recordset_sql("SELECT g.id, gg.groupingid
FROM {$CFG->prefix}groups g
JOIN {$CFG->prefix}groups_members gm ON gm.groupid = g.id
LEFT JOIN {$CFG->prefix}groupings_groups gg ON gg.groupid = g.id
WHERE gm.userid = $userid AND g.courseid = $courseid")) {
$sql = "SELECT g.id, gg.groupingid
FROM {groups} g
JOIN {groups_members} gm ON gm.groupid = g.id
LEFT JOIN {groupings_groups} gg ON gg.groupid = g.id
WHERE gm.userid = ? AND g.courseid = ?";
$params = array($userid, $courseid);
if (!$rs = $DB->get_recordset_sql($sql, $params)) {
return array('0' => array());
}
$result = array();
$allgroups = array();
while ($group = rs_fetch_next_record($rs)) {
foreach ($rs as $group) {
$allgroups[$group->id] = $group->id;
if (is_null($group->groupingid)) {
continue;
@@ -168,7 +179,7 @@ function groups_get_user_groups($courseid, $userid=0) {
}
$result[$group->groupingid][$group->id] = $group->id;
}
rs_close($rs);
$rs->close();
$result['0'] = array_keys($allgroups); // all groups
@@ -182,16 +193,16 @@ function groups_get_user_groups($courseid, $userid=0) {
* or an error occurred.
*/
function groups_get_all_groupings($courseid) {
global $CFG;
global $CFG, $DB;
// groupings are ignored when not enabled
if (empty($CFG->enablegroupings)) {
return(false);
}
return get_records_sql("SELECT *
FROM {$CFG->prefix}groupings
WHERE courseid = $courseid
ORDER BY name ASC");
return $DB->get_records_sql("SELECT *
FROM {groupings}
WHERE courseid = ?
ORDER BY name ASC", array($courseid));
}
@@ -205,13 +216,13 @@ function groups_get_all_groupings($courseid) {
* @return boolean True if the user is a member, false otherwise.
*/
function groups_is_member($groupid, $userid=null) {
global $USER;
global $USER, $DB;
if (!$userid) {
$userid = $USER->id;
}
return record_exists('groups_members', 'groupid', $groupid, 'userid', $userid);
return $DB->record_exists('groups_members', array('groupid'=>$groupid, 'userid'=>$userid));
}
/**
@@ -221,7 +232,7 @@ function groups_is_member($groupid, $userid=null) {
* @return booelan true if user member of at least one group used in activity
*/
function groups_has_membership($cm, $userid=null) {
global $CFG, $USER;
global $CFG, $USER, $DB;
static $cache = array();
@@ -242,17 +253,19 @@ function groups_has_membership($cm, $userid=null) {
if ($cm->groupingid) {
// find out if member of any group in selected activity grouping
$sql = "SELECT 'x'
FROM {$CFG->prefix}groups_members gm, {$CFG->prefix}groupings_groups gg
WHERE gm.userid = $userid AND gm.groupid = gg.groupid AND gg.groupingid = {$cm->groupingid}";
FROM {groups_members} gm, {groupings_groups} gg
WHERE gm.userid = ? AND gm.groupid = gg.groupid AND gg.groupingid = ?";
$params = array($userid, $cm->groupingid);
} else {
// no grouping used - check all groups in course
$sql = "SELECT 'x'
FROM {$CFG->prefix}groups_members gm, {$CFG->prefix}groups g
WHERE gm.userid = $userid AND gm.groupid = g.id AND g.courseid = {$cm->course}";
FROM {groups_members} gm, {groups} g
WHERE gm.userid = ? AND gm.groupid = g.id AND g.courseid = ?";
$params = array($userid, $cm->course);
}
$cache[$cachekey] = record_exists_sql($sql);
$cache[$cachekey] = $DB->record_exists_sql($sql, $params);
return $cache[$cachekey];
}
@@ -266,12 +279,12 @@ function groups_has_membership($cm, $userid=null) {
* group or false if no users or an error returned.
*/
function groups_get_members($groupid, $fields='u.*', $sort='lastname ASC') {
global $CFG;
global $DB;
return get_records_sql("SELECT $fields
FROM {$CFG->prefix}user u, {$CFG->prefix}groups_members gm
WHERE u.id = gm.userid AND gm.groupid = '$groupid'
ORDER BY $sort");
return $DB->get_records_sql("SELECT $fields
FROM {user} u, {groups_members} gm
WHERE u.id = gm.userid AND gm.groupid = ?
ORDER BY $sort", array($groupid));
}
@@ -284,14 +297,14 @@ function groups_get_members($groupid, $fields='u.*', $sort='lastname ASC') {
* group or false if no users or an error returned.
*/
function groups_get_grouping_members($groupingid, $fields='u.*', $sort='lastname ASC') {
global $CFG;
global $DB;
return get_records_sql("SELECT $fields
FROM {$CFG->prefix}user u
INNER JOIN {$CFG->prefix}groups_members gm ON u.id = gm.userid
INNER JOIN {$CFG->prefix}groupings_groups gg ON gm.groupid = gg.groupid
WHERE gg.groupingid = $groupingid
ORDER BY $sort");
return $DB->get_records_sql("SELECT $fields
FROM {user} u
INNER JOIN {groups_members} gm ON u.id = gm.userid
INNER JOIN {groupings_groups} gg ON gm.groupid = gg.groupid
WHERE gg.groupingid = ?
ORDER BY $sort", array($groupingid));
}
/**
@@ -310,7 +323,7 @@ function groups_get_course_groupmode($course) {
* @return integer group mode
*/
function groups_get_activity_groupmode($cm, $course=null) {
global $COURSE;
global $COURSE, $DB;
// get course object (reuse COURSE if possible)
if (isset($course->id) and $course->id == $cm->course) {
@@ -318,7 +331,7 @@ function groups_get_activity_groupmode($cm, $course=null) {
} else if ($cm->course == $COURSE->id) {
$course = $COURSE;
} else {
if (!$course = get_record('course', 'id', $cm->course)) {
if (!$course = $DB->get_record('course', array('id'=>$cm->course))) {
error('Incorrect course id in cm');
}
}
+3 -3
View File
@@ -141,11 +141,11 @@ function upgrade_local_db($continueto) {
require_once ($CFG->dirroot .'/local/db/upgrade.php');
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=true;
$DB->set_debug(true);
}
if (xmldb_local_upgrade($CFG->local_version)) {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=false;
$DB->set_debug(false);
}
if (set_config('local_version', $local_version)) {
notify(get_string('databasesuccess'), 'notifysuccess');
@@ -167,7 +167,7 @@ function upgrade_local_db($continueto) {
}
} else {
if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
$db->debug=false;
$DB->set_debug(false);
}
print_error('Upgrade failed! See local/version.php');
}
+13 -17
View File
@@ -1432,15 +1432,13 @@ function get_user_timezone($tz = 99) {
}
/**
* ?
* Returns cached timezone record for given $timezonename
*
* @uses $CFG
* @uses $db
* @param string $timezonename ?
* @return object
* @param string $timezonename
* @return mixed timezonerecord object or false
*/
function get_timezone_record($timezonename) {
global $CFG, $db;
global $CFG, $DB;
static $cache = NULL;
if ($cache === NULL) {
@@ -1451,8 +1449,8 @@ function get_timezone_record($timezonename) {
return $cache[$timezonename];
}
return $cache[$timezonename] = get_record_sql('SELECT * FROM '.$CFG->prefix.'timezone
WHERE name = '.$db->qstr($timezonename).' ORDER BY year DESC', true);
return $cache[$timezonename] = $DB->get_record_sql('SELECT * FROM {timezone}
WHERE name = ? ORDER BY year DESC', array($timezonename), true);
}
/**
@@ -2776,16 +2774,14 @@ function is_internal_auth($auth) {
/**
* Returns an array of user fields
*
* @uses $CFG
* @uses $db
* @return array User field/column names
*/
function get_user_fieldnames() {
global $DB;
global $CFG, $db;
$fieldarray = $db->MetaColumnNames($CFG->prefix.'user');
unset($fieldarray['ID']);
$fieldarray = $DB->get_columns('user');
unset($fieldarray['id']);
$fieldarray = array_keys($fieldarray);
return $fieldarray;
}
@@ -7525,7 +7521,7 @@ function array_is_nested($array) {
***
**/
function get_performance_info() {
global $CFG, $PERF, $rcache;
global $CFG, $PERF;
$info = array();
$info['html'] = ''; // holds userfriendly HTML representation
@@ -7602,14 +7598,14 @@ function get_performance_info() {
$info['txt'] .= "serverload: {$info['serverload']} ";
}
if (isset($rcache->hits) && isset($rcache->misses)) {
/* if (isset($rcache->hits) && isset($rcache->misses)) {
$info['rcachehits'] = $rcache->hits;
$info['rcachemisses'] = $rcache->misses;
$info['html'] .= '<span class="rcache">Record cache hit/miss ratio : '.
"{$rcache->hits}/{$rcache->misses}</span> ";
$info['txt'] .= 'rcache: '.
"{$rcache->hits}/{$rcache->misses} ";
}
}*/
$info['html'] = '<div class="performanceinfo">'.$info['html'].'</div>';
return $info;
}
+17 -75
View File
@@ -54,10 +54,15 @@ global $MCACHE;
*/
global $COURSE;
/**
* Definition of db type
* Legacy definition of db type TODO: remove in 2.0
* @global object(db) $db
*/
global $db;
/**
* Database instances
* @global object(mdb) $DB
*/
global $DB;
/**
* $THEME is a global that defines the site theme.
*
@@ -115,81 +120,16 @@ global $HTTPSPAGEREQUIRED;
exit;
}
/// Connect to the database using adodb
/// Set $CFG->dbfamily global
/// and configure some other specific variables for each db BEFORE attempting the connection
preconfigure_dbconnection();
require_once($CFG->libdir .'/adodb/adodb.inc.php'); // Database access functions
$db = &ADONewConnection($CFG->dbtype);
// See MDL-6760 for why this is necessary. In Moodle 1.8, once we start using NULLs properly,
// we probably want to change this value to ''.
$db->null2null = 'A long random string that will never, ever match something we want to insert into the database, I hope. \'';
error_reporting(0); // Hide errors
if (!isset($CFG->dbpersist) or !empty($CFG->dbpersist)) { // Use persistent connection (default)
$dbconnected = $db->PConnect($CFG->dbhost,$CFG->dbuser,$CFG->dbpass,$CFG->dbname);
} else { // Use single connection
$dbconnected = $db->Connect($CFG->dbhost,$CFG->dbuser,$CFG->dbpass,$CFG->dbname);
/// Define admin directory
if (!isset($CFG->admin)) { // Just in case it isn't defined in config.php
$CFG->admin = 'admin'; // This is relative to the wwwroot and dirroot
}
if (! $dbconnected) {
// In the name of protocol correctness, monitoring and performance
// profiling, set the appropriate error headers for machine comsumption
if (isset($_SERVER['SERVER_PROTOCOL'])) {
// Avoid it with cron.php. Note that we assume it's HTTP/1.x
header($_SERVER['SERVER_PROTOCOL'] . ' 503 Service Unavailable');
}
// and then for human consumption...
echo '<html><body>';
echo '<table align="center"><tr>';
echo '<td style="color:#990000; text-align:center; font-size:large; border-width:1px; '.
' border-color:#000000; border-style:solid; border-radius: 20px; border-collapse: collapse; '.
' -moz-border-radius: 20px; padding: 15px">';
echo '<p>Error: Database connection failed.</p>';
echo '<p>It is possible that the database is overloaded or otherwise not running properly.</p>';
echo '<p>The site administrator should also check that the database details have been correctly specified in config.php</p>';
echo '</td></tr></table>';
echo '</body></html>';
error_log('ADODB Error: '.$db->ErrorMsg()); // see MDL-14628
if (empty($CFG->noemailever) and !empty($CFG->emailconnectionerrorsto)) {
mail($CFG->emailconnectionerrorsto,
'WARNING: Database connection error: '.$CFG->wwwroot,
'Connection error: '.$CFG->wwwroot);
}
die;
}
/// Forcing ASSOC mode for ADOdb (some DBs default to FETCH_BOTH)
$db->SetFetchMode(ADODB_FETCH_ASSOC);
/// Starting here we have a correct DB conection but me must avoid
/// to execute any DB transaction until "set names" has been executed
/// some lines below!
error_reporting(E_ALL); // Show errors from now on.
if (!isset($CFG->prefix)) { // Just in case it isn't defined in config.php
$CFG->prefix = '';
}
/// Define admin directory
if (!isset($CFG->admin)) { // Just in case it isn't defined in config.php
$CFG->admin = 'admin'; // This is relative to the wwwroot and dirroot
}
/// Increase memory limits if possible
raise_memory_limit('96M'); // We should never NEED this much but just in case...
/// Load up standard libraries
require_once($CFG->libdir .'/textlib.class.php'); // Functions to handle multibyte strings
require_once($CFG->libdir .'/weblib.php'); // Functions for producing HTML
require_once($CFG->libdir .'/dmllib.php'); // Functions to handle DB data (DML)
@@ -204,6 +144,12 @@ global $HTTPSPAGEREQUIRED;
//the problem is that we need specific version of quickforms and hacked excel files :-(
ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
/// Connect to the database
setup_DB();
/// Increase memory limits if possible
raise_memory_limit('96M'); // We should never NEED this much but just in case...
/// Disable errors for now - needed for installation when debug enabled in config.php
if (isset($CFG->debug)) {
$originalconfigdebug = $CFG->debug;
@@ -212,16 +158,12 @@ global $HTTPSPAGEREQUIRED;
$originalconfigdebug = -1;
}
/// Set the client/server and connection to utf8
/// and configure some other specific variables for each db
configure_dbconnection();
/// Load up any configuration from the config table
$CFG = get_config();
/// Turn on SQL logging if required
if (!empty($CFG->logsql)) {
$db->LogSQL();
$DB->set_logging(true);
}
/// Prevent warnings from roles when upgrading with debug on
@@ -671,7 +613,7 @@ global $HTTPSPAGEREQUIRED;
$USER->lastname);
}
if (isset($USER->realuser)) {
if ($realuser = get_record('user', 'id', $USER->realuser)) {
if ($realuser = $DB->get_record('user', array('id'=>$USER->realuser))) {
$apachelog_username = clean_filename($realuser->username." as ".$apachelog_username);
$apachelog_name = clean_filename($realuser->firstname." ".$realuser->lastname ." as ".$apachelog_name);
$apachelog_userid = clean_filename($realuser->id." as ".$apachelog_userid);
-142
View File
@@ -164,148 +164,6 @@ function make_upload_directory($directory, $shownotices=true) {
return $currdir;
}
/**
* This function will introspect inside DB to detect it it's a UTF-8 DB or no
* Used from setup.php to set correctly "set names" when the installation
* process is performed without the initial and beautiful installer
*/
function setup_is_unicodedb() {
global $CFG, $db, $INSTALL;
$unicodedb = false;
// Calculate $CFG->dbfamily
$dbfamily = set_dbfamily();
switch ($dbfamily) {
case 'mysql':
$rs = $db->Execute("SHOW LOCAL VARIABLES LIKE 'character_set_database'");
if ($rs && !$rs->EOF) { // rs_EOF() not available yet
$records = $rs->GetAssoc(true);
$encoding = $records['character_set_database']['Value'];
if (strtoupper($encoding) == 'UTF8') {
$unicodedb = true;
}
}
break;
case 'postgres':
/// Get PostgreSQL server_encoding value
$rs = $db->Execute("SHOW server_encoding");
if ($rs && !$rs->EOF) { // rs_EOF() not available yet
$encoding = $rs->fields['server_encoding'];
if (strtoupper($encoding) == 'UNICODE' || strtoupper($encoding) == 'UTF8') {
$unicodedb = true;
}
}
break;
case 'mssql':
/// MSSQL only runs under UTF8 + the proper ODBTP driver (both for Unix and Win32)
$unicodedb = true;
break;
case 'oracle':
/// Get Oracle DB character set value
$rs = $db->Execute("SELECT parameter, value FROM nls_database_parameters where parameter = 'NLS_CHARACTERSET'");
if ($rs && !$rs->EOF) { // rs_EOF() not available yet
$encoding = $rs->fields['value'];
if (strtoupper($encoding) == 'AL32UTF8') {
$unicodedb = true;
}
}
break;
}
return $unicodedb;
}
/**
* This internal function sets and returns the proper value for $CFG->dbfamily based on $CFG->dbtype
* It's called by preconfigure_dbconnection() and at install time. Shouldn't be used
* in other places. Code should rely on dbfamily to perform conditional execution
* instead of using dbtype directly. This allows quicker adoption of different
* drivers going against the same DB backend.
*
* This function must contain the init code needed for each dbtype supported.
*
* return string dbfamily value (mysql, postgres, oracle, mssql)
*/
function set_dbfamily() {
global $CFG, $INSTALL;
// Since this function is also used during installation process, i.e. during install.php before $CFG->dbtype is set.
// we need to get dbtype from the right variable
if (!empty($INSTALL['dbtype'])) {
$dbtype = $INSTALL['dbtype'];
} else {
$dbtype = $CFG->dbtype;
}
switch ($dbtype) {
case 'mysql':
case 'mysqli':
$CFG->dbfamily='mysql';
break;
case 'postgres7':
$CFG->dbfamily='postgres';
break;
case 'mssql':
case 'mssql_n':
case 'odbc_mssql':
$CFG->dbfamily='mssql';
break;
case 'oci8po':
$CFG->dbfamily='oracle';
break;
}
return $CFG->dbfamily;
}
/**
* This internal function, called from setup.php BEFORE stabilishing the DB
* connection, defines the $CFG->dbfamily global -by calling set_dbfamily()-
* and predefines some constants needed by ADOdb to switch some default
* behaviours.
*
* This function must contain all the pre-connection code needed for each
* dbtype supported.
*/
function preconfigure_dbconnection() {
if (defined('ADODB_ASSOC_CASE')) {
return; // when in cli mode, it's possible for this to be called twice (eg cli installer)
}
global $CFG;
/// Define dbfamily
set_dbfamily();
/// Based on $CFG->dbfamily, set some ADOdb settings
switch ($CFG->dbfamily) {
/// list here family types where we know
/// the fieldnames will come in lowercase
/// so we can avoid expensive tolower()
case 'postgres':
case 'mysql':
case 'mssql':
define ('ADODB_ASSOC_CASE', 2);
break;
case 'oracle':
define ('ADODB_ASSOC_CASE', 0); /// Use lowercase fieldnames for ADODB_FETCH_ASSOC
/// (only meaningful for oci8po, it's the default
/// for other DB drivers so this won't affect them)
/// Row prefetching uses a bit of memory but saves a ton
/// of network latency. With current AdoDB and PHP, only
/// Oracle uses this setting.
define ('ADODB_PREFETCH_ROWS', 1000);
break;
default:
/// if we have to lowercase it, set to 0
/// - note that the lowercasing is very expensive
define ('ADODB_ASSOC_CASE', 0); //Use lowercase fieldnames for ADODB_FETCH_ASSOC
}
}
function init_memcached() {
global $CFG, $MCACHE;
+20 -20
View File
@@ -1375,7 +1375,7 @@ function format_text_menu() {
*/
function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
global $CFG, $COURSE;
global $CFG, $COURSE, $DB;
static $croncache = array();
@@ -1420,7 +1420,7 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL
}
}
if ($oldcacheitem = get_record_sql('SELECT * FROM '.$CFG->prefix.'cache_text WHERE md5key = \''.$md5key.'\'', true)) {
if ($oldcacheitem = $DB->get_record('cache_text', array('md5key'=>$md5key), '*', true)) {
if ($oldcacheitem->timemodified >= $time) {
if (defined('FULLME') and FULLME == 'cron') {
if (count($croncache) > 150) {
@@ -1523,16 +1523,16 @@ function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL
$newcacheitem = new object();
$newcacheitem->md5key = $md5key;
$newcacheitem->formattedtext = addslashes($text);
$newcacheitem->formattedtext = $text;
$newcacheitem->timemodified = time();
if ($oldcacheitem) { // See bug 4677 for discussion
$newcacheitem->id = $oldcacheitem->id;
@update_record('cache_text', $newcacheitem); // Update existing record in the cache table
@$DB->update_record('cache_text', $newcacheitem); // Update existing record in the cache table
// It's unlikely that the cron cache cleaner could have
// deleted this entry in the meantime, as it allows
// some extra time to cover these cases.
} else {
@insert_record('cache_text', $newcacheitem); // Insert a new record in the cache table
@$DB->insert_record('cache_text', $newcacheitem); // Insert a new record in the cache table
// Again, it's possible that another user has caused this
// record to be created already in the time that it took
// to traverse this function. That's OK too, as the
@@ -3003,7 +3003,7 @@ function current_theme() {
* @return string theme name
*/
function current_category_theme($categoryid=0) {
global $COURSE;
global $COURSE, $DB;
/// Use the COURSE global if the categoryid not set
if (empty($categoryid)) {
@@ -3015,7 +3015,7 @@ function current_category_theme($categoryid=0) {
}
/// Retrieve the current category
if ($category = get_record('course_categories', 'id', $categoryid)) {
if ($category = $DB->get_record('course_categories', array('id'=>$categoryid))) {
/// Return the category theme if it exists
if (!empty($category->theme)) {
@@ -3313,7 +3313,7 @@ function theme_setup($theme = '', $params=NULL) {
* @return string
*/
function user_login_string($course=NULL, $user=NULL) {
global $USER, $CFG, $SITE;
global $USER, $CFG, $SITE, $DB;
if (empty($user) and !empty($USER->id)) {
$user = $USER;
@@ -3324,7 +3324,7 @@ function user_login_string($course=NULL, $user=NULL) {
}
if (!empty($user->realuser)) {
if ($realuser = get_record('user', 'id', $user->realuser)) {
if ($realuser = $DB->get_record('user', array('id'=>$user->realuser))) {
$fullname = fullname($realuser, true);
$realuserinfo = " [<a $CFG->frametarget
href=\"$CFG->wwwroot/course/loginas.php?id=$course->id&amp;return=1&amp;sesskey=".sesskey()."\">$fullname</a>] ";
@@ -3347,7 +3347,7 @@ function user_login_string($course=NULL, $user=NULL) {
$fullname = fullname($user, true);
$username = "<a $CFG->frametarget href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">$fullname</a>";
if (is_mnet_remote_user($user) and $idprovider = get_record('mnet_host', 'id', $user->mnethostid)) {
if (is_mnet_remote_user($user) and $idprovider = $DB->get_record('mnet_host', array('id'=>$user->mnethostid))) {
$username .= " from <a $CFG->frametarget href=\"{$idprovider->wwwroot}\">{$idprovider->name}</a>";
}
if (isset($user->username) && $user->username == 'guest') {
@@ -3355,7 +3355,7 @@ function user_login_string($course=NULL, $user=NULL) {
" (<a $CFG->frametarget href=\"$wwwroot/login/index.php\">".get_string('login').'</a>)';
} else if (!empty($user->access['rsw'][$context->path])) {
$rolename = '';
if ($role = get_record('role', 'id', $user->access['rsw'][$context->path])) {
if ($role = $DB->get_record('role', array('id'=>$user->access['rsw'][$context->path]))) {
$rolename = ': '.format_string($role->name);
}
$loggedinas = get_string('loggedinas', 'moodle', $username).$rolename.
@@ -3641,7 +3641,7 @@ function print_navigation ($navigation, $separator=0, $return=false) {
* navigation strings.
*/
function build_navigation($extranavlinks, $cm = null) {
global $CFG, $COURSE;
global $CFG, $COURSE, $DB;
if (is_string($extranavlinks)) {
if ($extranavlinks == '') {
@@ -3675,7 +3675,7 @@ function build_navigation($extranavlinks, $cm = null) {
debugging('The field $cm->modname should be set if you call build_navigation with '.
'a $cm parameter. If you get $cm using get_coursemodule_from_instance or '.
'get_coursemodule_from_id, this will be done automatically.', DEBUG_DEVELOPER);
if (!$cm->modname = get_field('modules', 'name', 'id', $cm->module)) {
if (!$cm->modname = $DB->get_field('modules', 'name', array('id'=>$cm->module))) {
print_error('cannotmoduletype');
}
}
@@ -3683,7 +3683,7 @@ function build_navigation($extranavlinks, $cm = null) {
debugging('The field $cm->name should be set if you call build_navigation with '.
'a $cm parameter. If you get $cm using get_coursemodule_from_instance or '.
'get_coursemodule_from_id, this will be done automatically.', DEBUG_DEVELOPER);
if (!$cm->name = get_field($cm->modname, 'name', 'id', $cm->instance)) {
if (!$cm->name = $DB->get_field($cm->modname, 'name', array('id'=>$cm->instance))) {
print_error('cannotmodulename');
}
}
@@ -4284,7 +4284,7 @@ function print_file_picture($path, $courseid=0, $height='', $width='', $link='',
* @todo Finish documenting this function
*/
function print_user_picture($user, $courseid, $picture=NULL, $size=0, $return=false, $link=true, $target='', $alttext=true) {
global $CFG, $HTTPSPAGEREQUIRED;
global $CFG, $HTTPSPAGEREQUIRED, $DB;
$needrec = false;
// only touch the DB if we are missing data...
@@ -4315,7 +4315,7 @@ function print_user_picture($user, $courseid, $picture=NULL, $size=0, $return=fa
}
}
if ($needrec) {
$user = get_record('user','id',$user, '', '', '', '', 'id,firstname,lastname,imagealt');
$user = $DB->get_record('user', array('id'=>$user), 'id,firstname,lastname,imagealt');
}
if ($link) {
@@ -5208,7 +5208,7 @@ function update_categories_search_button($search,$page,$perpage) {
*/
function navmenu($course, $cm=NULL, $targetwindow='self') {
global $CFG, $THEME, $USER;
global $CFG, $THEME, $USER, $DB;
if (empty($THEME->navmenuwidth)) {
$width = 50;
@@ -5242,7 +5242,7 @@ function navmenu($course, $cm=NULL, $targetwindow='self') {
$menu = array();
$menustyle = array();
$sections = get_records('course_sections','course',$course->id,'section','section,visible,summary');
$sections = $DB->get_records('course_sections', array('course'=>$course->id), 'section', 'section,visible,summary');
if (!empty($THEME->makenavmenulist)) { /// A hack to produce an XHTML navmenu list for use in themes
$THEME->navmenulist = navmenulist($course, $sections, $modinfo, $strsection, $strjumpto, $width, $cm);
@@ -6075,7 +6075,7 @@ function redirect($url, $message='', $delay=-1) {
* @param bool $return whether to return an output string or echo now
*/
function notify($message, $style='notifyproblem', $align='center', $return=false) {
global $db;
global $DB;
if ($style == 'green') {
$style = 'notifysuccess'; // backward compatible with old color system
@@ -6084,7 +6084,7 @@ function notify($message, $style='notifyproblem', $align='center', $return=false
$message = clean_text($message);
if(!defined('CLI_UPGRADE')||!CLI_UPGRADE) {
$output = '<div class="'.$style.'" style="text-align:'. $align .'">'. $message .'</div>'."\n";
} else if (CLI_UPGRADE && $db->debug) {
} else if (CLI_UPGRADE && $DB->get_debug()) {
$output = '++'.$message.'++';
return ;
}
@@ -369,55 +369,6 @@ class XMLDBStatement extends XMLDBObject {
return $values;
}
/**
* This function will return the code needed to execute a collection
* of sentences present inside one statement for the specified BD
* and prefix.
* For now it only supports INSERT statements
*/
function getExecuteStatementSQL ($dbtype, $prefix, $statement_end=true) {
$results = array();
/// Based on statement type
switch ($this->type) {
case XMLDB_STATEMENT_INSERT:
$results = $this->getExecuteInsertSQL($dbtype, $prefix, $statement_end);
break;
case XMLDB_STATEMENT_UPDATE:
break;
case XMLDB_STATEMENT_DELETE:
break;
case XMLDB_STATEMENT_CUSTOM:
break;
}
return $results;
}
/**
* This function will return the code needed to execute a collection
* of insert sentences present inside the statement for the specified BD
* and prefix. Just one simple wrapper over generators.
*/
function getExecuteInsertSQL ($dbtype, $prefix, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getExecuteInsertSQL($this);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
}
?>
@@ -714,28 +714,6 @@ class XMLDBStructure extends XMLDBObject {
return false;
}
}
/**
* This function will return the SQL code needed to create the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getCreateStructureSQL ($dbtype, $prefix, $statement_end=true) {
$results = array();
if ($tables = $this->getTables()) {
foreach ($tables as $table) {
$results = array_merge($results, $table->getCreateTableSQL($dbtype, $prefix, $statement_end));
}
}
if ($statements = $this->getStatements()) {
foreach ($statements as $statement) {
$results = array_merge($results, $statement->getExecuteStatementSQL($dbtype, $prefix, $statement_end));
}
}
return $results;
}
}
?>
@@ -791,290 +791,6 @@ class XMLDBTable extends XMLDBObject {
return false;
}
}
/**
* This function will return the SQL code needed to create the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getCreateTableSQL ($dbtype, $prefix, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getCreateTableSQL($this);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to create the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getRenameTableSQL ($dbtype, $prefix, $newname, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getRenameTableSQL($this, $newname);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to drop the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getDropTableSQL ($dbtype, $prefix, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getDropTableSQL($this);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to add one field to the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getAddFieldSQL ($dbtype, $prefix, $xmldb_field, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getAddFieldSQL($this, $xmldb_field);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to drop one field from the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getDropFieldSQL ($dbtype, $prefix, $xmldb_field, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getDropFieldSQL($this, $xmldb_field);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to rename one field from the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getRenameFieldSQL ($dbtype, $prefix, $xmldb_field, $newname, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getRenameFieldSQL($this, $xmldb_field, $newname);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to alter one field in the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getAlterFieldSQL ($dbtype, $prefix, $xmldb_field, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getAlterFieldSQL($this, $xmldb_field);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to modify the enum of one field in the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getModifyEnumSQL ($dbtype, $prefix, $xmldb_field, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getModifyEnumSQL($this, $xmldb_field);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to modify the default of one field in the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getModifyDefaultSQL ($dbtype, $prefix, $xmldb_field, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getModifyDefaultSQL($this, $xmldb_field);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to add one key to the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getAddKeySQL ($dbtype, $prefix, $xmldb_key, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getAddKeySQL($this, $xmldb_key);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to drop one key from the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getDropKeySQL ($dbtype, $prefix, $xmldb_key, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getDropKeySQL($this, $xmldb_key);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to rename one key from the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getRenameKeySQL ($dbtype, $prefix, $xmldb_key, $newname, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getRenameKeySQL($this, $xmldb_key, $newname);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to add one index to the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getAddIndexSQL ($dbtype, $prefix, $xmldb_index, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getAddIndexSQL($this, $xmldb_index);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to drop one index from the table for the specified DB and
* prefix. Just one simple wrapper over generators.
*/
function getDropIndexSQL ($dbtype, $prefix, $xmldb_index, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getDropIndexSQL($this, $xmldb_index);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the SQL code needed to rename one index from the table for the specified DB and
* prefix. Just one simple wrapper over generators.
* Experimental. Shouldn't be used at all!
*/
function getRenameIndexSQL ($dbtype, $prefix, $xmldb_index, $newname, $statement_end=true) {
$results = array();
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
$results = $generator->getRenameIndexSQL($this, $xmldb_index, $newname);
if ($statement_end) {
$results = $generator->getEndedStatements($results);
}
return $results;
}
/**
* This function will return the name of the sequence created for the pk of the table specified
* Just one simple wrapper over generators. Returns false if not found
* Note that not all DB use sequences (only Oracle and PostgreSQL)
*/
function getSequenceFromDB($dbtype, $prefix) {
$classname = 'XMLDB' . $dbtype;
$generator = new $classname();
$generator->setPrefix($prefix);
return $generator->getSequenceFromDB($this);
}
}
?>
@@ -1,44 +0,0 @@
<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/// This class generate SQL code to be used against MSSQL
/// with extended support to automatic handling of the "N"
/// char for Unicode strings. As DB is the same, this inherits
/// everything from XMLDBmssql
require_once($CFG->libdir . '/xmldb/classes/generators/mssql/mssql.class.php');
class XMLDBmssql_n extends XMLDBmssql {
/**
* Creates one new XMLDBmssql
*/
function XMLDBmssql_n() {
XMLDBmssql::XMLDBmssql();
}
}
?>
@@ -1,43 +0,0 @@
<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/// This class generate SQL code to be used against MySQL
/// when running over mysqli (improved). As DB is the same, this inherits
/// everything from XMLDBmysql
require_once($CFG->libdir . '/xmldb/classes/generators/mysql/mysql.class.php');
class XMLDBmysqli extends XMLDBmysql {
/**
* Creates one new XMLDBmysql
*/
function XMLDBmysqli() {
XMLDBmysql::XMLDBmysql();
}
}
?>
@@ -1,43 +0,0 @@
<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.com //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/// This class generate SQL code to be used against MSSQL
/// when running over ODBC. As DB is the same, this inherits
/// everything from XMLDBmssql
require_once($CFG->libdir . '/xmldb/classes/generators/mssql/mssql.class.php');
class XMLDBodbc_mssql extends XMLDBmssql {
/**
* Creates one new XMLDBmssql
*/
function XMLDBodbc_mssql() {
XMLDBmssql::XMLDBmssql();
}
}
?>
+4 -26
View File
@@ -19,42 +19,20 @@
function xmldb_assignment_upgrade($oldversion=0) {
global $CFG, $THEME, $db;
global $CFG, $THEME, $DB;
$result = true;
if ($result && $oldversion < 2007091900) { /// MDL-11268
/// Changing nullability of field data1 on table assignment_submissions to null
$table = new XMLDBTable('assignment_submissions');
$field = new XMLDBField('data1');
$field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'numfiles');
/// Launch change of nullability for field data1
$result = $result && change_field_notnull($table, $field);
/// Changing nullability of field data2 on table assignment_submissions to null
$field = new XMLDBField('data2');
$field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'data1');
/// Launch change of nullability for field data2
$result = $result && change_field_notnull($table, $field);
}
if ($result && $oldversion < 2007091902) {
// add draft tracking default to existing upload assignments
$sql = "UPDATE {$CFG->prefix}assignment SET var4=1 WHERE assignmenttype='upload'";
$result = execute_sql($sql);
}
//===== 1.9.0 upgrade line ======//
if ($result && $oldversion < 2007101511) {
notify('Processing assignment grades, this may take a while if there are many assignments...', 'notifysuccess');
// change grade typo to text if no grades MDL-13920
require_once $CFG->dirroot.'/mod/assignment/lib.php';
// too much debug output
$db->debug = false;
$DB->set_debug(false);
assignment_update_grades();
$db->debug = true;
$DB->set_debug(true);
}
return $result;
+11 -17
View File
@@ -401,31 +401,25 @@ function chat_get_users($chatid, $groupid=0, $groupingid=0) {
}
function chat_get_latest_message($chatid, $groupid=0) {
/// Efficient way to extract just the latest message
/// Uses ADOdb directly instead of get_record_sql()
/// because the LIMIT command causes problems with
/// the developer debugging in there.
global $DB;
global $db, $CFG;
$params = array();
if ($groupid) {
$groupselect = " AND (groupid='$groupid' OR groupid='0')";
$groupselect = " AND (groupid=? OR groupid=0)";
$params[] = $groupid;
} else {
$groupselect = "";
}
if (!$rs = $db->SelectLimit("SELECT *
FROM {$CFG->prefix}chat_messages
WHERE chatid = '$chatid' $groupselect
ORDER BY timestamp DESC", 1)) {
return false;
}
$sql = "SELECT *
FROM {chat_messages}
WHERE chatid = ?
$groupselect
ORDER BY timestamp DESC";
$params[] = $chatid;
$result = rs_fetch_record($rs);
rs_close($rs);
return $result;
return $DB->get_record_sql($sql, $params, true);
}
+3 -2
View File
@@ -97,8 +97,9 @@ class mod_choice_mod_form extends moodleform_mod {
}
function data_preprocessing(&$default_values){
if (!empty($this->_instance) && ($options = get_records_menu('choice_options','choiceid', $this->_instance, 'id', 'id,text'))
&& ($options2 = get_records_menu('choice_options','choiceid', $this->_instance, 'id', 'id,maxanswers')) ) {
global $DB;
if (!empty($this->_instance) && ($options = $DB->get_records_menu('choice_options',array('choiceid'=>$this->_instance), 'id', 'id,text'))
&& ($options2 = $DB->get_records_menu('choice_options', array('choiceid'=>$this->_instance), 'id', 'id,maxanswers')) ) {
$choiceids=array_keys($options);
$options=array_values($options);
$options2=array_values($options2);
+10 -79
View File
@@ -19,83 +19,13 @@
function xmldb_data_upgrade($oldversion=0) {
global $CFG, $THEME, $db;
global $CFG, $THEME, $DB;
$dbman = $DB->get_manager();
$result = true;
/// And upgrade begins here. For each one, you'll need one
/// block of code similar to the next one. Please, delete
/// this comment lines once this file start handling proper
/// upgrade code.
/// if ($result && $oldversion < YYYYMMDD00) { //New version in version.php
/// $result = result of "/lib/ddllib.php" function calls
/// }
if ($result && $oldversion < 2006121300) {
/// Define field format to be added to data_comments
$table = new XMLDBTable('data_comments');
$field = new XMLDBField('format');
$field->setAttributes(XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'content');
/// Launch add field format
$result = $result && add_field($table, $field);
}
if ($result && $oldversion < 2007022600) {
/// Define field asearchtemplate to be added to data
$table = new XMLDBTable('data');
$field = new XMLDBField('asearchtemplate');
$field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'jstemplate');
/// Launch add field asearchtemplate
$result = $result && add_field($table, $field);
}
if ($result && $oldversion < 2007072200) {
require_once($CFG->dirroot.'/mod/data/lib.php');
// too much debug output
$db->debug = false;
data_update_grades();
$db->debug = true;
}
if ($result && $oldversion < 2007081400) {
/// Define field notification to be added to data
$table = new XMLDBTable('data');
$field = new XMLDBField('notification');
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null, 'editany');
/// Launch add field notification
$result = $result && add_field($table, $field);
}
if ($result && $oldversion < 2007081402) {
/// Define index type-dataid (not unique) to be added to data_fields
$table = new XMLDBTable('data_fields');
$index = new XMLDBIndex('type-dataid');
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('type', 'dataid'));
/// Launch add index type-dataid
if (!index_exists($table, $index)) {
$result = $result && add_index($table, $index);
}
/// Define index course (not unique) to be added to data
$table = new XMLDBTable('data');
$index = new XMLDBIndex('course');
$index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('course'));
/// Launch add index course
if (!index_exists($table, $index)) {
$result = $result && add_index($table, $index);
}
}
//===== 1.9.0 upgrade line ======//
if ($result && $oldversion < 2007101512) {
/// Launch add field asearchtemplate again if does not exists yet - reported on several sites
@@ -104,8 +34,8 @@ function xmldb_data_upgrade($oldversion=0) {
$field = new XMLDBField('asearchtemplate');
$field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null, 'jstemplate');
if (!field_exists($table, $field)) {
$result = $result && add_field($table, $field);
if (!$dbman->field_exists($table, $field)) {
$result = $result && $dbman->add_field($table, $field);
}
}
@@ -113,14 +43,15 @@ function xmldb_data_upgrade($oldversion=0) {
// Upgrade all the data->notification currently being
// NULL to 0
$sql = "UPDATE {$CFG->prefix}data SET notification=0 WHERE notification IS NULL";
$result = execute_sql($sql);
$result = $DB->execute($sql);
$table = new XMLDBTable('data');
$field = new XMLDBField('notification');
// First step, Set NOT NULL
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'editany');
$result = $result && change_field_notnull($table, $field);
$result = $result && $dbman->change_field_notnull($table, $field);
// Second step, Set default to 0
$result = $result && change_field_default($table, $field);
$result = $result && $dbman->change_field_default($table, $field);
}
return $result;
-1
View File
@@ -104,7 +104,6 @@
if (!$records = data_get_records_csv($filename, $fielddelimiter, $fieldenclosure)) {
print_error('get_records_csv failed to read data from the uploaded file. Please check file for field name typos and formatting errors.');
} else {
//$db->debug = true;
$fieldnames = array_shift($records);
foreach ($records as $record) {
+37 -34
View File
@@ -19,7 +19,9 @@
function xmldb_feedback_upgrade($oldversion=0) {
global $CFG, $THEME, $db;
global $CFG, $THEME, $DB;
$dbman = $DB->get_manager();
$result = true;
@@ -56,7 +58,7 @@ function xmldb_feedback_upgrade($oldversion=0) {
$key->setAttributes(XMLDB_KEY_FOREIGN, array('feedback'), 'feedback', 'id');
$table->addKey($key);
$result = $result && create_table($table);
$result = $result && $dbman->create_table($table);
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//create a new table feedback_valuetmp and the field-definition
@@ -94,7 +96,7 @@ function xmldb_feedback_upgrade($oldversion=0) {
$key->setAttributes(XMLDB_KEY_FOREIGN, array('item'), 'feedback_item', 'id');
$table->addKey($key);
$result = $result && create_table($table);
$result = $result && $dbman->create_table($table);
////////////////////////////////////////////////////////////
}
@@ -105,28 +107,28 @@ function xmldb_feedback_upgrade($oldversion=0) {
$field = new XMLDBField('random_response');
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
/// Launch add field1
$result = $result && add_field($table, $field);
$result = $result && $dbman->add_field($table, $field);
/// Define field anonymous_response to be added to feedback_completed
$table = new XMLDBTable('feedback_completed');
$field = new XMLDBField('anonymous_response');
$field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '1', null);
/// Launch add field2
$result = $result && add_field($table, $field);
$result = $result && $dbman->add_field($table, $field);
/// Define field random_response to be added to feedback_completed
$table = new XMLDBTable('feedback_completedtmp');
$field = new XMLDBField('random_response');
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
/// Launch add field1
$result = $result && add_field($table, $field);
$result = $result && $dbman->add_field($table, $field);
/// Define field anonymous_response to be added to feedback_completed
$table = new XMLDBTable('feedback_completedtmp');
$field = new XMLDBField('anonymous_response');
$field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '1', null);
/// Launch add field2
$result = $result && add_field($table, $field);
$result = $result && $dbman->add_field($table, $field);
////////////////////////////////////////////////////////////
}
@@ -136,39 +138,40 @@ function xmldb_feedback_upgrade($oldversion=0) {
$table = new XMLDBTable('feedback_template');
$field = new XMLDBField('ispublic');
if (!field_exists($table, $field)) {
$result = $result && table_column('feedback_template', 'public', 'ispublic', 'integer', 1);
$field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '1', null);
if (!$dbman->field_exists($table, $field)) {
$result = $result && $dbman->add_field($table, $field);
}
}
if ($result && $oldversion < 2008042400) { //New version in version.php
if($all_nonanonymous_feedbacks = get_records('feedback', 'anonymous', 2)) {
$update_sql = 'UPDATE '.$CFG->prefix.'feedback_completed SET anonymous_response = 2 WHERE feedback = ';
if ($all_nonanonymous_feedbacks = $DB->get_records('feedback', 'anonymous', 2)) {
$update_sql = 'UPDATE {feedback_completed} SET anonymous_response = 2 WHERE feedback = ';
foreach ($all_nonanonymous_feedbacks as $fb) {
$result = $result && execute_sql($update_sql.$fb->id);
$result = $result && $DB->execute($update_sql.$fb->id);
}
}
}
if ($result && $oldversion < 2008042401) { //New version in version.php
if($result) {
$concat_radio = sql_concat("'r>>>>>'",'presentation');
$concat_check = sql_concat("'d>>>>>'",'presentation');
$concat_dropdown = sql_concat("'c>>>>>'",'presentation');
if ($result) {
$concat_radio = $DB->sql_concat("'r>>>>>'",'presentation');
$concat_check = $DB->sql_concat("'d>>>>>'",'presentation');
$concat_dropdown = $DB->sql_concat("'c>>>>>'",'presentation');
$update_sql1 = "UPDATE ".$CFG->prefix."feedback_item SET presentation = ".$concat_radio." WHERE typ IN('radio','radiorated')";
$update_sql2 = "UPDATE ".$CFG->prefix."feedback_item SET presentation = ".$concat_dropdown." WHERE typ IN('dropdown','dropdownrated')";
$update_sql3 = "UPDATE ".$CFG->prefix."feedback_item SET presentation = ".$concat_check." WHERE typ = 'check'";
$update_sql1 = "UPDATE {feedback_item} SET presentation = ".$concat_radio." WHERE typ IN('radio','radiorated')";
$update_sql2 = "UPDATE {feedback_item} SET presentation = ".$concat_dropdown." WHERE typ IN('dropdown','dropdownrated')";
$update_sql3 = "UPDATE {feedback_item} SET presentation = ".$concat_check." WHERE typ = 'check'";
$result = $result && execute_sql($update_sql1);
$result = $result && execute_sql($update_sql2);
$result = $result && execute_sql($update_sql3);
$result = $result && $DB->execute($update_sql1);
$result = $result && $DB->execute($update_sql2);
$result = $result && $BB->execute($update_sql3);
}
if($result) {
$update_sql1 = "UPDATE ".$CFG->prefix."feedback_item SET typ = 'multichoice' WHERE typ IN('radio','check','dropdown')";
$update_sql2 = "UPDATE ".$CFG->prefix."feedback_item SET typ = 'multichoicerated' WHERE typ IN('radiorated','dropdownrated')";
$result = $result && execute_sql($update_sql1);
$result = $result && execute_sql($update_sql2);
if ($result) {
$update_sql1 = "UPDATE {feedback_item} SET typ = 'multichoice' WHERE typ IN('radio','check','dropdown')";
$update_sql2 = "UPDATE {feedback_item} SET typ = 'multichoicerated' WHERE typ IN('radiorated','dropdownrated')";
$result = $result && $DB->execute($update_sql1);
$result = $result && $DB->execute($update_sql2);
}
}
@@ -178,25 +181,25 @@ function xmldb_feedback_upgrade($oldversion=0) {
$new_log_display->action = 'startcomplete';
$new_log_display->mtable = 'feedback';
$new_log_display->field = 'name';
$result = $result && insert_record('log_display', $new_log_display);
$result = $result && $DB->insert_record('log_display', $new_log_display);
$new_log_display = clone($new_log_display);
$new_log_display->action = 'submit';
$result = $result && insert_record('log_display', $new_log_display);
$result = $result && $DB->insert_record('log_display', $new_log_display);
$new_log_display = clone($new_log_display);
$new_log_display->action = 'delete';
$result = $result && insert_record('log_display', $new_log_display);
$result = $result && $DB->insert_record('log_display', $new_log_display);
$new_log_display = clone($new_log_display);
$new_log_display->action = 'view';
$result = $result && insert_record('log_display', $new_log_display);
$result = $result && $DB->insert_record('log_display', $new_log_display);
$new_log_display = clone($new_log_display);
$new_log_display->action = 'view all';
$new_log_display->mtable = 'course';
$new_log_display->field = 'shortname';
$result = $result && insert_record('log_display', $new_log_display);
$result = $result && $DB->insert_record('log_display', $new_log_display);
}
if ($result && $oldversion < 2008042900) {
@@ -205,7 +208,7 @@ function xmldb_feedback_upgrade($oldversion=0) {
$field = new XMLDBField('autonumbering');
$field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1', 'multiple_submit');
/// Launch add field2
$result = $result && add_field($table, $field);
$result = $result && $dbman->add_field($table, $field);
}
if ($result && $oldversion < 2008050104) {
@@ -214,7 +217,7 @@ function xmldb_feedback_upgrade($oldversion=0) {
$field = new XMLDBField('site_after_submit');
$field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, false, null, null, '', 'autonumbering');
/// Launch add field2
$result = $result && add_field($table, $field);
$result = $result && $dbman->add_field($table, $field);
}
return $result;
}
+5 -14
View File
@@ -32,25 +32,16 @@ function xmldb_forum_upgrade($oldversion=0) {
/// $result = result of "/lib/ddllib.php" function calls
/// }
if ($result && $oldversion < 2007101000) {
/// Define field timemodified to be added to forum_queue
$table = new XMLDBTable('forum_queue');
$field = new XMLDBField('timemodified');
$field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'postid');
/// Launch add field timemodified
$result = $result && add_field($table, $field);
}
//===== 1.9.0 upgrade line ======//
if ($result and $oldversion < 2007101511) {
notify('Processing forum grades, this may take a while if there are many forums...', 'notifysuccess');
//MDL-13866 - send forum ratins to gradebook again
require_once($CFG->dirroot.'/mod/forum/lib.php');
// too much debug output
$db->debug = false;
$DB->set_debug(false);
forum_update_grades();
$db->debug = true;
$DB->set_debug(true);
}
if ($result && $oldversion < 2007101512) {
@@ -71,12 +62,12 @@ function xmldb_forum_upgrade($oldversion=0) {
WHERE ra.id IS NULL";
if ($rs = get_recordset_sql($sql)) {
$db->debug = false;
$DB->set_debug(false);
while ($remove = rs_fetch_next_record($rs)) {
delete_records('forum_subscriptions', 'userid', $remove->userid, 'forum', $remove->forumid);
echo '.';
}
$db->debug = true;
$DB->set_debug(true);
rs_close($rs);
}
}
+2 -2
View File
@@ -157,7 +157,7 @@ if ($mform->is_cancelled()){
$toform = new object();
if ($categoriesarr = get_records_menu("glossary_entries_categories", "entryid", $e, '', 'id, categoryid')){
if ($categoriesarr = $DB->get_records_menu("glossary_entries_categories", array("entryid"=>$e), '', 'id, categoryid')){
$toform->categories = array_values($categoriesarr);
} else {
$toform->categories = array(0);
@@ -181,7 +181,7 @@ if ($mform->is_cancelled()){
die;
}
if ( $aliases = get_records_menu("glossary_alias", "entryid", $e, '', 'id, alias') ) {
if ( $aliases = $DB->get_records_menu("glossary_alias", array("entryid"=>$e), '', 'id, alias') ) {
$toform->aliases = implode("\n", $aliases) . "\n";
}
$mform->set_data($toform);
+2 -2
View File
@@ -5,7 +5,7 @@ class mod_glossary_entry_form extends moodleform {
function definition() {
global $CFG, $COURSE;
global $CFG, $COURSE, $DB;
$mform =& $this->_form;
$glossary =& $this->_customdata['glossary'];
@@ -29,7 +29,7 @@ class mod_glossary_entry_form extends moodleform {
$mform->addElement('format');
$categories = array();
if ($categories = get_records_menu('glossary_categories', 'glossaryid', $glossary->id, 'name ASC', 'id, name')){
if ($categories = $DB->get_records_menu('glossary_categories', array('glossaryid'=>$glossary->id), 'name ASC', 'id, name')){
$categories = array(0 => get_string('notcategorised', 'glossary')) + $categories;
} else {
$categories = array(0 => get_string('notcategorised', 'glossary'));

Some files were not shown because too many files have changed in this diff Show More