3 // This file is part of Moodle - http://moodle.org/
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
21 * @copyright 2008 Petr Skoda (http://skodak.org)
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die();
27 class dml_test extends UnitTestCase {
28 private $tables = array();
29 /** @var moodle_database */
32 public static $includecoverage = array('lib/dml');
33 public static $excludecoverage = array('lib/dml/simpletest');
36 protected $olddisplay;
39 global $DB, $UNITTEST;
41 if (isset($UNITTEST->func_test_db)) {
42 $this->tdb = $UNITTEST->func_test_db;
49 $dbman = $this->tdb->get_manager();
51 foreach ($this->tables as $tablename) {
52 if ($dbman->table_exists($tablename)) {
53 $table = new xmldb_table($tablename);
54 $dbman->drop_table($table);
57 $this->tables = array();
61 * Get a xmldb_table object for testing, deleting any existing table
62 * of the same name, for example if one was left over from a previous test
65 * @param database_manager $dbman the database_manager to use.
66 * @param string $suffix table name suffix, use if you need more test tables
67 * @return xmldb_table the table object.
69 private function get_test_table($suffix = '') {
70 $dbman = $this->tdb->get_manager();
72 $tablename = "unit_table";
74 $tablename .= $suffix;
77 $table = new xmldb_table($tablename);
78 if ($dbman->table_exists($table)) {
79 $dbman->drop_table($table);
81 $table->setComment("This is a test'n drop table. You can drop it safely");
82 $this->tables[$tablename] = $tablename;
83 return new xmldb_table($tablename);
86 protected function enable_debugging() {
89 $this->olddebug = $CFG->debug; // Save current debug settings
90 $this->olddisplay = $CFG->debugdisplay;
91 $CFG->debug = DEBUG_DEVELOPER;
92 $CFG->debugdisplay = true;
93 ob_start(); // hide debug warning
97 protected function get_debugging() {
100 $debuginfo = ob_get_contents();
102 $CFG->debug = $this->olddebug; // Restore original debug settings
103 $CFG->debugdisplay = $this->olddisplay;
108 // NOTE: please keep order of test methods here matching the order of moodle_database class methods
110 function test_diagnose() {
112 $result = $DB->diagnose();
113 $this->assertNull($result, 'Database self diagnostics failed %s');
116 function test_get_server_info() {
118 $result = $DB->get_server_info();
119 $this->assertTrue(is_array($result));
120 $this->assertTrue(array_key_exists('description', $result));
121 $this->assertTrue(array_key_exists('version', $result));
124 public function test_get_in_or_equal() {
127 // SQL_PARAMS_QM - IN or =
129 // Correct usage of multiple values
130 $in_values = array('value1', 'value2', '3', 4, null, false, true);
131 list($usql, $params) = $DB->get_in_or_equal($in_values);
132 $this->assertEqual('IN ('.implode(',',array_fill(0, count($in_values), '?')).')', $usql);
133 $this->assertEqual(count($in_values), count($params));
134 foreach ($params as $key => $value) {
135 $this->assertIdentical($in_values[$key], $value);
138 // Correct usage of single value (in an array)
139 $in_values = array('value1');
140 list($usql, $params) = $DB->get_in_or_equal($in_values);
141 $this->assertEqual("= ?", $usql);
142 $this->assertEqual(1, count($params));
143 $this->assertEqual($in_values[0], $params[0]);
145 // Correct usage of single value
146 $in_value = 'value1';
147 list($usql, $params) = $DB->get_in_or_equal($in_values);
148 $this->assertEqual("= ?", $usql);
149 $this->assertEqual(1, count($params));
150 $this->assertEqual($in_value, $params[0]);
152 // SQL_PARAMS_QM - NOT IN or <>
154 // Correct usage of multiple values
155 $in_values = array('value1', 'value2', 'value3', 'value4');
156 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, null, false);
157 $this->assertEqual("NOT IN (?,?,?,?)", $usql);
158 $this->assertEqual(4, count($params));
159 foreach ($params as $key => $value) {
160 $this->assertEqual($in_values[$key], $value);
163 // Correct usage of single value (in array()
164 $in_values = array('value1');
165 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, null, false);
166 $this->assertEqual("<> ?", $usql);
167 $this->assertEqual(1, count($params));
168 $this->assertEqual($in_values[0], $params[0]);
170 // Correct usage of single value
171 $in_value = 'value1';
172 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, null, false);
173 $this->assertEqual("<> ?", $usql);
174 $this->assertEqual(1, count($params));
175 $this->assertEqual($in_value, $params[0]);
177 // SQL_PARAMS_NAMED - IN or =
179 // Correct usage of multiple values
180 $in_values = array('value1', 'value2', 'value3', 'value4');
181 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', true);
182 $this->assertEqual(4, count($params));
185 foreach ($params as $key => $value) {
186 $this->assertEqual(current($in_values), $value);
190 $this->assertEqual("IN (".implode(',', $ps).")", $usql);
192 // Correct usage of single values (in array)
193 $in_values = array('value1');
194 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', true);
195 $this->assertEqual(1, count($params));
196 $value = reset($params);
198 $this->assertEqual("= :$key", $usql);
199 $this->assertEqual($in_value, $value);
201 // Correct usage of single value
202 $in_value = 'value1';
203 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', true);
204 $this->assertEqual(1, count($params));
205 $value = reset($params);
207 $this->assertEqual("= :$key", $usql);
208 $this->assertEqual($in_value, $value);
210 // SQL_PARAMS_NAMED - NOT IN or <>
212 // Correct usage of multiple values
213 $in_values = array('value1', 'value2', 'value3', 'value4');
214 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false);
215 $this->assertEqual(4, count($params));
218 foreach ($params as $key => $value) {
219 $this->assertEqual(current($in_values), $value);
223 $this->assertEqual("NOT IN (".implode(',', $ps).")", $usql);
225 // Correct usage of single values (in array)
226 $in_values = array('value1');
227 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false);
228 $this->assertEqual(1, count($params));
229 $value = reset($params);
231 $this->assertEqual("<> :$key", $usql);
232 $this->assertEqual($in_value, $value);
234 // Correct usage of single value
235 $in_value = 'value1';
236 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false);
237 $this->assertEqual(1, count($params));
238 $value = reset($params);
240 $this->assertEqual("<> :$key", $usql);
241 $this->assertEqual($in_value, $value);
243 // make sure the param names are unique
244 list($usql1, $params1) = $DB->get_in_or_equal(array(1,2,3), SQL_PARAMS_NAMED, 'param');
245 list($usql2, $params2) = $DB->get_in_or_equal(array(1,2,3), SQL_PARAMS_NAMED, 'param');
246 $params1 = array_keys($params1);
247 $params2 = array_keys($params2);
248 $common = array_intersect($params1, $params2);
249 $this->assertEqual(count($common), 0);
251 // Some incorrect tests
253 // Incorrect usage passing not-allowed params type
254 $in_values = array(1, 2, 3);
256 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_DOLLAR, 'param', false);
257 $this->fail('An Exception is missing, expected due to not supported SQL_PARAMS_DOLLAR');
258 } catch (exception $e) {
259 $this->assertTrue($e instanceof dml_exception);
260 $this->assertEqual($e->errorcode, 'typenotimplement');
263 // Incorrect usage passing empty array
264 $in_values = array();
266 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false);
267 $this->fail('An Exception is missing, expected due to empty array of items');
268 } catch (exception $e) {
269 $this->assertTrue($e instanceof coding_exception);
272 // Test using $onemptyitems
274 // Correct usage passing empty array and $onemptyitems = NULL (equal = true, QM)
275 $in_values = array();
276 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, NULL);
277 $this->assertEqual(' IS NULL', $usql);
278 $this->assertIdentical(array(), $params);
280 // Correct usage passing empty array and $onemptyitems = NULL (equal = false, NAMED)
281 $in_values = array();
282 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, NULL);
283 $this->assertEqual(' IS NOT NULL', $usql);
284 $this->assertIdentical(array(), $params);
286 // Correct usage passing empty array and $onemptyitems = true (equal = true, QM)
287 $in_values = array();
288 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, true);
289 $this->assertEqual('= ?', $usql);
290 $this->assertIdentical(array(true), $params);
292 // Correct usage passing empty array and $onemptyitems = true (equal = false, NAMED)
293 $in_values = array();
294 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, true);
295 $this->assertEqual(1, count($params));
296 $value = reset($params);
298 $this->assertEqual('<> :'.$key, $usql);
299 $this->assertIdentical($value, true);
301 // Correct usage passing empty array and $onemptyitems = -1 (equal = true, QM)
302 $in_values = array();
303 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, -1);
304 $this->assertEqual('= ?', $usql);
305 $this->assertIdentical(array(-1), $params);
307 // Correct usage passing empty array and $onemptyitems = -1 (equal = false, NAMED)
308 $in_values = array();
309 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, -1);
310 $this->assertEqual(1, count($params));
311 $value = reset($params);
313 $this->assertEqual('<> :'.$key, $usql);
314 $this->assertIdentical($value, -1);
316 // Correct usage passing empty array and $onemptyitems = 'onevalue' (equal = true, QM)
317 $in_values = array();
318 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, 'onevalue');
319 $this->assertEqual('= ?', $usql);
320 $this->assertIdentical(array('onevalue'), $params);
322 // Correct usage passing empty array and $onemptyitems = 'onevalue' (equal = false, NAMED)
323 $in_values = array();
324 list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, 'onevalue');
325 $this->assertEqual(1, count($params));
326 $value = reset($params);
328 $this->assertEqual('<> :'.$key, $usql);
329 $this->assertIdentical($value, 'onevalue');
332 public function test_fix_table_names() {
333 $DB = new moodle_database_for_testing();
334 $prefix = $DB->get_prefix();
336 // Simple placeholder
337 $placeholder = "{user_123}";
338 $this->assertIdentical($prefix."user_123", $DB->public_fix_table_names($placeholder));
341 $placeholder = "{user-a}";
342 $this->assertIdentical($placeholder, $DB->public_fix_table_names($placeholder));
345 $placeholder = "{123user}";
346 $this->assertIdentical($placeholder, $DB->public_fix_table_names($placeholder));
349 $sql = "SELECT * FROM {user}, {funny_table_name}, {mdl_stupid_table} WHERE {user}.id = {funny_table_name}.userid";
350 $expected = "SELECT * FROM {$prefix}user, {$prefix}funny_table_name, {$prefix}mdl_stupid_table WHERE {$prefix}user.id = {$prefix}funny_table_name.userid";
351 $this->assertIdentical($expected, $DB->public_fix_table_names($sql));
354 function test_fix_sql_params() {
357 $table = $this->get_test_table();
358 $tablename = $table->getName();
360 // Correct table placeholder substitution
361 $sql = "SELECT * FROM {{$tablename}}";
362 $sqlarray = $DB->fix_sql_params($sql);
363 $this->assertEqual("SELECT * FROM {$DB->get_prefix()}".$tablename, $sqlarray[0]);
365 // Conversions of all param types
367 $sql[SQL_PARAMS_NAMED] = "SELECT * FROM {$DB->get_prefix()}testtable WHERE name = :param1, course = :param2";
368 $sql[SQL_PARAMS_QM] = "SELECT * FROM {$DB->get_prefix()}testtable WHERE name = ?, course = ?";
369 $sql[SQL_PARAMS_DOLLAR] = "SELECT * FROM {$DB->get_prefix()}testtable WHERE name = \$1, course = \$2";
372 $params[SQL_PARAMS_NAMED] = array('param1'=>'first record', 'param2'=>1);
373 $params[SQL_PARAMS_QM] = array('first record', 1);
374 $params[SQL_PARAMS_DOLLAR] = array('first record', 1);
376 list($rsql, $rparams, $rtype) = $DB->fix_sql_params($sql[SQL_PARAMS_NAMED], $params[SQL_PARAMS_NAMED]);
377 $this->assertIdentical($rsql, $sql[$rtype]);
378 $this->assertIdentical($rparams, $params[$rtype]);
380 list($rsql, $rparams, $rtype) = $DB->fix_sql_params($sql[SQL_PARAMS_QM], $params[SQL_PARAMS_QM]);
381 $this->assertIdentical($rsql, $sql[$rtype]);
382 $this->assertIdentical($rparams, $params[$rtype]);
384 list($rsql, $rparams, $rtype) = $DB->fix_sql_params($sql[SQL_PARAMS_DOLLAR], $params[SQL_PARAMS_DOLLAR]);
385 $this->assertIdentical($rsql, $sql[$rtype]);
386 $this->assertIdentical($rparams, $params[$rtype]);
389 // Malformed table placeholder
390 $sql = "SELECT * FROM [testtable]";
391 $sqlarray = $DB->fix_sql_params($sql);
392 $this->assertIdentical($sql, $sqlarray[0]);
395 // Mixed param types (colon and dollar)
396 $sql = "SELECT * FROM {{$tablename}} WHERE name = :param1, course = \$1";
397 $params = array('param1' => 'record1', 'param2' => 3);
399 $DB->fix_sql_params($sql, $params);
400 $this->fail("Expecting an exception, none occurred");
401 } catch (Exception $e) {
402 $this->assertTrue($e instanceof dml_exception);
405 // Mixed param types (question and dollar)
406 $sql = "SELECT * FROM {{$tablename}} WHERE name = ?, course = \$1";
407 $params = array('param1' => 'record2', 'param2' => 5);
409 $DB->fix_sql_params($sql, $params);
410 $this->fail("Expecting an exception, none occurred");
411 } catch (Exception $e) {
412 $this->assertTrue($e instanceof dml_exception);
415 // Too few params in sql
416 $sql = "SELECT * FROM {{$tablename}} WHERE name = ?, course = ?, id = ?";
417 $params = array('record2', 3);
419 $DB->fix_sql_params($sql, $params);
420 $this->fail("Expecting an exception, none occurred");
421 } catch (Exception $e) {
422 $this->assertTrue($e instanceof dml_exception);
425 // Too many params in array: no error, just use what is necessary
429 $sqlarray = $DB->fix_sql_params($sql, $params);
430 $this->assertTrue(is_array($sqlarray));
431 $this->assertEqual(count($sqlarray[1]), 3);
432 } catch (Exception $e) {
433 $this->fail("Unexpected ".get_class($e)." exception");
436 // Named params missing from array
437 $sql = "SELECT * FROM {{$tablename}} WHERE name = :name, course = :course";
438 $params = array('wrongname' => 'record1', 'course' => 1);
440 $DB->fix_sql_params($sql, $params);
441 $this->fail("Expecting an exception, none occurred");
442 } catch (Exception $e) {
443 $this->assertTrue($e instanceof dml_exception);
446 // Duplicate named param in query - this is a very important feature!!
447 // it helps with debugging of sloppy code
448 $sql = "SELECT * FROM {{$tablename}} WHERE name = :name, course = :name";
449 $params = array('name' => 'record2', 'course' => 3);
451 $DB->fix_sql_params($sql, $params);
452 $this->fail("Expecting an exception, none occurred");
453 } catch (Exception $e) {
454 $this->assertTrue($e instanceof dml_exception);
457 // Extra named param is ignored
458 $sql = "SELECT * FROM {{$tablename}} WHERE name = :name, course = :course";
459 $params = array('name' => 'record1', 'course' => 1, 'extrastuff'=>'haha');
461 $sqlarray = $DB->fix_sql_params($sql, $params);
462 $this->assertTrue(is_array($sqlarray));
463 $this->assertEqual(count($sqlarray[1]), 2);
464 } catch (Exception $e) {
465 $this->fail("Unexpected ".get_class($e)." exception");
468 // Params exceeding 30 chars length
469 $sql = "SELECT * FROM {{$tablename}} WHERE name = :long_placeholder_with_more_than_30";
470 $params = array('long_placeholder_with_more_than_30' => 'record1');
472 $DB->fix_sql_params($sql, $params);
473 $this->fail("Expecting an exception, none occurred");
474 } catch (Exception $e) {
475 $this->assertTrue($e instanceof coding_exception);
478 // Booleans in NAMED params are casting to 1/0 int
479 $sql = "SELECT * FROM {{$tablename}} WHERE course = ? OR course = ?";
480 $params = array(true, false);
481 list($sql, $params) = $DB->fix_sql_params($sql, $params);
482 $this->assertTrue(reset($params) === 1);
483 $this->assertTrue(next($params) === 0);
485 // Booleans in QM params are casting to 1/0 int
486 $sql = "SELECT * FROM {{$tablename}} WHERE course = :course1 OR course = :course2";
487 $params = array('course1' => true, 'course2' => false);
488 list($sql, $params) = $DB->fix_sql_params($sql, $params);
489 $this->assertTrue(reset($params) === 1);
490 $this->assertTrue(next($params) === 0);
492 // Booleans in DOLLAR params are casting to 1/0 int
493 $sql = "SELECT * FROM {{$tablename}} WHERE course = \$1 OR course = \$2";
494 $params = array(true, false);
495 list($sql, $params) = $DB->fix_sql_params($sql, $params);
496 $this->assertTrue(reset($params) === 1);
497 $this->assertTrue(next($params) === 0);
499 // No data types are touched except bool
500 $sql = "SELECT * FROM {{$tablename}} WHERE name IN (?,?,?,?,?,?)";
501 $inparams = array('abc', 'ABC', NULL, '1', 1, 1.4);
502 list($sql, $params) = $DB->fix_sql_params($sql, $inparams);
503 $this->assertIdentical(array_values($params), array_values($inparams));
506 public function test_strtok() {
507 // strtok was previously used by bound emulation, make sure it is not used any more
509 $dbman = $this->tdb->get_manager();
511 $table = $this->get_test_table();
512 $tablename = $table->getName();
514 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
515 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
516 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, 'lala');
517 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
518 $dbman->create_table($table);
521 $this->assertIdentical(strtok($str, '?'), 'a');
523 $DB->get_records($tablename, array('id'=>1));
525 $this->assertIdentical(strtok('?'), 'b');
528 public function test_tweak_param_names() {
529 // Note the tweak_param_names() method is only available in the oracle driver,
530 // hence we look for expected results indirectly, by testing various DML methods
531 // with some "extreme" conditions causing the tweak to happen.
533 $dbman = $this->tdb->get_manager();
535 $table = $this->get_test_table();
536 $tablename = $table->getName();
538 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
539 // Add some columns with 28 chars in the name
540 $table->add_field('long_int_columnname_with_28c', XMLDB_TYPE_INTEGER, '10');
541 $table->add_field('long_dec_columnname_with_28c', XMLDB_TYPE_NUMBER, '10,2');
542 $table->add_field('long_str_columnname_with_28c', XMLDB_TYPE_CHAR, '100');
543 // Add some columns with 30 chars in the name
544 $table->add_field('long_int_columnname_with_30cxx', XMLDB_TYPE_INTEGER, '10');
545 $table->add_field('long_dec_columnname_with_30cxx', XMLDB_TYPE_NUMBER, '10,2');
546 $table->add_field('long_str_columnname_with_30cxx', XMLDB_TYPE_CHAR, '100');
548 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
550 $dbman->create_table($table);
552 $this->assertTrue($dbman->table_exists($tablename));
554 // Test insert record
555 $rec1 = new stdClass();
556 $rec1->long_int_columnname_with_28c = 28;
557 $rec1->long_dec_columnname_with_28c = 28.28;
558 $rec1->long_str_columnname_with_28c = '28';
559 $rec1->long_int_columnname_with_30cxx = 30;
560 $rec1->long_dec_columnname_with_30cxx = 30.30;
561 $rec1->long_str_columnname_with_30cxx = '30';
564 $rec1->id = $DB->insert_record($tablename, $rec1);
565 $this->assertEqual($rec1, $DB->get_record($tablename, array('id' => $rec1->id)));
568 $DB->update_record($tablename, $rec1);
569 $this->assertEqual($rec1, $DB->get_record($tablename, array('id' => $rec1->id)));
572 $rec1->long_int_columnname_with_28c = 280;
573 $DB->set_field($tablename, 'long_int_columnname_with_28c', $rec1->long_int_columnname_with_28c,
574 array('id' => $rec1->id, 'long_int_columnname_with_28c' => 28));
575 $rec1->long_dec_columnname_with_28c = 280.28;
576 $DB->set_field($tablename, 'long_dec_columnname_with_28c', $rec1->long_dec_columnname_with_28c,
577 array('id' => $rec1->id, 'long_dec_columnname_with_28c' => 28.28));
578 $rec1->long_str_columnname_with_28c = '280';
579 $DB->set_field($tablename, 'long_str_columnname_with_28c', $rec1->long_str_columnname_with_28c,
580 array('id' => $rec1->id, 'long_str_columnname_with_28c' => '28'));
581 $rec1->long_int_columnname_with_30cxx = 300;
582 $DB->set_field($tablename, 'long_int_columnname_with_30cxx', $rec1->long_int_columnname_with_30cxx,
583 array('id' => $rec1->id, 'long_int_columnname_with_30cxx' => 30));
584 $rec1->long_dec_columnname_with_30cxx = 300.30;
585 $DB->set_field($tablename, 'long_dec_columnname_with_30cxx', $rec1->long_dec_columnname_with_30cxx,
586 array('id' => $rec1->id, 'long_dec_columnname_with_30cxx' => 30.30));
587 $rec1->long_str_columnname_with_30cxx = '300';
588 $DB->set_field($tablename, 'long_str_columnname_with_30cxx', $rec1->long_str_columnname_with_30cxx,
589 array('id' => $rec1->id, 'long_str_columnname_with_30cxx' => '30'));
590 $this->assertEqual($rec1, $DB->get_record($tablename, array('id' => $rec1->id)));
593 $rec2 = $DB->get_record($tablename, array('id' => $rec1->id));
594 $rec2->id = $DB->insert_record($tablename, $rec2);
595 $this->assertEqual(2, $DB->count_records($tablename));
596 $DB->delete_records($tablename, (array) $rec2);
597 $this->assertEqual(1, $DB->count_records($tablename));
600 $rs = $DB->get_recordset($tablename, (array) $rec1);
602 foreach ($rs as $rec2) {
606 $this->assertEqual(1, $iterations);
607 $this->assertEqual($rec1, $rec2);
610 $recs = $DB->get_records($tablename, (array) $rec1);
611 $this->assertEqual(1, count($recs));
612 $this->assertEqual($rec1, reset($recs));
614 // get_fieldset_select()
615 $select = 'id = :id AND
616 long_int_columnname_with_28c = :long_int_columnname_with_28c AND
617 long_dec_columnname_with_28c = :long_dec_columnname_with_28c AND
618 long_str_columnname_with_28c = :long_str_columnname_with_28c AND
619 long_int_columnname_with_30cxx = :long_int_columnname_with_30cxx AND
620 long_dec_columnname_with_30cxx = :long_dec_columnname_with_30cxx AND
621 long_str_columnname_with_30cxx = :long_str_columnname_with_30cxx';
622 $fields = $DB->get_fieldset_select($tablename, 'long_int_columnname_with_28c', $select, (array)$rec1);
623 $this->assertEqual(1, count($fields));
624 $this->assertEqual($rec1->long_int_columnname_with_28c, reset($fields));
625 $fields = $DB->get_fieldset_select($tablename, 'long_dec_columnname_with_28c', $select, (array)$rec1);
626 $this->assertEqual($rec1->long_dec_columnname_with_28c, reset($fields));
627 $fields = $DB->get_fieldset_select($tablename, 'long_str_columnname_with_28c', $select, (array)$rec1);
628 $this->assertEqual($rec1->long_str_columnname_with_28c, reset($fields));
629 $fields = $DB->get_fieldset_select($tablename, 'long_int_columnname_with_30cxx', $select, (array)$rec1);
630 $this->assertEqual($rec1->long_int_columnname_with_30cxx, reset($fields));
631 $fields = $DB->get_fieldset_select($tablename, 'long_dec_columnname_with_30cxx', $select, (array)$rec1);
632 $this->assertEqual($rec1->long_dec_columnname_with_30cxx, reset($fields));
633 $fields = $DB->get_fieldset_select($tablename, 'long_str_columnname_with_30cxx', $select, (array)$rec1);
634 $this->assertEqual($rec1->long_str_columnname_with_30cxx, reset($fields));
636 // overlapping placeholders (progressive str_replace)
637 $overlapselect = 'id = :p AND
638 long_int_columnname_with_28c = :param1 AND
639 long_dec_columnname_with_28c = :param2 AND
640 long_str_columnname_with_28c = :param_with_29_characters_long AND
641 long_int_columnname_with_30cxx = :param_with_30_characters_long_ AND
642 long_dec_columnname_with_30cxx = :param_ AND
643 long_str_columnname_with_30cxx = :param__';
644 $overlapparams = array(
646 'param1' => $rec1->long_int_columnname_with_28c,
647 'param2' => $rec1->long_dec_columnname_with_28c,
648 'param_with_29_characters_long' => $rec1->long_str_columnname_with_28c,
649 'param_with_30_characters_long_' => $rec1->long_int_columnname_with_30cxx,
650 'param_' => $rec1->long_dec_columnname_with_30cxx,
651 'param__' => $rec1->long_str_columnname_with_30cxx);
652 $recs = $DB->get_records_select($tablename, $overlapselect, $overlapparams);
653 $this->assertEqual(1, count($recs));
654 $this->assertEqual($rec1, reset($recs));
657 $DB->execute("DELETE FROM {{$tablename}} WHERE $select", (array)$rec1);
658 $this->assertEqual(0, $DB->count_records($tablename));
661 public function test_get_tables() {
663 $dbman = $this->tdb->get_manager();
665 // Need to test with multiple DBs
666 $table = $this->get_test_table();
667 $tablename = $table->getName();
669 $original_count = count($DB->get_tables());
671 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
672 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
674 $dbman->create_table($table);
675 $this->assertTrue(count($DB->get_tables()) == $original_count + 1);
677 $dbman->drop_table($table);
678 $this->assertTrue(count($DB->get_tables()) == $original_count);
681 public function test_get_indexes() {
683 $dbman = $this->tdb->get_manager();
685 $table = $this->get_test_table();
686 $tablename = $table->getName();
688 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
689 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
690 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
691 $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
692 $table->add_index('course-id', XMLDB_INDEX_UNIQUE, array('course', 'id'));
693 $dbman->create_table($table);
695 $indices = $DB->get_indexes($tablename);
696 $this->assertTrue(is_array($indices));
697 $this->assertEqual(count($indices), 2);
698 // we do not care about index names for now
699 $first = array_shift($indices);
700 $second = array_shift($indices);
701 if (count($first['columns']) == 2) {
708 $this->assertFalse($single['unique']);
709 $this->assertTrue($composed['unique']);
710 $this->assertEqual(1, count($single['columns']));
711 $this->assertEqual(2, count($composed['columns']));
712 $this->assertEqual('course', $single['columns'][0]);
713 $this->assertEqual('course', $composed['columns'][0]);
714 $this->assertEqual('id', $composed['columns'][1]);
717 public function test_get_columns() {
719 $dbman = $this->tdb->get_manager();
721 $table = $this->get_test_table();
722 $tablename = $table->getName();
724 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
725 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
726 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, 'lala');
727 $table->add_field('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
728 $table->add_field('enumfield', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, 'test2');
729 $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200);
730 $table->add_field('onefloat', XMLDB_TYPE_FLOAT, '10,2', null, null, null, 300);
731 $table->add_field('anotherfloat', XMLDB_TYPE_FLOAT, null, null, null, null, 400);
732 $table->add_field('negativedfltint', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '-1');
733 $table->add_field('negativedfltnumber', XMLDB_TYPE_NUMBER, '10', null, XMLDB_NOTNULL, null, '-2');
734 $table->add_field('negativedfltfloat', XMLDB_TYPE_FLOAT, '10', null, XMLDB_NOTNULL, null, '-3');
735 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
736 $dbman->create_table($table);
738 $columns = $DB->get_columns($tablename);
739 $this->assertTrue(is_array($columns));
741 $fields = $table->getFields();
742 $this->assertEqual(count($columns), count($fields));
744 $field = $columns['id'];
745 $this->assertEqual('R', $field->meta_type);
746 $this->assertTrue($field->auto_increment);
747 $this->assertTrue($field->unique);
749 $field = $columns['course'];
750 $this->assertEqual('I', $field->meta_type);
751 $this->assertFalse($field->auto_increment);
752 $this->assertTrue($field->has_default);
753 $this->assertEqual(0, $field->default_value);
754 $this->assertTrue($field->not_null);
756 $field = $columns['name'];
757 $this->assertEqual('C', $field->meta_type);
758 $this->assertFalse($field->auto_increment);
759 $this->assertEqual(255, $field->max_length);
760 $this->assertTrue($field->has_default);
761 $this->assertIdentical('lala', $field->default_value);
762 $this->assertFalse($field->not_null);
764 $field = $columns['description'];
765 $this->assertEqual('X', $field->meta_type);
766 $this->assertFalse($field->auto_increment);
767 $this->assertFalse($field->has_default);
768 $this->assertIdentical(null, $field->default_value);
769 $this->assertFalse($field->not_null);
771 $field = $columns['enumfield'];
772 $this->assertEqual('C', $field->meta_type);
773 $this->assertFalse($field->auto_increment);
774 $this->assertIdentical('test2', $field->default_value);
775 $this->assertTrue($field->not_null);
777 $field = $columns['onenum'];
778 $this->assertEqual('N', $field->meta_type);
779 $this->assertFalse($field->auto_increment);
780 $this->assertEqual(10, $field->max_length);
781 $this->assertEqual(2, $field->scale);
782 $this->assertTrue($field->has_default);
783 $this->assertEqual(200.0, $field->default_value);
784 $this->assertFalse($field->not_null);
786 $field = $columns['onefloat'];
787 $this->assertEqual('N', $field->meta_type);
788 $this->assertFalse($field->auto_increment);
789 $this->assertTrue($field->has_default);
790 $this->assertEqual(300.0, $field->default_value);
791 $this->assertFalse($field->not_null);
793 $field = $columns['anotherfloat'];
794 $this->assertEqual('N', $field->meta_type);
795 $this->assertFalse($field->auto_increment);
796 $this->assertTrue($field->has_default);
797 $this->assertEqual(400.0, $field->default_value);
798 $this->assertFalse($field->not_null);
800 // Test negative defaults in numerical columns
801 $field = $columns['negativedfltint'];
802 $this->assertTrue($field->has_default);
803 $this->assertEqual(-1, $field->default_value);
805 $field = $columns['negativedfltnumber'];
806 $this->assertTrue($field->has_default);
807 $this->assertEqual(-2, $field->default_value);
809 $field = $columns['negativedfltfloat'];
810 $this->assertTrue($field->has_default);
811 $this->assertEqual(-3, $field->default_value);
813 for ($i = 0; $i < count($columns); $i++) {
815 $next_column = reset($columns);
816 $next_field = reset($fields);
818 $next_column = next($columns);
819 $next_field = next($fields);
822 $this->assertEqual($next_column->name, $next_field->name);
825 // Test get_columns for non-existing table returns empty array. MDL-30147
826 $columns = $DB->get_columns('xxxx');
827 $this->assertEqual(array(), $columns);
830 public function test_get_manager() {
832 $dbman = $this->tdb->get_manager();
834 $this->assertTrue($dbman instanceof database_manager);
837 public function test_setup_is_unicodedb() {
839 $this->assertTrue($DB->setup_is_unicodedb());
842 public function test_set_debug() { //tests get_debug() too
844 $dbman = $this->tdb->get_manager();
846 $table = $this->get_test_table();
847 $tablename = $table->getName();
849 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
850 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
851 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
852 $dbman->create_table($table);
854 $sql = "SELECT * FROM {{$tablename}}";
856 $prevdebug = $DB->get_debug();
859 $DB->set_debug(true);
860 $this->assertTrue($DB->get_debug());
862 $DB->set_debug(false);
863 $this->assertFalse($DB->get_debug());
864 $debuginfo = ob_get_contents();
866 $this->assertFalse($debuginfo === '');
870 $debuginfo = ob_get_contents();
872 $this->assertTrue($debuginfo === '');
874 $DB->set_debug($prevdebug);
877 public function test_execute() {
879 $dbman = $this->tdb->get_manager();
881 $table1 = $this->get_test_table('1');
882 $tablename1 = $table1->getName();
883 $table1->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
884 $table1->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
885 $table1->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, '0');
886 $table1->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
887 $table1->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
888 $dbman->create_table($table1);
890 $table2 = $this->get_test_table('2');
891 $tablename2 = $table2->getName();
892 $table2->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
893 $table2->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
894 $table2->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
895 $dbman->create_table($table2);
897 $DB->insert_record($tablename1, array('course' => 3, 'name' => 'aaa'));
898 $DB->insert_record($tablename1, array('course' => 1, 'name' => 'bbb'));
899 $DB->insert_record($tablename1, array('course' => 7, 'name' => 'ccc'));
900 $DB->insert_record($tablename1, array('course' => 3, 'name' => 'ddd'));
902 // select results are ignored
903 $sql = "SELECT * FROM {{$tablename1}} WHERE course = :course";
904 $this->assertTrue($DB->execute($sql, array('course'=>3)));
906 // throw exception on error
907 $sql = "XXUPDATE SET XSSD";
910 $this->fail("Expecting an exception, none occurred");
911 } catch (Exception $e) {
912 $this->assertTrue($e instanceof dml_exception);
916 $sql = "UPDATE {{$tablename1}}
919 $this->assertTrue($DB->execute($sql, array('3')));
920 $this->assertEqual($DB->count_records($tablename1, array('course' => 6)), 2);
922 // update records with subquery condition
923 // confirm that the option not using table aliases is cross-db
924 $sql = "UPDATE {{$tablename1}}
928 FROM {{$tablename2}} tbl2
929 WHERE tbl2.course = {{$tablename1}}.course
930 AND 1 = 0)"; // Really we don't update anything, but verify the syntax is allowed
931 $this->assertTrue($DB->execute($sql));
933 // insert from one into second table
934 $sql = "INSERT INTO {{$tablename2}} (course)
937 FROM {{$tablename1}}";
938 $this->assertTrue($DB->execute($sql));
939 $this->assertEqual($DB->count_records($tablename2), 4);
942 public function test_get_recordset() {
944 $dbman = $DB->get_manager();
946 $table = $this->get_test_table();
947 $tablename = $table->getName();
949 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
950 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
951 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, '0');
952 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
953 $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
954 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
955 $dbman->create_table($table);
957 $data = array(array('id' => 1, 'course' => 3, 'name' => 'record1', 'onetext'=>'abc'),
958 array('id' => 2, 'course' => 3, 'name' => 'record2', 'onetext'=>'abcd'),
959 array('id' => 3, 'course' => 5, 'name' => 'record3', 'onetext'=>'abcde'));
961 foreach ($data as $record) {
962 $DB->insert_record($tablename, $record);
965 // standard recordset iteration
966 $rs = $DB->get_recordset($tablename);
967 $this->assertTrue($rs instanceof moodle_recordset);
969 foreach($rs as $record) {
970 $data_record = current($data);
971 foreach ($record as $k => $v) {
972 $this->assertEqual($data_record[$k], $v);
978 // iterator style usage
979 $rs = $DB->get_recordset($tablename);
980 $this->assertTrue($rs instanceof moodle_recordset);
982 while ($rs->valid()) {
983 $record = $rs->current();
984 $data_record = current($data);
985 foreach ($record as $k => $v) {
986 $this->assertEqual($data_record[$k], $v);
993 // make sure rewind is ignored
994 $rs = $DB->get_recordset($tablename);
995 $this->assertTrue($rs instanceof moodle_recordset);
998 foreach($rs as $record) {
1002 $this->fail('revind not ignored in recordsets');
1005 $data_record = current($data);
1006 foreach ($record as $k => $v) {
1007 $this->assertEqual($data_record[$k], $v);
1013 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
1014 $conditions = array('onetext' => '1');
1016 $rs = $DB->get_recordset($tablename, $conditions);
1018 // only in debug mode - hopefully all devs test code in debug mode...
1019 $this->fail('An Exception is missing, expected due to equating of text fields');
1021 } catch (exception $e) {
1022 $this->assertTrue($e instanceof dml_exception);
1023 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
1027 // * limits are tested in test_get_recordset_sql()
1028 // * where_clause() is used internally and is tested in test_get_records()
1031 public function test_get_recordset_iterator_keys() {
1033 $dbman = $DB->get_manager();
1035 $table = $this->get_test_table();
1036 $tablename = $table->getName();
1038 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1039 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1040 $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, '0');
1041 $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
1042 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1043 $dbman->create_table($table);
1045 $data = array(array('id'=> 1, 'course' => 3, 'name' => 'record1'),
1046 array('id'=> 2, 'course' => 3, 'name' => 'record2'),
1047 array('id'=> 3, 'course' => 5, 'name' => 'record3'));
1048 foreach ($data as $record) {
1049 $DB->insert_record($tablename, $record);
1052 // Test repeated numeric keys are returned ok
1053 $rs = $DB->get_recordset($tablename, NULL, NULL, 'course, name, id');
1057 foreach($rs as $key => $record) {
1058 $data_record = current($data);
1059 $this->assertEqual($data_record['course'], $key);
1064 $this->assertEqual($count, 3);
1066 // Test string keys are returned ok
1067 $rs = $DB->get_recordset($tablename, NULL, NULL, 'name, course, id');
1071 foreach($rs as $key => $record) {
1072 $data_record = current($data);
1073 $this->assertEqual($data_record['name'], $key);
1078 $this->assertEqual($count, 3);
1080 // Test numeric not starting in 1 keys are returned ok
1081 $rs = $DB->get_recordset($tablename, NULL, 'id DESC', 'id, course, name');
1083 $data = array_reverse($data);
1086 foreach($rs as $key => $record) {
1087 $data_record = current($data);
1088 $this->assertEqual($data_record['id'], $key);
1093 $this->assertEqual($count, 3);
1096 public function test_get_recordset_list() {
1098 $dbman = $DB->get_manager();
1100 $table = $this->get_test_table();
1101 $tablename = $table->getName();
1103 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1104 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1105 $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
1106 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1107 $dbman->create_table($table);
1109 $DB->insert_record($tablename, array('course' => 3));
1110 $DB->insert_record($tablename, array('course' => 3));
1111 $DB->insert_record($tablename, array('course' => 5));
1112 $DB->insert_record($tablename, array('course' => 2));
1114 $rs = $DB->get_recordset_list($tablename, 'course', array(3, 2));
1117 foreach ($rs as $record) {
1120 $this->assertEqual(3, $counter);
1123 $rs = $DB->get_recordset_list($tablename, 'course',array()); /// Must return 0 rows without conditions. MDL-17645
1126 foreach ($rs as $record) {
1130 $this->assertEqual(0, $counter);
1133 // * limits are tested in test_get_recordset_sql()
1134 // * where_clause() is used internally and is tested in test_get_records()
1137 public function test_get_recordset_select() {
1139 $dbman = $DB->get_manager();
1141 $table = $this->get_test_table();
1142 $tablename = $table->getName();
1144 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1145 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1146 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1147 $dbman->create_table($table);
1149 $DB->insert_record($tablename, array('course' => 3));
1150 $DB->insert_record($tablename, array('course' => 3));
1151 $DB->insert_record($tablename, array('course' => 5));
1152 $DB->insert_record($tablename, array('course' => 2));
1154 $rs = $DB->get_recordset_select($tablename, '');
1156 foreach ($rs as $record) {
1160 $this->assertEqual(4, $counter);
1162 $this->assertTrue($rs = $DB->get_recordset_select($tablename, 'course = 3'));
1164 foreach ($rs as $record) {
1168 $this->assertEqual(2, $counter);
1171 // * limits are tested in test_get_recordset_sql()
1174 public function test_get_recordset_sql() {
1176 $dbman = $DB->get_manager();
1178 $table = $this->get_test_table();
1179 $tablename = $table->getName();
1181 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1182 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1183 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1184 $dbman->create_table($table);
1186 $inskey1 = $DB->insert_record($tablename, array('course' => 3));
1187 $inskey2 = $DB->insert_record($tablename, array('course' => 5));
1188 $inskey3 = $DB->insert_record($tablename, array('course' => 4));
1189 $inskey4 = $DB->insert_record($tablename, array('course' => 3));
1190 $inskey5 = $DB->insert_record($tablename, array('course' => 2));
1191 $inskey6 = $DB->insert_record($tablename, array('course' => 1));
1192 $inskey7 = $DB->insert_record($tablename, array('course' => 0));
1194 $rs = $DB->get_recordset_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3));
1196 foreach ($rs as $record) {
1200 $this->assertEqual(2, $counter);
1202 // limits - only need to test this case, the rest have been tested by test_get_records_sql()
1203 // only limitfrom = skips that number of records
1204 $rs = $DB->get_recordset_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 2, 0);
1206 foreach($rs as $key => $record) {
1207 $records[$key] = $record;
1210 $this->assertEqual(5, count($records));
1211 $this->assertEqual($inskey3, reset($records)->id);
1212 $this->assertEqual($inskey7, end($records)->id);
1214 // note: fetching nulls, empties, LOBs already tested by test_insert_record() no needed here
1217 public function test_get_records() {
1219 $dbman = $DB->get_manager();
1221 $table = $this->get_test_table();
1222 $tablename = $table->getName();
1224 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1225 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1226 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
1227 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1228 $dbman->create_table($table);
1230 $DB->insert_record($tablename, array('course' => 3));
1231 $DB->insert_record($tablename, array('course' => 3));
1232 $DB->insert_record($tablename, array('course' => 5));
1233 $DB->insert_record($tablename, array('course' => 2));
1236 $records = $DB->get_records($tablename);
1237 $this->assertEqual(4, count($records));
1238 $this->assertEqual(3, $records[1]->course);
1239 $this->assertEqual(3, $records[2]->course);
1240 $this->assertEqual(5, $records[3]->course);
1241 $this->assertEqual(2, $records[4]->course);
1243 // Records matching certain conditions
1244 $records = $DB->get_records($tablename, array('course' => 3));
1245 $this->assertEqual(2, count($records));
1246 $this->assertEqual(3, $records[1]->course);
1247 $this->assertEqual(3, $records[2]->course);
1249 // All records sorted by course
1250 $records = $DB->get_records($tablename, null, 'course');
1251 $this->assertEqual(4, count($records));
1252 $current_record = reset($records);
1253 $this->assertEqual(4, $current_record->id);
1254 $current_record = next($records);
1255 $this->assertEqual(1, $current_record->id);
1256 $current_record = next($records);
1257 $this->assertEqual(2, $current_record->id);
1258 $current_record = next($records);
1259 $this->assertEqual(3, $current_record->id);
1261 // All records, but get only one field
1262 $records = $DB->get_records($tablename, null, '', 'id');
1263 $this->assertFalse(isset($records[1]->course));
1264 $this->assertTrue(isset($records[1]->id));
1265 $this->assertEqual(4, count($records));
1267 // Booleans into params
1268 $records = $DB->get_records($tablename, array('course' => true));
1269 $this->assertEqual(0, count($records));
1270 $records = $DB->get_records($tablename, array('course' => false));
1271 $this->assertEqual(0, count($records));
1273 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
1274 $conditions = array('onetext' => '1');
1276 $records = $DB->get_records($tablename, $conditions);
1278 // only in debug mode - hopefully all devs test code in debug mode...
1279 $this->fail('An Exception is missing, expected due to equating of text fields');
1281 } catch (exception $e) {
1282 $this->assertTrue($e instanceof dml_exception);
1283 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
1286 // test get_records passing non-existing table
1289 $records = $DB->get_records('xxxx', array('id' => 0));
1290 $this->fail('An Exception is missing, expected due to query against non-existing table');
1291 } catch (exception $e) {
1292 $this->assertTrue($e instanceof dml_exception);
1294 // information for developers only, normal users get general error message
1295 $this->assertEqual($e->errorcode, 'ddltablenotexist');
1298 // and without params
1300 $records = $DB->get_records('xxxx', array());
1301 $this->fail('An Exception is missing, expected due to query against non-existing table');
1302 } catch (exception $e) {
1303 $this->assertTrue($e instanceof dml_exception);
1305 // information for developers only, normal users get general error message
1306 $this->assertEqual($e->errorcode, 'ddltablenotexist');
1310 // test get_records passing non-existing column
1312 $records = $DB->get_records($tablename, array('xxxx' => 0));
1313 $this->fail('An Exception is missing, expected due to query against non-existing column');
1314 } catch (exception $e) {
1315 $this->assertTrue($e instanceof dml_exception);
1317 // information for developers only, normal users get general error message
1318 $this->assertEqual($e->errorcode, 'ddlfieldnotexist');
1322 // note: delegate limits testing to test_get_records_sql()
1325 public function test_get_records_list() {
1327 $dbman = $DB->get_manager();
1329 $table = $this->get_test_table();
1330 $tablename = $table->getName();
1332 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1333 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1334 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1335 $dbman->create_table($table);
1337 $DB->insert_record($tablename, array('course' => 3));
1338 $DB->insert_record($tablename, array('course' => 3));
1339 $DB->insert_record($tablename, array('course' => 5));
1340 $DB->insert_record($tablename, array('course' => 2));
1342 $records = $DB->get_records_list($tablename, 'course', array(3, 2));
1343 $this->assertTrue(is_array($records));
1344 $this->assertEqual(3, count($records));
1345 $this->assertEqual(1, reset($records)->id);
1346 $this->assertEqual(2, next($records)->id);
1347 $this->assertEqual(4, next($records)->id);
1349 $this->assertIdentical(array(), $records = $DB->get_records_list($tablename, 'course', array())); /// Must return 0 rows without conditions. MDL-17645
1350 $this->assertEqual(0, count($records));
1352 // note: delegate limits testing to test_get_records_sql()
1355 public function test_get_records_sql() {
1357 $dbman = $DB->get_manager();
1359 $table = $this->get_test_table();
1360 $tablename = $table->getName();
1362 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1363 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1364 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1365 $dbman->create_table($table);
1367 $inskey1 = $DB->insert_record($tablename, array('course' => 3));
1368 $inskey2 = $DB->insert_record($tablename, array('course' => 5));
1369 $inskey3 = $DB->insert_record($tablename, array('course' => 4));
1370 $inskey4 = $DB->insert_record($tablename, array('course' => 3));
1371 $inskey5 = $DB->insert_record($tablename, array('course' => 2));
1372 $inskey6 = $DB->insert_record($tablename, array('course' => 1));
1373 $inskey7 = $DB->insert_record($tablename, array('course' => 0));
1375 $table2 = $this->get_test_table("2");
1376 $tablename2 = $table2->getName();
1377 $table2->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1378 $table2->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1379 $table2->add_field('nametext', XMLDB_TYPE_TEXT, 'small', null, null, null, null);
1380 $table2->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1381 $dbman->create_table($table2);
1383 $DB->insert_record($tablename2, array('course'=>3, 'nametext'=>'badabing'));
1384 $DB->insert_record($tablename2, array('course'=>4, 'nametext'=>'badabang'));
1385 $DB->insert_record($tablename2, array('course'=>5, 'nametext'=>'badabung'));
1386 $DB->insert_record($tablename2, array('course'=>6, 'nametext'=>'badabong'));
1388 $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3));
1389 $this->assertEqual(2, count($records));
1390 $this->assertEqual($inskey1, reset($records)->id);
1391 $this->assertEqual($inskey4, next($records)->id);
1393 // Awful test, requires debug enabled and sent to browser. Let's do that and restore after test
1394 $this->enable_debugging();
1395 $records = $DB->get_records_sql("SELECT course AS id, course AS course FROM {{$tablename}}", null);
1396 $this->assertFalse($this->get_debugging() === '');
1397 $this->assertEqual(6, count($records));
1399 // negative limits = no limits
1400 $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, -1, -1);
1401 $this->assertEqual(7, count($records));
1403 // zero limits = no limits
1404 $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 0, 0);
1405 $this->assertEqual(7, count($records));
1407 // only limitfrom = skips that number of records
1408 $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 2, 0);
1409 $this->assertEqual(5, count($records));
1410 $this->assertEqual($inskey3, reset($records)->id);
1411 $this->assertEqual($inskey7, end($records)->id);
1413 // only limitnum = fetches that number of records
1414 $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 0, 3);
1415 $this->assertEqual(3, count($records));
1416 $this->assertEqual($inskey1, reset($records)->id);
1417 $this->assertEqual($inskey3, end($records)->id);
1419 // both limitfrom and limitnum = skips limitfrom records and fetches limitnum ones
1420 $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 3, 2);
1421 $this->assertEqual(2, count($records));
1422 $this->assertEqual($inskey4, reset($records)->id);
1423 $this->assertEqual($inskey5, end($records)->id);
1425 // both limitfrom and limitnum in query having subqueris
1426 // note the subquery skips records with course = 0 and 3
1427 $sql = "SELECT * FROM {{$tablename}}
1428 WHERE course NOT IN (
1429 SELECT course FROM {{$tablename}}
1430 WHERE course IN (0, 3))
1432 $records = $DB->get_records_sql($sql, null, 0, 2); // Skip 0, get 2
1433 $this->assertEqual(2, count($records));
1434 $this->assertEqual($inskey6, reset($records)->id);
1435 $this->assertEqual($inskey5, end($records)->id);
1436 $records = $DB->get_records_sql($sql, null, 2, 2); // Skip 2, get 2
1437 $this->assertEqual(2, count($records));
1438 $this->assertEqual($inskey3, reset($records)->id);
1439 $this->assertEqual($inskey2, end($records)->id);
1441 // test 2 tables with aliases and limits with order bys
1442 $sql = "SELECT t1.id, t1.course AS cid, t2.nametext
1443 FROM {{$tablename}} t1, {{$tablename2}} t2
1444 WHERE t2.course=t1.course
1445 ORDER BY t1.course, ". $DB->sql_compare_text('t2.nametext');
1446 $records = $DB->get_records_sql($sql, null, 2, 2); // Skip courses 3 and 6, get 4 and 5
1447 $this->assertEqual(2, count($records));
1448 $this->assertEqual('5', end($records)->cid);
1449 $this->assertEqual('4', reset($records)->cid);
1451 // test 2 tables with aliases and limits with the highest INT limit works
1452 $records = $DB->get_records_sql($sql, null, 2, PHP_INT_MAX); // Skip course {3,6}, get {4,5}
1453 $this->assertEqual(2, count($records));
1454 $this->assertEqual('5', end($records)->cid);
1455 $this->assertEqual('4', reset($records)->cid);
1457 // test 2 tables with aliases and limits with order bys (limit which is highest INT number)
1458 $records = $DB->get_records_sql($sql, null, PHP_INT_MAX, 2); // Skip all courses
1459 $this->assertEqual(0, count($records));
1461 // test 2 tables with aliases and limits with order bys (limit which s highest INT number)
1462 $records = $DB->get_records_sql($sql, null, PHP_INT_MAX, PHP_INT_MAX); // Skip all courses
1463 $this->assertEqual(0, count($records));
1465 // TODO: Test limits in queries having DISTINCT clauses
1467 // note: fetching nulls, empties, LOBs already tested by test_update_record() no needed here
1470 public function test_get_records_menu() {
1472 $dbman = $DB->get_manager();
1474 $table = $this->get_test_table();
1475 $tablename = $table->getName();
1477 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1478 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1479 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1480 $dbman->create_table($table);
1482 $DB->insert_record($tablename, array('course' => 3));
1483 $DB->insert_record($tablename, array('course' => 3));
1484 $DB->insert_record($tablename, array('course' => 5));
1485 $DB->insert_record($tablename, array('course' => 2));
1487 $records = $DB->get_records_menu($tablename, array('course' => 3));
1488 $this->assertTrue(is_array($records));
1489 $this->assertEqual(2, count($records));
1490 $this->assertFalse(empty($records[1]));
1491 $this->assertFalse(empty($records[2]));
1492 $this->assertEqual(3, $records[1]);
1493 $this->assertEqual(3, $records[2]);
1495 // note: delegate limits testing to test_get_records_sql()
1498 public function test_get_records_select_menu() {
1500 $dbman = $DB->get_manager();
1502 $table = $this->get_test_table();
1503 $tablename = $table->getName();
1505 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1506 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1507 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1508 $dbman->create_table($table);
1510 $DB->insert_record($tablename, array('course' => 3));
1511 $DB->insert_record($tablename, array('course' => 2));
1512 $DB->insert_record($tablename, array('course' => 3));
1513 $DB->insert_record($tablename, array('course' => 5));
1515 $records = $DB->get_records_select_menu($tablename, "course > ?", array(2));
1516 $this->assertTrue(is_array($records));
1518 $this->assertEqual(3, count($records));
1519 $this->assertFalse(empty($records[1]));
1520 $this->assertTrue(empty($records[2]));
1521 $this->assertFalse(empty($records[3]));
1522 $this->assertFalse(empty($records[4]));
1523 $this->assertEqual(3, $records[1]);
1524 $this->assertEqual(3, $records[3]);
1525 $this->assertEqual(5, $records[4]);
1527 // note: delegate limits testing to test_get_records_sql()
1530 public function test_get_records_sql_menu() {
1532 $dbman = $DB->get_manager();
1534 $table = $this->get_test_table();
1535 $tablename = $table->getName();
1537 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1538 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1539 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1540 $dbman->create_table($table);
1542 $DB->insert_record($tablename, array('course' => 3));
1543 $DB->insert_record($tablename, array('course' => 2));
1544 $DB->insert_record($tablename, array('course' => 3));
1545 $DB->insert_record($tablename, array('course' => 5));
1547 $records = $DB->get_records_sql_menu("SELECT * FROM {{$tablename}} WHERE course > ?", array(2));
1548 $this->assertTrue(is_array($records));
1550 $this->assertEqual(3, count($records));
1551 $this->assertFalse(empty($records[1]));
1552 $this->assertTrue(empty($records[2]));
1553 $this->assertFalse(empty($records[3]));
1554 $this->assertFalse(empty($records[4]));
1555 $this->assertEqual(3, $records[1]);
1556 $this->assertEqual(3, $records[3]);
1557 $this->assertEqual(5, $records[4]);
1559 // note: delegate limits testing to test_get_records_sql()
1562 public function test_get_record() {
1564 $dbman = $DB->get_manager();
1566 $table = $this->get_test_table();
1567 $tablename = $table->getName();
1569 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1570 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1571 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1572 $dbman->create_table($table);
1574 $DB->insert_record($tablename, array('course' => 3));
1575 $DB->insert_record($tablename, array('course' => 2));
1577 $record = $DB->get_record($tablename, array('id' => 2));
1578 $this->assertTrue($record instanceof stdClass);
1580 $this->assertEqual(2, $record->course);
1581 $this->assertEqual(2, $record->id);
1585 public function test_get_record_select() {
1587 $dbman = $DB->get_manager();
1589 $table = $this->get_test_table();
1590 $tablename = $table->getName();
1592 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1593 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1594 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1595 $dbman->create_table($table);
1597 $DB->insert_record($tablename, array('course' => 3));
1598 $DB->insert_record($tablename, array('course' => 2));
1600 $record = $DB->get_record_select($tablename, "id = ?", array(2));
1601 $this->assertTrue($record instanceof stdClass);
1603 $this->assertEqual(2, $record->course);
1605 // note: delegates limit testing to test_get_records_sql()
1608 public function test_get_record_sql() {
1610 $dbman = $DB->get_manager();
1612 $table = $this->get_test_table();
1613 $tablename = $table->getName();
1615 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1616 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1617 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1618 $dbman->create_table($table);
1620 $DB->insert_record($tablename, array('course' => 3));
1621 $DB->insert_record($tablename, array('course' => 2));
1624 $record = $DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(2));
1625 $this->assertTrue($record instanceof stdClass);
1626 $this->assertEqual(2, $record->course);
1627 $this->assertEqual(2, $record->id);
1629 // backwards compatibility with $ignoremultiple
1630 $this->assertFalse(IGNORE_MISSING);
1631 $this->assertTrue(IGNORE_MULTIPLE);
1633 // record not found - ignore
1634 $this->assertFalse($DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(666), IGNORE_MISSING));
1635 $this->assertFalse($DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(666), IGNORE_MULTIPLE));
1637 // record not found error
1639 $DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(666), MUST_EXIST);
1640 $this->fail("Exception expected");
1641 } catch (dml_missing_record_exception $e) {
1642 $this->assertTrue(true);
1645 $this->enable_debugging();
1646 $this->assertTrue($DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), IGNORE_MISSING));
1647 $this->assertFalse($this->get_debugging() === '');
1649 // multiple matches ignored
1650 $this->assertTrue($DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), IGNORE_MULTIPLE));
1652 // multiple found error
1654 $DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), MUST_EXIST);
1655 $this->fail("Exception expected");
1656 } catch (dml_multiple_records_exception $e) {
1657 $this->assertTrue(true);
1661 public function test_get_field() {
1663 $dbman = $DB->get_manager();
1665 $table = $this->get_test_table();
1666 $tablename = $table->getName();
1668 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1669 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1670 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
1671 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1672 $dbman->create_table($table);
1674 $id1 = $DB->insert_record($tablename, array('course' => 3));
1675 $DB->insert_record($tablename, array('course' => 5));
1676 $DB->insert_record($tablename, array('course' => 5));
1678 $this->assertEqual(3, $DB->get_field($tablename, 'course', array('id' => $id1)));
1679 $this->assertEqual(3, $DB->get_field($tablename, 'course', array('course' => 3)));
1681 $this->assertIdentical(false, $DB->get_field($tablename, 'course', array('course' => 11), IGNORE_MISSING));
1683 $DB->get_field($tablename, 'course', array('course' => 4), MUST_EXIST);
1684 $this->assertFail('Exception expected due to missing record');
1685 } catch (dml_exception $ex) {
1686 $this->assertTrue(true);
1689 $this->enable_debugging();
1690 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('course' => 5), IGNORE_MULTIPLE));
1691 $this->assertIdentical($this->get_debugging(), '');
1693 $this->enable_debugging();
1694 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('course' => 5), IGNORE_MISSING));
1695 $this->assertFalse($this->get_debugging() === '');
1697 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
1698 $conditions = array('onetext' => '1');
1700 $DB->get_field($tablename, 'course', $conditions);
1702 // only in debug mode - hopefully all devs test code in debug mode...
1703 $this->fail('An Exception is missing, expected due to equating of text fields');
1705 } catch (exception $e) {
1706 $this->assertTrue($e instanceof dml_exception);
1707 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
1711 public function test_get_field_select() {
1713 $dbman = $DB->get_manager();
1715 $table = $this->get_test_table();
1716 $tablename = $table->getName();
1718 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1719 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1720 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1721 $dbman->create_table($table);
1723 $DB->insert_record($tablename, array('course' => 3));
1725 $this->assertEqual(3, $DB->get_field_select($tablename, 'course', "id = ?", array(1)));
1728 public function test_get_field_sql() {
1730 $dbman = $DB->get_manager();
1732 $table = $this->get_test_table();
1733 $tablename = $table->getName();
1735 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1736 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1737 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1738 $dbman->create_table($table);
1740 $DB->insert_record($tablename, array('course' => 3));
1742 $this->assertEqual(3, $DB->get_field_sql("SELECT course FROM {{$tablename}} WHERE id = ?", array(1)));
1745 public function test_get_fieldset_select() {
1747 $dbman = $DB->get_manager();
1749 $table = $this->get_test_table();
1750 $tablename = $table->getName();
1752 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1753 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1754 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1755 $dbman->create_table($table);
1757 $DB->insert_record($tablename, array('course' => 1));
1758 $DB->insert_record($tablename, array('course' => 3));
1759 $DB->insert_record($tablename, array('course' => 2));
1760 $DB->insert_record($tablename, array('course' => 6));
1762 $fieldset = $DB->get_fieldset_select($tablename, 'course', "course > ?", array(1));
1763 $this->assertTrue(is_array($fieldset));
1765 $this->assertEqual(3, count($fieldset));
1766 $this->assertEqual(3, $fieldset[0]);
1767 $this->assertEqual(2, $fieldset[1]);
1768 $this->assertEqual(6, $fieldset[2]);
1771 public function test_get_fieldset_sql() {
1773 $dbman = $DB->get_manager();
1775 $table = $this->get_test_table();
1776 $tablename = $table->getName();
1778 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1779 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1780 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1781 $dbman->create_table($table);
1783 $DB->insert_record($tablename, array('course' => 1));
1784 $DB->insert_record($tablename, array('course' => 3));
1785 $DB->insert_record($tablename, array('course' => 2));
1786 $DB->insert_record($tablename, array('course' => 6));
1788 $fieldset = $DB->get_fieldset_sql("SELECT * FROM {{$tablename}} WHERE course > ?", array(1));
1789 $this->assertTrue(is_array($fieldset));
1791 $this->assertEqual(3, count($fieldset));
1792 $this->assertEqual(2, $fieldset[0]);
1793 $this->assertEqual(3, $fieldset[1]);
1794 $this->assertEqual(4, $fieldset[2]);
1797 public function test_insert_record_raw() {
1799 $dbman = $DB->get_manager();
1801 $table = $this->get_test_table();
1802 $tablename = $table->getName();
1804 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1805 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1806 $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring');
1807 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1808 $dbman->create_table($table);
1810 $record = (object)array('course' => 1, 'onechar' => 'xx');
1811 $before = clone($record);
1812 $result = $DB->insert_record_raw($tablename, $record);
1813 $this->assertIdentical(1, $result);
1814 $this->assertIdentical($record, $before);
1816 $record = $DB->get_record($tablename, array('course' => 1));
1817 $this->assertTrue($record instanceof stdClass);
1818 $this->assertIdentical('xx', $record->onechar);
1820 $result = $DB->insert_record_raw($tablename, array('course' => 2, 'onechar' => 'yy'), false);
1821 $this->assertIdentical(true, $result);
1823 // note: bulk not implemented yet
1824 $DB->insert_record_raw($tablename, array('course' => 3, 'onechar' => 'zz'), true, true);
1825 $record = $DB->get_record($tablename, array('course' => 3));
1826 $this->assertTrue($record instanceof stdClass);
1827 $this->assertIdentical('zz', $record->onechar);
1829 // custom sequence (id) - returnid is ignored
1830 $result = $DB->insert_record_raw($tablename, array('id' => 10, 'course' => 3, 'onechar' => 'bb'), true, false, true);
1831 $this->assertIdentical(true, $result);
1832 $record = $DB->get_record($tablename, array('id' => 10));
1833 $this->assertTrue($record instanceof stdClass);
1834 $this->assertIdentical('bb', $record->onechar);
1836 // custom sequence - missing id error
1838 $DB->insert_record_raw($tablename, array('course' => 3, 'onechar' => 'bb'), true, false, true);
1839 $this->assertFail('Exception expected due to missing record');
1840 } catch (coding_exception $ex) {
1841 $this->assertTrue(true);
1844 // wrong column error
1846 $DB->insert_record_raw($tablename, array('xxxxx' => 3, 'onechar' => 'bb'));
1847 $this->assertFail('Exception expected due to invalid column');
1848 } catch (dml_exception $ex) {
1849 $this->assertTrue(true);
1853 public function test_insert_record() {
1854 // All the information in this test is fetched from DB by get_recordset() so we
1855 // have such method properly tested against nulls, empties and friends...
1858 $dbman = $DB->get_manager();
1860 $table = $this->get_test_table();
1861 $tablename = $table->getName();
1863 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
1864 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
1865 $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, 100);
1866 $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200);
1867 $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring');
1868 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
1869 $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null);
1870 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
1871 $dbman->create_table($table);
1873 $this->assertIdentical(1, $DB->insert_record($tablename, array('course' => 1), true));
1874 $record = $DB->get_record($tablename, array('course' => 1));
1875 $this->assertEqual(1, $record->id);
1876 $this->assertEqual(100, $record->oneint); // Just check column defaults have been applied
1877 $this->assertEqual(200, $record->onenum);
1878 $this->assertIdentical('onestring', $record->onechar);
1879 $this->assertNull($record->onetext);
1880 $this->assertNull($record->onebinary);
1882 // without returning id, bulk not implemented
1883 $result = $this->assertIdentical(true, $DB->insert_record($tablename, array('course' => 99), false, true));
1884 $record = $DB->get_record($tablename, array('course' => 99));
1885 $this->assertEqual(2, $record->id);
1886 $this->assertEqual(99, $record->course);
1888 // Check nulls are set properly for all types
1889 $record = new stdClass();
1890 $record->oneint = null;
1891 $record->onenum = null;
1892 $record->onechar = null;
1893 $record->onetext = null;
1894 $record->onebinary = null;
1895 $recid = $DB->insert_record($tablename, $record);
1896 $record = $DB->get_record($tablename, array('id' => $recid));
1897 $this->assertEqual(0, $record->course);
1898 $this->assertNull($record->oneint);
1899 $this->assertNull($record->onenum);
1900 $this->assertNull($record->onechar);
1901 $this->assertNull($record->onetext);
1902 $this->assertNull($record->onebinary);
1904 // Check zeros are set properly for all types
1905 $record = new stdClass();
1906 $record->oneint = 0;
1907 $record->onenum = 0;
1908 $recid = $DB->insert_record($tablename, $record);
1909 $record = $DB->get_record($tablename, array('id' => $recid));
1910 $this->assertEqual(0, $record->oneint);
1911 $this->assertEqual(0, $record->onenum);
1913 // Check booleans are set properly for all types
1914 $record = new stdClass();
1915 $record->oneint = true; // trues
1916 $record->onenum = true;
1917 $record->onechar = true;
1918 $record->onetext = true;
1919 $recid = $DB->insert_record($tablename, $record);
1920 $record = $DB->get_record($tablename, array('id' => $recid));
1921 $this->assertEqual(1, $record->oneint);
1922 $this->assertEqual(1, $record->onenum);
1923 $this->assertEqual(1, $record->onechar);
1924 $this->assertEqual(1, $record->onetext);
1926 $record = new stdClass();
1927 $record->oneint = false; // falses
1928 $record->onenum = false;
1929 $record->onechar = false;
1930 $record->onetext = false;
1931 $recid = $DB->insert_record($tablename, $record);
1932 $record = $DB->get_record($tablename, array('id' => $recid));
1933 $this->assertEqual(0, $record->oneint);
1934 $this->assertEqual(0, $record->onenum);
1935 $this->assertEqual(0, $record->onechar);
1936 $this->assertEqual(0, $record->onetext);
1938 // Check string data causes exception in numeric types
1939 $record = new stdClass();
1940 $record->oneint = 'onestring';
1941 $record->onenum = 0;
1943 $DB->insert_record($tablename, $record);
1944 $this->fail("Expecting an exception, none occurred");
1945 } catch (exception $e) {
1946 $this->assertTrue($e instanceof dml_exception);
1948 $record = new stdClass();
1949 $record->oneint = 0;
1950 $record->onenum = 'onestring';
1952 $DB->insert_record($tablename, $record);
1953 $this->fail("Expecting an exception, none occurred");
1954 } catch (exception $e) {
1955 $this->assertTrue($e instanceof dml_exception);
1958 // Check empty string data is stored as 0 in numeric datatypes
1959 $record = new stdClass();
1960 $record->oneint = ''; // empty string
1961 $record->onenum = 0;
1962 $recid = $DB->insert_record($tablename, $record);
1963 $record = $DB->get_record($tablename, array('id' => $recid));
1964 $this->assertTrue(is_numeric($record->oneint) && $record->oneint == 0);
1966 $record = new stdClass();
1967 $record->oneint = 0;
1968 $record->onenum = ''; // empty string
1969 $recid = $DB->insert_record($tablename, $record);
1970 $record = $DB->get_record($tablename, array('id' => $recid));
1971 $this->assertTrue(is_numeric($record->onenum) && $record->onenum == 0);
1973 // Check empty strings are set properly in string types
1974 $record = new stdClass();
1975 $record->oneint = 0;
1976 $record->onenum = 0;
1977 $record->onechar = '';
1978 $record->onetext = '';
1979 $recid = $DB->insert_record($tablename, $record);
1980 $record = $DB->get_record($tablename, array('id' => $recid));
1981 $this->assertTrue($record->onechar === '');
1982 $this->assertTrue($record->onetext === '');
1984 // Check operation ((210.10 + 39.92) - 150.02) against numeric types
1985 $record = new stdClass();
1986 $record->oneint = ((210.10 + 39.92) - 150.02);
1987 $record->onenum = ((210.10 + 39.92) - 150.02);
1988 $recid = $DB->insert_record($tablename, $record);
1989 $record = $DB->get_record($tablename, array('id' => $recid));
1990 $this->assertEqual(100, $record->oneint);
1991 $this->assertEqual(100, $record->onenum);
1993 // Check various quotes/backslashes combinations in string types
1994 $teststrings = array(
1995 'backslashes and quotes alone (even): "" \'\' \\\\',
1996 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\',
1997 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'',
1998 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\'');
1999 foreach ($teststrings as $teststring) {
2000 $record = new stdClass();
2001 $record->onechar = $teststring;
2002 $record->onetext = $teststring;
2003 $recid = $DB->insert_record($tablename, $record);
2004 $record = $DB->get_record($tablename, array('id' => $recid));
2005 $this->assertEqual($teststring, $record->onechar);
2006 $this->assertEqual($teststring, $record->onetext);
2009 // Check LOBs in text/binary columns
2010 $clob = file_get_contents(dirname(__FILE__).'/fixtures/clob.txt');
2011 $blob = file_get_contents(dirname(__FILE__).'/fixtures/randombinary');
2012 $record = new stdClass();
2013 $record->onetext = $clob;
2014 $record->onebinary = $blob;
2015 $recid = $DB->insert_record($tablename, $record);
2016 $rs = $DB->get_recordset($tablename, array('id' => $recid));
2017 $record = $rs->current();
2019 $this->assertEqual($clob, $record->onetext, 'Test CLOB insert (full contents output disabled)');
2020 $this->assertEqual($blob, $record->onebinary, 'Test BLOB insert (full contents output disabled)');
2022 // And "small" LOBs too, just in case
2023 $newclob = substr($clob, 0, 500);
2024 $newblob = substr($blob, 0, 250);
2025 $record = new stdClass();
2026 $record->onetext = $newclob;
2027 $record->onebinary = $newblob;
2028 $recid = $DB->insert_record($tablename, $record);
2029 $rs = $DB->get_recordset($tablename, array('id' => $recid));
2030 $record = $rs->current();
2032 $this->assertEqual($newclob, $record->onetext, 'Test "small" CLOB insert (full contents output disabled)');
2033 $this->assertEqual($newblob, $record->onebinary, 'Test "small" BLOB insert (full contents output disabled)');
2034 $this->assertEqual(false, $rs->key()); // Ensure recordset key() method to be working ok after closing
2036 // And "diagnostic" LOBs too, just in case
2037 $newclob = '\'"\\;/ěščřžýáíé';
2038 $newblob = '\'"\\;/ěščřžýáíé';
2039 $record = new stdClass();
2040 $record->onetext = $newclob;
2041 $record->onebinary = $newblob;
2042 $recid = $DB->insert_record($tablename, $record);
2043 $rs = $DB->get_recordset($tablename, array('id' => $recid));
2044 $record = $rs->current();
2046 $this->assertIdentical($newclob, $record->onetext);
2047 $this->assertIdentical($newblob, $record->onebinary);
2048 $this->assertEqual(false, $rs->key()); // Ensure recordset key() method to be working ok after closing
2050 // test data is not modified
2051 $record = new stdClass();
2052 $record->id = -1; // has to be ignored
2053 $record->course = 3;
2054 $record->lalala = 'lalal'; // unused
2055 $before = clone($record);
2056 $DB->insert_record($tablename, $record);
2057 $this->assertEqual($record, $before);
2059 // make sure the id is always increasing and never reuses the same id
2060 $id1 = $DB->insert_record($tablename, array('course' => 3));
2061 $id2 = $DB->insert_record($tablename, array('course' => 3));
2062 $this->assertTrue($id1 < $id2);
2063 $DB->delete_records($tablename, array('id'=>$id2));
2064 $id3 = $DB->insert_record($tablename, array('course' => 3));
2065 $this->assertTrue($id2 < $id3);
2066 $DB->delete_records($tablename, array());
2067 $id4 = $DB->insert_record($tablename, array('course' => 3));
2068 $this->assertTrue($id3 < $id4);
2070 // Test saving a float in a CHAR column, and reading it back.
2071 $id = $DB->insert_record($tablename, array('onechar' => 1.0));
2072 $this->assertEqual(1.0, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2073 $id = $DB->insert_record($tablename, array('onechar' => 1e20));
2074 $this->assertEqual(1e20, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2075 $id = $DB->insert_record($tablename, array('onechar' => 1e-4));
2076 $this->assertEqual(1e-4, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2077 $id = $DB->insert_record($tablename, array('onechar' => 1e-5));
2078 $this->assertEqual(1e-5, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2079 $id = $DB->insert_record($tablename, array('onechar' => 1e-300));
2080 $this->assertEqual(1e-300, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2081 $id = $DB->insert_record($tablename, array('onechar' => 1e300));
2082 $this->assertEqual(1e300, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2084 // Test saving a float in a TEXT column, and reading it back.
2085 $id = $DB->insert_record($tablename, array('onetext' => 1.0));
2086 $this->assertEqual(1.0, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2087 $id = $DB->insert_record($tablename, array('onetext' => 1e20));
2088 $this->assertEqual(1e20, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2089 $id = $DB->insert_record($tablename, array('onetext' => 1e-4));
2090 $this->assertEqual(1e-4, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2091 $id = $DB->insert_record($tablename, array('onetext' => 1e-5));
2092 $this->assertEqual(1e-5, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2093 $id = $DB->insert_record($tablename, array('onetext' => 1e-300));
2094 $this->assertEqual(1e-300, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2095 $id = $DB->insert_record($tablename, array('onetext' => 1e300));
2096 $this->assertEqual(1e300, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2099 public function test_import_record() {
2100 // All the information in this test is fetched from DB by get_recordset() so we
2101 // have such method properly tested against nulls, empties and friends...
2104 $dbman = $DB->get_manager();
2106 $table = $this->get_test_table();
2107 $tablename = $table->getName();
2109 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2110 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2111 $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, 100);
2112 $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200);
2113 $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring');
2114 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2115 $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null);
2116 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2117 $dbman->create_table($table);
2119 $this->assertIdentical(1, $DB->insert_record($tablename, array('course' => 1), true));
2120 $record = $DB->get_record($tablename, array('course' => 1));
2121 $this->assertEqual(1, $record->id);
2122 $this->assertEqual(100, $record->oneint); // Just check column defaults have been applied
2123 $this->assertEqual(200, $record->onenum);
2124 $this->assertIdentical('onestring', $record->onechar);
2125 $this->assertNull($record->onetext);
2126 $this->assertNull($record->onebinary);
2128 // ignore extra columns
2129 $record = (object)array('id'=>13, 'course'=>2, 'xxxx'=>788778);
2130 $before = clone($record);
2131 $this->assertIdentical(true, $DB->import_record($tablename, $record));
2132 $this->assertIdentical($record, $before);
2133 $records = $DB->get_records($tablename);
2134 $this->assertEqual(2, $records[13]->course);
2136 // Check nulls are set properly for all types
2137 $record = new stdClass();
2139 $record->oneint = null;
2140 $record->onenum = null;
2141 $record->onechar = null;
2142 $record->onetext = null;
2143 $record->onebinary = null;
2144 $this->assertTrue($DB->import_record($tablename, $record));
2145 $record = $DB->get_record($tablename, array('id' => 20));
2146 $this->assertEqual(0, $record->course);
2147 $this->assertNull($record->oneint);
2148 $this->assertNull($record->onenum);
2149 $this->assertNull($record->onechar);
2150 $this->assertNull($record->onetext);
2151 $this->assertNull($record->onebinary);
2153 // Check zeros are set properly for all types
2154 $record = new stdClass();
2156 $record->oneint = 0;
2157 $record->onenum = 0;
2158 $this->assertTrue($DB->import_record($tablename, $record));
2159 $record = $DB->get_record($tablename, array('id' => 23));
2160 $this->assertEqual(0, $record->oneint);
2161 $this->assertEqual(0, $record->onenum);
2163 // Check string data causes exception in numeric types
2164 $record = new stdClass();
2166 $record->oneint = 'onestring';
2167 $record->onenum = 0;
2169 $DB->import_record($tablename, $record);
2170 $this->fail("Expecting an exception, none occurred");
2171 } catch (exception $e) {
2172 $this->assertTrue($e instanceof dml_exception);
2174 $record = new stdClass();
2176 $record->oneint = 0;
2177 $record->onenum = 'onestring';
2179 $DB->import_record($tablename, $record);
2180 $this->fail("Expecting an exception, none occurred");
2181 } catch (exception $e) {
2182 $this->assertTrue($e instanceof dml_exception);
2185 // Check empty strings are set properly in string types
2186 $record = new stdClass();
2188 $record->oneint = 0;
2189 $record->onenum = 0;
2190 $record->onechar = '';
2191 $record->onetext = '';
2192 $this->assertTrue($DB->import_record($tablename, $record));
2193 $record = $DB->get_record($tablename, array('id' => 44));
2194 $this->assertTrue($record->onechar === '');
2195 $this->assertTrue($record->onetext === '');
2197 // Check operation ((210.10 + 39.92) - 150.02) against numeric types
2198 $record = new stdClass();
2200 $record->oneint = ((210.10 + 39.92) - 150.02);
2201 $record->onenum = ((210.10 + 39.92) - 150.02);
2202 $this->assertTrue($DB->import_record($tablename, $record));
2203 $record = $DB->get_record($tablename, array('id' => 47));
2204 $this->assertEqual(100, $record->oneint);
2205 $this->assertEqual(100, $record->onenum);
2207 // Check various quotes/backslashes combinations in string types
2209 $teststrings = array(
2210 'backslashes and quotes alone (even): "" \'\' \\\\',
2211 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\',
2212 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'',
2213 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\'');
2214 foreach ($teststrings as $teststring) {
2215 $record = new stdClass();
2217 $record->onechar = $teststring;
2218 $record->onetext = $teststring;
2219 $this->assertTrue($DB->import_record($tablename, $record));
2220 $record = $DB->get_record($tablename, array('id' => $i));
2221 $this->assertEqual($teststring, $record->onechar);
2222 $this->assertEqual($teststring, $record->onetext);
2226 // Check LOBs in text/binary columns
2227 $clob = file_get_contents(dirname(__FILE__).'/fixtures/clob.txt');
2228 $record = new stdClass();
2230 $record->onetext = $clob;
2231 $record->onebinary = '';
2232 $this->assertTrue($DB->import_record($tablename, $record));
2233 $rs = $DB->get_recordset($tablename, array('id' => 70));
2234 $record = $rs->current();
2236 $this->assertEqual($clob, $record->onetext, 'Test CLOB insert (full contents output disabled)');
2238 $blob = file_get_contents(dirname(__FILE__).'/fixtures/randombinary');
2239 $record = new stdClass();
2241 $record->onetext = '';
2242 $record->onebinary = $blob;
2243 $this->assertTrue($DB->import_record($tablename, $record));
2244 $rs = $DB->get_recordset($tablename, array('id' => 71));
2245 $record = $rs->current();
2247 $this->assertEqual($blob, $record->onebinary, 'Test BLOB insert (full contents output disabled)');
2249 // And "small" LOBs too, just in case
2250 $newclob = substr($clob, 0, 500);
2251 $newblob = substr($blob, 0, 250);
2252 $record = new stdClass();
2254 $record->onetext = $newclob;
2255 $record->onebinary = $newblob;
2256 $this->assertTrue($DB->import_record($tablename, $record));
2257 $rs = $DB->get_recordset($tablename, array('id' => 73));
2258 $record = $rs->current();
2260 $this->assertEqual($newclob, $record->onetext, 'Test "small" CLOB insert (full contents output disabled)');
2261 $this->assertEqual($newblob, $record->onebinary, 'Test "small" BLOB insert (full contents output disabled)');
2262 $this->assertEqual(false, $rs->key()); // Ensure recordset key() method to be working ok after closing
2265 public function test_update_record_raw() {
2267 $dbman = $DB->get_manager();
2269 $table = $this->get_test_table();
2270 $tablename = $table->getName();
2272 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2273 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2274 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2275 $dbman->create_table($table);
2277 $DB->insert_record($tablename, array('course' => 1));
2278 $DB->insert_record($tablename, array('course' => 3));
2280 $record = $DB->get_record($tablename, array('course' => 1));
2281 $record->course = 2;
2282 $this->assertTrue($DB->update_record_raw($tablename, $record));
2283 $this->assertEqual(0, $DB->count_records($tablename, array('course' => 1)));
2284 $this->assertEqual(1, $DB->count_records($tablename, array('course' => 2)));
2285 $this->assertEqual(1, $DB->count_records($tablename, array('course' => 3)));
2287 $record = $DB->get_record($tablename, array('course' => 1));
2290 $DB->update_record_raw($tablename, $record);
2291 $this->fail("Expecting an exception, none occurred");
2292 } catch (Exception $e) {
2293 $this->assertTrue($e instanceof coding_exception);
2296 $record = $DB->get_record($tablename, array('course' => 3));
2299 $DB->update_record_raw($tablename, $record);
2300 $this->fail("Expecting an exception, none occurred");
2301 } catch (Exception $e) {
2302 $this->assertTrue($e instanceof coding_exception);
2306 public function test_update_record() {
2308 // All the information in this test is fetched from DB by get_record() so we
2309 // have such method properly tested against nulls, empties and friends...
2312 $dbman = $DB->get_manager();
2314 $table = $this->get_test_table();
2315 $tablename = $table->getName();
2317 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2318 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2319 $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, 100);
2320 $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200);
2321 $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring');
2322 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2323 $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null);
2324 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2325 $dbman->create_table($table);
2327 $DB->insert_record($tablename, array('course' => 1));
2328 $record = $DB->get_record($tablename, array('course' => 1));
2329 $record->course = 2;
2331 $this->assertTrue($DB->update_record($tablename, $record));
2332 $this->assertFalse($record = $DB->get_record($tablename, array('course' => 1)));
2333 $this->assertTrue($record = $DB->get_record($tablename, array('course' => 2)));
2334 $this->assertEqual(100, $record->oneint); // Just check column defaults have been applied
2335 $this->assertEqual(200, $record->onenum);
2336 $this->assertEqual('onestring', $record->onechar);
2337 $this->assertNull($record->onetext);
2338 $this->assertNull($record->onebinary);
2340 // Check nulls are set properly for all types
2341 $record->oneint = null;
2342 $record->onenum = null;
2343 $record->onechar = null;
2344 $record->onetext = null;
2345 $record->onebinary = null;
2346 $DB->update_record($tablename, $record);
2347 $record = $DB->get_record($tablename, array('course' => 2));
2348 $this->assertNull($record->oneint);
2349 $this->assertNull($record->onenum);
2350 $this->assertNull($record->onechar);
2351 $this->assertNull($record->onetext);
2352 $this->assertNull($record->onebinary);
2354 // Check zeros are set properly for all types
2355 $record->oneint = 0;
2356 $record->onenum = 0;
2357 $DB->update_record($tablename, $record);
2358 $record = $DB->get_record($tablename, array('course' => 2));
2359 $this->assertEqual(0, $record->oneint);
2360 $this->assertEqual(0, $record->onenum);
2362 // Check booleans are set properly for all types
2363 $record->oneint = true; // trues
2364 $record->onenum = true;
2365 $record->onechar = true;
2366 $record->onetext = true;
2367 $DB->update_record($tablename, $record);
2368 $record = $DB->get_record($tablename, array('course' => 2));
2369 $this->assertEqual(1, $record->oneint);
2370 $this->assertEqual(1, $record->onenum);
2371 $this->assertEqual(1, $record->onechar);
2372 $this->assertEqual(1, $record->onetext);
2374 $record->oneint = false; // falses
2375 $record->onenum = false;
2376 $record->onechar = false;
2377 $record->onetext = false;
2378 $DB->update_record($tablename, $record);
2379 $record = $DB->get_record($tablename, array('course' => 2));
2380 $this->assertEqual(0, $record->oneint);
2381 $this->assertEqual(0, $record->onenum);
2382 $this->assertEqual(0, $record->onechar);
2383 $this->assertEqual(0, $record->onetext);
2385 // Check string data causes exception in numeric types
2386 $record->oneint = 'onestring';
2387 $record->onenum = 0;
2389 $DB->update_record($tablename, $record);
2390 $this->fail("Expecting an exception, none occurred");
2391 } catch (exception $e) {
2392 $this->assertTrue($e instanceof dml_exception);
2394 $record->oneint = 0;
2395 $record->onenum = 'onestring';
2397 $DB->update_record($tablename, $record);
2398 $this->fail("Expecting an exception, none occurred");
2399 } catch (exception $e) {
2400 $this->assertTrue($e instanceof dml_exception);
2403 // Check empty string data is stored as 0 in numeric datatypes
2404 $record->oneint = ''; // empty string
2405 $record->onenum = 0;
2406 $DB->update_record($tablename, $record);
2407 $record = $DB->get_record($tablename, array('course' => 2));
2408 $this->assertTrue(is_numeric($record->oneint) && $record->oneint == 0);
2410 $record->oneint = 0;
2411 $record->onenum = ''; // empty string
2412 $DB->update_record($tablename, $record);
2413 $record = $DB->get_record($tablename, array('course' => 2));
2414 $this->assertTrue(is_numeric($record->onenum) && $record->onenum == 0);
2416 // Check empty strings are set properly in string types
2417 $record->oneint = 0;
2418 $record->onenum = 0;
2419 $record->onechar = '';
2420 $record->onetext = '';
2421 $DB->update_record($tablename, $record);
2422 $record = $DB->get_record($tablename, array('course' => 2));
2423 $this->assertTrue($record->onechar === '');
2424 $this->assertTrue($record->onetext === '');
2426 // Check operation ((210.10 + 39.92) - 150.02) against numeric types
2427 $record->oneint = ((210.10 + 39.92) - 150.02);
2428 $record->onenum = ((210.10 + 39.92) - 150.02);
2429 $DB->update_record($tablename, $record);
2430 $record = $DB->get_record($tablename, array('course' => 2));
2431 $this->assertEqual(100, $record->oneint);
2432 $this->assertEqual(100, $record->onenum);
2434 // Check various quotes/backslashes combinations in string types
2435 $teststrings = array(
2436 'backslashes and quotes alone (even): "" \'\' \\\\',
2437 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\',
2438 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'',
2439 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\'');
2440 foreach ($teststrings as $teststring) {
2441 $record->onechar = $teststring;
2442 $record->onetext = $teststring;
2443 $DB->update_record($tablename, $record);
2444 $record = $DB->get_record($tablename, array('course' => 2));
2445 $this->assertEqual($teststring, $record->onechar);
2446 $this->assertEqual($teststring, $record->onetext);
2449 // Check LOBs in text/binary columns
2450 $clob = file_get_contents(dirname(__FILE__).'/fixtures/clob.txt');
2451 $blob = file_get_contents(dirname(__FILE__).'/fixtures/randombinary');
2452 $record->onetext = $clob;
2453 $record->onebinary = $blob;
2454 $DB->update_record($tablename, $record);
2455 $record = $DB->get_record($tablename, array('course' => 2));
2456 $this->assertEqual($clob, $record->onetext, 'Test CLOB update (full contents output disabled)');
2457 $this->assertEqual($blob, $record->onebinary, 'Test BLOB update (full contents output disabled)');
2459 // And "small" LOBs too, just in case
2460 $newclob = substr($clob, 0, 500);
2461 $newblob = substr($blob, 0, 250);
2462 $record->onetext = $newclob;
2463 $record->onebinary = $newblob;
2464 $DB->update_record($tablename, $record);
2465 $record = $DB->get_record($tablename, array('course' => 2));
2466 $this->assertEqual($newclob, $record->onetext, 'Test "small" CLOB update (full contents output disabled)');
2467 $this->assertEqual($newblob, $record->onebinary, 'Test "small" BLOB update (full contents output disabled)');
2469 // Test saving a float in a CHAR column, and reading it back.
2470 $id = $DB->insert_record($tablename, array('onechar' => 'X'));
2471 $DB->update_record($tablename, array('id' => $id, 'onechar' => 1.0));
2472 $this->assertEqual(1.0, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2473 $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e20));
2474 $this->assertEqual(1e20, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2475 $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e-4));
2476 $this->assertEqual(1e-4, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2477 $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e-5));
2478 $this->assertEqual(1e-5, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2479 $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e-300));
2480 $this->assertEqual(1e-300, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2481 $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e300));
2482 $this->assertEqual(1e300, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2484 // Test saving a float in a TEXT column, and reading it back.
2485 $id = $DB->insert_record($tablename, array('onetext' => 'X'));
2486 $DB->update_record($tablename, array('id' => $id, 'onetext' => 1.0));
2487 $this->assertEqual(1.0, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2488 $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e20));
2489 $this->assertEqual(1e20, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2490 $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e-4));
2491 $this->assertEqual(1e-4, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2492 $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e-5));
2493 $this->assertEqual(1e-5, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2494 $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e-300));
2495 $this->assertEqual(1e-300, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2496 $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e300));
2497 $this->assertEqual(1e300, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2500 public function test_set_field() {
2502 $dbman = $DB->get_manager();
2504 $table = $this->get_test_table();
2505 $tablename = $table->getName();
2507 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2508 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2509 $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null);
2510 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2511 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2512 $dbman->create_table($table);
2515 $id1 = $DB->insert_record($tablename, array('course' => 1));
2516 $id2 = $DB->insert_record($tablename, array('course' => 1));
2517 $id3 = $DB->insert_record($tablename, array('course' => 3));
2518 $this->assertTrue($DB->set_field($tablename, 'course', 2, array('id' => $id1)));
2519 $this->assertEqual(2, $DB->get_field($tablename, 'course', array('id' => $id1)));
2520 $this->assertEqual(1, $DB->get_field($tablename, 'course', array('id' => $id2)));
2521 $this->assertEqual(3, $DB->get_field($tablename, 'course', array('id' => $id3)));
2522 $DB->delete_records($tablename, array());
2524 // multiple fields affected
2525 $id1 = $DB->insert_record($tablename, array('course' => 1));
2526 $id2 = $DB->insert_record($tablename, array('course' => 1));
2527 $id3 = $DB->insert_record($tablename, array('course' => 3));
2528 $DB->set_field($tablename, 'course', '5', array('course' => 1));
2529 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('id' => $id1)));
2530 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('id' => $id2)));
2531 $this->assertEqual(3, $DB->get_field($tablename, 'course', array('id' => $id3)));
2532 $DB->delete_records($tablename, array());
2534 // no field affected
2535 $id1 = $DB->insert_record($tablename, array('course' => 1));
2536 $id2 = $DB->insert_record($tablename, array('course' => 1));
2537 $id3 = $DB->insert_record($tablename, array('course' => 3));
2538 $DB->set_field($tablename, 'course', '5', array('course' => 0));
2539 $this->assertEqual(1, $DB->get_field($tablename, 'course', array('id' => $id1)));
2540 $this->assertEqual(1, $DB->get_field($tablename, 'course', array('id' => $id2)));
2541 $this->assertEqual(3, $DB->get_field($tablename, 'course', array('id' => $id3)));
2542 $DB->delete_records($tablename, array());
2544 // all fields - no condition
2545 $id1 = $DB->insert_record($tablename, array('course' => 1));
2546 $id2 = $DB->insert_record($tablename, array('course' => 1));
2547 $id3 = $DB->insert_record($tablename, array('course' => 3));
2548 $DB->set_field($tablename, 'course', 5, array());
2549 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('id' => $id1)));
2550 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('id' => $id2)));
2551 $this->assertEqual(5, $DB->get_field($tablename, 'course', array('id' => $id3)));
2553 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
2554 $conditions = array('onetext' => '1');
2556 $DB->set_field($tablename, 'onechar', 'frog', $conditions);
2558 // only in debug mode - hopefully all devs test code in debug mode...
2559 $this->fail('An Exception is missing, expected due to equating of text fields');
2561 } catch (exception $e) {
2562 $this->assertTrue($e instanceof dml_exception);
2563 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
2566 // Test saving a float in a CHAR column, and reading it back.
2567 $id = $DB->insert_record($tablename, array('onechar' => 'X'));
2568 $DB->set_field($tablename, 'onechar', 1.0, array('id' => $id));
2569 $this->assertEqual(1.0, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2570 $DB->set_field($tablename, 'onechar', 1e20, array('id' => $id));
2571 $this->assertEqual(1e20, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2572 $DB->set_field($tablename, 'onechar', 1e-4, array('id' => $id));
2573 $this->assertEqual(1e-4, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2574 $DB->set_field($tablename, 'onechar', 1e-5, array('id' => $id));
2575 $this->assertEqual(1e-5, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2576 $DB->set_field($tablename, 'onechar', 1e-300, array('id' => $id));
2577 $this->assertEqual(1e-300, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2578 $DB->set_field($tablename, 'onechar', 1e300, array('id' => $id));
2579 $this->assertEqual(1e300, $DB->get_field($tablename, 'onechar', array('id' => $id)));
2581 // Test saving a float in a TEXT column, and reading it back.
2582 $id = $DB->insert_record($tablename, array('onetext' => 'X'));
2583 $DB->set_field($tablename, 'onetext', 1.0, array('id' => $id));
2584 $this->assertEqual(1.0, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2585 $DB->set_field($tablename, 'onetext', 1e20, array('id' => $id));
2586 $this->assertEqual(1e20, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2587 $DB->set_field($tablename, 'onetext', 1e-4, array('id' => $id));
2588 $this->assertEqual(1e-4, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2589 $DB->set_field($tablename, 'onetext', 1e-5, array('id' => $id));
2590 $this->assertEqual(1e-5, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2591 $DB->set_field($tablename, 'onetext', 1e-300, array('id' => $id));
2592 $this->assertEqual(1e-300, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2593 $DB->set_field($tablename, 'onetext', 1e300, array('id' => $id));
2594 $this->assertEqual(1e300, $DB->get_field($tablename, 'onetext', array('id' => $id)));
2596 // Note: All the nulls, booleans, empties, quoted and backslashes tests
2597 // go to set_field_select() because set_field() is just one wrapper over it
2600 public function test_set_field_select() {
2602 // All the information in this test is fetched from DB by get_field() so we
2603 // have such method properly tested against nulls, empties and friends...
2606 $dbman = $DB->get_manager();
2608 $table = $this->get_test_table();
2609 $tablename = $table->getName();
2611 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2612 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2613 $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null);
2614 $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null);
2615 $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null);
2616 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2617 $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null);
2618 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2619 $dbman->create_table($table);
2621 $DB->insert_record($tablename, array('course' => 1));
2623 $this->assertTrue($DB->set_field_select($tablename, 'course', 2, 'id = ?', array(1)));
2624 $this->assertEqual(2, $DB->get_field($tablename, 'course', array('id' => 1)));
2626 // Check nulls are set properly for all types
2627 $DB->set_field_select($tablename, 'oneint', null, 'id = ?', array(1)); // trues
2628 $DB->set_field_select($tablename, 'onenum', null, 'id = ?', array(1));
2629 $DB->set_field_select($tablename, 'onechar', null, 'id = ?', array(1));
2630 $DB->set_field_select($tablename, 'onetext', null, 'id = ?', array(1));
2631 $DB->set_field_select($tablename, 'onebinary', null, 'id = ?', array(1));
2632 $this->assertNull($DB->get_field($tablename, 'oneint', array('id' => 1)));
2633 $this->assertNull($DB->get_field($tablename, 'onenum', array('id' => 1)));
2634 $this->assertNull($DB->get_field($tablename, 'onechar', array('id' => 1)));
2635 $this->assertNull($DB->get_field($tablename, 'onetext', array('id' => 1)));
2636 $this->assertNull($DB->get_field($tablename, 'onebinary', array('id' => 1)));
2638 // Check zeros are set properly for all types
2639 $DB->set_field_select($tablename, 'oneint', 0, 'id = ?', array(1));
2640 $DB->set_field_select($tablename, 'onenum', 0, 'id = ?', array(1));
2641 $this->assertEqual(0, $DB->get_field($tablename, 'oneint', array('id' => 1)));
2642 $this->assertEqual(0, $DB->get_field($tablename, 'onenum', array('id' => 1)));
2644 // Check booleans are set properly for all types
2645 $DB->set_field_select($tablename, 'oneint', true, 'id = ?', array(1)); // trues
2646 $DB->set_field_select($tablename, 'onenum', true, 'id = ?', array(1));
2647 $DB->set_field_select($tablename, 'onechar', true, 'id = ?', array(1));
2648 $DB->set_field_select($tablename, 'onetext', true, 'id = ?', array(1));
2649 $this->assertEqual(1, $DB->get_field($tablename, 'oneint', array('id' => 1)));
2650 $this->assertEqual(1, $DB->get_field($tablename, 'onenum', array('id' => 1)));
2651 $this->assertEqual(1, $DB->get_field($tablename, 'onechar', array('id' => 1)));
2652 $this->assertEqual(1, $DB->get_field($tablename, 'onetext', array('id' => 1)));
2654 $DB->set_field_select($tablename, 'oneint', false, 'id = ?', array(1)); // falses
2655 $DB->set_field_select($tablename, 'onenum', false, 'id = ?', array(1));
2656 $DB->set_field_select($tablename, 'onechar', false, 'id = ?', array(1));
2657 $DB->set_field_select($tablename, 'onetext', false, 'id = ?', array(1));
2658 $this->assertEqual(0, $DB->get_field($tablename, 'oneint', array('id' => 1)));
2659 $this->assertEqual(0, $DB->get_field($tablename, 'onenum', array('id' => 1)));
2660 $this->assertEqual(0, $DB->get_field($tablename, 'onechar', array('id' => 1)));
2661 $this->assertEqual(0, $DB->get_field($tablename, 'onetext', array('id' => 1)));
2663 // Check string data causes exception in numeric types
2665 $DB->set_field_select($tablename, 'oneint', 'onestring', 'id = ?', array(1));
2666 $this->fail("Expecting an exception, none occurred");
2667 } catch (exception $e) {
2668 $this->assertTrue($e instanceof dml_exception);
2671 $DB->set_field_select($tablename, 'onenum', 'onestring', 'id = ?', array(1));
2672 $this->fail("Expecting an exception, none occurred");
2673 } catch (exception $e) {
2674 $this->assertTrue($e instanceof dml_exception);
2677 // Check empty string data is stored as 0 in numeric datatypes
2678 $DB->set_field_select($tablename, 'oneint', '', 'id = ?', array(1));
2679 $field = $DB->get_field($tablename, 'oneint', array('id' => 1));
2680 $this->assertTrue(is_numeric($field) && $field == 0);
2682 $DB->set_field_select($tablename, 'onenum', '', 'id = ?', array(1));
2683 $field = $DB->get_field($tablename, 'onenum', array('id' => 1));
2684 $this->assertTrue(is_numeric($field) && $field == 0);
2686 // Check empty strings are set properly in string types
2687 $DB->set_field_select($tablename, 'onechar', '', 'id = ?', array(1));
2688 $DB->set_field_select($tablename, 'onetext', '', 'id = ?', array(1));
2689 $this->assertTrue($DB->get_field($tablename, 'onechar', array('id' => 1)) === '');
2690 $this->assertTrue($DB->get_field($tablename, 'onetext', array('id' => 1)) === '');
2692 // Check operation ((210.10 + 39.92) - 150.02) against numeric types
2693 $DB->set_field_select($tablename, 'oneint', ((210.10 + 39.92) - 150.02), 'id = ?', array(1));
2694 $DB->set_field_select($tablename, 'onenum', ((210.10 + 39.92) - 150.02), 'id = ?', array(1));
2695 $this->assertEqual(100, $DB->get_field($tablename, 'oneint', array('id' => 1)));
2696 $this->assertEqual(100, $DB->get_field($tablename, 'onenum', array('id' => 1)));
2698 // Check various quotes/backslashes combinations in string types
2699 $teststrings = array(
2700 'backslashes and quotes alone (even): "" \'\' \\\\',
2701 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\',
2702 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'',
2703 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\'');
2704 foreach ($teststrings as $teststring) {
2705 $DB->set_field_select($tablename, 'onechar', $teststring, 'id = ?', array(1));
2706 $DB->set_field_select($tablename, 'onetext', $teststring, 'id = ?', array(1));
2707 $this->assertEqual($teststring, $DB->get_field($tablename, 'onechar', array('id' => 1)));
2708 $this->assertEqual($teststring, $DB->get_field($tablename, 'onetext', array('id' => 1)));
2711 // Check LOBs in text/binary columns
2712 $clob = file_get_contents(dirname(__FILE__).'/fixtures/clob.txt');
2713 $blob = file_get_contents(dirname(__FILE__).'/fixtures/randombinary');
2714 $DB->set_field_select($tablename, 'onetext', $clob, 'id = ?', array(1));
2715 $DB->set_field_select($tablename, 'onebinary', $blob, 'id = ?', array(1));
2716 $this->assertEqual($clob, $DB->get_field($tablename, 'onetext', array('id' => 1)), 'Test CLOB set_field (full contents output disabled)');
2717 $this->assertEqual($blob, $DB->get_field($tablename, 'onebinary', array('id' => 1)), 'Test BLOB set_field (full contents output disabled)');
2719 // And "small" LOBs too, just in case
2720 $newclob = substr($clob, 0, 500);
2721 $newblob = substr($blob, 0, 250);
2722 $DB->set_field_select($tablename, 'onetext', $newclob, 'id = ?', array(1));
2723 $DB->set_field_select($tablename, 'onebinary', $newblob, 'id = ?', array(1));
2724 $this->assertEqual($newclob, $DB->get_field($tablename, 'onetext', array('id' => 1)), 'Test "small" CLOB set_field (full contents output disabled)');
2725 $this->assertEqual($newblob, $DB->get_field($tablename, 'onebinary', array('id' => 1)), 'Test "small" BLOB set_field (full contents output disabled)');
2727 // This is the failure from MDL-24863. This was giving an error on MSSQL,
2728 // which converts the '1' to an integer, which cannot then be compared with
2729 // onetext cast to a varchar. This should be fixed and working now.
2731 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
2732 $params = array('onetext' => '1');
2734 $DB->set_field_select($tablename, 'onechar', $newchar, $DB->sql_compare_text('onetext') . ' = ?', $params);
2735 $this->assertTrue(true, 'No exceptions thrown with numerical text param comparison for text field.');
2736 } catch (dml_exception $e) {
2737 $this->assertFalse(true, 'We have an unexpected exception.');
2744 public function test_count_records() {
2747 $dbman = $DB->get_manager();
2749 $table = $this->get_test_table();
2750 $tablename = $table->getName();
2752 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2753 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2754 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2755 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2756 $dbman->create_table($table);
2758 $this->assertEqual(0, $DB->count_records($tablename));
2760 $DB->insert_record($tablename, array('course' => 3));
2761 $DB->insert_record($tablename, array('course' => 4));
2762 $DB->insert_record($tablename, array('course' => 5));
2764 $this->assertEqual(3, $DB->count_records($tablename));
2766 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
2767 $conditions = array('onetext' => '1');
2769 $DB->count_records($tablename, $conditions);
2771 // only in debug mode - hopefully all devs test code in debug mode...
2772 $this->fail('An Exception is missing, expected due to equating of text fields');
2774 } catch (exception $e) {
2775 $this->assertTrue($e instanceof dml_exception);
2776 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
2780 public function test_count_records_select() {
2783 $dbman = $DB->get_manager();
2785 $table = $this->get_test_table();
2786 $tablename = $table->getName();
2788 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2789 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2790 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2791 $dbman->create_table($table);
2793 $this->assertEqual(0, $DB->count_records($tablename));
2795 $DB->insert_record($tablename, array('course' => 3));
2796 $DB->insert_record($tablename, array('course' => 4));
2797 $DB->insert_record($tablename, array('course' => 5));
2799 $this->assertEqual(2, $DB->count_records_select($tablename, 'course > ?', array(3)));
2802 public function test_count_records_sql() {
2804 $dbman = $DB->get_manager();
2806 $table = $this->get_test_table();
2807 $tablename = $table->getName();
2809 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2810 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2811 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2812 $dbman->create_table($table);
2814 $this->assertEqual(0, $DB->count_records($tablename));
2816 $DB->insert_record($tablename, array('course' => 3));
2817 $DB->insert_record($tablename, array('course' => 4));
2818 $DB->insert_record($tablename, array('course' => 5));
2820 $this->assertEqual(2, $DB->count_records_sql("SELECT COUNT(*) FROM {{$tablename}} WHERE course > ?", array(3)));
2823 public function test_record_exists() {
2825 $dbman = $DB->get_manager();
2827 $table = $this->get_test_table();
2828 $tablename = $table->getName();
2830 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2831 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2832 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2833 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2834 $dbman->create_table($table);
2836 $this->assertEqual(0, $DB->count_records($tablename));
2838 $this->assertFalse($DB->record_exists($tablename, array('course' => 3)));
2839 $DB->insert_record($tablename, array('course' => 3));
2841 $this->assertTrue($DB->record_exists($tablename, array('course' => 3)));
2844 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
2845 $conditions = array('onetext' => '1');
2847 $DB->record_exists($tablename, $conditions);
2849 // only in debug mode - hopefully all devs test code in debug mode...
2850 $this->fail('An Exception is missing, expected due to equating of text fields');
2852 } catch (exception $e) {
2853 $this->assertTrue($e instanceof dml_exception);
2854 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
2858 public function test_record_exists_select() {
2860 $dbman = $DB->get_manager();
2862 $table = $this->get_test_table();
2863 $tablename = $table->getName();
2865 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2866 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2867 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2868 $dbman->create_table($table);
2870 $this->assertEqual(0, $DB->count_records($tablename));
2872 $this->assertFalse($DB->record_exists_select($tablename, "course = ?", array(3)));
2873 $DB->insert_record($tablename, array('course' => 3));
2875 $this->assertTrue($DB->record_exists_select($tablename, "course = ?", array(3)));
2878 public function test_record_exists_sql() {
2880 $dbman = $DB->get_manager();
2882 $table = $this->get_test_table();
2883 $tablename = $table->getName();
2885 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2886 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2887 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2888 $dbman->create_table($table);
2890 $this->assertEqual(0, $DB->count_records($tablename));
2892 $this->assertFalse($DB->record_exists_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3)));
2893 $DB->insert_record($tablename, array('course' => 3));
2895 $this->assertTrue($DB->record_exists_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3)));
2898 public function test_recordset_locks_delete() {
2900 $dbman = $DB->get_manager();
2903 $table = $this->get_test_table();
2904 $tablename = $table->getName();
2906 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2907 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2908 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2909 $dbman->create_table($table);
2911 $DB->insert_record($tablename, array('course' => 1));
2912 $DB->insert_record($tablename, array('course' => 2));
2913 $DB->insert_record($tablename, array('course' => 3));
2914 $DB->insert_record($tablename, array('course' => 4));
2915 $DB->insert_record($tablename, array('course' => 5));
2916 $DB->insert_record($tablename, array('course' => 6));
2918 // Test against db write locking while on an open recordset
2919 $rs = $DB->get_recordset($tablename, array(), null, 'course', 2, 2); // get courses = {3,4}
2920 foreach ($rs as $record) {
2921 $cid = $record->course;
2922 $DB->delete_records($tablename, array('course' => $cid));
2923 $this->assertFalse($DB->record_exists($tablename, array('course' => $cid)));
2927 $this->assertEqual(4, $DB->count_records($tablename, array()));
2930 public function test_recordset_locks_update() {
2932 $dbman = $DB->get_manager();
2935 $table = $this->get_test_table();
2936 $tablename = $table->getName();
2938 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2939 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2940 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2941 $dbman->create_table($table);
2943 $DB->insert_record($tablename, array('course' => 1));
2944 $DB->insert_record($tablename, array('course' => 2));
2945 $DB->insert_record($tablename, array('course' => 3));
2946 $DB->insert_record($tablename, array('course' => 4));
2947 $DB->insert_record($tablename, array('course' => 5));
2948 $DB->insert_record($tablename, array('course' => 6));
2950 // Test against db write locking while on an open recordset
2951 $rs = $DB->get_recordset($tablename, array(), null, 'course', 2, 2); // get courses = {3,4}
2952 foreach ($rs as $record) {
2953 $cid = $record->course;
2954 $DB->set_field($tablename, 'course', 10, array('course' => $cid));
2955 $this->assertFalse($DB->record_exists($tablename, array('course' => $cid)));
2959 $this->assertEqual(2, $DB->count_records($tablename, array('course' => 10)));
2962 public function test_delete_records() {
2964 $dbman = $DB->get_manager();
2966 $table = $this->get_test_table();
2967 $tablename = $table->getName();
2969 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
2970 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
2971 $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null);
2972 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
2973 $dbman->create_table($table);
2975 $DB->insert_record($tablename, array('course' => 3));
2976 $DB->insert_record($tablename, array('course' => 2));
2977 $DB->insert_record($tablename, array('course' => 2));
2979 // Delete all records
2980 $this->assertTrue($DB->delete_records($tablename));
2981 $this->assertEqual(0, $DB->count_records($tablename));
2983 // Delete subset of records
2984 $DB->insert_record($tablename, array('course' => 3));
2985 $DB->insert_record($tablename, array('course' => 2));
2986 $DB->insert_record($tablename, array('course' => 2));
2988 $this->assertTrue($DB->delete_records($tablename, array('course' => 2)));
2989 $this->assertEqual(1, $DB->count_records($tablename));
2992 $this->assertTrue($DB->delete_records($tablename, array()));
2993 $this->assertEqual(0, $DB->count_records($tablename));
2995 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
2996 $conditions = array('onetext'=>'1');
2998 $DB->delete_records($tablename, $conditions);
3000 // only in debug mode - hopefully all devs test code in debug mode...
3001 $this->fail('An Exception is missing, expected due to equating of text fields');
3003 } catch (exception $e) {
3004 $this->assertTrue($e instanceof dml_exception);
3005 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
3008 // test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int)
3009 $conditions = array('onetext' => 1);
3011 $DB->delete_records($tablename, $conditions);
3013 // only in debug mode - hopefully all devs test code in debug mode...
3014 $this->fail('An Exception is missing, expected due to equating of text fields');
3016 } catch (exception $e) {
3017 $this->assertTrue($e instanceof dml_exception);
3018 $this->assertEqual($e->errorcode, 'textconditionsnotallowed');
3022 public function test_delete_records_select() {
3024 $dbman = $DB->get_manager();
3026 $table = $this->get_test_table();
3027 $tablename = $table->getName();
3029 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3030 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3031 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3032 $dbman->create_table($table);
3034 $DB->insert_record($tablename, array('course' => 3));
3035 $DB->insert_record($tablename, array('course' => 2));
3036 $DB->insert_record($tablename, array('course' => 2));
3038 $this->assertTrue($DB->delete_records_select($tablename, 'course = ?', array(2)));
3039 $this->assertEqual(1, $DB->count_records($tablename));
3042 public function test_delete_records_list() {
3044 $dbman = $DB->get_manager();
3046 $table = $this->get_test_table();
3047 $tablename = $table->getName();
3049 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3050 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3051 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3052 $dbman->create_table($table);
3054 $DB->insert_record($tablename, array('course' => 1));
3055 $DB->insert_record($tablename, array('course' => 2));
3056 $DB->insert_record($tablename, array('course' => 3));
3058 $this->assertTrue($DB->delete_records_list($tablename, 'course', array(2, 3)));
3059 $this->assertEqual(1, $DB->count_records($tablename));
3061 $this->assertTrue($DB->delete_records_list($tablename, 'course', array())); /// Must delete 0 rows without conditions. MDL-17645
3062 $this->assertEqual(1, $DB->count_records($tablename));
3065 public function test_object_params() {
3067 $dbman = $DB->get_manager();
3069 $table = $this->get_test_table();
3070 $tablename = $table->getName();
3071 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3072 $table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3073 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3074 $dbman->create_table($table);
3076 $o = new stdClass(); // objects without __toString - never worked
3078 $DB->fix_sql_params("SELECT {{$tablename}} WHERE course = ? ", array($o));
3079 $this->fail('coding_exception expected');
3080 } catch (Exception $e) {
3081 $this->assertTrue($e instanceof coding_exception);
3084 // objects with __toString() forbidden everywhere since 2.3
3085 $o = new dml_test_object_one();
3087 $DB->fix_sql_params("SELECT {{$tablename}} WHERE course = ? ", array($o));
3088 $this->fail('coding_exception expected');
3089 } catch (Exception $e) {
3090 $this->assertTrue($e instanceof coding_exception);
3094 $DB->execute("SELECT {{$tablename}} WHERE course = ? ", array($o));
3095 $this->fail('coding_exception expected');
3096 } catch (Exception $e) {
3097 $this->assertTrue($e instanceof coding_exception);
3101 $DB->get_recordset_sql("SELECT {{$tablename}} WHERE course = ? ", array($o));
3102 $this->fail('coding_exception expected');
3103 } catch (Exception $e) {
3104 $this->assertTrue($e instanceof coding_exception);
3108 $DB->get_records_sql("SELECT {{$tablename}} WHERE course = ? ", array($o));
3109 $this->fail('coding_exception expected');
3110 } catch (Exception $e) {
3111 $this->assertTrue($e instanceof coding_exception);
3115 $record = new stdClass();
3116 $record->course = $o;
3117 $DB->insert_record_raw($tablename, $record);
3118 $this->fail('coding_exception expected');
3119 } catch (Exception $e) {
3120 $this->assertTrue($e instanceof coding_exception);
3124 $record = new stdClass();
3125 $record->course = $o;
3126 $DB->insert_record($tablename, $record);
3127 $this->fail('coding_exception expected');
3128 } catch (Exception $e) {
3129 $this->assertTrue($e instanceof coding_exception);
3133 $record = new stdClass();
3134 $record->course = $o;
3135 $DB->import_record($tablename, $record);
3136 $this->fail('coding_exception expected');
3137 } catch (Exception $e) {
3138 $this->assertTrue($e instanceof coding_exception);
3142 $record = new stdClass();
3144 $record->course = $o;
3145 $DB->update_record_raw($tablename, $record);
3146 $this->fail('coding_exception expected');
3147 } catch (Exception $e) {
3148 $this->assertTrue($e instanceof coding_exception);
3152 $record = new stdClass();
3154 $record->course = $o;
3155 $DB->update_record($tablename, $record);
3156 $this->fail('coding_exception expected');
3157 } catch (Exception $e) {
3158 $this->assertTrue($e instanceof coding_exception);
3162 $DB->set_field_select($tablename, 'course', 1, "course = ? ", array($o));
3163 $this->fail('coding_exception expected');
3164 } catch (Exception $e) {
3165 $this->assertTrue($e instanceof coding_exception);
3169 $DB->delete_records_select($tablename, "course = ? ", array($o));
3170 $this->fail('coding_exception expected');
3171 } catch (Exception $e) {
3172 $this->assertTrue($e instanceof coding_exception);
3176 function test_sql_null_from_clause() {
3178 $sql = "SELECT 1 AS id ".$DB->sql_null_from_clause();
3179 $this->assertEqual($DB->get_field_sql($sql), 1);
3182 function test_sql_bitand() {
3184 $dbman = $DB->get_manager();
3186 $table = $this->get_test_table();
3187 $tablename = $table->getName();
3189 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3190 $table->add_field('col1', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3191 $table->add_field('col2', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3192 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3193 $dbman->create_table($table);
3195 $DB->insert_record($tablename, array('col1' => 3, 'col2' => 10));
3197 $sql = "SELECT ".$DB->sql_bitand(10, 3)." AS res ".$DB->sql_null_from_clause();
3198 $this->assertEqual($DB->get_field_sql($sql), 2);
3200 $sql = "SELECT id, ".$DB->sql_bitand('col1', 'col2')." AS res FROM {{$tablename}}";
3201 $result = $DB->get_records_sql($sql);
3202 $this->assertEqual(count($result), 1);
3203 $this->assertEqual(reset($result)->res, 2);
3205 $sql = "SELECT id, ".$DB->sql_bitand('col1', '?')." AS res FROM {{$tablename}}";
3206 $result = $DB->get_records_sql($sql, array(10));
3207 $this->assertEqual(count($result), 1);
3208 $this->assertEqual(reset($result)->res, 2);
3211 function test_sql_bitnot() {
3214 $not = $DB->sql_bitnot(2);
3215 $notlimited = $DB->sql_bitand($not, 7); // might be positive or negative number which can not fit into PHP INT!
3217 $sql = "SELECT $notlimited AS res ".$DB->sql_null_from_clause();
3218 $this->assertEqual($DB->get_field_sql($sql), 5);
3221 function test_sql_bitor() {
3223 $dbman = $DB->get_manager();
3225 $table = $this->get_test_table();
3226 $tablename = $table->getName();
3228 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3229 $table->add_field('col1', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3230 $table->add_field('col2', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3231 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3232 $dbman->create_table($table);
3234 $DB->insert_record($tablename, array('col1' => 3, 'col2' => 10));
3236 $sql = "SELECT ".$DB->sql_bitor(10, 3)." AS res ".$DB->sql_null_from_clause();
3237 $this->assertEqual($DB->get_field_sql($sql), 11);
3239 $sql = "SELECT id, ".$DB->sql_bitor('col1', 'col2')." AS res FROM {{$tablename}}";
3240 $result = $DB->get_records_sql($sql);
3241 $this->assertEqual(count($result), 1);
3242 $this->assertEqual(reset($result)->res, 11);
3244 $sql = "SELECT id, ".$DB->sql_bitor('col1', '?')." AS res FROM {{$tablename}}";
3245 $result = $DB->get_records_sql($sql, array(10));
3246 $this->assertEqual(count($result), 1);
3247 $this->assertEqual(reset($result)->res, 11);
3250 function test_sql_bitxor() {
3252 $dbman = $DB->get_manager();
3254 $table = $this->get_test_table();
3255 $tablename = $table->getName();
3257 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
3258 $table->add_field('col1', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3259 $table->add_field('col2', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
3260 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
3261 $dbman->create_table($table);
3263 $DB->insert_record($tablename, array('col1' => 3, 'col2' => 10));
3265 $sql = "SELECT ".$DB->sql_bitxor(10, 3)." AS res ".$DB->sql_null_from_clause();
3266 $this->assertEqual($DB->get_field_sql($sql), 9);