moodle/admin/xmldb/actions/test/test.class.php

1145 lines
50 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle 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.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package xmldb-editor
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will perform one full test of all the available DDL
* functions under your DB
* This class will will check all the db directories existing under the
* current Moodle installation, sending them to the SESSION->dbdirs array
*
* @package xmldb-editor
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class test extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
/// Set own custom attributes
/// Get needed strings
$this->loadStrings(array(
'back' => 'xmldb'
));
}
/**
* Invoke method, every class will have its own
* returns true/false on completion, setting both
* errormsg and output as necessary
*/
function invoke() {
parent::invoke();
$result = true;
/// Set own core attributes
//$this->does_generate = ACTION_NONE;
$this->does_generate = ACTION_GENERATE_HTML;
/// These are always here
global $XMLDB, $DB, $CFG;
$dbman = $DB->get_manager();
$gen = $dbman->generator;
$dbfamily = $DB->get_dbfamily();
/// Where all the tests will be stored
$tests = array();
/// The back to edit table button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o = $b;
/// Silenty drop any previous test tables
$table = new xmldb_table('testtable');
if ($dbman->table_exists($table)) {
$dbman->drop_table($table);
}
$table = new xmldb_table ('anothertest');
if ($dbman->table_exists($table)) {
$dbman->drop_table($table);
}
$table = new xmldb_table ('newnameforthetable');
if ($dbman->table_exists($table)) {
$dbman->drop_table($table);
}
/// 1st test. Complete table creation.
$table = new xmldb_table('testtable');
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general');
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null);
$table->add_field('intro', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null);
$table->add_field('logo', XMLDB_TYPE_BINARY, 'big', null, XMLDB_NOTNULL, null);
$table->add_field('assessed', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('assesstimestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('assesstimefinish', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('scale', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('maxbytes', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('forcesubscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('trackingtype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '1');
$table->add_field('rsstype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('rssarticles', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('grade', XMLDB_TYPE_NUMBER, '20,0', XMLDB_UNSIGNED, null, null, null);
$table->add_field('percent', XMLDB_TYPE_NUMBER, '5,2', null, null, null, null);
$table->add_field('warnafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('blockafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('blockperiod', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('type-name', XMLDB_KEY_UNIQUE, array('type', 'name'));
$table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
$table->add_index('rsstype', XMLDB_INDEX_UNIQUE, array('rsstype'));
$table->setComment("This is a test'n drop table. You can drop it safely");
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getCreateTableSQL($table);
try {
$dbman->create_table($table);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['create table'] = $test;
/// 2nd test. drop table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getDropTableSQL($table);
try {
$dbman->drop_table($table);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop table'] = $test;
}
/// 3rd test. creating another, smaller table
if ($test->status) {
$table = new xmldb_table ('anothertest');
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('name', XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
$table->add_field('secondname', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null);
$table->add_field('intro', XMLDB_TYPE_TEXT, 'medium', null, XMLDB_NOTNULL, null, null);
$table->add_field('avatar', XMLDB_TYPE_BINARY, 'medium', null, null, null, null);
$table->add_field('grade', XMLDB_TYPE_NUMBER, '20,10', null, null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getCreateTableSQL($table);
try {
$dbman->create_table($table);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['create table - 2'] = $test;
}
if ($test->status) {
/// Insert two records to do the work with real data
$rec = new stdClass;
$rec->course = 1;
$rec->name = 'Martin';
$rec->secondname = 'Dougiamas';
$rec->intro = 'The creator of Moodle';
$rec->grade = 10.0001;
$DB->insert_record('anothertest', $rec);
$rec->course = 2;
$rec->name = 'Eloy';
$rec->secondname = 'Lafuente';
$rec->intro = 'One poor developer';
$rec->grade = 9.99;
$DB->insert_record('anothertest', $rec);
}
/// 4th test. Adding one field
if ($test->status) {
/// Create a new field with complex specs
$field = new xmldb_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getAddFieldSQL($table, $field);
try {
$dbman->add_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add field'] = $test;
}
/// 5th test. Dropping one complex field
if ($test->status) {
/// Create a new field with complex specs
$test = new stdClass;
$test->sql = $gen->getDropFieldSQL($table, $field);
try {
$dbman->drop_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop field'] = $test;
}
/// 6th test. Adding one complex field again
if ($test->status) {
/// Create a new field with complex specs
$field = new xmldb_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getAddFieldSQL($table, $field);
try {
$dbman->add_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add field again'] = $test;
}
/// 7th test. Dropping one complex field again
if ($test->status) {
/// Create a new field with complex specs
$field = new xmldb_field('type');
$test = new stdClass;
$test->sql = $gen->getDropFieldSQL($table, $field);
try {
$dbman->drop_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop field again'] = $test;
}
/// 8th test. Adding one numeric field
if ($test->status) {
/// Create a new field (numeric)
$field = new xmldb_field('onenumber', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, 0, 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getAddFieldSQL($table, $field);
try {
$dbman->add_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add numeric field'] = $test;
}
/// 9th test. Change the type of one column from integer to varchar
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('course', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, '0');
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_type($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field type (int2char)'] = $test;
}
/// 10th test. Change the type of one column from varchar to integer
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_type($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field type (char2int)'] = $test;
}
/// 11th test. Change the type of one column from number to varchar
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, "test'n drop");
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_type($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field type (number2char)'] = $test;
}
/// 12th test. Change the type of one column from varchar to float
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade', XMLDB_TYPE_FLOAT, '20,10', XMLDB_UNSIGNED, null, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_type($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field type (char2float)'] = $test;
}
/// 13th test. Change the type of one column from float to char
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'test');
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_type($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field type (float2char)'] = $test;
}
/// 14th test. Change the type of one column from char to number
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '20,10', XMLDB_UNSIGNED, null, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_type($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field type (char2number)'] = $test;
}
/// 15th test. Change the precision of one text field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('intro');
$field->set_attributes(XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_precision($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field precision (text)'] = $test;
}
/// 16th test. Change the precision of one char field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('secondname');
$field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_precision($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field precision (char)'] = $test;
}
/// 17th test. Change the precision of one numeric field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade');
$field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_precision($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field precision (number)'] = $test;
}
/// 18th test. Change the precision of one integer field to a smaller one
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('course');
$field->set_attributes(XMLDB_TYPE_INTEGER, '5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_precision($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field precision (integer) to smaller one'] = $test;
}
/// 19th test. Change the sign of one numeric field to unsigned
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade');
$field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', XMLDB_UNSIGNED, null, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_unsigned($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field sign (unsigned)'] = $test;
}
/// 20th test. Change the sign of one numeric field to signed
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('grade');
$field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null);
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_unsigned($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field sign (signed)'] = $test;
}
/// 21th test. Change the nullability of one char field to not null
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, 'Moodle');
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_notnull($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field nullability (not null)'] = $test;
}
/// 22th test. Change the nullability of one char field to null
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
$test->sql = $gen->getAlterFieldSQL($table, $field);
try {
$dbman->change_field_notnull($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['change field nullability (null)'] = $test;
}
/// 23th test. Dropping the default of one field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, null);
$test->sql = $gen->getModifyDefaultSQL($table, $field);
try {
$dbman->change_field_default($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop field default of NULL field'] = $test;
}
/// 24th test. Creating the default for one field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, 'Moodle');
$test->sql = $gen->getModifyDefaultSQL($table, $field);
try {
$dbman->change_field_default($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add field default of NULL field'] = $test;
}
/// 25th test. Creating the default for one field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('secondname');
$field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, 'Moodle2');
$test->sql = $gen->getModifyDefaultSQL($table, $field);
try {
$dbman->change_field_default($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add field default of NOT NULL field'] = $test;
}
/// 26th test. Dropping the default of one NOT NULL field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('secondname');
$field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null);
$test->sql = $gen->getModifyDefaultSQL($table, $field);
try {
$dbman->change_field_default($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop field default of NOT NULL field'] = $test;
}
/// 27th test. Adding one unique index to the table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$index = new xmldb_index('secondname');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('name', 'secondname', 'grade'));
$test->sql = $gen->getAddIndexSQL($table, $index);
try {
$dbman->add_index($table, $index, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add unique index'] = $test;
}
/// 28th test. Adding one not unique index to the table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$index = new xmldb_index('secondname');
$index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'name'));
$test->sql = $gen->getAddIndexSQL($table, $index);
try {
$dbman->add_index($table, $index, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add not unique index'] = $test;
}
/// 29th test. Re-add the same index than previous test. Check find_index_name() works.
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$index = new xmldb_index('secondname');
$index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('name', 'course'));
if ($indexfound = $dbman->find_index_name($table, $index)) {
$test->status = true;
$test->sql = array();
} else {
$test->status = true;
$test->error = 'Index not found!';
$test->sql = array();
}
$tests['check find_index_name()'] = $test;
}
/// 30th test. Dropping one index from the table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$index = new xmldb_index('name');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('name', 'grade', 'secondname'));
$test->sql = $gen->getDropIndexSQL($table, $index);
try {
$dbman->drop_index($table, $index, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop index'] = $test;
}
/// 31th test. Adding one unique key to the table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$key = new xmldb_key('id-course-grade');
$key->set_attributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
$test->sql = $gen->getAddKeySQL($table, $key);
try {
$dbman->add_key($table, $key, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add unique key'] = $test;
}
/// 32th test. Adding one foreign+unique key to the table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'anothertest', array('id'));
$test->sql = $gen->getAddKeySQL($table, $key);
try {
$dbman->add_key($table, $key, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add foreign+unique key'] = $test;
}
/// 33th test. Drop one key
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'anothertest', array('id'));
$test->sql = $gen->getDropKeySQL($table, $key);
try {
$dbman->drop_key($table, $key, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop foreign+unique key'] = $test;
}
/// 34th test. Adding one foreign key to the table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN, array('course'), 'anothertest', array('id'));
$test->sql = $gen->getAddKeySQL($table, $key);
try {
$dbman->add_key($table, $key, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add foreign key'] = $test;
}
/// 35th test. Drop one foreign key
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN, array('course'), 'anothertest', array('id'));
$test->sql = $gen->getDropKeySQL($table, $key);
try {
$dbman->drop_key($table, $key, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop foreign key'] = $test;
}
/// 36th test. Adding one complex field and forcing creation of enum/ck manually (to test dropping latter)
/// TODO: Drop this test in Moodle 2.1
if ($test->status) {
/// Create a new field with complex specs (enums are good candidates)
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getAddFieldSQL($table, $field);
try {
$dbman->add_field($table, $field, false, false);
$test->status = true;
/// Now, let's add one enum/check manually, because XMLDB stuff hasn't support for that
/// anymore. We are dropping enums support, but need to check dropping them until Moodle 2.1.
switch ($dbfamily) {
case 'mysql':
$create_enum = "ALTER TABLE {anothertest} MODIFY COLUMN type enum('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda') NOT NULL DEFAULT 'general'";
break;
case 'mssql':
case 'oracle':
case 'postgres':
$create_enum = "ALTER TABLE {anothertest} ADD CONSTRAINT xmldb_ck CHECK (type IN ('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'))";
break;
}
$test->sql[] = $create_enum;
$DB->execute($create_enum); /// Create the enum/check. Not the best way but works for this needed test
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add field with enum/ck manually'] = $test;
}
/// 37th test. Dropping one field containing enum/ck
/// TODO: Drop this test in Moodle 2.1
if ($test->status) {
$test = new stdClass;
$test->sql = $gen->getDropFieldSQL($table, $field);
$field = new xmldb_field('type');
try {
$dbman->drop_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop field with enum/ck'] = $test;
}
/// 38th test. Adding one complex field and forcing creation of enum/ck manually (to test dropping latter)
/// TODO: Drop this test in Moodle 2.1
if ($test->status) {
/// Create a new field with complex specs (enums are good candidates)
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getAddFieldSQL($table, $field);
try {
$dbman->add_field($table, $field, false, false);
$test->status = true;
/// Now, let's add one enum/check manually, because XMLDB stuff hasn't support for that
/// anymore. We are dropping enums support, but need to check dropping them until Moodle 2.1.
switch ($dbfamily) {
case 'mysql':
$create_enum = "ALTER TABLE {anothertest} MODIFY COLUMN type enum('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda') NOT NULL DEFAULT 'general'";
break;
case 'mssql':
case 'oracle':
case 'postgres':
$create_enum = "ALTER TABLE {anothertest} ADD CONSTRAINT xmldb_ck CHECK (type IN ('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'))";
break;
}
$test->sql[] = $create_enum;
$DB->execute($create_enum); /// Create the enum/check. Not the best way but works for this needed test
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['add field with enum/ck manually again'] = $test;
}
/// 39th test. Dropping the enum from one field
/// TODO: Drop this test in Moodle 2.1
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
$test->sql = $gen->getDropEnumSQL($table, $field);
try {
$dbman->drop_enum_from_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop enum/ck from field containing enum'] = $test;
}
/// 40th test. Drop enum from field not containing enum
/// TODO: Drop this test in Moodle 2.1
if ($test->status) {
/// Drop enum from field not containing enum
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getDropEnumSQL($table, $field);
try {
$dbman->drop_enum_from_field($table, $field, false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['drop enum/ck from field not containing enum'] = $test;
}
/// 41th test. Renaming one index
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$index = new xmldb_index('anyname');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('name', 'course'));
$test->sql = $gen->getRenameIndexSQL($table, $index, 'newnamefortheindex');
try {
$dbman->rename_index($table, $index, 'newnamefortheindex', false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . "Getting this error is the expected behaviour. Function is experimental and ins't used in code at all. Don't worry!";
}
$tests['rename index (experimental. DO NOT USE IT)'] = $test;
$test = new stdClass;
$test->status = true; // ignore errors here
}
/// 42th test. Renaming one key
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$key = new xmldb_key('anyname');
$key->set_attributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
$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
}
try {
$dbman->rename_key($table, $key, 'newnameforthekey', false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . "Getting this error is the expected behaviour. Function is experimental and ins't used in code at all. Don't worry!";
}
$CFG->debug = $olddebug;
$tests['rename key (experimental. DO NOT USE IT)'] = $test;
$test = new stdClass;
$test->status = true; // ignore errors here
}
/// 43th test. Renaming one field
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, 'general', 'course');
$test->sql = $gen->getRenameFieldSQL($table, $field, 'newnameforthefield', true);
try {
$dbman->rename_field($table, $field, 'newnameforthefield', false, false);
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['rename field'] = $test;
}
/// 44th test. Renaming one table
if ($test->status) {
/// Get SQL code and execute it
$test = new stdClass;
$test->sql = $gen->getRenameTableSQL($table, 'newnameforthetable', true);
try {
$dbman->rename_table($table, 'newnameforthetable');
$test->status = true;
} catch (moodle_exception $e) {
$test->status = false;
$test->error = $DB->get_last_error() . "\n" . $e;
}
$tests['rename table'] = $test;
}
/// 45th test. Inserting TEXT contents
$textlib = textlib_get_instance();
if ($test->status) {
$test = new stdClass;
$test->status = false;
$test->sql = array();
$basetext = "\\ ''語 • Русский • Deutsch • English • Español • Français • Italiano • Nederlands • Polski • Português • Svenska • العربية • فارسی 한국어 • עברית • ไทย中文 Ελληνικά • Български • Српски • Українська • Bosanski • Català • Česky • Dansk • Eesti • Simple English • Esperanto • Euskara • Galego • Hrvatski • Ido • Bahasa Indonesia • Íslenska • Lëtzebuergesch • Lietuvių • Magyar • Bahasa Melayu اردو • ئۇيغۇرچه • हिन्दी • नेपाल भाषा मराठी • தமிழ் Հայերեն • Беларуская • Чăваш • Ирон æвзаг • Македонски • Сибирской говор • Afrikaans • Aragonés • Arpitan • Asturianu • Kreyòl Ayisyen • Azərbaycan • Bân-lâm-gú • Basa Banyumasan • Brezhoneg • Corsu • Cymraeg • Deitsch • Føroyskt • Frysk • Furlan • Gaeilge • Gàidhlig • Ilokano • Interlingua • Basa Jawa • Kapampangan • Kernewek • Kurdî كوردی • Ladino לאדינו • Latina • Latviešu • Limburgs • Lumbaart • Nedersaksisch • Nouormand • Occitan • Ozbek • Piemontèis • Plattdüütsch • Ripoarisch • Sámegiella • Scots • Shqip • Sicilianu • Sinugboanon • Srpskohrvatski / Српскохрватски • Basa Sunda • Kiswahili • Tagalog • Tatarça • Walon • Winaray Авар • Башҡорт • Кыргызча Монгол • Қазақша • Тоҷикӣ • Удмурт • Armãneashce • Bamanankan • Eald Englisc • Gaelg • Interlingue • Kaszëbsczi • Kongo • Ligure • Lingála • lojban • Malagasy • Malti • Māori • Nāhuatl • Ekakairũ Naoero • Novial • Pangasinán • Tok Pisin • Romani / रोमानी • Rumantsch • Runa Simi • Sardu • Tetun • Türkmen / تركمن / Туркмен • Vèneto • Volapük • Võro • West-Vlaoms • Wollof • Zazaki • Žemaitėška";
/// Create one big text (1.500.000 chars)
$fulltext = '';
for ($i=0; $i<1000; $i++) { //1500 * 1000 chars
$fulltext .= $basetext;
}
/// Build the record to insert
$rec->intro = $fulltext;
$rec->name = 'texttest';
/// Calculate its length
$textlen = $textlib->strlen($fulltext);
$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->get_last_error();
$test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
$test->status = false;
}
} else {
$test->error = $DB->get_last_error().'xx';
}
$tests['insert record '. $textlen . ' cc. (text)'] = $test;
}
/// 46th test. Inserting BINARY contents
if ($test->status) {
$test = new stdClass;
$test->status = false;
/// Build the record to insert
$rec->avatar = $fulltext;
$rec->name = 'binarytest';
/// Calculate its length
$textlen = strlen($rec->avatar);
$rec->id = $DB->insert_record('newnameforthetable', $rec);
if ($new = $DB->get_record('newnameforthetable', array('id'=>$rec->id))) {
$newtextlen = strlen($new->avatar);
if ($rec->avatar === $new->avatar) {
$test->sql = array($newtextlen . ' bytes (binary) sent and received ok');
$test->status = true;
} else {
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' bytes (binary) transfer failed. Data changed!');
$test->status = false;
}
} else {
$test->error = $DB->get_last_error();
}
$tests['insert record '. $textlen . ' bytes (binary)'] = $test;
}
/// 47th test. $DB->update_record with TEXT and BINARY contents
if ($test->status) {
$test = new stdClass;
$test->status = false;
$test->sql = array();
/// Build the record to insert
$rec->intro = $basetext;
$rec->avatar = $basetext;
$rec->name = 'updatelobs';
/// Calculate its length
$textlen = $textlib->strlen($basetext);
$imglen = strlen($basetext);
$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) {
$test->sql = array($newtextlen . ' cc. (text) sent and received ok',
$newimglen . ' bytes (binary) sent and received ok');
$test->status = true;
} else {
if ($rec->avatar !== $new->avatar) {
$test->error = $DB->get_last_error();
$test->sql = array($newimglen . ' bytes (binary) transfer failed. Data changed!');
$test->status = false;
} else {
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
$test->status = false;
}
}
} else {
$test->error = $DB->get_last_error();
}
$tests['update record '. $textlen . ' cc. (text) and ' . $imglen . ' bytes (binary)'] = $test;
}
/// 48th test. $DB->set_field with TEXT contents
if ($test->status) {
$test = new stdClass;
$test->status = false;
$test->sql = array();
/// Build the record to insert
$rec->intro = $fulltext;
$rec->name = 'updatelobs';
/// Calculate its length
$textlen = $textlib->strlen($fulltext);
$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->get_last_error();
$test->sql = array($newtextlen . ' cc. (text) transfer failed. Data changed!');
$test->status = false;
}
} else {
$test->error = $DB->get_last_error();
}
$tests['set field '. $textlen . ' cc. (text)'] = $test;
}
/// 49th test. $DB->set_field with BINARY contents
if ($test->status) {
$test = new stdClass;
$test->status = false;
$test->sql = array();
/// Build the record to insert
$rec->avatar = $fulltext;
$rec->name = 'updatelobs';
/// Calculate its length
$textlen = strlen($rec->avatar);
$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 ($rec->avatar === $new->avatar) {
$test->sql = array($newtextlen . ' bytes (binary) sent and received ok');
$test->status = true;
} else {
$test->error = $DB->get_last_error();
$test->sql = array($newtextlen . ' bytes (binary) transfer failed. Data changed!');
$test->status = false;
}
} else {
$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 has the correct value
/// Iterate over tests, showing information as needed
$o .= '<ol>';
foreach ($tests as $key => $test) {
$o .= '<li>' . $key . ($test->status ? '<font color="green"> Ok</font>' : ' <font color="red">Error</font>');
if (!$test->status) {
$o .= '<br/><font color="red">' . $test->error . '</font>';
}
$o .= '<pre>' . implode('<br/>', $test->sql) . '</pre>';
$o .= '</li>';
}
$o .= '</ol>';
$this->output = $o;
/// Finally drop all the potentially existing test tables
$table = new XMLDBTable('testtable');
if (table_exists($table)) {
$status = drop_table($table, true, false);
}
$table = new XMLDBTable ('anothertest');
if (table_exists($table)) {
$status = drop_table($table, true, false);
}
$table = new XMLDBTable ('newnameforthetable');
if (table_exists($table)) {
$status = drop_table($table, true, false);
}
/// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
/// Return ok if arrived here
return $result;
}
}