/** * Commit new records. * * @return void */ public function commit() { $request = (object) array('pid' => getmypid(), 'threadid' => ZEND_THREAD_SAFE ? zend_thread_id() : null, 'uid' => getmyuid(), 'url' => $this->url->out_as_local_url(false), 'hostname' => gethostname(), 'memory' => memory_get_usage(), 'peakmemory' => memory_get_peak_usage()); // Not supported on Windows until PHP 7 if (function_exists('getrusage')) { $resourceusage = getrusage(); $request->numswaps = $resourceusage['ru_nswap']; $request->numpagefaults = $resourceusage['ru_majflt']; $request->usertime = $resourceusage['ru_utime.tv_usec']; } $request->id = $this->db->insert_record('telemetry_request', $request); foreach ($this->additionalstate as $collector) { $table = $collector->get_table(); $records = $collector->get_records(); foreach ($records as $record) { $record->requestid = $request->id; } $this->db->insert_records($table, $records); } }
/** * Object constructor. * * @param moodle_database $mdb Connection to the target database (a * @see moodle_database object). Use null to use the current $DB connection. * @param boolean $check_schema - whether or not to check that XML database * schema matches the RDBMS database schema before importing (inside * @see begin_database_import). */ public function __construct(moodle_database $mdb, $check_schema = true) { $this->mdb = $mdb; $this->manager = $mdb->get_manager(); $this->schema = $this->manager->get_install_xml_schema(); $this->check_schema = $check_schema; }
function definition() { $mform = $this->_form; $mform->addElement('header', 'database', get_string('dbtransfer', 'tool_dbtransfer')); $supported = array('mysqli/native', 'pgsql/native', 'mssql/native', 'oci/native', 'sqlsrv/native'); $drivers = array(); foreach ($supported as $driver) { list($dbtype, $dblibrary) = explode('/', $driver); $targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary); if ($targetdb->driver_installed() !== true) { continue; } $drivers[$driver] = $driver; } $mform->addElement('select', 'driver', get_string('dbtype', 'install'), $drivers); $mform->addElement('text', 'dbhost', get_string('dbhost', 'install')); $mform->addElement('text', 'dbname', get_string('database', 'install')); $mform->addElement('text', 'dbuser', get_string('user')); $mform->addElement('text', 'dbpass', get_string('password')); $mform->addElement('text', 'prefix', get_string('dbprefix', 'install')); $mform->addElement('text', 'dbport', get_string('dbport', 'install')); $mform->addElement('text', 'dbsocket', get_string('databasesocket', 'install')); $mform->addRule('dbhost', get_string('required'), 'required', null); $mform->addRule('dbname', get_string('required'), 'required', null); $mform->addRule('dbuser', get_string('required'), 'required', null); $mform->addRule('dbpass', get_string('required'), 'required', null); $mform->addRule('prefix', get_string('required'), 'required', null); $this->add_action_buttons(false, get_string('transferdata', 'tool_dbtransfer')); }
/** * Dispose off database connection after pushing any buffered events to the database. */ public function dispose() { $this->helper_dispose(); if ($this->extdb) { $this->extdb->dispose(); } $this->extdb = null; }
/** * Save the discussion to the DB * * @param object $discussion * @param upload_file $uploader */ public function save_discussion($discussion, upload_file $uploader) { $message = ''; $discussion->id = hsuforum_add_discussion($discussion, null, $message); $file = $uploader->process_file_upload($discussion->firstpost); if (!is_null($file)) { $this->db->set_field('hsuforum_posts', 'attachment', 1, array('id' => $discussion->firstpost)); } }
/** * GC session handler. * * {@see http://php.net/manual/en/function.session-set-save-handler.php} * * @param int $ignored_maxlifetime moodle uses special timeout rules * @return bool success */ public function handler_gc($ignored_maxlifetime) { // This should do something only if cron is not running properly... if (!($stalelifetime = ini_get('session.gc_maxlifetime'))) { return true; } $params = array('purgebefore' => time() - $stalelifetime); $this->database->delete_records_select('sessions', 'userid = 0 AND timemodified < :purgebefore', $params); return true; }
/** * Release a lock that was previously obtained with @lock. * @param lock $lock - a lock obtained from this factory. * @return boolean - true if the lock is no longer held (including if it was never held). */ public function release_lock(lock $lock) { $params = array('locktype' => $this->dblockid, 'token' => $lock->get_key()); $result = $this->db->get_record_sql('SELECT pg_advisory_unlock(:locktype, :token) AS unlocked', $params); $result = $result->unlocked === 't'; if ($result) { unset($this->openlocks[$lock->get_key()]); } return $result; }
/** * Extend a lock that was previously obtained with @lock. * @param lock $lock - a lock obtained from this factory. * @param int $maxlifetime - the new lifetime for the lock (in seconds). * @return boolean - true if the lock was extended. */ public function extend_lock(lock $lock, $maxlifetime = 86400) { $now = time(); $expires = $now + $maxlifetime; $params = array('expires' => $expires, 'token' => $lock->get_key()); $sql = 'UPDATE {lock_db} SET expires = :expires, WHERE owner = :token'; $this->db->execute($sql, $params); $countparams = array('owner' => $lock->get_key()); $result = $this->count_records('lock_db', $countparams); return $result === 0; }
public function test_concurrent_temp_tables() { $DB = $this->tdb; // do not use global $DB! $dbman = $this->tdb->get_manager(); // Define 2 records $record1 = (object) array('course' => 1, 'secondname' => '11 important', 'intro' => '111 important'); $record2 = (object) array('course' => 2, 'secondname' => '22 important', 'intro' => '222 important'); // Create temp table1 and insert 1 record (in DB) $table = $this->tables['test_table1']; $dbman->create_temp_table($table); $this->assertTrue($dbman->table_exists('test_table1')); $inserted = $DB->insert_record('test_table1', $record1); // Switch to new connection $cfg = $DB->export_dbconfig(); if (!isset($cfg->dboptions)) { $cfg->dboptions = array(); } $DB2 = moodle_database::get_driver_instance($cfg->dbtype, $cfg->dblibrary); $DB2->connect($cfg->dbhost, $cfg->dbuser, $cfg->dbpass, $cfg->dbname, $cfg->prefix, $cfg->dboptions); $dbman2 = $DB2->get_manager(); $this->assertFalse($dbman2->table_exists('test_table1')); // Temp table not exists in DB2 // Create temp table1 and insert 1 record (in DB2) $table = $this->tables['test_table1']; $dbman2->create_temp_table($table); $this->assertTrue($dbman2->table_exists('test_table1')); $inserted = $DB2->insert_record('test_table1', $record2); $dbman2->drop_temp_table($table); // Drop temp table before closing DB2 $this->assertFalse($dbman2->table_exists('test_table1')); $DB2->dispose(); // Close DB2 $this->assertTrue($dbman->table_exists('test_table1')); // Check table continues existing for DB $dbman->drop_temp_table($table); // Drop temp table $this->assertFalse($dbman->table_exists('test_table1')); }
/** * Does all the grunt work for updating a post * * @param object $course * @param object $cm * @param object $forum * @param \context_module $context * @param object $discussion * @param object $post * @param array $deletefiles * @param array $options These override default post values, EG: set the post message with this * @return json_response */ public function handle_update_post($course, $cm, $forum, $context, $discussion, $post, array $deletefiles = array(), array $options) { $this->require_can_edit_post($forum, $context, $discussion, $post); $uploader = new upload_file(new attachments($forum, $context, $deletefiles), \mod_hsuforum_post_form::attachment_options($forum)); // Apply updates to the post. foreach ($options as $name => $value) { if (property_exists($post, $name)) { $post->{$name} = $value; } } $post->itemid = empty($options['itemid']) ? 0 : $options['itemid']; $errors = $this->validate_post($course, $cm, $forum, $context, $discussion, $post, $uploader); if (!empty($errors)) { return $this->create_error_response($errors); } $this->save_post($discussion, $post, $uploader); // If the user has access to all groups and they are changing the group, then update the post. if (empty($post->parent) && has_capability('mod/hsuforum:movediscussions', $context)) { $this->db->set_field('hsuforum_discussions', 'groupid', $options['groupid'], array('id' => $discussion->id)); } $this->trigger_post_updated($context, $forum, $discussion, $post); return new json_response((object) array('eventaction' => 'postupdated', 'discussionid' => (int) $discussion->id, 'postid' => (int) $post->id, 'livelog' => get_string('postwasupdated', 'hsuforum'), 'html' => $this->discussionservice->render_full_thread($discussion->id))); }
/** * Returns list of fully working database drivers present in system. * @return array */ function tool_dbtransfer_get_drivers() { global $CFG; $files = new RegexIterator(new DirectoryIterator("{$CFG->libdir}/dml"), '|^.*_moodle_database\\.php$|'); $drivers = array(); foreach ($files as $file) { $matches = null; preg_match('|^([a-z0-9]+)_([a-z]+)_moodle_database\\.php$|', $file->getFilename(), $matches); if (!$matches) { continue; } $dbtype = $matches[1]; $dblibrary = $matches[2]; if ($dbtype === 'sqlite3') { // Blacklist unfinished drivers. continue; } $targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary, false); if ($targetdb->driver_installed() !== true) { continue; } $driver = $dbtype . '/' . $dblibrary; $drivers[$driver] = $targetdb->get_name(); } return $drivers; }
/** * Called before each db query. * * Overridden to ensure $this->lastErorr is reset each query * * @param string $sql * @param array array of parameters * @param int $type type of query * @param mixed $extrainfo driver specific extra information * @return void */ protected function query_start($sql, array $params = null, $type, $extrainfo = null) { $this->lastError = null; parent::query_start($sql, $params, $type, $extrainfo); }
/** * on DBs that support it, rollback the transaction */ public function rollback_sql() { if (!parent::rollback_sql()) { return false; } $sql = "ROLLBACK"; $this->query_start($sql, NULL, SQL_QUERY_AUX); $result = pg_query($this->pgsql, $sql); $this->query_end($result); pg_free_result($result); return true; }
public function test_session_locks() { $DB = $this->tdb; $dbman = $DB->get_manager(); // Open second connection. $cfg = $DB->export_dbconfig(); if (!isset($cfg->dboptions)) { $cfg->dboptions = array(); } $DB2 = moodle_database::get_driver_instance($cfg->dbtype, $cfg->dblibrary); $DB2->connect($cfg->dbhost, $cfg->dbuser, $cfg->dbpass, $cfg->dbname, $cfg->prefix, $cfg->dboptions); // Testing that acquiring a lock effectively locks. // Get a session lock on connection1. $rowid = rand(100, 200); $timeout = 1; $DB->get_session_lock($rowid, $timeout); // Try to get the same session lock on connection2. try { $DB2->get_session_lock($rowid, $timeout); $DB2->release_session_lock($rowid); // Should not be executed, but here for safety. $this->fail('An Exception is missing, expected due to session lock acquired.'); } catch (moodle_exception $e) { $this->assertInstanceOf('dml_sessionwait_exception', $e); $DB->release_session_lock($rowid); // Release lock on connection1. } // Testing that releasing a lock effectively frees. // Get a session lock on connection1. $rowid = rand(100, 200); $timeout = 1; $DB->get_session_lock($rowid, $timeout); // Release the lock on connection1. $DB->release_session_lock($rowid); // Get the just released lock on connection2. $DB2->get_session_lock($rowid, $timeout); // Release the lock on connection2. $DB2->release_session_lock($rowid); $DB2->dispose(); }
$checked = $config->dbsocket ? 'checked="checked' : ''; echo '<div class="formrow"><label for="id_dbsocket" class="formlabel">' . $strdbsocket . '</label>'; echo '<input type="hidden" value="0" name="dbsocket" />'; echo '<input type="checkbox" id="id_dbsocket" value="1" name="dbsocket" ' . $checked . ' class="forminput" />'; echo '</div>'; } echo '<div class="hint">' . $hint_database . '</div>'; echo '</div>'; install_print_footer($config); die; } if ($config->stage == INSTALL_DATABASETYPE) { /// Finally ask for DB type install_print_header($config, get_string('database', 'install'), get_string('databasetypehead', 'install'), get_string('databasetypesub', 'install')); // TODO: move this PHP5 code to lib/installib.php so that this file parses in PHP4 $databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'), 'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'), 'oci' => moodle_database::get_driver_instance('oci', 'native')); echo '<div class="userinput">'; echo '<div class="formrow"><label class="formlabel" for="dbtype">' . get_string('dbtype', 'install') . '</label>'; echo '<select id="dbtype" name="dbtype" class="forminput">'; $disabled = array(); $options = array(); foreach ($databases as $type => $database) { if ($database->driver_installed() !== true) { $disabled[$type] = $database; continue; } echo '<option value="' . s($type) . '">' . $database->get_name() . '</option>'; } if ($disabled) { echo '<optgroup label="' . s(get_string('notavailable')) . '">'; foreach ($disabled as $type => $database) {
/** * Returns list of fully working database drivers present in system. * @return array */ public static function get_drivers() { return array('' => get_string('choosedots'), 'native/mysqli' => \moodle_database::get_driver_instance('mysqli', 'native')->get_name(), 'native/mariadb' => \moodle_database::get_driver_instance('mariadb', 'native')->get_name(), 'native/pgsql' => \moodle_database::get_driver_instance('pgsql', 'native')->get_name(), 'native/oci' => \moodle_database::get_driver_instance('oci', 'native')->get_name(), 'native/sqlsrv' => \moodle_database::get_driver_instance('sqlsrv', 'native')->get_name(), 'native/mssql' => \moodle_database::get_driver_instance('mssql', 'native')->get_name()); }
public function release_session_lock($rowid) { if (!$this->session_lock_supported()) { return; } parent::release_session_lock($rowid); $fullname = $this->dbname . '-' . $this->prefix . '-session-' . $rowid; $params = array('lockname' => $fullname); $sql = 'SELECT MOODLE_LOCKS.RELEASE_LOCK(:lockname) FROM DUAL'; $this->query_start($sql, $params, SQL_QUERY_AUX); $stmt = $this->parse_query($sql); $this->bind_params($stmt, $params); $result = oci_execute($stmt, $this->commit_status); $this->query_end($result, $stmt); oci_free_statement($stmt); }
/** * Sets up global $DB moodle_database instance * * @global object * @global object * @return void */ function setup_DB() { global $CFG, $DB; if (isset($DB)) { return; } if (!isset($CFG->dbuser)) { $CFG->dbuser = ''; } if (!isset($CFG->dbpass)) { $CFG->dbpass = ''; } if (!isset($CFG->dbname)) { $CFG->dbname = ''; } if (!isset($CFG->dblibrary)) { $CFG->dblibrary = 'native'; // use new drivers instead of the old adodb driver names switch ($CFG->dbtype) { case 'postgres7': $CFG->dbtype = 'pgsql'; break; case 'mssql_n': $CFG->dbtype = 'mssql'; break; case 'oci8po': $CFG->dbtype = 'oci'; break; case 'mysql': $CFG->dbtype = 'mysqli'; break; } } if (!isset($CFG->dboptions)) { $CFG->dboptions = array(); } if (isset($CFG->dbpersist)) { $CFG->dboptions['dbpersist'] = $CFG->dbpersist; } if (!($DB = moodle_database::get_driver_instance($CFG->dbtype, $CFG->dblibrary))) { throw new dml_exception('dbdriverproblem', "Unknown driver {$CFG->dblibrary}/{$CFG->dbtype}"); } try { $DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, $CFG->dboptions); } catch (moodle_exception $e) { if (empty($CFG->noemailever) and !empty($CFG->emailconnectionerrorsto)) { if (file_exists($CFG->dataroot . '/emailcount')) { $fp = @fopen($CFG->dataroot . '/emailcount', 'r'); $content = @fread($fp, 24); @fclose($fp); if (time() - (int) $content > 600) { //email directly rather than using messaging @mail($CFG->emailconnectionerrorsto, 'WARNING: Database connection error: ' . $CFG->wwwroot, 'Connection error: ' . $CFG->wwwroot); $fp = @fopen($CFG->dataroot . '/emailcount', 'w'); @fwrite($fp, time()); } } else { //email directly rather than using messaging @mail($CFG->emailconnectionerrorsto, 'WARNING: Database connection error: ' . $CFG->wwwroot, 'Connection error: ' . $CFG->wwwroot); $fp = @fopen($CFG->dataroot . '/emailcount', 'w'); @fwrite($fp, time()); } } // rethrow the exception throw $e; } $CFG->dbfamily = $DB->get_dbfamily(); // TODO: BC only for now return true; }
public function release_session_lock($rowid) { if (!$this->used_for_db_sessions) { return; } parent::release_session_lock($rowid); $fullname = $this->dbname . '-' . $this->prefix . '-session-' . $rowid; $sql = "SELECT RELEASE_LOCK('{$fullname}')"; $this->query_start($sql, null, SQL_QUERY_AUX); $result = $this->mysqli->query($sql); $this->query_end($result); if ($result) { $result->close(); } }
if ($config->stage == INSTALL_DATABASETYPE) { $CFG->early_install_lang = false; // Finally ask for DB type install_print_header($config, get_string('database', 'install'), get_string('databasetypehead', 'install'), get_string('databasetypesub', 'install')); $databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'), 'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'), 'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'), 'oci' => moodle_database::get_driver_instance('oci', 'native'), 'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver 'mssql' => moodle_database::get_driver_instance('mssql', 'native'), // FreeTDS driver ); echo '<div class="userinput">'; echo '<div class="formrow"><label class="formlabel" for="dbtype">'.get_string('dbtype', 'install').'</label>'; echo '<select id="dbtype" name="dbtype" class="forminput">'; $disabled = array(); $options = array(); foreach ($databases as $type=>$database) { if ($database->driver_installed() !== true) { $disabled[$type] = $database; continue; } echo '<option value="'.s($type).'">'.$database->get_name().'</option>'; } if ($disabled) {
public function release_session_lock($rowid) { if (!$this->session_lock_supported()) { return; } if (!$this->used_for_db_sessions) { return; } parent::release_session_lock($rowid); $sql = "SELECT pg_advisory_unlock({$rowid})"; $this->query_start($sql, null, SQL_QUERY_AUX); $result = pg_query($this->pgsql, $sql); $this->query_end($result); if ($result) { pg_free_result($result); } }
} else { spl_autoload_register('core_component::classloader'); } require $CFG->dirroot . '/version.php'; $CFG->target_release = $release; \core\session\manager::init_empty_session(); global $SESSION; global $USER; global $COURSE; $COURSE = new stdClass(); $COURSE->id = 1; global $SITE; $SITE = $COURSE; define('SITEID', 1); //Database types $databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'), 'mariadb' => moodle_database::get_driver_instance('mariadb', 'native'), 'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'), 'oci' => moodle_database::get_driver_instance('oci', 'native'), 'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), 'mssql' => moodle_database::get_driver_instance('mssql', 'native')); foreach ($databases as $type => $database) { if ($database->driver_installed() !== true) { unset($databases[$type]); } } if (empty($databases)) { $defaultdb = ''; } else { reset($databases); $defaultdb = key($databases); } // now get cli options list($options, $unrecognized) = cli_get_params(array('chmod' => isset($distro->directorypermissions) ? sprintf('%04o', $distro->directorypermissions) : '2777', 'lang' => $CFG->lang, 'wwwroot' => '', 'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))) . '/moodledata') : $distro->dataroot, 'dbtype' => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, 'dbhost' => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, 'dbname' => 'moodle', 'dbuser' => empty($distro->dbuser) ? 'root' : $distro->dbuser, 'dbpass' => '', 'dbport' => '', 'dbsocket' => '', 'prefix' => 'mdl_', 'fullname' => '', 'shortname' => '', 'summary' => '', 'adminuser' => 'admin', 'adminpass' => '', 'adminemail' => '', 'non-interactive' => false, 'agree-license' => false, 'allow-unstable' => false, 'help' => false), array('h' => 'help')); $interactive = empty($options['non-interactive']); // set up language
/** * Returns content of config.php file. * * Uses PHP_EOL for generating proper end of lines for the given platform. * * @param moodle_database $database database instance * @param object $cfg copy of $CFG * @return string */ function install_generate_configphp($database, $cfg) { $configphp = '<?php // Moodle configuration file' . PHP_EOL . PHP_EOL; $configphp .= 'unset($CFG);' . PHP_EOL; $configphp .= 'global $CFG;' . PHP_EOL; $configphp .= '$CFG = new stdClass();' . PHP_EOL . PHP_EOL; // prevent PHP5 strict warnings $dbconfig = $database->export_dbconfig(); foreach ($dbconfig as $key => $value) { $key = str_pad($key, 9); $configphp .= '$CFG->' . $key . ' = ' . var_export($value, true) . ';' . PHP_EOL; } $configphp .= PHP_EOL; $configphp .= '$CFG->wwwroot = ' . var_export($cfg->wwwroot, true) . ';' . PHP_EOL; $configphp .= '$CFG->dataroot = ' . var_export($cfg->dataroot, true) . ';' . PHP_EOL; $configphp .= '$CFG->admin = ' . var_export($cfg->admin, true) . ';' . PHP_EOL . PHP_EOL; if (empty($cfg->directorypermissions)) { $chmod = '02777'; } else { $chmod = '0' . decoct($cfg->directorypermissions); } $configphp .= '$CFG->directorypermissions = ' . $chmod . ';' . PHP_EOL . PHP_EOL; $configphp .= '$CFG->passwordsaltmain = ' . var_export(complex_random_string(), true) . ';' . PHP_EOL . PHP_EOL; $configphp .= 'require_once(dirname(__FILE__) . \'/lib/setup.php\');' . PHP_EOL . PHP_EOL; $configphp .= '// There is no php closing tag in this file,' . PHP_EOL; $configphp .= '// it is intentional because it prevents trailing whitespace problems!' . PHP_EOL; return $configphp; }
/** * Creates a new sql_generator. * @param moodle_database $mdb The moodle_database object instance. * @param moodle_temptables $temptables The optional moodle_temptables instance, null by default. */ public function __construct($mdb, $temptables = null) { $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 $this->temptables = $temptables; }
/** * Destroy session handler * * {@see http://php.net/manual/en/function.session-set-save-handler.php} * * @param string $sid * @return bool success */ public function handler_destroy($sid) { session_kill($sid); if (isset($this->record->id) and $this->record->sid === $sid) { try { $this->database->release_session_lock($this->record->id); } catch (Exception $ex) { // ignore problems } $this->record = null; } $this->lasthash = null; return true; }
public function release_session_lock($rowid) { if (!$this->session_lock_supported()) { return; } if (!$this->used_for_db_sessions) { return; } parent::release_session_lock($rowid); $fullname = $this->dbname . '-' . $this->prefix . '-session-' . $rowid; $sql = "sp_releaseapplock '{$fullname}', 'Session'"; $this->query_start($sql, null, SQL_QUERY_AUX); $result = mssql_query($sql, $this->mssql); $this->query_end($result); $this->free_result($result); }
* @copyright 2008 Petr Skoda * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ define('NO_OUTPUT_BUFFERING', true); require '../../../config.php'; require_once 'locallib.php'; require_once 'database_transfer_form.php'; require_login(); admin_externalpage_setup('tooldbtransfer'); // Create the form $form = new database_transfer_form(); // If we have valid input. if ($data = $form->get_data()) { // Connect to the other database. list($dbtype, $dblibrary) = explode('/', $data->driver); $targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary); $dboptions = array(); if ($data->dbport) { $dboptions['dbport'] = $data->dbport; } if ($data->dbsocket) { $dboptions['dbsocket'] = $data->dbsocket; } if (!$targetdb->connect($data->dbhost, $data->dbuser, $data->dbpass, $data->dbname, $data->prefix, $dboptions)) { throw new dbtransfer_exception('notargetconectexception', null, "{$CFG->wwwroot}/{$CFG->admin}/tool/dbtransfer/"); } if ($targetdb->get_tables()) { throw new dbtransfer_exception('targetdatabasenotempty', null, "{$CFG->wwwroot}/{$CFG->admin}/tool/dbtransfer/"); } // Start output. echo $OUTPUT->header();
function test_concurent_transactions() { // Notes about this test: // 1- MySQL needs to use one engine with transactions support (InnoDB). // 2- MSSQL needs to have enabled versioning for read committed // transactions (ALTER DATABASE xxx SET READ_COMMITTED_SNAPSHOT ON) $DB = $this->tdb; $dbman = $DB->get_manager(); $table = $this->get_test_table(); $tablename = $table->getName(); $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_key('primary', XMLDB_KEY_PRIMARY, array('id')); $dbman->create_table($table); $transaction = $DB->start_delegated_transaction(); $data = (object) array('course' => 1); $this->assertEqual(0, $DB->count_records($tablename)); $DB->insert_record($tablename, $data); $this->assertEqual(1, $DB->count_records($tablename)); //open second connection $cfg = $DB->export_dbconfig(); if (!isset($cfg->dboptions)) { $cfg->dboptions = array(); } $DB2 = moodle_database::get_driver_instance($cfg->dbtype, $cfg->dblibrary); $DB2->connect($cfg->dbhost, $cfg->dbuser, $cfg->dbpass, $cfg->dbname, $cfg->prefix, $cfg->dboptions); // second instance should not see pending inserts $this->assertEqual(0, $DB2->count_records($tablename)); $data = (object) array('course' => 2); $DB2->insert_record($tablename, $data); $this->assertEqual(1, $DB2->count_records($tablename)); // first should see the changes done from second $this->assertEqual(2, $DB->count_records($tablename)); // now commit and we should see it finally in second connections $transaction->allow_commit(); $this->assertEqual(2, $DB2->count_records($tablename)); $DB2->dispose(); }
/** * Call this statically to connect to the DB using the unittest prefix, instantiate * the unit test db, store it as a member variable, instantiate $this and use it as the new global $DB. */ public static function instantiate() { global $CFG, $DB; UnitTestDB::$real_db = clone $DB; if (empty($CFG->unittestprefix)) { print_error("prefixnotset", 'tool_unittest'); } if (empty(UnitTestDB::$DB)) { UnitTestDB::$DB = moodle_database::get_driver_instance($CFG->dbtype, $CFG->dblibrary); UnitTestDB::$DB->connect($CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->unittestprefix); } $manager = UnitTestDB::$DB->get_manager(); if (!$manager->table_exists('user')) { print_error('tablesnotsetup', 'tool_unittest'); } $DB = new UnitTestDB(); }
public function test_limits_and_offsets() { $DB = $this->tdb; $dbman = $DB->get_manager(); if (false) { $DB = new moodle_database(); } $table = $this->get_test_table(); $tablename = $table->getName(); $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, null); $table->add_field('content', XMLDB_TYPE_TEXT, 'big', XMLDB_UNSIGNED, XMLDB_NOTNULL); $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); $dbman->create_table($table); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'a', 'content' => 'one'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'b', 'content' => 'two'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'c', 'content' => 'three'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'd', 'content' => 'four'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'e', 'content' => 'five'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'f', 'content' => 'six'))); $sqlqm = "SELECT *\n FROM {{$tablename}}"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 4)); $this->assertEquals(2, count($records)); $this->assertEquals('e', reset($records)->name); $this->assertEquals('f', end($records)->name); $sqlqm = "SELECT *\n FROM {{$tablename}}"; $this->assertEmpty($records = $DB->get_records_sql($sqlqm, null, 8)); $sqlqm = "SELECT *\n FROM {{$tablename}}"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 0, 4)); $this->assertEquals(4, count($records)); $this->assertEquals('a', reset($records)->name); $this->assertEquals('d', end($records)->name); $sqlqm = "SELECT *\n FROM {{$tablename}}"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 0, 8)); $this->assertEquals(6, count($records)); $this->assertEquals('a', reset($records)->name); $this->assertEquals('f', end($records)->name); $sqlqm = "SELECT *\n FROM {{$tablename}}"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 1, 4)); $this->assertEquals(4, count($records)); $this->assertEquals('b', reset($records)->name); $this->assertEquals('e', end($records)->name); $sqlqm = "SELECT *\n FROM {{$tablename}}"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 4, 4)); $this->assertEquals(2, count($records)); $this->assertEquals('e', reset($records)->name); $this->assertEquals('f', end($records)->name); $sqlqm = "SELECT t.*, t.name AS test\n FROM {{$tablename}} t\n ORDER BY t.id ASC"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 4, 4)); $this->assertEquals(2, count($records)); $this->assertEquals('e', reset($records)->name); $this->assertEquals('f', end($records)->name); $sqlqm = "SELECT DISTINCT t.name, t.name AS test\n FROM {{$tablename}} t\n ORDER BY t.name DESC"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 4, 4)); $this->assertEquals(2, count($records)); $this->assertEquals('b', reset($records)->name); $this->assertEquals('a', end($records)->name); $sqlqm = "SELECT 1\n FROM {{$tablename}} t\n WHERE t.name = 'a'"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 0, 1)); $this->assertEquals(1, count($records)); $sqlqm = "SELECT 'constant'\n FROM {{$tablename}} t\n WHERE t.name = 'a'"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 0, 8)); $this->assertEquals(1, count($records)); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'a', 'content' => 'one'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'b', 'content' => 'two'))); $this->assertNotEmpty($DB->insert_record($tablename, array('name' => 'c', 'content' => 'three'))); $sqlqm = "SELECT t.name, COUNT(DISTINCT t2.id) AS count, 'Test' AS teststring\n FROM {{$tablename}} t\n LEFT JOIN (\n SELECT t.id, t.name\n FROM {{$tablename}} t\n ) t2 ON t2.name = t.name\n GROUP BY t.name\n ORDER BY t.name ASC"; $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm)); $this->assertEquals(6, count($records)); // a,b,c,d,e,f $this->assertEquals(2, reset($records)->count); // a has 2 records now $this->assertEquals(1, end($records)->count); // f has 1 record still $this->assertNotEmpty($records = $DB->get_records_sql($sqlqm, null, 0, 2)); $this->assertEquals(2, count($records)); $this->assertEquals(2, reset($records)->count); $this->assertEquals(2, end($records)->count); }