Commit | Line | Data |
---|---|---|
a3d5830a PS |
1 | <?php |
2 | // This file is part of Moodle - http://moodle.org/ | |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
9d6d32b6 | 18 | * DML layer tests. |
a3d5830a | 19 | * |
00902cd9 | 20 | * @package core_dml |
a3d5830a PS |
21 | * @category phpunit |
22 | * @copyright 2008 Nicolas Connault | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | ||
26 | defined('MOODLE_INTERNAL') || die(); | |
27 | ||
8252b7c2 | 28 | class core_dml_testcase extends database_driver_testcase { |
a3d5830a | 29 | |
4787e466 PS |
30 | protected function setUp() { |
31 | parent::setUp(); | |
9d6d32b6 | 32 | $dbman = $this->tdb->get_manager(); // Loads DDL libs. |
4787e466 PS |
33 | } |
34 | ||
a3d5830a PS |
35 | /** |
36 | * Get a xmldb_table object for testing, deleting any existing table | |
37 | * of the same name, for example if one was left over from a previous test | |
38 | * run that crashed. | |
39 | * | |
40 | * @param string $suffix table name suffix, use if you need more test tables | |
41 | * @return xmldb_table the table object. | |
42 | */ | |
43 | private function get_test_table($suffix = '') { | |
44 | $tablename = "test_table"; | |
45 | if ($suffix !== '') { | |
46 | $tablename .= $suffix; | |
47 | } | |
48 | ||
49 | $table = new xmldb_table($tablename); | |
50 | $table->setComment("This is a test'n drop table. You can drop it safely"); | |
51 | return new xmldb_table($tablename); | |
52 | } | |
53 | ||
9d6d32b6 | 54 | public function test_diagnose() { |
a3d5830a PS |
55 | $DB = $this->tdb; |
56 | $result = $DB->diagnose(); | |
57 | $this->assertNull($result, 'Database self diagnostics failed %s'); | |
58 | } | |
59 | ||
9d6d32b6 | 60 | public function test_get_server_info() { |
a3d5830a PS |
61 | $DB = $this->tdb; |
62 | $result = $DB->get_server_info(); | |
9d6d32b6 PS |
63 | $this->assertInternalType('array', $result); |
64 | $this->assertArrayHasKey('description', $result); | |
65 | $this->assertArrayHasKey('version', $result); | |
a3d5830a PS |
66 | } |
67 | ||
68 | public function test_get_in_or_equal() { | |
69 | $DB = $this->tdb; | |
70 | ||
9d6d32b6 | 71 | // SQL_PARAMS_QM - IN or =. |
a3d5830a | 72 | |
9d6d32b6 | 73 | // Correct usage of multiple values. |
a3d5830a PS |
74 | $in_values = array('value1', 'value2', '3', 4, null, false, true); |
75 | list($usql, $params) = $DB->get_in_or_equal($in_values); | |
9d6d32b6 | 76 | $this->assertSame('IN ('.implode(',', array_fill(0, count($in_values), '?')).')', $usql); |
a3d5830a PS |
77 | $this->assertEquals(count($in_values), count($params)); |
78 | foreach ($params as $key => $value) { | |
79 | $this->assertSame($in_values[$key], $value); | |
80 | } | |
81 | ||
9d6d32b6 | 82 | // Correct usage of single value (in an array). |
a3d5830a PS |
83 | $in_values = array('value1'); |
84 | list($usql, $params) = $DB->get_in_or_equal($in_values); | |
85 | $this->assertEquals("= ?", $usql); | |
9d6d32b6 | 86 | $this->assertCount(1, $params); |
a3d5830a PS |
87 | $this->assertEquals($in_values[0], $params[0]); |
88 | ||
9d6d32b6 | 89 | // Correct usage of single value. |
a3d5830a PS |
90 | $in_value = 'value1'; |
91 | list($usql, $params) = $DB->get_in_or_equal($in_values); | |
92 | $this->assertEquals("= ?", $usql); | |
9d6d32b6 | 93 | $this->assertCount(1, $params); |
a3d5830a PS |
94 | $this->assertEquals($in_value, $params[0]); |
95 | ||
9d6d32b6 | 96 | // SQL_PARAMS_QM - NOT IN or <>. |
a3d5830a | 97 | |
9d6d32b6 | 98 | // Correct usage of multiple values. |
a3d5830a PS |
99 | $in_values = array('value1', 'value2', 'value3', 'value4'); |
100 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, null, false); | |
101 | $this->assertEquals("NOT IN (?,?,?,?)", $usql); | |
9d6d32b6 | 102 | $this->assertCount(4, $params); |
a3d5830a PS |
103 | foreach ($params as $key => $value) { |
104 | $this->assertEquals($in_values[$key], $value); | |
105 | } | |
106 | ||
9d6d32b6 | 107 | // Correct usage of single value (in array(). |
a3d5830a PS |
108 | $in_values = array('value1'); |
109 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, null, false); | |
110 | $this->assertEquals("<> ?", $usql); | |
9d6d32b6 | 111 | $this->assertCount(1, $params); |
a3d5830a PS |
112 | $this->assertEquals($in_values[0], $params[0]); |
113 | ||
9d6d32b6 | 114 | // Correct usage of single value. |
a3d5830a PS |
115 | $in_value = 'value1'; |
116 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, null, false); | |
117 | $this->assertEquals("<> ?", $usql); | |
9d6d32b6 | 118 | $this->assertCount(1, $params); |
a3d5830a PS |
119 | $this->assertEquals($in_value, $params[0]); |
120 | ||
9d6d32b6 | 121 | // SQL_PARAMS_NAMED - IN or =. |
a3d5830a | 122 | |
9d6d32b6 | 123 | // Correct usage of multiple values. |
a3d5830a PS |
124 | $in_values = array('value1', 'value2', 'value3', 'value4'); |
125 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', true); | |
9d6d32b6 | 126 | $this->assertCount(4, $params); |
a3d5830a PS |
127 | reset($in_values); |
128 | $ps = array(); | |
129 | foreach ($params as $key => $value) { | |
130 | $this->assertEquals(current($in_values), $value); | |
131 | next($in_values); | |
132 | $ps[] = ':'.$key; | |
133 | } | |
134 | $this->assertEquals("IN (".implode(',', $ps).")", $usql); | |
135 | ||
9d6d32b6 | 136 | // Correct usage of single values (in array). |
a3d5830a PS |
137 | $in_values = array('value1'); |
138 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', true); | |
9d6d32b6 | 139 | $this->assertCount(1, $params); |
a3d5830a PS |
140 | $value = reset($params); |
141 | $key = key($params); | |
142 | $this->assertEquals("= :$key", $usql); | |
143 | $this->assertEquals($in_value, $value); | |
144 | ||
9d6d32b6 | 145 | // Correct usage of single value. |
a3d5830a PS |
146 | $in_value = 'value1'; |
147 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', true); | |
9d6d32b6 | 148 | $this->assertCount(1, $params); |
a3d5830a PS |
149 | $value = reset($params); |
150 | $key = key($params); | |
151 | $this->assertEquals("= :$key", $usql); | |
152 | $this->assertEquals($in_value, $value); | |
153 | ||
9d6d32b6 | 154 | // SQL_PARAMS_NAMED - NOT IN or <>. |
a3d5830a | 155 | |
9d6d32b6 | 156 | // Correct usage of multiple values. |
a3d5830a PS |
157 | $in_values = array('value1', 'value2', 'value3', 'value4'); |
158 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false); | |
9d6d32b6 | 159 | $this->assertCount(4, $params); |
a3d5830a PS |
160 | reset($in_values); |
161 | $ps = array(); | |
162 | foreach ($params as $key => $value) { | |
163 | $this->assertEquals(current($in_values), $value); | |
164 | next($in_values); | |
165 | $ps[] = ':'.$key; | |
166 | } | |
167 | $this->assertEquals("NOT IN (".implode(',', $ps).")", $usql); | |
168 | ||
9d6d32b6 | 169 | // Correct usage of single values (in array). |
a3d5830a PS |
170 | $in_values = array('value1'); |
171 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false); | |
9d6d32b6 | 172 | $this->assertCount(1, $params); |
a3d5830a PS |
173 | $value = reset($params); |
174 | $key = key($params); | |
175 | $this->assertEquals("<> :$key", $usql); | |
176 | $this->assertEquals($in_value, $value); | |
177 | ||
9d6d32b6 | 178 | // Correct usage of single value. |
a3d5830a PS |
179 | $in_value = 'value1'; |
180 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false); | |
9d6d32b6 | 181 | $this->assertCount(1, $params); |
a3d5830a PS |
182 | $value = reset($params); |
183 | $key = key($params); | |
184 | $this->assertEquals("<> :$key", $usql); | |
185 | $this->assertEquals($in_value, $value); | |
186 | ||
9d6d32b6 PS |
187 | // Make sure the param names are unique. |
188 | list($usql1, $params1) = $DB->get_in_or_equal(array(1, 2, 3), SQL_PARAMS_NAMED, 'param'); | |
189 | list($usql2, $params2) = $DB->get_in_or_equal(array(1, 2, 3), SQL_PARAMS_NAMED, 'param'); | |
a3d5830a PS |
190 | $params1 = array_keys($params1); |
191 | $params2 = array_keys($params2); | |
192 | $common = array_intersect($params1, $params2); | |
9d6d32b6 | 193 | $this->assertCount(0, $common); |
a3d5830a | 194 | |
9d6d32b6 | 195 | // Some incorrect tests. |
a3d5830a | 196 | |
9d6d32b6 | 197 | // Incorrect usage passing not-allowed params type. |
a3d5830a PS |
198 | $in_values = array(1, 2, 3); |
199 | try { | |
200 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_DOLLAR, 'param', false); | |
201 | $this->fail('An Exception is missing, expected due to not supported SQL_PARAMS_DOLLAR'); | |
9d6d32b6 PS |
202 | } catch (moodle_exception $e) { |
203 | $this->assertInstanceOf('dml_exception', $e); | |
204 | $this->assertSame('typenotimplement', $e->errorcode); | |
a3d5830a PS |
205 | } |
206 | ||
9d6d32b6 | 207 | // Incorrect usage passing empty array. |
a3d5830a PS |
208 | $in_values = array(); |
209 | try { | |
210 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false); | |
211 | $this->fail('An Exception is missing, expected due to empty array of items'); | |
9d6d32b6 PS |
212 | } catch (moodle_exception $e) { |
213 | $this->assertInstanceOf('coding_exception', $e); | |
a3d5830a PS |
214 | } |
215 | ||
9d6d32b6 | 216 | // Test using $onemptyitems. |
a3d5830a | 217 | |
9d6d32b6 | 218 | // Correct usage passing empty array and $onemptyitems = null (equal = true, QM). |
a3d5830a | 219 | $in_values = array(); |
9d6d32b6 PS |
220 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, null); |
221 | $this->assertSame(' IS NULL', $usql); | |
a3d5830a PS |
222 | $this->assertSame(array(), $params); |
223 | ||
9d6d32b6 | 224 | // Correct usage passing empty array and $onemptyitems = null (equal = false, NAMED). |
a3d5830a | 225 | $in_values = array(); |
9d6d32b6 PS |
226 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, null); |
227 | $this->assertSame(' IS NOT NULL', $usql); | |
a3d5830a PS |
228 | $this->assertSame(array(), $params); |
229 | ||
9d6d32b6 | 230 | // Correct usage passing empty array and $onemptyitems = true (equal = true, QM). |
a3d5830a PS |
231 | $in_values = array(); |
232 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, true); | |
9d6d32b6 | 233 | $this->assertSame('= ?', $usql); |
a3d5830a PS |
234 | $this->assertSame(array(true), $params); |
235 | ||
9d6d32b6 | 236 | // Correct usage passing empty array and $onemptyitems = true (equal = false, NAMED). |
a3d5830a PS |
237 | $in_values = array(); |
238 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, true); | |
9d6d32b6 | 239 | $this->assertCount(1, $params); |
a3d5830a PS |
240 | $value = reset($params); |
241 | $key = key($params); | |
9d6d32b6 | 242 | $this->assertSame('<> :'.$key, $usql); |
a3d5830a PS |
243 | $this->assertSame($value, true); |
244 | ||
9d6d32b6 | 245 | // Correct usage passing empty array and $onemptyitems = -1 (equal = true, QM). |
a3d5830a PS |
246 | $in_values = array(); |
247 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, -1); | |
9d6d32b6 | 248 | $this->assertSame('= ?', $usql); |
a3d5830a PS |
249 | $this->assertSame(array(-1), $params); |
250 | ||
9d6d32b6 | 251 | // Correct usage passing empty array and $onemptyitems = -1 (equal = false, NAMED). |
a3d5830a PS |
252 | $in_values = array(); |
253 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, -1); | |
9d6d32b6 | 254 | $this->assertCount(1, $params); |
a3d5830a PS |
255 | $value = reset($params); |
256 | $key = key($params); | |
9d6d32b6 | 257 | $this->assertSame('<> :'.$key, $usql); |
a3d5830a PS |
258 | $this->assertSame($value, -1); |
259 | ||
9d6d32b6 | 260 | // Correct usage passing empty array and $onemptyitems = 'onevalue' (equal = true, QM). |
a3d5830a PS |
261 | $in_values = array(); |
262 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_QM, 'param', true, 'onevalue'); | |
9d6d32b6 | 263 | $this->assertSame('= ?', $usql); |
a3d5830a PS |
264 | $this->assertSame(array('onevalue'), $params); |
265 | ||
9d6d32b6 | 266 | // Correct usage passing empty array and $onemptyitems = 'onevalue' (equal = false, NAMED). |
a3d5830a PS |
267 | $in_values = array(); |
268 | list($usql, $params) = $DB->get_in_or_equal($in_values, SQL_PARAMS_NAMED, 'param', false, 'onevalue'); | |
9d6d32b6 | 269 | $this->assertCount(1, $params); |
a3d5830a PS |
270 | $value = reset($params); |
271 | $key = key($params); | |
9d6d32b6 | 272 | $this->assertSame('<> :'.$key, $usql); |
a3d5830a PS |
273 | $this->assertSame($value, 'onevalue'); |
274 | } | |
275 | ||
276 | public function test_fix_table_names() { | |
277 | $DB = new moodle_database_for_testing(); | |
278 | $prefix = $DB->get_prefix(); | |
279 | ||
9d6d32b6 | 280 | // Simple placeholder. |
a3d5830a PS |
281 | $placeholder = "{user_123}"; |
282 | $this->assertSame($prefix."user_123", $DB->public_fix_table_names($placeholder)); | |
283 | ||
9d6d32b6 | 284 | // Wrong table name. |
a3d5830a PS |
285 | $placeholder = "{user-a}"; |
286 | $this->assertSame($placeholder, $DB->public_fix_table_names($placeholder)); | |
287 | ||
9d6d32b6 | 288 | // Wrong table name. |
a3d5830a PS |
289 | $placeholder = "{123user}"; |
290 | $this->assertSame($placeholder, $DB->public_fix_table_names($placeholder)); | |
291 | ||
9d6d32b6 | 292 | // Full SQL. |
a3d5830a PS |
293 | $sql = "SELECT * FROM {user}, {funny_table_name}, {mdl_stupid_table} WHERE {user}.id = {funny_table_name}.userid"; |
294 | $expected = "SELECT * FROM {$prefix}user, {$prefix}funny_table_name, {$prefix}mdl_stupid_table WHERE {$prefix}user.id = {$prefix}funny_table_name.userid"; | |
295 | $this->assertSame($expected, $DB->public_fix_table_names($sql)); | |
296 | } | |
297 | ||
9d6d32b6 | 298 | public function test_fix_sql_params() { |
a3d5830a | 299 | $DB = $this->tdb; |
c56cdae9 | 300 | $prefix = $DB->get_prefix(); |
a3d5830a PS |
301 | |
302 | $table = $this->get_test_table(); | |
303 | $tablename = $table->getName(); | |
304 | ||
9d6d32b6 | 305 | // Correct table placeholder substitution. |
a3d5830a PS |
306 | $sql = "SELECT * FROM {{$tablename}}"; |
307 | $sqlarray = $DB->fix_sql_params($sql); | |
c56cdae9 | 308 | $this->assertEquals("SELECT * FROM {$prefix}".$tablename, $sqlarray[0]); |
a3d5830a | 309 | |
9d6d32b6 | 310 | // Conversions of all param types. |
a3d5830a | 311 | $sql = array(); |
c56cdae9 PŠ |
312 | $sql[SQL_PARAMS_NAMED] = "SELECT * FROM {$prefix}testtable WHERE name = :param1, course = :param2"; |
313 | $sql[SQL_PARAMS_QM] = "SELECT * FROM {$prefix}testtable WHERE name = ?, course = ?"; | |
314 | $sql[SQL_PARAMS_DOLLAR] = "SELECT * FROM {$prefix}testtable WHERE name = \$1, course = \$2"; | |
a3d5830a PS |
315 | |
316 | $params = array(); | |
317 | $params[SQL_PARAMS_NAMED] = array('param1'=>'first record', 'param2'=>1); | |
318 | $params[SQL_PARAMS_QM] = array('first record', 1); | |
319 | $params[SQL_PARAMS_DOLLAR] = array('first record', 1); | |
320 | ||
321 | list($rsql, $rparams, $rtype) = $DB->fix_sql_params($sql[SQL_PARAMS_NAMED], $params[SQL_PARAMS_NAMED]); | |
322 | $this->assertSame($rsql, $sql[$rtype]); | |
323 | $this->assertSame($rparams, $params[$rtype]); | |
324 | ||
325 | list($rsql, $rparams, $rtype) = $DB->fix_sql_params($sql[SQL_PARAMS_QM], $params[SQL_PARAMS_QM]); | |
326 | $this->assertSame($rsql, $sql[$rtype]); | |
327 | $this->assertSame($rparams, $params[$rtype]); | |
328 | ||
329 | list($rsql, $rparams, $rtype) = $DB->fix_sql_params($sql[SQL_PARAMS_DOLLAR], $params[SQL_PARAMS_DOLLAR]); | |
330 | $this->assertSame($rsql, $sql[$rtype]); | |
331 | $this->assertSame($rparams, $params[$rtype]); | |
332 | ||
9d6d32b6 | 333 | // Malformed table placeholder. |
a3d5830a PS |
334 | $sql = "SELECT * FROM [testtable]"; |
335 | $sqlarray = $DB->fix_sql_params($sql); | |
336 | $this->assertSame($sql, $sqlarray[0]); | |
337 | ||
9d6d32b6 | 338 | // Mixed param types (colon and dollar). |
a3d5830a PS |
339 | $sql = "SELECT * FROM {{$tablename}} WHERE name = :param1, course = \$1"; |
340 | $params = array('param1' => 'record1', 'param2' => 3); | |
341 | try { | |
342 | $DB->fix_sql_params($sql, $params); | |
343 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
344 | } catch (moodle_exception $e) { |
345 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
346 | } |
347 | ||
9d6d32b6 | 348 | // Mixed param types (question and dollar). |
a3d5830a PS |
349 | $sql = "SELECT * FROM {{$tablename}} WHERE name = ?, course = \$1"; |
350 | $params = array('param1' => 'record2', 'param2' => 5); | |
351 | try { | |
352 | $DB->fix_sql_params($sql, $params); | |
353 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
354 | } catch (moodle_exception $e) { |
355 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
356 | } |
357 | ||
9d6d32b6 | 358 | // Too few params in sql. |
a3d5830a PS |
359 | $sql = "SELECT * FROM {{$tablename}} WHERE name = ?, course = ?, id = ?"; |
360 | $params = array('record2', 3); | |
361 | try { | |
362 | $DB->fix_sql_params($sql, $params); | |
363 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
364 | } catch (moodle_exception $e) { |
365 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
366 | } |
367 | ||
9d6d32b6 | 368 | // Too many params in array: no error, just use what is necessary. |
a3d5830a PS |
369 | $params[] = 1; |
370 | $params[] = time(); | |
9d6d32b6 PS |
371 | $sqlarray = $DB->fix_sql_params($sql, $params); |
372 | $this->assertInternalType('array', $sqlarray); | |
373 | $this->assertCount(3, $sqlarray[1]); | |
a3d5830a | 374 | |
9d6d32b6 | 375 | // Named params missing from array. |
a3d5830a PS |
376 | $sql = "SELECT * FROM {{$tablename}} WHERE name = :name, course = :course"; |
377 | $params = array('wrongname' => 'record1', 'course' => 1); | |
378 | try { | |
379 | $DB->fix_sql_params($sql, $params); | |
380 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
381 | } catch (moodle_exception $e) { |
382 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
383 | } |
384 | ||
385 | // Duplicate named param in query - this is a very important feature!! | |
9d6d32b6 | 386 | // it helps with debugging of sloppy code. |
a3d5830a PS |
387 | $sql = "SELECT * FROM {{$tablename}} WHERE name = :name, course = :name"; |
388 | $params = array('name' => 'record2', 'course' => 3); | |
389 | try { | |
390 | $DB->fix_sql_params($sql, $params); | |
391 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
392 | } catch (moodle_exception $e) { |
393 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
394 | } |
395 | ||
9d6d32b6 | 396 | // Extra named param is ignored. |
a3d5830a PS |
397 | $sql = "SELECT * FROM {{$tablename}} WHERE name = :name, course = :course"; |
398 | $params = array('name' => 'record1', 'course' => 1, 'extrastuff'=>'haha'); | |
9d6d32b6 PS |
399 | $sqlarray = $DB->fix_sql_params($sql, $params); |
400 | $this->assertInternalType('array', $sqlarray); | |
401 | $this->assertCount(2, $sqlarray[1]); | |
a3d5830a | 402 | |
9d6d32b6 | 403 | // Params exceeding 30 chars length. |
a3d5830a PS |
404 | $sql = "SELECT * FROM {{$tablename}} WHERE name = :long_placeholder_with_more_than_30"; |
405 | $params = array('long_placeholder_with_more_than_30' => 'record1'); | |
406 | try { | |
407 | $DB->fix_sql_params($sql, $params); | |
408 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
409 | } catch (moodle_exception $e) { |
410 | $this->assertInstanceOf('coding_exception', $e); | |
a3d5830a PS |
411 | } |
412 | ||
9d6d32b6 | 413 | // Booleans in NAMED params are casting to 1/0 int. |
a3d5830a PS |
414 | $sql = "SELECT * FROM {{$tablename}} WHERE course = ? OR course = ?"; |
415 | $params = array(true, false); | |
416 | list($sql, $params) = $DB->fix_sql_params($sql, $params); | |
417 | $this->assertTrue(reset($params) === 1); | |
418 | $this->assertTrue(next($params) === 0); | |
419 | ||
9d6d32b6 | 420 | // Booleans in QM params are casting to 1/0 int. |
a3d5830a PS |
421 | $sql = "SELECT * FROM {{$tablename}} WHERE course = :course1 OR course = :course2"; |
422 | $params = array('course1' => true, 'course2' => false); | |
423 | list($sql, $params) = $DB->fix_sql_params($sql, $params); | |
424 | $this->assertTrue(reset($params) === 1); | |
425 | $this->assertTrue(next($params) === 0); | |
426 | ||
9d6d32b6 | 427 | // Booleans in DOLLAR params are casting to 1/0 int. |
a3d5830a PS |
428 | $sql = "SELECT * FROM {{$tablename}} WHERE course = \$1 OR course = \$2"; |
429 | $params = array(true, false); | |
430 | list($sql, $params) = $DB->fix_sql_params($sql, $params); | |
431 | $this->assertTrue(reset($params) === 1); | |
432 | $this->assertTrue(next($params) === 0); | |
433 | ||
9d6d32b6 | 434 | // No data types are touched except bool. |
a3d5830a | 435 | $sql = "SELECT * FROM {{$tablename}} WHERE name IN (?,?,?,?,?,?)"; |
9d6d32b6 | 436 | $inparams = array('abc', 'ABC', null, '1', 1, 1.4); |
a3d5830a PS |
437 | list($sql, $params) = $DB->fix_sql_params($sql, $inparams); |
438 | $this->assertSame(array_values($params), array_values($inparams)); | |
439 | } | |
440 | ||
441 | public function test_strtok() { | |
9d6d32b6 | 442 | // Strtok was previously used by bound emulation, make sure it is not used any more. |
a3d5830a PS |
443 | $DB = $this->tdb; |
444 | $dbman = $this->tdb->get_manager(); | |
445 | ||
446 | $table = $this->get_test_table(); | |
447 | $tablename = $table->getName(); | |
448 | ||
9d6d32b6 PS |
449 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
450 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
451 | $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, 'lala'); |
452 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
453 | $dbman->create_table($table); | |
454 | ||
455 | $str = 'a?b?c?d'; | |
456 | $this->assertSame(strtok($str, '?'), 'a'); | |
457 | ||
458 | $DB->get_records($tablename, array('id'=>1)); | |
459 | ||
460 | $this->assertSame(strtok('?'), 'b'); | |
461 | } | |
462 | ||
463 | public function test_tweak_param_names() { | |
464 | // Note the tweak_param_names() method is only available in the oracle driver, | |
9d6d32b6 | 465 | // hence we look for expected results indirectly, by testing various DML methods. |
a3d5830a PS |
466 | // with some "extreme" conditions causing the tweak to happen. |
467 | $DB = $this->tdb; | |
468 | $dbman = $this->tdb->get_manager(); | |
469 | ||
470 | $table = $this->get_test_table(); | |
471 | $tablename = $table->getName(); | |
472 | ||
9d6d32b6 PS |
473 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
474 | // Add some columns with 28 chars in the name. | |
a3d5830a PS |
475 | $table->add_field('long_int_columnname_with_28c', XMLDB_TYPE_INTEGER, '10'); |
476 | $table->add_field('long_dec_columnname_with_28c', XMLDB_TYPE_NUMBER, '10,2'); | |
477 | $table->add_field('long_str_columnname_with_28c', XMLDB_TYPE_CHAR, '100'); | |
9d6d32b6 | 478 | // Add some columns with 30 chars in the name. |
a3d5830a PS |
479 | $table->add_field('long_int_columnname_with_30cxx', XMLDB_TYPE_INTEGER, '10'); |
480 | $table->add_field('long_dec_columnname_with_30cxx', XMLDB_TYPE_NUMBER, '10,2'); | |
481 | $table->add_field('long_str_columnname_with_30cxx', XMLDB_TYPE_CHAR, '100'); | |
482 | ||
483 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
484 | ||
485 | $dbman->create_table($table); | |
486 | ||
487 | $this->assertTrue($dbman->table_exists($tablename)); | |
488 | ||
9d6d32b6 | 489 | // Test insert record. |
a3d5830a PS |
490 | $rec1 = new stdClass(); |
491 | $rec1->long_int_columnname_with_28c = 28; | |
492 | $rec1->long_dec_columnname_with_28c = 28.28; | |
493 | $rec1->long_str_columnname_with_28c = '28'; | |
494 | $rec1->long_int_columnname_with_30cxx = 30; | |
495 | $rec1->long_dec_columnname_with_30cxx = 30.30; | |
496 | $rec1->long_str_columnname_with_30cxx = '30'; | |
497 | ||
9d6d32b6 | 498 | // Insert_record(). |
a3d5830a PS |
499 | $rec1->id = $DB->insert_record($tablename, $rec1); |
500 | $this->assertEquals($rec1, $DB->get_record($tablename, array('id' => $rec1->id))); | |
501 | ||
9d6d32b6 | 502 | // Update_record(). |
a3d5830a PS |
503 | $DB->update_record($tablename, $rec1); |
504 | $this->assertEquals($rec1, $DB->get_record($tablename, array('id' => $rec1->id))); | |
505 | ||
9d6d32b6 | 506 | // Set_field(). |
a3d5830a PS |
507 | $rec1->long_int_columnname_with_28c = 280; |
508 | $DB->set_field($tablename, 'long_int_columnname_with_28c', $rec1->long_int_columnname_with_28c, | |
509 | array('id' => $rec1->id, 'long_int_columnname_with_28c' => 28)); | |
510 | $rec1->long_dec_columnname_with_28c = 280.28; | |
511 | $DB->set_field($tablename, 'long_dec_columnname_with_28c', $rec1->long_dec_columnname_with_28c, | |
512 | array('id' => $rec1->id, 'long_dec_columnname_with_28c' => 28.28)); | |
513 | $rec1->long_str_columnname_with_28c = '280'; | |
514 | $DB->set_field($tablename, 'long_str_columnname_with_28c', $rec1->long_str_columnname_with_28c, | |
515 | array('id' => $rec1->id, 'long_str_columnname_with_28c' => '28')); | |
516 | $rec1->long_int_columnname_with_30cxx = 300; | |
517 | $DB->set_field($tablename, 'long_int_columnname_with_30cxx', $rec1->long_int_columnname_with_30cxx, | |
518 | array('id' => $rec1->id, 'long_int_columnname_with_30cxx' => 30)); | |
519 | $rec1->long_dec_columnname_with_30cxx = 300.30; | |
520 | $DB->set_field($tablename, 'long_dec_columnname_with_30cxx', $rec1->long_dec_columnname_with_30cxx, | |
521 | array('id' => $rec1->id, 'long_dec_columnname_with_30cxx' => 30.30)); | |
522 | $rec1->long_str_columnname_with_30cxx = '300'; | |
523 | $DB->set_field($tablename, 'long_str_columnname_with_30cxx', $rec1->long_str_columnname_with_30cxx, | |
524 | array('id' => $rec1->id, 'long_str_columnname_with_30cxx' => '30')); | |
525 | $this->assertEquals($rec1, $DB->get_record($tablename, array('id' => $rec1->id))); | |
526 | ||
9d6d32b6 | 527 | // Delete_records(). |
a3d5830a PS |
528 | $rec2 = $DB->get_record($tablename, array('id' => $rec1->id)); |
529 | $rec2->id = $DB->insert_record($tablename, $rec2); | |
530 | $this->assertEquals(2, $DB->count_records($tablename)); | |
531 | $DB->delete_records($tablename, (array) $rec2); | |
532 | $this->assertEquals(1, $DB->count_records($tablename)); | |
533 | ||
9d6d32b6 | 534 | // Get_recordset(). |
a3d5830a PS |
535 | $rs = $DB->get_recordset($tablename, (array) $rec1); |
536 | $iterations = 0; | |
537 | foreach ($rs as $rec2) { | |
538 | $iterations++; | |
539 | } | |
540 | $rs->close(); | |
541 | $this->assertEquals(1, $iterations); | |
542 | $this->assertEquals($rec1, $rec2); | |
543 | ||
9d6d32b6 | 544 | // Get_records(). |
a3d5830a | 545 | $recs = $DB->get_records($tablename, (array) $rec1); |
9d6d32b6 | 546 | $this->assertCount(1, $recs); |
a3d5830a PS |
547 | $this->assertEquals($rec1, reset($recs)); |
548 | ||
9d6d32b6 | 549 | // Get_fieldset_select(). |
a3d5830a PS |
550 | $select = 'id = :id AND |
551 | long_int_columnname_with_28c = :long_int_columnname_with_28c AND | |
552 | long_dec_columnname_with_28c = :long_dec_columnname_with_28c AND | |
553 | long_str_columnname_with_28c = :long_str_columnname_with_28c AND | |
554 | long_int_columnname_with_30cxx = :long_int_columnname_with_30cxx AND | |
555 | long_dec_columnname_with_30cxx = :long_dec_columnname_with_30cxx AND | |
556 | long_str_columnname_with_30cxx = :long_str_columnname_with_30cxx'; | |
557 | $fields = $DB->get_fieldset_select($tablename, 'long_int_columnname_with_28c', $select, (array)$rec1); | |
9d6d32b6 | 558 | $this->assertCount(1, $fields); |
a3d5830a PS |
559 | $this->assertEquals($rec1->long_int_columnname_with_28c, reset($fields)); |
560 | $fields = $DB->get_fieldset_select($tablename, 'long_dec_columnname_with_28c', $select, (array)$rec1); | |
561 | $this->assertEquals($rec1->long_dec_columnname_with_28c, reset($fields)); | |
562 | $fields = $DB->get_fieldset_select($tablename, 'long_str_columnname_with_28c', $select, (array)$rec1); | |
563 | $this->assertEquals($rec1->long_str_columnname_with_28c, reset($fields)); | |
564 | $fields = $DB->get_fieldset_select($tablename, 'long_int_columnname_with_30cxx', $select, (array)$rec1); | |
565 | $this->assertEquals($rec1->long_int_columnname_with_30cxx, reset($fields)); | |
566 | $fields = $DB->get_fieldset_select($tablename, 'long_dec_columnname_with_30cxx', $select, (array)$rec1); | |
567 | $this->assertEquals($rec1->long_dec_columnname_with_30cxx, reset($fields)); | |
568 | $fields = $DB->get_fieldset_select($tablename, 'long_str_columnname_with_30cxx', $select, (array)$rec1); | |
569 | $this->assertEquals($rec1->long_str_columnname_with_30cxx, reset($fields)); | |
570 | ||
9d6d32b6 | 571 | // Overlapping placeholders (progressive str_replace). |
a3d5830a PS |
572 | $overlapselect = 'id = :p AND |
573 | long_int_columnname_with_28c = :param1 AND | |
574 | long_dec_columnname_with_28c = :param2 AND | |
575 | long_str_columnname_with_28c = :param_with_29_characters_long AND | |
576 | long_int_columnname_with_30cxx = :param_with_30_characters_long_ AND | |
577 | long_dec_columnname_with_30cxx = :param_ AND | |
578 | long_str_columnname_with_30cxx = :param__'; | |
579 | $overlapparams = array( | |
580 | 'p' => $rec1->id, | |
581 | 'param1' => $rec1->long_int_columnname_with_28c, | |
582 | 'param2' => $rec1->long_dec_columnname_with_28c, | |
583 | 'param_with_29_characters_long' => $rec1->long_str_columnname_with_28c, | |
584 | 'param_with_30_characters_long_' => $rec1->long_int_columnname_with_30cxx, | |
585 | 'param_' => $rec1->long_dec_columnname_with_30cxx, | |
586 | 'param__' => $rec1->long_str_columnname_with_30cxx); | |
587 | $recs = $DB->get_records_select($tablename, $overlapselect, $overlapparams); | |
9d6d32b6 | 588 | $this->assertCount(1, $recs); |
a3d5830a PS |
589 | $this->assertEquals($rec1, reset($recs)); |
590 | ||
9d6d32b6 | 591 | // Execute(). |
a3d5830a PS |
592 | $DB->execute("DELETE FROM {{$tablename}} WHERE $select", (array)$rec1); |
593 | $this->assertEquals(0, $DB->count_records($tablename)); | |
594 | } | |
595 | ||
596 | public function test_get_tables() { | |
597 | $DB = $this->tdb; | |
598 | $dbman = $this->tdb->get_manager(); | |
599 | ||
9d6d32b6 | 600 | // Need to test with multiple DBs. |
a3d5830a PS |
601 | $table = $this->get_test_table(); |
602 | $tablename = $table->getName(); | |
603 | ||
604 | $original_count = count($DB->get_tables()); | |
605 | ||
9d6d32b6 | 606 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
a3d5830a PS |
607 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
608 | ||
609 | $dbman->create_table($table); | |
610 | $this->assertTrue(count($DB->get_tables()) == $original_count + 1); | |
611 | ||
612 | $dbman->drop_table($table); | |
613 | $this->assertTrue(count($DB->get_tables()) == $original_count); | |
614 | } | |
615 | ||
616 | public function test_get_indexes() { | |
617 | $DB = $this->tdb; | |
618 | $dbman = $this->tdb->get_manager(); | |
619 | ||
620 | $table = $this->get_test_table(); | |
621 | $tablename = $table->getName(); | |
622 | ||
9d6d32b6 PS |
623 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
624 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
625 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
626 | $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course')); | |
627 | $table->add_index('course-id', XMLDB_INDEX_UNIQUE, array('course', 'id')); | |
628 | $dbman->create_table($table); | |
629 | ||
630 | $indices = $DB->get_indexes($tablename); | |
9d6d32b6 PS |
631 | $this->assertInternalType('array', $indices); |
632 | $this->assertCount(2, $indices); | |
633 | // We do not care about index names for now. | |
a3d5830a PS |
634 | $first = array_shift($indices); |
635 | $second = array_shift($indices); | |
636 | if (count($first['columns']) == 2) { | |
637 | $composed = $first; | |
638 | $single = $second; | |
639 | } else { | |
640 | $composed = $second; | |
641 | $single = $first; | |
642 | } | |
643 | $this->assertFalse($single['unique']); | |
644 | $this->assertTrue($composed['unique']); | |
9d6d32b6 PS |
645 | $this->assertCount(1, $single['columns']); |
646 | $this->assertCount(2, $composed['columns']); | |
647 | $this->assertSame('course', $single['columns'][0]); | |
648 | $this->assertSame('course', $composed['columns'][0]); | |
649 | $this->assertSame('id', $composed['columns'][1]); | |
a3d5830a PS |
650 | } |
651 | ||
652 | public function test_get_columns() { | |
653 | $DB = $this->tdb; | |
654 | $dbman = $this->tdb->get_manager(); | |
655 | ||
656 | $table = $this->get_test_table(); | |
657 | $tablename = $table->getName(); | |
658 | ||
9d6d32b6 PS |
659 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
660 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
661 | $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, 'lala'); |
662 | $table->add_field('description', XMLDB_TYPE_TEXT, 'small', null, null, null, null); | |
663 | $table->add_field('enumfield', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, 'test2'); | |
664 | $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200); | |
665 | $table->add_field('onefloat', XMLDB_TYPE_FLOAT, '10,2', null, null, null, 300); | |
666 | $table->add_field('anotherfloat', XMLDB_TYPE_FLOAT, null, null, null, null, 400); | |
667 | $table->add_field('negativedfltint', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '-1'); | |
668 | $table->add_field('negativedfltnumber', XMLDB_TYPE_NUMBER, '10', null, XMLDB_NOTNULL, null, '-2'); | |
669 | $table->add_field('negativedfltfloat', XMLDB_TYPE_FLOAT, '10', null, XMLDB_NOTNULL, null, '-3'); | |
bc5a5527 PS |
670 | $table->add_field('someint1', XMLDB_TYPE_INTEGER, '1', null, null, null, '0'); |
671 | $table->add_field('someint2', XMLDB_TYPE_INTEGER, '2', null, null, null, '0'); | |
672 | $table->add_field('someint3', XMLDB_TYPE_INTEGER, '3', null, null, null, '0'); | |
673 | $table->add_field('someint4', XMLDB_TYPE_INTEGER, '4', null, null, null, '0'); | |
674 | $table->add_field('someint5', XMLDB_TYPE_INTEGER, '5', null, null, null, '0'); | |
675 | $table->add_field('someint6', XMLDB_TYPE_INTEGER, '6', null, null, null, '0'); | |
676 | $table->add_field('someint7', XMLDB_TYPE_INTEGER, '7', null, null, null, '0'); | |
677 | $table->add_field('someint8', XMLDB_TYPE_INTEGER, '8', null, null, null, '0'); | |
678 | $table->add_field('someint9', XMLDB_TYPE_INTEGER, '9', null, null, null, '0'); | |
679 | $table->add_field('someint10', XMLDB_TYPE_INTEGER, '10', null, null, null, '0'); | |
680 | $table->add_field('someint18', XMLDB_TYPE_INTEGER, '18', null, null, null, '0'); | |
a3d5830a PS |
681 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
682 | $dbman->create_table($table); | |
683 | ||
684 | $columns = $DB->get_columns($tablename); | |
9d6d32b6 | 685 | $this->assertInternalType('array', $columns); |
a3d5830a PS |
686 | |
687 | $fields = $table->getFields(); | |
9d6d32b6 | 688 | $this->assertCount(count($columns), $fields); |
a3d5830a PS |
689 | |
690 | $field = $columns['id']; | |
9d6d32b6 | 691 | $this->assertSame('R', $field->meta_type); |
a3d5830a PS |
692 | $this->assertTrue($field->auto_increment); |
693 | $this->assertTrue($field->unique); | |
694 | ||
695 | $field = $columns['course']; | |
9d6d32b6 | 696 | $this->assertSame('I', $field->meta_type); |
a3d5830a PS |
697 | $this->assertFalse($field->auto_increment); |
698 | $this->assertTrue($field->has_default); | |
699 | $this->assertEquals(0, $field->default_value); | |
700 | $this->assertTrue($field->not_null); | |
701 | ||
9d6d32b6 | 702 | for ($i=1; $i<=10; $i++) { |
bc5a5527 | 703 | $field = $columns['someint'.$i]; |
9d6d32b6 | 704 | $this->assertSame('I', $field->meta_type); |
bc5a5527 PS |
705 | $this->assertGreaterThanOrEqual($i, $field->max_length); |
706 | } | |
707 | $field = $columns['someint18']; | |
9d6d32b6 | 708 | $this->assertSame('I', $field->meta_type); |
bc5a5527 PS |
709 | $this->assertGreaterThanOrEqual(18, $field->max_length); |
710 | ||
a3d5830a | 711 | $field = $columns['name']; |
9d6d32b6 | 712 | $this->assertSame('C', $field->meta_type); |
a3d5830a PS |
713 | $this->assertFalse($field->auto_increment); |
714 | $this->assertEquals(255, $field->max_length); | |
715 | $this->assertTrue($field->has_default); | |
716 | $this->assertSame('lala', $field->default_value); | |
717 | $this->assertFalse($field->not_null); | |
718 | ||
719 | $field = $columns['description']; | |
9d6d32b6 | 720 | $this->assertSame('X', $field->meta_type); |
a3d5830a PS |
721 | $this->assertFalse($field->auto_increment); |
722 | $this->assertFalse($field->has_default); | |
9d6d32b6 | 723 | $this->assertNull($field->default_value); |
a3d5830a PS |
724 | $this->assertFalse($field->not_null); |
725 | ||
726 | $field = $columns['enumfield']; | |
9d6d32b6 | 727 | $this->assertSame('C', $field->meta_type); |
a3d5830a PS |
728 | $this->assertFalse($field->auto_increment); |
729 | $this->assertSame('test2', $field->default_value); | |
730 | $this->assertTrue($field->not_null); | |
731 | ||
732 | $field = $columns['onenum']; | |
9d6d32b6 | 733 | $this->assertSame('N', $field->meta_type); |
a3d5830a PS |
734 | $this->assertFalse($field->auto_increment); |
735 | $this->assertEquals(10, $field->max_length); | |
736 | $this->assertEquals(2, $field->scale); | |
737 | $this->assertTrue($field->has_default); | |
738 | $this->assertEquals(200.0, $field->default_value); | |
739 | $this->assertFalse($field->not_null); | |
740 | ||
741 | $field = $columns['onefloat']; | |
9d6d32b6 | 742 | $this->assertSame('N', $field->meta_type); |
a3d5830a PS |
743 | $this->assertFalse($field->auto_increment); |
744 | $this->assertTrue($field->has_default); | |
745 | $this->assertEquals(300.0, $field->default_value); | |
746 | $this->assertFalse($field->not_null); | |
747 | ||
748 | $field = $columns['anotherfloat']; | |
9d6d32b6 | 749 | $this->assertSame('N', $field->meta_type); |
a3d5830a PS |
750 | $this->assertFalse($field->auto_increment); |
751 | $this->assertTrue($field->has_default); | |
752 | $this->assertEquals(400.0, $field->default_value); | |
753 | $this->assertFalse($field->not_null); | |
754 | ||
9d6d32b6 | 755 | // Test negative defaults in numerical columns. |
a3d5830a PS |
756 | $field = $columns['negativedfltint']; |
757 | $this->assertTrue($field->has_default); | |
758 | $this->assertEquals(-1, $field->default_value); | |
759 | ||
760 | $field = $columns['negativedfltnumber']; | |
761 | $this->assertTrue($field->has_default); | |
762 | $this->assertEquals(-2, $field->default_value); | |
763 | ||
764 | $field = $columns['negativedfltfloat']; | |
765 | $this->assertTrue($field->has_default); | |
766 | $this->assertEquals(-3, $field->default_value); | |
767 | ||
768 | for ($i = 0; $i < count($columns); $i++) { | |
769 | if ($i == 0) { | |
770 | $next_column = reset($columns); | |
771 | $next_field = reset($fields); | |
772 | } else { | |
773 | $next_column = next($columns); | |
774 | $next_field = next($fields); | |
775 | } | |
776 | ||
94417438 | 777 | $this->assertEquals($next_column->name, $next_field->getName()); |
a3d5830a PS |
778 | } |
779 | ||
9d6d32b6 | 780 | // Test get_columns for non-existing table returns empty array. MDL-30147. |
a3d5830a PS |
781 | $columns = $DB->get_columns('xxxx'); |
782 | $this->assertEquals(array(), $columns); | |
4bf85577 | 783 | |
9d6d32b6 | 784 | // Create something similar to "context_temp" with id column without sequence. |
4bf85577 PS |
785 | $dbman->drop_table($table); |
786 | $table = $this->get_test_table(); | |
787 | $tablename = $table->getName(); | |
9d6d32b6 PS |
788 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); |
789 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
4bf85577 PS |
790 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
791 | $dbman->create_table($table); | |
792 | ||
793 | $columns = $DB->get_columns($tablename); | |
794 | $this->assertFalse($columns['id']->auto_increment); | |
a3d5830a PS |
795 | } |
796 | ||
797 | public function test_get_manager() { | |
798 | $DB = $this->tdb; | |
799 | $dbman = $this->tdb->get_manager(); | |
800 | ||
9d6d32b6 | 801 | $this->assertInstanceOf('database_manager', $dbman); |
a3d5830a PS |
802 | } |
803 | ||
804 | public function test_setup_is_unicodedb() { | |
805 | $DB = $this->tdb; | |
806 | $this->assertTrue($DB->setup_is_unicodedb()); | |
807 | } | |
808 | ||
9d6d32b6 | 809 | public function test_set_debug() { // Tests get_debug() too. |
a3d5830a PS |
810 | $DB = $this->tdb; |
811 | $dbman = $this->tdb->get_manager(); | |
812 | ||
813 | $table = $this->get_test_table(); | |
814 | $tablename = $table->getName(); | |
815 | ||
9d6d32b6 PS |
816 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
817 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
818 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
819 | $dbman->create_table($table); | |
820 | ||
821 | $sql = "SELECT * FROM {{$tablename}}"; | |
822 | ||
823 | $prevdebug = $DB->get_debug(); | |
824 | ||
825 | ob_start(); | |
826 | $DB->set_debug(true); | |
827 | $this->assertTrue($DB->get_debug()); | |
828 | $DB->execute($sql); | |
829 | $DB->set_debug(false); | |
830 | $this->assertFalse($DB->get_debug()); | |
831 | $debuginfo = ob_get_contents(); | |
832 | ob_end_clean(); | |
833 | $this->assertFalse($debuginfo === ''); | |
834 | ||
835 | ob_start(); | |
836 | $DB->execute($sql); | |
837 | $debuginfo = ob_get_contents(); | |
838 | ob_end_clean(); | |
839 | $this->assertTrue($debuginfo === ''); | |
840 | ||
841 | $DB->set_debug($prevdebug); | |
842 | } | |
843 | ||
844 | public function test_execute() { | |
845 | $DB = $this->tdb; | |
846 | $dbman = $this->tdb->get_manager(); | |
847 | ||
848 | $table1 = $this->get_test_table('1'); | |
849 | $tablename1 = $table1->getName(); | |
9d6d32b6 PS |
850 | $table1->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
851 | $table1->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
852 | $table1->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, '0'); |
853 | $table1->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course')); | |
854 | $table1->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
855 | $dbman->create_table($table1); | |
856 | ||
857 | $table2 = $this->get_test_table('2'); | |
858 | $tablename2 = $table2->getName(); | |
9d6d32b6 PS |
859 | $table2->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
860 | $table2->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
861 | $table2->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
862 | $dbman->create_table($table2); | |
863 | ||
864 | $DB->insert_record($tablename1, array('course' => 3, 'name' => 'aaa')); | |
865 | $DB->insert_record($tablename1, array('course' => 1, 'name' => 'bbb')); | |
866 | $DB->insert_record($tablename1, array('course' => 7, 'name' => 'ccc')); | |
867 | $DB->insert_record($tablename1, array('course' => 3, 'name' => 'ddd')); | |
868 | ||
9d6d32b6 | 869 | // Select results are ignored. |
a3d5830a PS |
870 | $sql = "SELECT * FROM {{$tablename1}} WHERE course = :course"; |
871 | $this->assertTrue($DB->execute($sql, array('course'=>3))); | |
872 | ||
9d6d32b6 | 873 | // Throw exception on error. |
a3d5830a PS |
874 | $sql = "XXUPDATE SET XSSD"; |
875 | try { | |
876 | $DB->execute($sql); | |
877 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
878 | } catch (moodle_exception $e) { |
879 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
880 | } |
881 | ||
9d6d32b6 | 882 | // Update records. |
a3d5830a PS |
883 | $sql = "UPDATE {{$tablename1}} |
884 | SET course = 6 | |
885 | WHERE course = ?"; | |
886 | $this->assertTrue($DB->execute($sql, array('3'))); | |
9d6d32b6 | 887 | $this->assertEquals(2, $DB->count_records($tablename1, array('course' => 6))); |
a3d5830a | 888 | |
9d6d32b6 PS |
889 | // Update records with subquery condition. |
890 | // Confirm that the option not using table aliases is cross-db. | |
a3d5830a PS |
891 | $sql = "UPDATE {{$tablename1}} |
892 | SET course = 0 | |
893 | WHERE NOT EXISTS ( | |
894 | SELECT course | |
895 | FROM {{$tablename2}} tbl2 | |
896 | WHERE tbl2.course = {{$tablename1}}.course | |
9d6d32b6 | 897 | AND 1 = 0)"; // Really we don't update anything, but verify the syntax is allowed. |
a3d5830a PS |
898 | $this->assertTrue($DB->execute($sql)); |
899 | ||
9d6d32b6 | 900 | // Insert from one into second table. |
a3d5830a PS |
901 | $sql = "INSERT INTO {{$tablename2}} (course) |
902 | ||
903 | SELECT course | |
904 | FROM {{$tablename1}}"; | |
905 | $this->assertTrue($DB->execute($sql)); | |
9d6d32b6 | 906 | $this->assertEquals(4, $DB->count_records($tablename2)); |
a3d5830a PS |
907 | } |
908 | ||
909 | public function test_get_recordset() { | |
910 | $DB = $this->tdb; | |
911 | $dbman = $DB->get_manager(); | |
912 | ||
913 | $table = $this->get_test_table(); | |
914 | $tablename = $table->getName(); | |
915 | ||
9d6d32b6 PS |
916 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
917 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
918 | $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, '0'); |
919 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); | |
920 | $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course')); | |
921 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
922 | $dbman->create_table($table); | |
923 | ||
401793a3 PŠ |
924 | $data = array(array('course' => 3, 'name' => 'record1', 'onetext'=>'abc'), |
925 | array('course' => 3, 'name' => 'record2', 'onetext'=>'abcd'), | |
926 | array('course' => 5, 'name' => 'record3', 'onetext'=>'abcde')); | |
a3d5830a | 927 | |
9d6d32b6 | 928 | foreach ($data as $key => $record) { |
401793a3 | 929 | $data[$key]['id'] = $DB->insert_record($tablename, $record); |
a3d5830a PS |
930 | } |
931 | ||
9d6d32b6 | 932 | // Standard recordset iteration. |
a3d5830a | 933 | $rs = $DB->get_recordset($tablename); |
9d6d32b6 | 934 | $this->assertInstanceOf('moodle_recordset', $rs); |
a3d5830a | 935 | reset($data); |
9d6d32b6 | 936 | foreach ($rs as $record) { |
a3d5830a PS |
937 | $data_record = current($data); |
938 | foreach ($record as $k => $v) { | |
939 | $this->assertEquals($data_record[$k], $v); | |
940 | } | |
941 | next($data); | |
942 | } | |
943 | $rs->close(); | |
944 | ||
9d6d32b6 | 945 | // Iterator style usage. |
a3d5830a | 946 | $rs = $DB->get_recordset($tablename); |
9d6d32b6 | 947 | $this->assertInstanceOf('moodle_recordset', $rs); |
a3d5830a PS |
948 | reset($data); |
949 | while ($rs->valid()) { | |
950 | $record = $rs->current(); | |
951 | $data_record = current($data); | |
952 | foreach ($record as $k => $v) { | |
953 | $this->assertEquals($data_record[$k], $v); | |
954 | } | |
955 | next($data); | |
956 | $rs->next(); | |
957 | } | |
958 | $rs->close(); | |
959 | ||
9d6d32b6 | 960 | // Make sure rewind is ignored. |
a3d5830a | 961 | $rs = $DB->get_recordset($tablename); |
9d6d32b6 | 962 | $this->assertInstanceOf('moodle_recordset', $rs); |
a3d5830a PS |
963 | reset($data); |
964 | $i = 0; | |
9d6d32b6 | 965 | foreach ($rs as $record) { |
a3d5830a PS |
966 | $i++; |
967 | $rs->rewind(); | |
968 | if ($i > 10) { | |
969 | $this->fail('revind not ignored in recordsets'); | |
970 | break; | |
971 | } | |
972 | $data_record = current($data); | |
973 | foreach ($record as $k => $v) { | |
974 | $this->assertEquals($data_record[$k], $v); | |
975 | } | |
976 | next($data); | |
977 | } | |
978 | $rs->close(); | |
979 | ||
9d6d32b6 | 980 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
981 | $conditions = array('onetext' => '1'); |
982 | try { | |
983 | $rs = $DB->get_recordset($tablename, $conditions); | |
eb10d554 | 984 | $this->fail('An Exception is missing, expected due to equating of text fields'); |
9d6d32b6 PS |
985 | } catch (moodle_exception $e) { |
986 | $this->assertInstanceOf('dml_exception', $e); | |
987 | $this->assertSame('textconditionsnotallowed', $e->errorcode); | |
a3d5830a PS |
988 | } |
989 | ||
541ca062 PŠ |
990 | // Test nested iteration. |
991 | $rs1 = $DB->get_recordset($tablename); | |
992 | $i = 0; | |
9d6d32b6 | 993 | foreach ($rs1 as $record1) { |
541ca062 PŠ |
994 | $rs2 = $DB->get_recordset($tablename); |
995 | $i++; | |
996 | $j = 0; | |
9d6d32b6 | 997 | foreach ($rs2 as $record2) { |
541ca062 PŠ |
998 | $j++; |
999 | } | |
1000 | $rs2->close(); | |
9d6d32b6 | 1001 | $this->assertCount($j, $data); |
541ca062 PŠ |
1002 | } |
1003 | $rs1->close(); | |
9d6d32b6 | 1004 | $this->assertCount($i, $data); |
541ca062 | 1005 | |
9d6d32b6 | 1006 | // Notes: |
a3d5830a PS |
1007 | // * limits are tested in test_get_recordset_sql() |
1008 | // * where_clause() is used internally and is tested in test_get_records() | |
1009 | } | |
1010 | ||
3b5f6e6c PŠ |
1011 | public function test_get_recordset_static() { |
1012 | $DB = $this->tdb; | |
1013 | $dbman = $DB->get_manager(); | |
1014 | ||
1015 | $table = $this->get_test_table(); | |
1016 | $tablename = $table->getName(); | |
1017 | ||
9d6d32b6 PS |
1018 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1019 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
3b5f6e6c PŠ |
1020 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1021 | $dbman->create_table($table); | |
1022 | ||
1023 | $DB->insert_record($tablename, array('course' => 1)); | |
1024 | $DB->insert_record($tablename, array('course' => 2)); | |
1025 | $DB->insert_record($tablename, array('course' => 3)); | |
1026 | $DB->insert_record($tablename, array('course' => 4)); | |
1027 | ||
1028 | $rs = $DB->get_recordset($tablename, array(), 'id'); | |
1029 | ||
1030 | $DB->set_field($tablename, 'course', 666, array('course'=>1)); | |
1031 | $DB->delete_records($tablename, array('course'=>2)); | |
1032 | ||
1033 | $i = 0; | |
9d6d32b6 | 1034 | foreach ($rs as $record) { |
3b5f6e6c PŠ |
1035 | $i++; |
1036 | $this->assertEquals($i, $record->course); | |
1037 | } | |
1038 | $rs->close(); | |
1039 | $this->assertEquals(4, $i); | |
1040 | ||
1041 | // Now repeat with limits because it may use different code. | |
1042 | $DB->delete_records($tablename, array()); | |
1043 | ||
1044 | $DB->insert_record($tablename, array('course' => 1)); | |
1045 | $DB->insert_record($tablename, array('course' => 2)); | |
1046 | $DB->insert_record($tablename, array('course' => 3)); | |
1047 | $DB->insert_record($tablename, array('course' => 4)); | |
1048 | ||
1049 | $rs = $DB->get_recordset($tablename, array(), 'id', '*', 0, 3); | |
1050 | ||
1051 | $DB->set_field($tablename, 'course', 666, array('course'=>1)); | |
1052 | $DB->delete_records($tablename, array('course'=>2)); | |
1053 | ||
1054 | $i = 0; | |
9d6d32b6 | 1055 | foreach ($rs as $record) { |
3b5f6e6c PŠ |
1056 | $i++; |
1057 | $this->assertEquals($i, $record->course); | |
1058 | } | |
1059 | $rs->close(); | |
1060 | $this->assertEquals(3, $i); | |
1061 | } | |
1062 | ||
a3d5830a PS |
1063 | public function test_get_recordset_iterator_keys() { |
1064 | $DB = $this->tdb; | |
1065 | $dbman = $DB->get_manager(); | |
1066 | ||
1067 | $table = $this->get_test_table(); | |
1068 | $tablename = $table->getName(); | |
1069 | ||
9d6d32b6 PS |
1070 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1071 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1072 | $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null, '0'); |
1073 | $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course')); | |
1074 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1075 | $dbman->create_table($table); | |
1076 | ||
401793a3 PŠ |
1077 | $data = array(array('course' => 3, 'name' => 'record1'), |
1078 | array('course' => 3, 'name' => 'record2'), | |
1079 | array('course' => 5, 'name' => 'record3')); | |
9d6d32b6 | 1080 | foreach ($data as $key => $record) { |
401793a3 | 1081 | $data[$key]['id'] = $DB->insert_record($tablename, $record); |
a3d5830a PS |
1082 | } |
1083 | ||
9d6d32b6 PS |
1084 | // Test repeated numeric keys are returned ok. |
1085 | $rs = $DB->get_recordset($tablename, null, null, 'course, name, id'); | |
a3d5830a PS |
1086 | |
1087 | reset($data); | |
1088 | $count = 0; | |
9d6d32b6 | 1089 | foreach ($rs as $key => $record) { |
a3d5830a PS |
1090 | $data_record = current($data); |
1091 | $this->assertEquals($data_record['course'], $key); | |
1092 | next($data); | |
1093 | $count++; | |
1094 | } | |
1095 | $rs->close(); | |
9d6d32b6 | 1096 | $this->assertEquals(3, $count); |
a3d5830a | 1097 | |
9d6d32b6 PS |
1098 | // Test string keys are returned ok. |
1099 | $rs = $DB->get_recordset($tablename, null, null, 'name, course, id'); | |
a3d5830a PS |
1100 | |
1101 | reset($data); | |
1102 | $count = 0; | |
9d6d32b6 | 1103 | foreach ($rs as $key => $record) { |
a3d5830a PS |
1104 | $data_record = current($data); |
1105 | $this->assertEquals($data_record['name'], $key); | |
1106 | next($data); | |
1107 | $count++; | |
1108 | } | |
1109 | $rs->close(); | |
9d6d32b6 | 1110 | $this->assertEquals(3, $count); |
a3d5830a | 1111 | |
9d6d32b6 PS |
1112 | // Test numeric not starting in 1 keys are returned ok. |
1113 | $rs = $DB->get_recordset($tablename, null, 'id DESC', 'id, course, name'); | |
a3d5830a PS |
1114 | |
1115 | $data = array_reverse($data); | |
1116 | reset($data); | |
1117 | $count = 0; | |
9d6d32b6 | 1118 | foreach ($rs as $key => $record) { |
a3d5830a PS |
1119 | $data_record = current($data); |
1120 | $this->assertEquals($data_record['id'], $key); | |
1121 | next($data); | |
1122 | $count++; | |
1123 | } | |
1124 | $rs->close(); | |
9d6d32b6 | 1125 | $this->assertEquals(3, $count); |
a3d5830a PS |
1126 | } |
1127 | ||
1128 | public function test_get_recordset_list() { | |
1129 | $DB = $this->tdb; | |
1130 | $dbman = $DB->get_manager(); | |
1131 | ||
1132 | $table = $this->get_test_table(); | |
1133 | $tablename = $table->getName(); | |
1134 | ||
9d6d32b6 PS |
1135 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1136 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, null, null, '0'); | |
a3d5830a PS |
1137 | $table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course')); |
1138 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1139 | $dbman->create_table($table); | |
1140 | ||
1141 | $DB->insert_record($tablename, array('course' => 3)); | |
1142 | $DB->insert_record($tablename, array('course' => 3)); | |
1143 | $DB->insert_record($tablename, array('course' => 5)); | |
1144 | $DB->insert_record($tablename, array('course' => 2)); | |
7f22fb4d PŠ |
1145 | $DB->insert_record($tablename, array('course' => null)); |
1146 | $DB->insert_record($tablename, array('course' => 1)); | |
1147 | $DB->insert_record($tablename, array('course' => 0)); | |
a3d5830a PS |
1148 | |
1149 | $rs = $DB->get_recordset_list($tablename, 'course', array(3, 2)); | |
a3d5830a PS |
1150 | $counter = 0; |
1151 | foreach ($rs as $record) { | |
1152 | $counter++; | |
1153 | } | |
1154 | $this->assertEquals(3, $counter); | |
1155 | $rs->close(); | |
1156 | ||
7f22fb4d PŠ |
1157 | $rs = $DB->get_recordset_list($tablename, 'course', array(3)); |
1158 | $counter = 0; | |
1159 | foreach ($rs as $record) { | |
1160 | $counter++; | |
1161 | } | |
1162 | $this->assertEquals(2, $counter); | |
1163 | $rs->close(); | |
1164 | ||
1165 | $rs = $DB->get_recordset_list($tablename, 'course', array(null)); | |
1166 | $counter = 0; | |
1167 | foreach ($rs as $record) { | |
1168 | $counter++; | |
1169 | } | |
1170 | $this->assertEquals(1, $counter); | |
1171 | $rs->close(); | |
1172 | ||
1173 | $rs = $DB->get_recordset_list($tablename, 'course', array(6, null)); | |
1174 | $counter = 0; | |
1175 | foreach ($rs as $record) { | |
1176 | $counter++; | |
1177 | } | |
1178 | $this->assertEquals(1, $counter); | |
1179 | $rs->close(); | |
1180 | ||
1181 | $rs = $DB->get_recordset_list($tablename, 'course', array(null, 5, 5, 5)); | |
1182 | $counter = 0; | |
1183 | foreach ($rs as $record) { | |
1184 | $counter++; | |
1185 | } | |
1186 | $this->assertEquals(2, $counter); | |
1187 | $rs->close(); | |
1188 | ||
1189 | $rs = $DB->get_recordset_list($tablename, 'course', array(true)); | |
1190 | $counter = 0; | |
1191 | foreach ($rs as $record) { | |
1192 | $counter++; | |
1193 | } | |
1194 | $this->assertEquals(1, $counter); | |
1195 | $rs->close(); | |
1196 | ||
1197 | $rs = $DB->get_recordset_list($tablename, 'course', array(false)); | |
1198 | $counter = 0; | |
1199 | foreach ($rs as $record) { | |
1200 | $counter++; | |
1201 | } | |
1202 | $this->assertEquals(1, $counter); | |
1203 | $rs->close(); | |
1204 | ||
9d6d32b6 | 1205 | $rs = $DB->get_recordset_list($tablename, 'course', array()); // Must return 0 rows without conditions. MDL-17645. |
a3d5830a PS |
1206 | |
1207 | $counter = 0; | |
1208 | foreach ($rs as $record) { | |
1209 | $counter++; | |
1210 | } | |
1211 | $rs->close(); | |
1212 | $this->assertEquals(0, $counter); | |
1213 | ||
9d6d32b6 | 1214 | // Notes: |
a3d5830a PS |
1215 | // * limits are tested in test_get_recordset_sql() |
1216 | // * where_clause() is used internally and is tested in test_get_records() | |
1217 | } | |
1218 | ||
1219 | public function test_get_recordset_select() { | |
1220 | $DB = $this->tdb; | |
1221 | $dbman = $DB->get_manager(); | |
1222 | ||
1223 | $table = $this->get_test_table(); | |
1224 | $tablename = $table->getName(); | |
1225 | ||
9d6d32b6 PS |
1226 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1227 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1228 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1229 | $dbman->create_table($table); | |
1230 | ||
1231 | $DB->insert_record($tablename, array('course' => 3)); | |
1232 | $DB->insert_record($tablename, array('course' => 3)); | |
1233 | $DB->insert_record($tablename, array('course' => 5)); | |
1234 | $DB->insert_record($tablename, array('course' => 2)); | |
1235 | ||
1236 | $rs = $DB->get_recordset_select($tablename, ''); | |
1237 | $counter = 0; | |
1238 | foreach ($rs as $record) { | |
1239 | $counter++; | |
1240 | } | |
1241 | $rs->close(); | |
1242 | $this->assertEquals(4, $counter); | |
1243 | ||
1244 | $this->assertNotEmpty($rs = $DB->get_recordset_select($tablename, 'course = 3')); | |
1245 | $counter = 0; | |
1246 | foreach ($rs as $record) { | |
1247 | $counter++; | |
1248 | } | |
1249 | $rs->close(); | |
1250 | $this->assertEquals(2, $counter); | |
1251 | ||
9d6d32b6 | 1252 | // Notes: |
a3d5830a PS |
1253 | // * limits are tested in test_get_recordset_sql() |
1254 | } | |
1255 | ||
1256 | public function test_get_recordset_sql() { | |
1257 | $DB = $this->tdb; | |
1258 | $dbman = $DB->get_manager(); | |
1259 | ||
1260 | $table = $this->get_test_table(); | |
1261 | $tablename = $table->getName(); | |
1262 | ||
9d6d32b6 PS |
1263 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1264 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1265 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1266 | $dbman->create_table($table); | |
1267 | ||
1268 | $inskey1 = $DB->insert_record($tablename, array('course' => 3)); | |
1269 | $inskey2 = $DB->insert_record($tablename, array('course' => 5)); | |
1270 | $inskey3 = $DB->insert_record($tablename, array('course' => 4)); | |
1271 | $inskey4 = $DB->insert_record($tablename, array('course' => 3)); | |
1272 | $inskey5 = $DB->insert_record($tablename, array('course' => 2)); | |
1273 | $inskey6 = $DB->insert_record($tablename, array('course' => 1)); | |
1274 | $inskey7 = $DB->insert_record($tablename, array('course' => 0)); | |
1275 | ||
1276 | $rs = $DB->get_recordset_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3)); | |
1277 | $counter = 0; | |
1278 | foreach ($rs as $record) { | |
1279 | $counter++; | |
1280 | } | |
1281 | $rs->close(); | |
1282 | $this->assertEquals(2, $counter); | |
1283 | ||
9d6d32b6 PS |
1284 | // Limits - only need to test this case, the rest have been tested by test_get_records_sql() |
1285 | // only limitfrom = skips that number of records. | |
a3d5830a PS |
1286 | $rs = $DB->get_recordset_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 2, 0); |
1287 | $records = array(); | |
9d6d32b6 | 1288 | foreach ($rs as $key => $record) { |
a3d5830a PS |
1289 | $records[$key] = $record; |
1290 | } | |
1291 | $rs->close(); | |
9d6d32b6 | 1292 | $this->assertCount(5, $records); |
a3d5830a PS |
1293 | $this->assertEquals($inskey3, reset($records)->id); |
1294 | $this->assertEquals($inskey7, end($records)->id); | |
1295 | ||
9d6d32b6 | 1296 | // Note: fetching nulls, empties, LOBs already tested by test_insert_record() no needed here. |
a3d5830a PS |
1297 | } |
1298 | ||
cabc4112 PS |
1299 | public function test_export_table_recordset() { |
1300 | $DB = $this->tdb; | |
1301 | $dbman = $DB->get_manager(); | |
1302 | ||
1303 | $table = $this->get_test_table(); | |
1304 | $tablename = $table->getName(); | |
1305 | ||
1306 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); | |
1307 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
1308 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1309 | $dbman->create_table($table); | |
1310 | ||
1311 | $ids = array(); | |
1312 | $ids[] = $DB->insert_record($tablename, array('course' => 3)); | |
1313 | $ids[] = $DB->insert_record($tablename, array('course' => 5)); | |
1314 | $ids[] = $DB->insert_record($tablename, array('course' => 4)); | |
1315 | $ids[] = $DB->insert_record($tablename, array('course' => 3)); | |
1316 | $ids[] = $DB->insert_record($tablename, array('course' => 2)); | |
1317 | $ids[] = $DB->insert_record($tablename, array('course' => 1)); | |
1318 | $ids[] = $DB->insert_record($tablename, array('course' => 0)); | |
1319 | ||
1320 | $rs = $DB->export_table_recordset($tablename); | |
1321 | $rids = array(); | |
1322 | foreach ($rs as $record) { | |
1323 | $rids[] = $record->id; | |
1324 | } | |
1325 | $rs->close(); | |
1326 | $this->assertEquals($ids, $rids, '', 0, 0, true); | |
1327 | } | |
1328 | ||
a3d5830a PS |
1329 | public function test_get_records() { |
1330 | $DB = $this->tdb; | |
1331 | $dbman = $DB->get_manager(); | |
1332 | ||
1333 | $table = $this->get_test_table(); | |
1334 | $tablename = $table->getName(); | |
1335 | ||
9d6d32b6 PS |
1336 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1337 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1338 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); |
1339 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1340 | $dbman->create_table($table); | |
1341 | ||
1342 | $DB->insert_record($tablename, array('course' => 3)); | |
1343 | $DB->insert_record($tablename, array('course' => 3)); | |
1344 | $DB->insert_record($tablename, array('course' => 5)); | |
1345 | $DB->insert_record($tablename, array('course' => 2)); | |
1346 | ||
9d6d32b6 | 1347 | // All records. |
a3d5830a | 1348 | $records = $DB->get_records($tablename); |
9d6d32b6 | 1349 | $this->assertCount(4, $records); |
a3d5830a PS |
1350 | $this->assertEquals(3, $records[1]->course); |
1351 | $this->assertEquals(3, $records[2]->course); | |
1352 | $this->assertEquals(5, $records[3]->course); | |
1353 | $this->assertEquals(2, $records[4]->course); | |
1354 | ||
9d6d32b6 | 1355 | // Records matching certain conditions. |
a3d5830a | 1356 | $records = $DB->get_records($tablename, array('course' => 3)); |
9d6d32b6 | 1357 | $this->assertCount(2, $records); |
a3d5830a PS |
1358 | $this->assertEquals(3, $records[1]->course); |
1359 | $this->assertEquals(3, $records[2]->course); | |
1360 | ||
9d6d32b6 | 1361 | // All records sorted by course. |
a3d5830a | 1362 | $records = $DB->get_records($tablename, null, 'course'); |
9d6d32b6 | 1363 | $this->assertCount(4, $records); |
a3d5830a PS |
1364 | $current_record = reset($records); |
1365 | $this->assertEquals(4, $current_record->id); | |
1366 | $current_record = next($records); | |
1367 | $this->assertEquals(1, $current_record->id); | |
1368 | $current_record = next($records); | |
1369 | $this->assertEquals(2, $current_record->id); | |
1370 | $current_record = next($records); | |
1371 | $this->assertEquals(3, $current_record->id); | |
1372 | ||
9d6d32b6 | 1373 | // All records, but get only one field. |
a3d5830a PS |
1374 | $records = $DB->get_records($tablename, null, '', 'id'); |
1375 | $this->assertFalse(isset($records[1]->course)); | |
1376 | $this->assertTrue(isset($records[1]->id)); | |
9d6d32b6 | 1377 | $this->assertCount(4, $records); |
a3d5830a | 1378 | |
9d6d32b6 | 1379 | // Booleans into params. |
a3d5830a | 1380 | $records = $DB->get_records($tablename, array('course' => true)); |
9d6d32b6 | 1381 | $this->assertCount(0, $records); |
a3d5830a | 1382 | $records = $DB->get_records($tablename, array('course' => false)); |
9d6d32b6 | 1383 | $this->assertCount(0, $records); |
a3d5830a | 1384 | |
9d6d32b6 | 1385 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
1386 | $conditions = array('onetext' => '1'); |
1387 | try { | |
1388 | $records = $DB->get_records($tablename, $conditions); | |
1389 | if (debugging()) { | |
9d6d32b6 | 1390 | // Only in debug mode - hopefully all devs test code in debug mode... |
a3d5830a PS |
1391 | $this->fail('An Exception is missing, expected due to equating of text fields'); |
1392 | } | |
9d6d32b6 PS |
1393 | } catch (moodle_exception $e) { |
1394 | $this->assertInstanceOf('dml_exception', $e); | |
1395 | $this->assertSame('textconditionsnotallowed', $e->errorcode); | |
a3d5830a PS |
1396 | } |
1397 | ||
9d6d32b6 PS |
1398 | // Test get_records passing non-existing table. |
1399 | // with params. | |
a3d5830a PS |
1400 | try { |
1401 | $records = $DB->get_records('xxxx', array('id' => 0)); | |
1402 | $this->fail('An Exception is missing, expected due to query against non-existing table'); | |
9d6d32b6 PS |
1403 | } catch (moodle_exception $e) { |
1404 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a | 1405 | if (debugging()) { |
9d6d32b6 PS |
1406 | // Information for developers only, normal users get general error message. |
1407 | $this->assertSame('ddltablenotexist', $e->errorcode); | |
a3d5830a PS |
1408 | } |
1409 | } | |
9d6d32b6 | 1410 | // And without params. |
a3d5830a PS |
1411 | try { |
1412 | $records = $DB->get_records('xxxx', array()); | |
1413 | $this->fail('An Exception is missing, expected due to query against non-existing table'); | |
9d6d32b6 PS |
1414 | } catch (moodle_exception $e) { |
1415 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a | 1416 | if (debugging()) { |
9d6d32b6 PS |
1417 | // Information for developers only, normal users get general error message. |
1418 | $this->assertSame('ddltablenotexist', $e->errorcode); | |
a3d5830a PS |
1419 | } |
1420 | } | |
1421 | ||
9d6d32b6 | 1422 | // Test get_records passing non-existing column. |
a3d5830a PS |
1423 | try { |
1424 | $records = $DB->get_records($tablename, array('xxxx' => 0)); | |
1425 | $this->fail('An Exception is missing, expected due to query against non-existing column'); | |
9d6d32b6 PS |
1426 | } catch (moodle_exception $e) { |
1427 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a | 1428 | if (debugging()) { |
9d6d32b6 PS |
1429 | // Information for developers only, normal users get general error message. |
1430 | $this->assertSame('ddlfieldnotexist', $e->errorcode); | |
a3d5830a PS |
1431 | } |
1432 | } | |
1433 | ||
9d6d32b6 | 1434 | // Note: delegate limits testing to test_get_records_sql(). |
a3d5830a PS |
1435 | } |
1436 | ||
1437 | public function test_get_records_list() { | |
1438 | $DB = $this->tdb; | |
1439 | $dbman = $DB->get_manager(); | |
1440 | ||
1441 | $table = $this->get_test_table(); | |
1442 | $tablename = $table->getName(); | |
1443 | ||
9d6d32b6 PS |
1444 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1445 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1446 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1447 | $dbman->create_table($table); | |
1448 | ||
1449 | $DB->insert_record($tablename, array('course' => 3)); | |
1450 | $DB->insert_record($tablename, array('course' => 3)); | |
1451 | $DB->insert_record($tablename, array('course' => 5)); | |
1452 | $DB->insert_record($tablename, array('course' => 2)); | |
1453 | ||
1454 | $records = $DB->get_records_list($tablename, 'course', array(3, 2)); | |
9d6d32b6 PS |
1455 | $this->assertInternalType('array', $records); |
1456 | $this->assertCount(3, $records); | |
a3d5830a PS |
1457 | $this->assertEquals(1, reset($records)->id); |
1458 | $this->assertEquals(2, next($records)->id); | |
1459 | $this->assertEquals(4, next($records)->id); | |
1460 | ||
9d6d32b6 PS |
1461 | $this->assertSame(array(), $records = $DB->get_records_list($tablename, 'course', array())); // Must return 0 rows without conditions. MDL-17645. |
1462 | $this->assertCount(0, $records); | |
a3d5830a | 1463 | |
9d6d32b6 | 1464 | // Note: delegate limits testing to test_get_records_sql(). |
a3d5830a PS |
1465 | } |
1466 | ||
1467 | public function test_get_records_sql() { | |
1468 | $DB = $this->tdb; | |
1469 | $dbman = $DB->get_manager(); | |
1470 | ||
1471 | $table = $this->get_test_table(); | |
1472 | $tablename = $table->getName(); | |
1473 | ||
9d6d32b6 PS |
1474 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1475 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1476 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1477 | $dbman->create_table($table); | |
1478 | ||
1479 | $inskey1 = $DB->insert_record($tablename, array('course' => 3)); | |
1480 | $inskey2 = $DB->insert_record($tablename, array('course' => 5)); | |
1481 | $inskey3 = $DB->insert_record($tablename, array('course' => 4)); | |
1482 | $inskey4 = $DB->insert_record($tablename, array('course' => 3)); | |
1483 | $inskey5 = $DB->insert_record($tablename, array('course' => 2)); | |
1484 | $inskey6 = $DB->insert_record($tablename, array('course' => 1)); | |
1485 | $inskey7 = $DB->insert_record($tablename, array('course' => 0)); | |
1486 | ||
1487 | $table2 = $this->get_test_table("2"); | |
1488 | $tablename2 = $table2->getName(); | |
9d6d32b6 PS |
1489 | $table2->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1490 | $table2->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1491 | $table2->add_field('nametext', XMLDB_TYPE_TEXT, 'small', null, null, null, null); |
1492 | $table2->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1493 | $dbman->create_table($table2); | |
1494 | ||
1495 | $DB->insert_record($tablename2, array('course'=>3, 'nametext'=>'badabing')); | |
1496 | $DB->insert_record($tablename2, array('course'=>4, 'nametext'=>'badabang')); | |
1497 | $DB->insert_record($tablename2, array('course'=>5, 'nametext'=>'badabung')); | |
1498 | $DB->insert_record($tablename2, array('course'=>6, 'nametext'=>'badabong')); | |
1499 | ||
1500 | $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3)); | |
9d6d32b6 | 1501 | $this->assertCount(2, $records); |
a3d5830a PS |
1502 | $this->assertEquals($inskey1, reset($records)->id); |
1503 | $this->assertEquals($inskey4, next($records)->id); | |
1504 | ||
9d6d32b6 | 1505 | // Awful test, requires debug enabled and sent to browser. Let's do that and restore after test. |
a3d5830a | 1506 | $records = $DB->get_records_sql("SELECT course AS id, course AS course FROM {{$tablename}}", null); |
eb10d554 | 1507 | $this->assertDebuggingCalled(); |
9d6d32b6 | 1508 | $this->assertCount(6, $records); |
96f81ea3 | 1509 | set_debugging(DEBUG_MINIMAL); |
eb10d554 PS |
1510 | $records = $DB->get_records_sql("SELECT course AS id, course AS course FROM {{$tablename}}", null); |
1511 | $this->assertDebuggingNotCalled(); | |
9d6d32b6 | 1512 | $this->assertCount(6, $records); |
96f81ea3 | 1513 | set_debugging(DEBUG_DEVELOPER); |
a3d5830a | 1514 | |
9d6d32b6 | 1515 | // Negative limits = no limits. |
a3d5830a | 1516 | $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, -1, -1); |
9d6d32b6 | 1517 | $this->assertCount(7, $records); |
a3d5830a | 1518 | |
9d6d32b6 | 1519 | // Zero limits = no limits. |
a3d5830a | 1520 | $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 0, 0); |
9d6d32b6 | 1521 | $this->assertCount(7, $records); |
a3d5830a | 1522 | |
9d6d32b6 | 1523 | // Only limitfrom = skips that number of records. |
a3d5830a | 1524 | $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 2, 0); |
9d6d32b6 | 1525 | $this->assertCount(5, $records); |
a3d5830a PS |
1526 | $this->assertEquals($inskey3, reset($records)->id); |
1527 | $this->assertEquals($inskey7, end($records)->id); | |
1528 | ||
9d6d32b6 | 1529 | // Only limitnum = fetches that number of records. |
a3d5830a | 1530 | $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 0, 3); |
9d6d32b6 | 1531 | $this->assertCount(3, $records); |
a3d5830a PS |
1532 | $this->assertEquals($inskey1, reset($records)->id); |
1533 | $this->assertEquals($inskey3, end($records)->id); | |
1534 | ||
9d6d32b6 | 1535 | // Both limitfrom and limitnum = skips limitfrom records and fetches limitnum ones. |
a3d5830a | 1536 | $records = $DB->get_records_sql("SELECT * FROM {{$tablename}} ORDER BY id", null, 3, 2); |
9d6d32b6 | 1537 | $this->assertCount(2, $records); |
a3d5830a PS |
1538 | $this->assertEquals($inskey4, reset($records)->id); |
1539 | $this->assertEquals($inskey5, end($records)->id); | |
1540 | ||
9d6d32b6 PS |
1541 | // Both limitfrom and limitnum in query having subqueris. |
1542 | // Note the subquery skips records with course = 0 and 3. | |
a3d5830a PS |
1543 | $sql = "SELECT * FROM {{$tablename}} |
1544 | WHERE course NOT IN ( | |
1545 | SELECT course FROM {{$tablename}} | |
1546 | WHERE course IN (0, 3)) | |
1547 | ORDER BY course"; | |
9d6d32b6 PS |
1548 | $records = $DB->get_records_sql($sql, null, 0, 2); // Skip 0, get 2. |
1549 | $this->assertCount(2, $records); | |
a3d5830a PS |
1550 | $this->assertEquals($inskey6, reset($records)->id); |
1551 | $this->assertEquals($inskey5, end($records)->id); | |
9d6d32b6 PS |
1552 | $records = $DB->get_records_sql($sql, null, 2, 2); // Skip 2, get 2. |
1553 | $this->assertCount(2, $records); | |
a3d5830a PS |
1554 | $this->assertEquals($inskey3, reset($records)->id); |
1555 | $this->assertEquals($inskey2, end($records)->id); | |
1556 | ||
9d6d32b6 | 1557 | // Test 2 tables with aliases and limits with order bys. |
a3d5830a PS |
1558 | $sql = "SELECT t1.id, t1.course AS cid, t2.nametext |
1559 | FROM {{$tablename}} t1, {{$tablename2}} t2 | |
1560 | WHERE t2.course=t1.course | |
1561 | ORDER BY t1.course, ". $DB->sql_compare_text('t2.nametext'); | |
9d6d32b6 PS |
1562 | $records = $DB->get_records_sql($sql, null, 2, 2); // Skip courses 3 and 6, get 4 and 5. |
1563 | $this->assertCount(2, $records); | |
1564 | $this->assertSame('5', end($records)->cid); | |
1565 | $this->assertSame('4', reset($records)->cid); | |
a3d5830a | 1566 | |
9d6d32b6 PS |
1567 | // Test 2 tables with aliases and limits with the highest INT limit works. |
1568 | $records = $DB->get_records_sql($sql, null, 2, PHP_INT_MAX); // Skip course {3,6}, get {4,5}. | |
1569 | $this->assertCount(2, $records); | |
1570 | $this->assertSame('5', end($records)->cid); | |
1571 | $this->assertSame('4', reset($records)->cid); | |
a3d5830a | 1572 | |
9d6d32b6 PS |
1573 | // Test 2 tables with aliases and limits with order bys (limit which is highest INT number). |
1574 | $records = $DB->get_records_sql($sql, null, PHP_INT_MAX, 2); // Skip all courses. | |
1575 | $this->assertCount(0, $records); | |
a3d5830a | 1576 | |
9d6d32b6 PS |
1577 | // Test 2 tables with aliases and limits with order bys (limit which s highest INT number). |
1578 | $records = $DB->get_records_sql($sql, null, PHP_INT_MAX, PHP_INT_MAX); // Skip all courses. | |
1579 | $this->assertCount(0, $records); | |
a3d5830a | 1580 | |
9d6d32b6 | 1581 | // TODO: Test limits in queries having DISTINCT clauses. |
a3d5830a | 1582 | |
9d6d32b6 | 1583 | // Note: fetching nulls, empties, LOBs already tested by test_update_record() no needed here. |
a3d5830a PS |
1584 | } |
1585 | ||
1586 | public function test_get_records_menu() { | |
1587 | $DB = $this->tdb; | |
1588 | $dbman = $DB->get_manager(); | |
1589 | ||
1590 | $table = $this->get_test_table(); | |
1591 | $tablename = $table->getName(); | |
1592 | ||
9d6d32b6 PS |
1593 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1594 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1595 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1596 | $dbman->create_table($table); | |
1597 | ||
1598 | $DB->insert_record($tablename, array('course' => 3)); | |
1599 | $DB->insert_record($tablename, array('course' => 3)); | |
1600 | $DB->insert_record($tablename, array('course' => 5)); | |
1601 | $DB->insert_record($tablename, array('course' => 2)); | |
1602 | ||
1603 | $records = $DB->get_records_menu($tablename, array('course' => 3)); | |
9d6d32b6 PS |
1604 | $this->assertInternalType('array', $records); |
1605 | $this->assertCount(2, $records); | |
1606 | $this->assertNotEmpty($records[1]); | |
1607 | $this->assertNotEmpty($records[2]); | |
a3d5830a PS |
1608 | $this->assertEquals(3, $records[1]); |
1609 | $this->assertEquals(3, $records[2]); | |
1610 | ||
9d6d32b6 | 1611 | // Note: delegate limits testing to test_get_records_sql(). |
a3d5830a PS |
1612 | } |
1613 | ||
1614 | public function test_get_records_select_menu() { | |
1615 | $DB = $this->tdb; | |
1616 | $dbman = $DB->get_manager(); | |
1617 | ||
1618 | $table = $this->get_test_table(); | |
1619 | $tablename = $table->getName(); | |
1620 | ||
9d6d32b6 PS |
1621 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1622 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1623 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1624 | $dbman->create_table($table); | |
1625 | ||
1626 | $DB->insert_record($tablename, array('course' => 3)); | |
1627 | $DB->insert_record($tablename, array('course' => 2)); | |
1628 | $DB->insert_record($tablename, array('course' => 3)); | |
1629 | $DB->insert_record($tablename, array('course' => 5)); | |
1630 | ||
1631 | $records = $DB->get_records_select_menu($tablename, "course > ?", array(2)); | |
9d6d32b6 PS |
1632 | $this->assertInternalType('array', $records); |
1633 | ||
1634 | $this->assertCount(3, $records); | |
1635 | $this->assertArrayHasKey(1, $records); | |
1636 | $this->assertArrayNotHasKey(2, $records); | |
1637 | $this->assertArrayHasKey(3, $records); | |
1638 | $this->assertArrayHasKey(4, $records); | |
1639 | $this->assertSame('3', $records[1]); | |
1640 | $this->assertSame('3', $records[3]); | |
1641 | $this->assertSame('5', $records[4]); | |
1642 | ||
1643 | // Note: delegate limits testing to test_get_records_sql(). | |
a3d5830a PS |
1644 | } |
1645 | ||
1646 | public function test_get_records_sql_menu() { | |
1647 | $DB = $this->tdb; | |
1648 | $dbman = $DB->get_manager(); | |
1649 | ||
1650 | $table = $this->get_test_table(); | |
1651 | $tablename = $table->getName(); | |
1652 | ||
9d6d32b6 PS |
1653 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1654 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1655 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1656 | $dbman->create_table($table); | |
1657 | ||
1658 | $DB->insert_record($tablename, array('course' => 3)); | |
1659 | $DB->insert_record($tablename, array('course' => 2)); | |
1660 | $DB->insert_record($tablename, array('course' => 3)); | |
1661 | $DB->insert_record($tablename, array('course' => 5)); | |
1662 | ||
1663 | $records = $DB->get_records_sql_menu("SELECT * FROM {{$tablename}} WHERE course > ?", array(2)); | |
9d6d32b6 PS |
1664 | $this->assertInternalType('array', $records); |
1665 | ||
1666 | $this->assertCount(3, $records); | |
1667 | $this->assertArrayHasKey(1, $records); | |
1668 | $this->assertArrayNotHasKey(2, $records); | |
1669 | $this->assertArrayHasKey(3, $records); | |
1670 | $this->assertArrayHasKey(4, $records); | |
1671 | $this->assertSame('3', $records[1]); | |
1672 | $this->assertSame('3', $records[3]); | |
1673 | $this->assertSame('5', $records[4]); | |
1674 | ||
1675 | // Note: delegate limits testing to test_get_records_sql(). | |
a3d5830a PS |
1676 | } |
1677 | ||
1678 | public function test_get_record() { | |
1679 | $DB = $this->tdb; | |
1680 | $dbman = $DB->get_manager(); | |
1681 | ||
1682 | $table = $this->get_test_table(); | |
1683 | $tablename = $table->getName(); | |
1684 | ||
9d6d32b6 PS |
1685 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1686 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1687 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1688 | $dbman->create_table($table); | |
1689 | ||
1690 | $DB->insert_record($tablename, array('course' => 3)); | |
1691 | $DB->insert_record($tablename, array('course' => 2)); | |
1692 | ||
1693 | $record = $DB->get_record($tablename, array('id' => 2)); | |
9d6d32b6 | 1694 | $this->assertInstanceOf('stdClass', $record); |
a3d5830a PS |
1695 | |
1696 | $this->assertEquals(2, $record->course); | |
1697 | $this->assertEquals(2, $record->id); | |
1698 | } | |
1699 | ||
1700 | ||
1701 | public function test_get_record_select() { | |
1702 | $DB = $this->tdb; | |
1703 | $dbman = $DB->get_manager(); | |
1704 | ||
1705 | $table = $this->get_test_table(); | |
1706 | $tablename = $table->getName(); | |
1707 | ||
9d6d32b6 PS |
1708 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1709 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1710 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1711 | $dbman->create_table($table); | |
1712 | ||
1713 | $DB->insert_record($tablename, array('course' => 3)); | |
1714 | $DB->insert_record($tablename, array('course' => 2)); | |
1715 | ||
1716 | $record = $DB->get_record_select($tablename, "id = ?", array(2)); | |
9d6d32b6 | 1717 | $this->assertInstanceOf('stdClass', $record); |
a3d5830a PS |
1718 | |
1719 | $this->assertEquals(2, $record->course); | |
1720 | ||
9d6d32b6 | 1721 | // Note: delegates limit testing to test_get_records_sql(). |
a3d5830a PS |
1722 | } |
1723 | ||
1724 | public function test_get_record_sql() { | |
1725 | $DB = $this->tdb; | |
1726 | $dbman = $DB->get_manager(); | |
1727 | ||
1728 | $table = $this->get_test_table(); | |
1729 | $tablename = $table->getName(); | |
1730 | ||
9d6d32b6 PS |
1731 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1732 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1733 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1734 | $dbman->create_table($table); | |
1735 | ||
1736 | $DB->insert_record($tablename, array('course' => 3)); | |
1737 | $DB->insert_record($tablename, array('course' => 2)); | |
1738 | ||
9d6d32b6 | 1739 | // Standard use. |
a3d5830a | 1740 | $record = $DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(2)); |
9d6d32b6 | 1741 | $this->assertInstanceOf('stdClass', $record); |
a3d5830a PS |
1742 | $this->assertEquals(2, $record->course); |
1743 | $this->assertEquals(2, $record->id); | |
1744 | ||
9d6d32b6 | 1745 | // Backwards compatibility with $ignoremultiple. |
a3d5830a PS |
1746 | $this->assertFalse((bool)IGNORE_MISSING); |
1747 | $this->assertTrue((bool)IGNORE_MULTIPLE); | |
1748 | ||
9d6d32b6 | 1749 | // Record not found - ignore. |
a3d5830a PS |
1750 | $this->assertFalse($DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(666), IGNORE_MISSING)); |
1751 | $this->assertFalse($DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(666), IGNORE_MULTIPLE)); | |
1752 | ||
9d6d32b6 | 1753 | // Record not found error. |
a3d5830a PS |
1754 | try { |
1755 | $DB->get_record_sql("SELECT * FROM {{$tablename}} WHERE id = ?", array(666), MUST_EXIST); | |
1756 | $this->fail("Exception expected"); | |
1757 | } catch (dml_missing_record_exception $e) { | |
1758 | $this->assertTrue(true); | |
1759 | } | |
1760 | ||
a3d5830a | 1761 | $this->assertNotEmpty($DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), IGNORE_MISSING)); |
eb10d554 | 1762 | $this->assertDebuggingCalled(); |
96f81ea3 | 1763 | set_debugging(DEBUG_MINIMAL); |
eb10d554 PS |
1764 | $this->assertNotEmpty($DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), IGNORE_MISSING)); |
1765 | $this->assertDebuggingNotCalled(); | |
96f81ea3 | 1766 | set_debugging(DEBUG_DEVELOPER); |
a3d5830a | 1767 | |
9d6d32b6 | 1768 | // Multiple matches ignored. |
a3d5830a PS |
1769 | $this->assertNotEmpty($DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), IGNORE_MULTIPLE)); |
1770 | ||
9d6d32b6 | 1771 | // Multiple found error. |
a3d5830a PS |
1772 | try { |
1773 | $DB->get_record_sql("SELECT * FROM {{$tablename}}", array(), MUST_EXIST); | |
1774 | $this->fail("Exception expected"); | |
1775 | } catch (dml_multiple_records_exception $e) { | |
1776 | $this->assertTrue(true); | |
1777 | } | |
1778 | } | |
1779 | ||
1780 | public function test_get_field() { | |
1781 | $DB = $this->tdb; | |
1782 | $dbman = $DB->get_manager(); | |
1783 | ||
1784 | $table = $this->get_test_table(); | |
1785 | $tablename = $table->getName(); | |
1786 | ||
9d6d32b6 PS |
1787 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1788 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1789 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); |
1790 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1791 | $dbman->create_table($table); | |
1792 | ||
1793 | $id1 = $DB->insert_record($tablename, array('course' => 3)); | |
1794 | $DB->insert_record($tablename, array('course' => 5)); | |
1795 | $DB->insert_record($tablename, array('course' => 5)); | |
1796 | ||
1797 | $this->assertEquals(3, $DB->get_field($tablename, 'course', array('id' => $id1))); | |
1798 | $this->assertEquals(3, $DB->get_field($tablename, 'course', array('course' => 3))); | |
1799 | ||
9d6d32b6 | 1800 | $this->assertFalse($DB->get_field($tablename, 'course', array('course' => 11), IGNORE_MISSING)); |
a3d5830a PS |
1801 | try { |
1802 | $DB->get_field($tablename, 'course', array('course' => 4), MUST_EXIST); | |
17222a4a | 1803 | $this->fail('Exception expected due to missing record'); |
a3d5830a PS |
1804 | } catch (dml_exception $ex) { |
1805 | $this->assertTrue(true); | |
1806 | } | |
1807 | ||
a3d5830a | 1808 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('course' => 5), IGNORE_MULTIPLE)); |
eb10d554 | 1809 | $this->assertDebuggingNotCalled(); |
a3d5830a | 1810 | |
a3d5830a | 1811 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('course' => 5), IGNORE_MISSING)); |
eb10d554 | 1812 | $this->assertDebuggingCalled(); |
a3d5830a | 1813 | |
9d6d32b6 | 1814 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
1815 | $conditions = array('onetext' => '1'); |
1816 | try { | |
1817 | $DB->get_field($tablename, 'course', $conditions); | |
1818 | if (debugging()) { | |
9d6d32b6 | 1819 | // Only in debug mode - hopefully all devs test code in debug mode... |
a3d5830a PS |
1820 | $this->fail('An Exception is missing, expected due to equating of text fields'); |
1821 | } | |
9d6d32b6 PS |
1822 | } catch (moodle_exception $e) { |
1823 | $this->assertInstanceOf('dml_exception', $e); | |
1824 | $this->assertSame('textconditionsnotallowed', $e->errorcode); | |
a3d5830a PS |
1825 | } |
1826 | } | |
1827 | ||
1828 | public function test_get_field_select() { | |
1829 | $DB = $this->tdb; | |
1830 | $dbman = $DB->get_manager(); | |
1831 | ||
1832 | $table = $this->get_test_table(); | |
1833 | $tablename = $table->getName(); | |
1834 | ||
9d6d32b6 PS |
1835 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1836 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1837 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1838 | $dbman->create_table($table); | |
1839 | ||
1840 | $DB->insert_record($tablename, array('course' => 3)); | |
1841 | ||
1842 | $this->assertEquals(3, $DB->get_field_select($tablename, 'course', "id = ?", array(1))); | |
1843 | } | |
1844 | ||
1845 | public function test_get_field_sql() { | |
1846 | $DB = $this->tdb; | |
1847 | $dbman = $DB->get_manager(); | |
1848 | ||
1849 | $table = $this->get_test_table(); | |
1850 | $tablename = $table->getName(); | |
1851 | ||
9d6d32b6 PS |
1852 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1853 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1854 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1855 | $dbman->create_table($table); | |
1856 | ||
1857 | $DB->insert_record($tablename, array('course' => 3)); | |
1858 | ||
1859 | $this->assertEquals(3, $DB->get_field_sql("SELECT course FROM {{$tablename}} WHERE id = ?", array(1))); | |
1860 | } | |
1861 | ||
1862 | public function test_get_fieldset_select() { | |
1863 | $DB = $this->tdb; | |
1864 | $dbman = $DB->get_manager(); | |
1865 | ||
1866 | $table = $this->get_test_table(); | |
1867 | $tablename = $table->getName(); | |
1868 | ||
9d6d32b6 PS |
1869 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1870 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1871 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1872 | $dbman->create_table($table); | |
1873 | ||
1874 | $DB->insert_record($tablename, array('course' => 1)); | |
1875 | $DB->insert_record($tablename, array('course' => 3)); | |
1876 | $DB->insert_record($tablename, array('course' => 2)); | |
1877 | $DB->insert_record($tablename, array('course' => 6)); | |
1878 | ||
1879 | $fieldset = $DB->get_fieldset_select($tablename, 'course', "course > ?", array(1)); | |
9d6d32b6 | 1880 | $this->assertInternalType('array', $fieldset); |
a3d5830a | 1881 | |
9d6d32b6 | 1882 | $this->assertCount(3, $fieldset); |
a3d5830a PS |
1883 | $this->assertEquals(3, $fieldset[0]); |
1884 | $this->assertEquals(2, $fieldset[1]); | |
1885 | $this->assertEquals(6, $fieldset[2]); | |
1886 | } | |
1887 | ||
1888 | public function test_get_fieldset_sql() { | |
1889 | $DB = $this->tdb; | |
1890 | $dbman = $DB->get_manager(); | |
1891 | ||
1892 | $table = $this->get_test_table(); | |
1893 | $tablename = $table->getName(); | |
1894 | ||
9d6d32b6 PS |
1895 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1896 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1897 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1898 | $dbman->create_table($table); | |
1899 | ||
1900 | $DB->insert_record($tablename, array('course' => 1)); | |
1901 | $DB->insert_record($tablename, array('course' => 3)); | |
1902 | $DB->insert_record($tablename, array('course' => 2)); | |
1903 | $DB->insert_record($tablename, array('course' => 6)); | |
1904 | ||
1905 | $fieldset = $DB->get_fieldset_sql("SELECT * FROM {{$tablename}} WHERE course > ?", array(1)); | |
9d6d32b6 | 1906 | $this->assertInternalType('array', $fieldset); |
a3d5830a | 1907 | |
9d6d32b6 | 1908 | $this->assertCount(3, $fieldset); |
a3d5830a PS |
1909 | $this->assertEquals(2, $fieldset[0]); |
1910 | $this->assertEquals(3, $fieldset[1]); | |
1911 | $this->assertEquals(4, $fieldset[2]); | |
1912 | } | |
1913 | ||
1914 | public function test_insert_record_raw() { | |
1915 | $DB = $this->tdb; | |
1916 | $dbman = $DB->get_manager(); | |
1917 | ||
1918 | $table = $this->get_test_table(); | |
1919 | $tablename = $table->getName(); | |
1920 | ||
9d6d32b6 PS |
1921 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1922 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
1923 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring'); |
1924 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
1925 | $dbman->create_table($table); | |
1926 | ||
1927 | $record = (object)array('course' => 1, 'onechar' => 'xx'); | |
1928 | $before = clone($record); | |
1929 | $result = $DB->insert_record_raw($tablename, $record); | |
1930 | $this->assertSame(1, $result); | |
1931 | $this->assertEquals($record, $before); | |
1932 | ||
1933 | $record = $DB->get_record($tablename, array('course' => 1)); | |
9d6d32b6 | 1934 | $this->assertInstanceOf('stdClass', $record); |
a3d5830a PS |
1935 | $this->assertSame('xx', $record->onechar); |
1936 | ||
1937 | $result = $DB->insert_record_raw($tablename, array('course' => 2, 'onechar' => 'yy'), false); | |
9d6d32b6 | 1938 | $this->assertTrue($result); |
a3d5830a | 1939 | |
9d6d32b6 | 1940 | // Note: bulk not implemented yet. |
a3d5830a PS |
1941 | $DB->insert_record_raw($tablename, array('course' => 3, 'onechar' => 'zz'), true, true); |
1942 | $record = $DB->get_record($tablename, array('course' => 3)); | |
9d6d32b6 | 1943 | $this->assertInstanceOf('stdClass', $record); |
a3d5830a PS |
1944 | $this->assertSame('zz', $record->onechar); |
1945 | ||
9d6d32b6 | 1946 | // Custom sequence (id) - returnid is ignored. |
a3d5830a | 1947 | $result = $DB->insert_record_raw($tablename, array('id' => 10, 'course' => 3, 'onechar' => 'bb'), true, false, true); |
9d6d32b6 | 1948 | $this->assertTrue($result); |
a3d5830a | 1949 | $record = $DB->get_record($tablename, array('id' => 10)); |
9d6d32b6 | 1950 | $this->assertInstanceOf('stdClass', $record); |
a3d5830a PS |
1951 | $this->assertSame('bb', $record->onechar); |
1952 | ||
9d6d32b6 | 1953 | // Custom sequence - missing id error. |
a3d5830a PS |
1954 | try { |
1955 | $DB->insert_record_raw($tablename, array('course' => 3, 'onechar' => 'bb'), true, false, true); | |
17222a4a | 1956 | $this->fail('Exception expected due to missing record'); |
a3d5830a PS |
1957 | } catch (coding_exception $ex) { |
1958 | $this->assertTrue(true); | |
1959 | } | |
1960 | ||
9d6d32b6 | 1961 | // Wrong column error. |
a3d5830a PS |
1962 | try { |
1963 | $DB->insert_record_raw($tablename, array('xxxxx' => 3, 'onechar' => 'bb')); | |
17222a4a | 1964 | $this->fail('Exception expected due to invalid column'); |
a3d5830a PS |
1965 | } catch (dml_exception $ex) { |
1966 | $this->assertTrue(true); | |
1967 | } | |
3b4f7338 | 1968 | |
9d6d32b6 | 1969 | // Create something similar to "context_temp" with id column without sequence. |
3b4f7338 PS |
1970 | $dbman->drop_table($table); |
1971 | $table = $this->get_test_table(); | |
1972 | $tablename = $table->getName(); | |
9d6d32b6 PS |
1973 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); |
1974 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
3b4f7338 PS |
1975 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
1976 | $dbman->create_table($table); | |
1977 | ||
1978 | $record = (object)array('id'=>5, 'course' => 1); | |
1979 | $DB->insert_record_raw($tablename, $record, false, false, true); | |
1980 | $record = $DB->get_record($tablename, array()); | |
1981 | $this->assertEquals(5, $record->id); | |
a3d5830a PS |
1982 | } |
1983 | ||
1984 | public function test_insert_record() { | |
1985 | // All the information in this test is fetched from DB by get_recordset() so we | |
1986 | // have such method properly tested against nulls, empties and friends... | |
1987 | ||
1988 | $DB = $this->tdb; | |
1989 | $dbman = $DB->get_manager(); | |
1990 | ||
1991 | $table = $this->get_test_table(); | |
1992 | $tablename = $table->getName(); | |
1993 | ||
9d6d32b6 PS |
1994 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
1995 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
1996 | $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', null, null, null, 100); | |
a3d5830a PS |
1997 | $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200); |
1998 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring'); | |
1999 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); | |
2000 | $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null); | |
2001 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
2002 | $dbman->create_table($table); | |
2003 | ||
2004 | $this->assertSame(1, $DB->insert_record($tablename, array('course' => 1), true)); | |
2005 | $record = $DB->get_record($tablename, array('course' => 1)); | |
2006 | $this->assertEquals(1, $record->id); | |
9d6d32b6 | 2007 | $this->assertEquals(100, $record->oneint); // Just check column defaults have been applied. |
a3d5830a PS |
2008 | $this->assertEquals(200, $record->onenum); |
2009 | $this->assertSame('onestring', $record->onechar); | |
2010 | $this->assertNull($record->onetext); | |
2011 | $this->assertNull($record->onebinary); | |
2012 | ||
9d6d32b6 PS |
2013 | // Without returning id, bulk not implemented. |
2014 | $result = $this->assertTrue($DB->insert_record($tablename, array('course' => 99), false, true)); | |
a3d5830a PS |
2015 | $record = $DB->get_record($tablename, array('course' => 99)); |
2016 | $this->assertEquals(2, $record->id); | |
2017 | $this->assertEquals(99, $record->course); | |
2018 | ||
9d6d32b6 | 2019 | // Check nulls are set properly for all types. |
a3d5830a PS |
2020 | $record = new stdClass(); |
2021 | $record->oneint = null; | |
2022 | $record->onenum = null; | |
2023 | $record->onechar = null; | |
2024 | $record->onetext = null; | |
2025 | $record->onebinary = null; | |
2026 | $recid = $DB->insert_record($tablename, $record); | |
2027 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2028 | $this->assertEquals(0, $record->course); | |
2029 | $this->assertNull($record->oneint); | |
2030 | $this->assertNull($record->onenum); | |
2031 | $this->assertNull($record->onechar); | |
2032 | $this->assertNull($record->onetext); | |
2033 | $this->assertNull($record->onebinary); | |
2034 | ||
9d6d32b6 | 2035 | // Check zeros are set properly for all types. |
a3d5830a PS |
2036 | $record = new stdClass(); |
2037 | $record->oneint = 0; | |
2038 | $record->onenum = 0; | |
2039 | $recid = $DB->insert_record($tablename, $record); | |
2040 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2041 | $this->assertEquals(0, $record->oneint); | |
2042 | $this->assertEquals(0, $record->onenum); | |
2043 | ||
9d6d32b6 | 2044 | // Check booleans are set properly for all types. |
a3d5830a | 2045 | $record = new stdClass(); |
9d6d32b6 | 2046 | $record->oneint = true; // Trues. |
a3d5830a PS |
2047 | $record->onenum = true; |
2048 | $record->onechar = true; | |
2049 | $record->onetext = true; | |
2050 | $recid = $DB->insert_record($tablename, $record); | |
2051 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2052 | $this->assertEquals(1, $record->oneint); | |
2053 | $this->assertEquals(1, $record->onenum); | |
2054 | $this->assertEquals(1, $record->onechar); | |
2055 | $this->assertEquals(1, $record->onetext); | |
2056 | ||
2057 | $record = new stdClass(); | |
9d6d32b6 | 2058 | $record->oneint = false; // Falses. |
a3d5830a PS |
2059 | $record->onenum = false; |
2060 | $record->onechar = false; | |
2061 | $record->onetext = false; | |
2062 | $recid = $DB->insert_record($tablename, $record); | |
2063 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2064 | $this->assertEquals(0, $record->oneint); | |
2065 | $this->assertEquals(0, $record->onenum); | |
2066 | $this->assertEquals(0, $record->onechar); | |
2067 | $this->assertEquals(0, $record->onetext); | |
2068 | ||
9d6d32b6 | 2069 | // Check string data causes exception in numeric types. |
a3d5830a PS |
2070 | $record = new stdClass(); |
2071 | $record->oneint = 'onestring'; | |
2072 | $record->onenum = 0; | |
2073 | try { | |
2074 | $DB->insert_record($tablename, $record); | |
2075 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2076 | } catch (moodle_exception $e) { |
2077 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2078 | } |
2079 | $record = new stdClass(); | |
2080 | $record->oneint = 0; | |
2081 | $record->onenum = 'onestring'; | |
2082 | try { | |
2083 | $DB->insert_record($tablename, $record); | |
2084 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2085 | } catch (moodle_exception $e) { |
2086 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2087 | } |
2088 | ||
9d6d32b6 | 2089 | // Check empty string data is stored as 0 in numeric datatypes. |
a3d5830a | 2090 | $record = new stdClass(); |
9d6d32b6 | 2091 | $record->oneint = ''; // Empty string. |
a3d5830a PS |
2092 | $record->onenum = 0; |
2093 | $recid = $DB->insert_record($tablename, $record); | |
2094 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2095 | $this->assertTrue(is_numeric($record->oneint) && $record->oneint == 0); | |
2096 | ||
2097 | $record = new stdClass(); | |
2098 | $record->oneint = 0; | |
9d6d32b6 | 2099 | $record->onenum = ''; // Empty string. |
a3d5830a PS |
2100 | $recid = $DB->insert_record($tablename, $record); |
2101 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2102 | $this->assertTrue(is_numeric($record->onenum) && $record->onenum == 0); | |
2103 | ||
9d6d32b6 | 2104 | // Check empty strings are set properly in string types. |
a3d5830a PS |
2105 | $record = new stdClass(); |
2106 | $record->oneint = 0; | |
2107 | $record->onenum = 0; | |
2108 | $record->onechar = ''; | |
2109 | $record->onetext = ''; | |
2110 | $recid = $DB->insert_record($tablename, $record); | |
2111 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2112 | $this->assertTrue($record->onechar === ''); | |
2113 | $this->assertTrue($record->onetext === ''); | |
2114 | ||
9d6d32b6 | 2115 | // Check operation ((210.10 + 39.92) - 150.02) against numeric types. |
a3d5830a PS |
2116 | $record = new stdClass(); |
2117 | $record->oneint = ((210.10 + 39.92) - 150.02); | |
2118 | $record->onenum = ((210.10 + 39.92) - 150.02); | |
2119 | $recid = $DB->insert_record($tablename, $record); | |
2120 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2121 | $this->assertEquals(100, $record->oneint); | |
2122 | $this->assertEquals(100, $record->onenum); | |
2123 | ||
9d6d32b6 | 2124 | // Check various quotes/backslashes combinations in string types. |
a3d5830a PS |
2125 | $teststrings = array( |
2126 | 'backslashes and quotes alone (even): "" \'\' \\\\', | |
2127 | 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\', | |
2128 | 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'', | |
2129 | 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\''); | |
2130 | foreach ($teststrings as $teststring) { | |
2131 | $record = new stdClass(); | |
2132 | $record->onechar = $teststring; | |
2133 | $record->onetext = $teststring; | |
2134 | $recid = $DB->insert_record($tablename, $record); | |
2135 | $record = $DB->get_record($tablename, array('id' => $recid)); | |
2136 | $this->assertEquals($teststring, $record->onechar); | |
2137 | $this->assertEquals($teststring, $record->onetext); | |
2138 | } | |
2139 | ||
9d6d32b6 | 2140 | // Check LOBs in text/binary columns. |
a3d5830a PS |
2141 | $clob = file_get_contents(__DIR__ . '/fixtures/clob.txt'); |
2142 | $blob = file_get_contents(__DIR__ . '/fixtures/randombinary'); | |
2143 | $record = new stdClass(); | |
2144 | $record->onetext = $clob; | |
2145 | $record->onebinary = $blob; | |
2146 | $recid = $DB->insert_record($tablename, $record); | |
2147 | $rs = $DB->get_recordset($tablename, array('id' => $recid)); | |
2148 | $record = $rs->current(); | |
2149 | $rs->close(); | |
2150 | $this->assertEquals($clob, $record->onetext, 'Test CLOB insert (full contents output disabled)'); | |
2151 | $this->assertEquals($blob, $record->onebinary, 'Test BLOB insert (full contents output disabled)'); | |
2152 | ||
9d6d32b6 | 2153 | // And "small" LOBs too, just in case. |
a3d5830a PS |
2154 | $newclob = substr($clob, 0, 500); |
2155 | $newblob = substr($blob, 0, 250); | |
2156 | $record = new stdClass(); | |
2157 | $record->onetext = $newclob; | |
2158 | $record->onebinary = $newblob; | |
2159 | $recid = $DB->insert_record($tablename, $record); | |
2160 | $rs = $DB->get_recordset($tablename, array('id' => $recid)); | |
2161 | $record = $rs->current(); | |
2162 | $rs->close(); | |
2163 | $this->assertEquals($newclob, $record->onetext, 'Test "small" CLOB insert (full contents output disabled)'); | |
2164 | $this->assertEquals($newblob, $record->onebinary, 'Test "small" BLOB insert (full contents output disabled)'); | |
9d6d32b6 | 2165 | $this->assertEquals(false, $rs->key()); // Ensure recordset key() method to be working ok after closing. |
a3d5830a | 2166 | |
9d6d32b6 | 2167 | // And "diagnostic" LOBs too, just in case. |
a3d5830a PS |
2168 | $newclob = '\'"\\;/ěščřžýáíé'; |
2169 | $newblob = '\'"\\;/ěščřžýáíé'; | |
2170 | $record = new stdClass(); | |
2171 | $record->onetext = $newclob; | |
2172 | $record->onebinary = $newblob; | |
2173 | $recid = $DB->insert_record($tablename, $record); | |
2174 | $rs = $DB->get_recordset($tablename, array('id' => $recid)); | |
2175 | $record = $rs->current(); | |
2176 | $rs->close(); | |
2177 | $this->assertSame($newclob, $record->onetext); | |
2178 | $this->assertSame($newblob, $record->onebinary); | |
9d6d32b6 | 2179 | $this->assertEquals(false, $rs->key()); // Ensure recordset key() method to be working ok after closing. |
a3d5830a | 2180 | |
9d6d32b6 | 2181 | // Test data is not modified. |
a3d5830a | 2182 | $record = new stdClass(); |
9d6d32b6 | 2183 | $record->id = -1; // Has to be ignored. |
a3d5830a | 2184 | $record->course = 3; |
9d6d32b6 | 2185 | $record->lalala = 'lalal'; // Unused. |
a3d5830a PS |
2186 | $before = clone($record); |
2187 | $DB->insert_record($tablename, $record); | |
2188 | $this->assertEquals($record, $before); | |
2189 | ||
9d6d32b6 | 2190 | // Make sure the id is always increasing and never reuses the same id. |
a3d5830a PS |
2191 | $id1 = $DB->insert_record($tablename, array('course' => 3)); |
2192 | $id2 = $DB->insert_record($tablename, array('course' => 3)); | |
2193 | $this->assertTrue($id1 < $id2); | |
2194 | $DB->delete_records($tablename, array('id'=>$id2)); | |
2195 | $id3 = $DB->insert_record($tablename, array('course' => 3)); | |
2196 | $this->assertTrue($id2 < $id3); | |
2197 | $DB->delete_records($tablename, array()); | |
2198 | $id4 = $DB->insert_record($tablename, array('course' => 3)); | |
2199 | $this->assertTrue($id3 < $id4); | |
2200 | ||
2201 | // Test saving a float in a CHAR column, and reading it back. | |
2202 | $id = $DB->insert_record($tablename, array('onechar' => 1.0)); | |
2203 | $this->assertEquals(1.0, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2204 | $id = $DB->insert_record($tablename, array('onechar' => 1e20)); | |
2205 | $this->assertEquals(1e20, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2206 | $id = $DB->insert_record($tablename, array('onechar' => 1e-4)); | |
2207 | $this->assertEquals(1e-4, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2208 | $id = $DB->insert_record($tablename, array('onechar' => 1e-5)); | |
2209 | $this->assertEquals(1e-5, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2210 | $id = $DB->insert_record($tablename, array('onechar' => 1e-300)); | |
2211 | $this->assertEquals(1e-300, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2212 | $id = $DB->insert_record($tablename, array('onechar' => 1e300)); | |
2213 | $this->assertEquals(1e300, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2214 | ||
2215 | // Test saving a float in a TEXT column, and reading it back. | |
2216 | $id = $DB->insert_record($tablename, array('onetext' => 1.0)); | |
2217 | $this->assertEquals(1.0, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2218 | $id = $DB->insert_record($tablename, array('onetext' => 1e20)); | |
2219 | $this->assertEquals(1e20, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2220 | $id = $DB->insert_record($tablename, array('onetext' => 1e-4)); | |
2221 | $this->assertEquals(1e-4, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2222 | $id = $DB->insert_record($tablename, array('onetext' => 1e-5)); | |
2223 | $this->assertEquals(1e-5, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2224 | $id = $DB->insert_record($tablename, array('onetext' => 1e-300)); | |
2225 | $this->assertEquals(1e-300, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2226 | $id = $DB->insert_record($tablename, array('onetext' => 1e300)); | |
2227 | $this->assertEquals(1e300, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
cbdcdd47 EL |
2228 | |
2229 | // Test that inserting data violating one unique key leads to error. | |
2230 | // Empty the table completely. | |
2231 | $this->assertTrue($DB->delete_records($tablename)); | |
2232 | ||
2233 | // Add one unique constraint (index). | |
2234 | $key = new xmldb_key('testuk', XMLDB_KEY_UNIQUE, array('course', 'oneint')); | |
2235 | $dbman->add_key($table, $key); | |
2236 | ||
2237 | // Let's insert one record violating the constraint multiple times. | |
2238 | $record = (object)array('course' => 1, 'oneint' => 1); | |
9d6d32b6 | 2239 | $this->assertTrue($DB->insert_record($tablename, $record, false)); // Insert 1st. No problem expected. |
cbdcdd47 EL |
2240 | |
2241 | // Re-insert same record, not returning id. dml_exception expected. | |
2242 | try { | |
2243 | $DB->insert_record($tablename, $record, false); | |
2244 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2245 | } catch (moodle_exception $e) { |
2246 | $this->assertInstanceOf('dml_exception', $e); | |
cbdcdd47 EL |
2247 | } |
2248 | ||
2249 | // Re-insert same record, returning id. dml_exception expected. | |
2250 | try { | |
2251 | $DB->insert_record($tablename, $record, true); | |
2252 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2253 | } catch (moodle_exception $e) { |
2254 | $this->assertInstanceOf('dml_exception', $e); | |
cbdcdd47 | 2255 | } |
a3d5830a PS |
2256 | } |
2257 | ||
2258 | public function test_import_record() { | |
2259 | // All the information in this test is fetched from DB by get_recordset() so we | |
2260 | // have such method properly tested against nulls, empties and friends... | |
2261 | ||
2262 | $DB = $this->tdb; | |
2263 | $dbman = $DB->get_manager(); | |
2264 | ||
2265 | $table = $this->get_test_table(); | |
2266 | $tablename = $table->getName(); | |
2267 | ||
9d6d32b6 PS |
2268 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2269 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
2270 | $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', null, null, null, 100); | |
a3d5830a PS |
2271 | $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200); |
2272 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring'); | |
2273 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); | |
2274 | $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null); | |
2275 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
2276 | $dbman->create_table($table); | |
2277 | ||
2278 | $this->assertSame(1, $DB->insert_record($tablename, array('course' => 1), true)); | |
2279 | $record = $DB->get_record($tablename, array('course' => 1)); | |
2280 | $this->assertEquals(1, $record->id); | |
9d6d32b6 | 2281 | $this->assertEquals(100, $record->oneint); // Just check column defaults have been applied. |
a3d5830a PS |
2282 | $this->assertEquals(200, $record->onenum); |
2283 | $this->assertSame('onestring', $record->onechar); | |
2284 | $this->assertNull($record->onetext); | |
2285 | $this->assertNull($record->onebinary); | |
2286 | ||
9d6d32b6 | 2287 | // Ignore extra columns. |
a3d5830a PS |
2288 | $record = (object)array('id'=>13, 'course'=>2, 'xxxx'=>788778); |
2289 | $before = clone($record); | |
9d6d32b6 | 2290 | $this->assertTrue($DB->import_record($tablename, $record)); |
a3d5830a PS |
2291 | $this->assertEquals($record, $before); |
2292 | $records = $DB->get_records($tablename); | |
2293 | $this->assertEquals(2, $records[13]->course); | |
2294 | ||
9d6d32b6 | 2295 | // Check nulls are set properly for all types. |
a3d5830a PS |
2296 | $record = new stdClass(); |
2297 | $record->id = 20; | |
2298 | $record->oneint = null; | |
2299 | $record->onenum = null; | |
2300 | $record->onechar = null; | |
2301 | $record->onetext = null; | |
2302 | $record->onebinary = null; | |
2303 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2304 | $record = $DB->get_record($tablename, array('id' => 20)); | |
2305 | $this->assertEquals(0, $record->course); | |
2306 | $this->assertNull($record->oneint); | |
2307 | $this->assertNull($record->onenum); | |
2308 | $this->assertNull($record->onechar); | |
2309 | $this->assertNull($record->onetext); | |
2310 | $this->assertNull($record->onebinary); | |
2311 | ||
9d6d32b6 | 2312 | // Check zeros are set properly for all types. |
a3d5830a PS |
2313 | $record = new stdClass(); |
2314 | $record->id = 23; | |
2315 | $record->oneint = 0; | |
2316 | $record->onenum = 0; | |
2317 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2318 | $record = $DB->get_record($tablename, array('id' => 23)); | |
2319 | $this->assertEquals(0, $record->oneint); | |
2320 | $this->assertEquals(0, $record->onenum); | |
2321 | ||
9d6d32b6 | 2322 | // Check string data causes exception in numeric types. |
a3d5830a PS |
2323 | $record = new stdClass(); |
2324 | $record->id = 32; | |
2325 | $record->oneint = 'onestring'; | |
2326 | $record->onenum = 0; | |
2327 | try { | |
2328 | $DB->import_record($tablename, $record); | |
2329 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2330 | } catch (moodle_exception $e) { |
2331 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2332 | } |
2333 | $record = new stdClass(); | |
2334 | $record->id = 35; | |
2335 | $record->oneint = 0; | |
2336 | $record->onenum = 'onestring'; | |
2337 | try { | |
2338 | $DB->import_record($tablename, $record); | |
2339 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2340 | } catch (moodle_exception $e) { |
2341 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2342 | } |
2343 | ||
9d6d32b6 | 2344 | // Check empty strings are set properly in string types. |
a3d5830a PS |
2345 | $record = new stdClass(); |
2346 | $record->id = 44; | |
2347 | $record->oneint = 0; | |
2348 | $record->onenum = 0; | |
2349 | $record->onechar = ''; | |
2350 | $record->onetext = ''; | |
2351 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2352 | $record = $DB->get_record($tablename, array('id' => 44)); | |
2353 | $this->assertTrue($record->onechar === ''); | |
2354 | $this->assertTrue($record->onetext === ''); | |
2355 | ||
9d6d32b6 | 2356 | // Check operation ((210.10 + 39.92) - 150.02) against numeric types. |
a3d5830a PS |
2357 | $record = new stdClass(); |
2358 | $record->id = 47; | |
2359 | $record->oneint = ((210.10 + 39.92) - 150.02); | |
2360 | $record->onenum = ((210.10 + 39.92) - 150.02); | |
2361 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2362 | $record = $DB->get_record($tablename, array('id' => 47)); | |
2363 | $this->assertEquals(100, $record->oneint); | |
2364 | $this->assertEquals(100, $record->onenum); | |
2365 | ||
9d6d32b6 | 2366 | // Check various quotes/backslashes combinations in string types. |
a3d5830a PS |
2367 | $i = 50; |
2368 | $teststrings = array( | |
2369 | 'backslashes and quotes alone (even): "" \'\' \\\\', | |
2370 | 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\', | |
2371 | 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'', | |
2372 | 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\''); | |
2373 | foreach ($teststrings as $teststring) { | |
2374 | $record = new stdClass(); | |
2375 | $record->id = $i; | |
2376 | $record->onechar = $teststring; | |
2377 | $record->onetext = $teststring; | |
2378 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2379 | $record = $DB->get_record($tablename, array('id' => $i)); | |
2380 | $this->assertEquals($teststring, $record->onechar); | |
2381 | $this->assertEquals($teststring, $record->onetext); | |
2382 | $i = $i + 3; | |
2383 | } | |
2384 | ||
9d6d32b6 | 2385 | // Check LOBs in text/binary columns. |
a3d5830a PS |
2386 | $clob = file_get_contents(__DIR__ . '/fixtures/clob.txt'); |
2387 | $record = new stdClass(); | |
2388 | $record->id = 70; | |
2389 | $record->onetext = $clob; | |
2390 | $record->onebinary = ''; | |
2391 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2392 | $rs = $DB->get_recordset($tablename, array('id' => 70)); | |
2393 | $record = $rs->current(); | |
2394 | $rs->close(); | |
2395 | $this->assertEquals($clob, $record->onetext, 'Test CLOB insert (full contents output disabled)'); | |
2396 | ||
2397 | $blob = file_get_contents(__DIR__ . '/fixtures/randombinary'); | |
2398 | $record = new stdClass(); | |
2399 | $record->id = 71; | |
2400 | $record->onetext = ''; | |
2401 | $record->onebinary = $blob; | |
2402 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2403 | $rs = $DB->get_recordset($tablename, array('id' => 71)); | |
2404 | $record = $rs->current(); | |
2405 | $rs->close(); | |
2406 | $this->assertEquals($blob, $record->onebinary, 'Test BLOB insert (full contents output disabled)'); | |
2407 | ||
9d6d32b6 | 2408 | // And "small" LOBs too, just in case. |
a3d5830a PS |
2409 | $newclob = substr($clob, 0, 500); |
2410 | $newblob = substr($blob, 0, 250); | |
2411 | $record = new stdClass(); | |
2412 | $record->id = 73; | |
2413 | $record->onetext = $newclob; | |
2414 | $record->onebinary = $newblob; | |
2415 | $this->assertTrue($DB->import_record($tablename, $record)); | |
2416 | $rs = $DB->get_recordset($tablename, array('id' => 73)); | |
2417 | $record = $rs->current(); | |
2418 | $rs->close(); | |
2419 | $this->assertEquals($newclob, $record->onetext, 'Test "small" CLOB insert (full contents output disabled)'); | |
2420 | $this->assertEquals($newblob, $record->onebinary, 'Test "small" BLOB insert (full contents output disabled)'); | |
9d6d32b6 | 2421 | $this->assertEquals(false, $rs->key()); // Ensure recordset key() method to be working ok after closing. |
a3d5830a PS |
2422 | } |
2423 | ||
2424 | public function test_update_record_raw() { | |
2425 | $DB = $this->tdb; | |
2426 | $dbman = $DB->get_manager(); | |
2427 | ||
2428 | $table = $this->get_test_table(); | |
2429 | $tablename = $table->getName(); | |
2430 | ||
9d6d32b6 PS |
2431 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2432 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
2433 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
2434 | $dbman->create_table($table); | |
2435 | ||
2436 | $DB->insert_record($tablename, array('course' => 1)); | |
2437 | $DB->insert_record($tablename, array('course' => 3)); | |
2438 | ||
2439 | $record = $DB->get_record($tablename, array('course' => 1)); | |
2440 | $record->course = 2; | |
2441 | $this->assertTrue($DB->update_record_raw($tablename, $record)); | |
2442 | $this->assertEquals(0, $DB->count_records($tablename, array('course' => 1))); | |
2443 | $this->assertEquals(1, $DB->count_records($tablename, array('course' => 2))); | |
2444 | $this->assertEquals(1, $DB->count_records($tablename, array('course' => 3))); | |
2445 | ||
2446 | $record = $DB->get_record($tablename, array('course' => 3)); | |
2447 | $record->xxxxx = 2; | |
2448 | try { | |
2449 | $DB->update_record_raw($tablename, $record); | |
2450 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2451 | } catch (moodle_exception $e) { |
2452 | $this->assertInstanceOf('moodle_exception', $e); | |
a3d5830a PS |
2453 | } |
2454 | ||
2455 | $record = $DB->get_record($tablename, array('course' => 3)); | |
2456 | unset($record->id); | |
2457 | try { | |
2458 | $DB->update_record_raw($tablename, $record); | |
2459 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2460 | } catch (moodle_exception $e) { |
2461 | $this->assertInstanceOf('coding_exception', $e); | |
a3d5830a PS |
2462 | } |
2463 | } | |
2464 | ||
2465 | public function test_update_record() { | |
2466 | ||
2467 | // All the information in this test is fetched from DB by get_record() so we | |
2468 | // have such method properly tested against nulls, empties and friends... | |
2469 | ||
2470 | $DB = $this->tdb; | |
2471 | $dbman = $DB->get_manager(); | |
2472 | ||
2473 | $table = $this->get_test_table(); | |
2474 | $tablename = $table->getName(); | |
2475 | ||
9d6d32b6 PS |
2476 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2477 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
2478 | $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', null, null, null, 100); | |
a3d5830a PS |
2479 | $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null, 200); |
2480 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null, 'onestring'); | |
2481 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); | |
2482 | $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null); | |
2483 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
2484 | $dbman->create_table($table); | |
2485 | ||
2486 | $DB->insert_record($tablename, array('course' => 1)); | |
2487 | $record = $DB->get_record($tablename, array('course' => 1)); | |
2488 | $record->course = 2; | |
2489 | ||
2490 | $this->assertTrue($DB->update_record($tablename, $record)); | |
2491 | $this->assertFalse($record = $DB->get_record($tablename, array('course' => 1))); | |
2492 | $this->assertNotEmpty($record = $DB->get_record($tablename, array('course' => 2))); | |
9d6d32b6 | 2493 | $this->assertEquals(100, $record->oneint); // Just check column defaults have been applied. |
a3d5830a | 2494 | $this->assertEquals(200, $record->onenum); |
9d6d32b6 | 2495 | $this->assertSame('onestring', $record->onechar); |
a3d5830a PS |
2496 | $this->assertNull($record->onetext); |
2497 | $this->assertNull($record->onebinary); | |
2498 | ||
9d6d32b6 | 2499 | // Check nulls are set properly for all types. |
a3d5830a PS |
2500 | $record->oneint = null; |
2501 | $record->onenum = null; | |
2502 | $record->onechar = null; | |
2503 | $record->onetext = null; | |
2504 | $record->onebinary = null; | |
2505 | $DB->update_record($tablename, $record); | |
2506 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2507 | $this->assertNull($record->oneint); | |
2508 | $this->assertNull($record->onenum); | |
2509 | $this->assertNull($record->onechar); | |
2510 | $this->assertNull($record->onetext); | |
2511 | $this->assertNull($record->onebinary); | |
2512 | ||
9d6d32b6 | 2513 | // Check zeros are set properly for all types. |
a3d5830a PS |
2514 | $record->oneint = 0; |
2515 | $record->onenum = 0; | |
2516 | $DB->update_record($tablename, $record); | |
2517 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2518 | $this->assertEquals(0, $record->oneint); | |
2519 | $this->assertEquals(0, $record->onenum); | |
2520 | ||
9d6d32b6 PS |
2521 | // Check booleans are set properly for all types. |
2522 | $record->oneint = true; // Trues. | |
a3d5830a PS |
2523 | $record->onenum = true; |
2524 | $record->onechar = true; | |
2525 | $record->onetext = true; | |
2526 | $DB->update_record($tablename, $record); | |
2527 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2528 | $this->assertEquals(1, $record->oneint); | |
2529 | $this->assertEquals(1, $record->onenum); | |
2530 | $this->assertEquals(1, $record->onechar); | |
2531 | $this->assertEquals(1, $record->onetext); | |
2532 | ||
9d6d32b6 | 2533 | $record->oneint = false; // Falses. |
a3d5830a PS |
2534 | $record->onenum = false; |
2535 | $record->onechar = false; | |
2536 | $record->onetext = false; | |
2537 | $DB->update_record($tablename, $record); | |
2538 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2539 | $this->assertEquals(0, $record->oneint); | |
2540 | $this->assertEquals(0, $record->onenum); | |
2541 | $this->assertEquals(0, $record->onechar); | |
2542 | $this->assertEquals(0, $record->onetext); | |
2543 | ||
9d6d32b6 | 2544 | // Check string data causes exception in numeric types. |
a3d5830a PS |
2545 | $record->oneint = 'onestring'; |
2546 | $record->onenum = 0; | |
2547 | try { | |
2548 | $DB->update_record($tablename, $record); | |
2549 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2550 | } catch (moodle_exception $e) { |
2551 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2552 | } |
2553 | $record->oneint = 0; | |
2554 | $record->onenum = 'onestring'; | |
2555 | try { | |
2556 | $DB->update_record($tablename, $record); | |
2557 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2558 | } catch (moodle_exception $e) { |
2559 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2560 | } |
2561 | ||
9d6d32b6 PS |
2562 | // Check empty string data is stored as 0 in numeric datatypes. |
2563 | $record->oneint = ''; // Empty string. | |
a3d5830a PS |
2564 | $record->onenum = 0; |
2565 | $DB->update_record($tablename, $record); | |
2566 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2567 | $this->assertTrue(is_numeric($record->oneint) && $record->oneint == 0); | |
2568 | ||
2569 | $record->oneint = 0; | |
9d6d32b6 | 2570 | $record->onenum = ''; // Empty string. |
a3d5830a PS |
2571 | $DB->update_record($tablename, $record); |
2572 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2573 | $this->assertTrue(is_numeric($record->onenum) && $record->onenum == 0); | |
2574 | ||
9d6d32b6 | 2575 | // Check empty strings are set properly in string types. |
a3d5830a PS |
2576 | $record->oneint = 0; |
2577 | $record->onenum = 0; | |
2578 | $record->onechar = ''; | |
2579 | $record->onetext = ''; | |
2580 | $DB->update_record($tablename, $record); | |
2581 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2582 | $this->assertTrue($record->onechar === ''); | |
2583 | $this->assertTrue($record->onetext === ''); | |
2584 | ||
9d6d32b6 | 2585 | // Check operation ((210.10 + 39.92) - 150.02) against numeric types. |
a3d5830a PS |
2586 | $record->oneint = ((210.10 + 39.92) - 150.02); |
2587 | $record->onenum = ((210.10 + 39.92) - 150.02); | |
2588 | $DB->update_record($tablename, $record); | |
2589 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2590 | $this->assertEquals(100, $record->oneint); | |
2591 | $this->assertEquals(100, $record->onenum); | |
2592 | ||
9d6d32b6 | 2593 | // Check various quotes/backslashes combinations in string types. |
a3d5830a PS |
2594 | $teststrings = array( |
2595 | 'backslashes and quotes alone (even): "" \'\' \\\\', | |
2596 | 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\', | |
2597 | 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'', | |
2598 | 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\''); | |
2599 | foreach ($teststrings as $teststring) { | |
2600 | $record->onechar = $teststring; | |
2601 | $record->onetext = $teststring; | |
2602 | $DB->update_record($tablename, $record); | |
2603 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2604 | $this->assertEquals($teststring, $record->onechar); | |
2605 | $this->assertEquals($teststring, $record->onetext); | |
2606 | } | |
2607 | ||
9d6d32b6 | 2608 | // Check LOBs in text/binary columns. |
a3d5830a PS |
2609 | $clob = file_get_contents(__DIR__ . '/fixtures/clob.txt'); |
2610 | $blob = file_get_contents(__DIR__ . '/fixtures/randombinary'); | |
2611 | $record->onetext = $clob; | |
2612 | $record->onebinary = $blob; | |
2613 | $DB->update_record($tablename, $record); | |
2614 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2615 | $this->assertEquals($clob, $record->onetext, 'Test CLOB update (full contents output disabled)'); | |
2616 | $this->assertEquals($blob, $record->onebinary, 'Test BLOB update (full contents output disabled)'); | |
2617 | ||
9d6d32b6 | 2618 | // And "small" LOBs too, just in case. |
a3d5830a PS |
2619 | $newclob = substr($clob, 0, 500); |
2620 | $newblob = substr($blob, 0, 250); | |
2621 | $record->onetext = $newclob; | |
2622 | $record->onebinary = $newblob; | |
2623 | $DB->update_record($tablename, $record); | |
2624 | $record = $DB->get_record($tablename, array('course' => 2)); | |
2625 | $this->assertEquals($newclob, $record->onetext, 'Test "small" CLOB update (full contents output disabled)'); | |
2626 | $this->assertEquals($newblob, $record->onebinary, 'Test "small" BLOB update (full contents output disabled)'); | |
2627 | ||
2628 | // Test saving a float in a CHAR column, and reading it back. | |
2629 | $id = $DB->insert_record($tablename, array('onechar' => 'X')); | |
2630 | $DB->update_record($tablename, array('id' => $id, 'onechar' => 1.0)); | |
2631 | $this->assertEquals(1.0, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2632 | $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e20)); | |
2633 | $this->assertEquals(1e20, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2634 | $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e-4)); | |
2635 | $this->assertEquals(1e-4, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2636 | $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e-5)); | |
2637 | $this->assertEquals(1e-5, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2638 | $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e-300)); | |
2639 | $this->assertEquals(1e-300, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2640 | $DB->update_record($tablename, array('id' => $id, 'onechar' => 1e300)); | |
2641 | $this->assertEquals(1e300, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2642 | ||
2643 | // Test saving a float in a TEXT column, and reading it back. | |
2644 | $id = $DB->insert_record($tablename, array('onetext' => 'X')); | |
2645 | $DB->update_record($tablename, array('id' => $id, 'onetext' => 1.0)); | |
2646 | $this->assertEquals(1.0, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2647 | $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e20)); | |
2648 | $this->assertEquals(1e20, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2649 | $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e-4)); | |
2650 | $this->assertEquals(1e-4, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2651 | $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e-5)); | |
2652 | $this->assertEquals(1e-5, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2653 | $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e-300)); | |
2654 | $this->assertEquals(1e-300, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2655 | $DB->update_record($tablename, array('id' => $id, 'onetext' => 1e300)); | |
2656 | $this->assertEquals(1e300, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2657 | } | |
2658 | ||
2659 | public function test_set_field() { | |
2660 | $DB = $this->tdb; | |
2661 | $dbman = $DB->get_manager(); | |
2662 | ||
2663 | $table = $this->get_test_table(); | |
2664 | $tablename = $table->getName(); | |
2665 | ||
9d6d32b6 PS |
2666 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2667 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
2668 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null); |
2669 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); | |
2670 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
2671 | $dbman->create_table($table); | |
2672 | ||
9d6d32b6 | 2673 | // Simple set_field. |
a3d5830a PS |
2674 | $id1 = $DB->insert_record($tablename, array('course' => 1)); |
2675 | $id2 = $DB->insert_record($tablename, array('course' => 1)); | |
2676 | $id3 = $DB->insert_record($tablename, array('course' => 3)); | |
2677 | $this->assertTrue($DB->set_field($tablename, 'course', 2, array('id' => $id1))); | |
2678 | $this->assertEquals(2, $DB->get_field($tablename, 'course', array('id' => $id1))); | |
2679 | $this->assertEquals(1, $DB->get_field($tablename, 'course', array('id' => $id2))); | |
2680 | $this->assertEquals(3, $DB->get_field($tablename, 'course', array('id' => $id3))); | |
2681 | $DB->delete_records($tablename, array()); | |
2682 | ||
9d6d32b6 | 2683 | // Multiple fields affected. |
a3d5830a PS |
2684 | $id1 = $DB->insert_record($tablename, array('course' => 1)); |
2685 | $id2 = $DB->insert_record($tablename, array('course' => 1)); | |
2686 | $id3 = $DB->insert_record($tablename, array('course' => 3)); | |
2687 | $DB->set_field($tablename, 'course', '5', array('course' => 1)); | |
2688 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('id' => $id1))); | |
2689 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('id' => $id2))); | |
2690 | $this->assertEquals(3, $DB->get_field($tablename, 'course', array('id' => $id3))); | |
2691 | $DB->delete_records($tablename, array()); | |
2692 | ||
9d6d32b6 | 2693 | // No field affected. |
a3d5830a PS |
2694 | $id1 = $DB->insert_record($tablename, array('course' => 1)); |
2695 | $id2 = $DB->insert_record($tablename, array('course' => 1)); | |
2696 | $id3 = $DB->insert_record($tablename, array('course' => 3)); | |
2697 | $DB->set_field($tablename, 'course', '5', array('course' => 0)); | |
2698 | $this->assertEquals(1, $DB->get_field($tablename, 'course', array('id' => $id1))); | |
2699 | $this->assertEquals(1, $DB->get_field($tablename, 'course', array('id' => $id2))); | |
2700 | $this->assertEquals(3, $DB->get_field($tablename, 'course', array('id' => $id3))); | |
2701 | $DB->delete_records($tablename, array()); | |
2702 | ||
9d6d32b6 | 2703 | // All fields - no condition. |
a3d5830a PS |
2704 | $id1 = $DB->insert_record($tablename, array('course' => 1)); |
2705 | $id2 = $DB->insert_record($tablename, array('course' => 1)); | |
2706 | $id3 = $DB->insert_record($tablename, array('course' => 3)); | |
2707 | $DB->set_field($tablename, 'course', 5, array()); | |
2708 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('id' => $id1))); | |
2709 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('id' => $id2))); | |
2710 | $this->assertEquals(5, $DB->get_field($tablename, 'course', array('id' => $id3))); | |
2711 | ||
9d6d32b6 | 2712 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
2713 | $conditions = array('onetext' => '1'); |
2714 | try { | |
2715 | $DB->set_field($tablename, 'onechar', 'frog', $conditions); | |
2716 | if (debugging()) { | |
9d6d32b6 | 2717 | // Only in debug mode - hopefully all devs test code in debug mode... |
a3d5830a PS |
2718 | $this->fail('An Exception is missing, expected due to equating of text fields'); |
2719 | } | |
9d6d32b6 PS |
2720 | } catch (moodle_exception $e) { |
2721 | $this->assertInstanceOf('dml_exception', $e); | |
2722 | $this->assertSame('textconditionsnotallowed', $e->errorcode); | |
a3d5830a PS |
2723 | } |
2724 | ||
2725 | // Test saving a float in a CHAR column, and reading it back. | |
2726 | $id = $DB->insert_record($tablename, array('onechar' => 'X')); | |
2727 | $DB->set_field($tablename, 'onechar', 1.0, array('id' => $id)); | |
2728 | $this->assertEquals(1.0, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2729 | $DB->set_field($tablename, 'onechar', 1e20, array('id' => $id)); | |
2730 | $this->assertEquals(1e20, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2731 | $DB->set_field($tablename, 'onechar', 1e-4, array('id' => $id)); | |
2732 | $this->assertEquals(1e-4, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2733 | $DB->set_field($tablename, 'onechar', 1e-5, array('id' => $id)); | |
2734 | $this->assertEquals(1e-5, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2735 | $DB->set_field($tablename, 'onechar', 1e-300, array('id' => $id)); | |
2736 | $this->assertEquals(1e-300, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2737 | $DB->set_field($tablename, 'onechar', 1e300, array('id' => $id)); | |
2738 | $this->assertEquals(1e300, $DB->get_field($tablename, 'onechar', array('id' => $id))); | |
2739 | ||
2740 | // Test saving a float in a TEXT column, and reading it back. | |
2741 | $id = $DB->insert_record($tablename, array('onetext' => 'X')); | |
2742 | $DB->set_field($tablename, 'onetext', 1.0, array('id' => $id)); | |
2743 | $this->assertEquals(1.0, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2744 | $DB->set_field($tablename, 'onetext', 1e20, array('id' => $id)); | |
2745 | $this->assertEquals(1e20, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2746 | $DB->set_field($tablename, 'onetext', 1e-4, array('id' => $id)); | |
2747 | $this->assertEquals(1e-4, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2748 | $DB->set_field($tablename, 'onetext', 1e-5, array('id' => $id)); | |
2749 | $this->assertEquals(1e-5, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2750 | $DB->set_field($tablename, 'onetext', 1e-300, array('id' => $id)); | |
2751 | $this->assertEquals(1e-300, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2752 | $DB->set_field($tablename, 'onetext', 1e300, array('id' => $id)); | |
2753 | $this->assertEquals(1e300, $DB->get_field($tablename, 'onetext', array('id' => $id))); | |
2754 | ||
2755 | // Note: All the nulls, booleans, empties, quoted and backslashes tests | |
9d6d32b6 | 2756 | // go to set_field_select() because set_field() is just one wrapper over it. |
a3d5830a PS |
2757 | } |
2758 | ||
2759 | public function test_set_field_select() { | |
2760 | ||
2761 | // All the information in this test is fetched from DB by get_field() so we | |
2762 | // have such method properly tested against nulls, empties and friends... | |
2763 | ||
2764 | $DB = $this->tdb; | |
2765 | $dbman = $DB->get_manager(); | |
2766 | ||
2767 | $table = $this->get_test_table(); | |
2768 | $tablename = $table->getName(); | |
2769 | ||
9d6d32b6 PS |
2770 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2771 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
2772 | $table->add_field('oneint', XMLDB_TYPE_INTEGER, '10', null, null, null); | |
a3d5830a PS |
2773 | $table->add_field('onenum', XMLDB_TYPE_NUMBER, '10,2', null, null, null); |
2774 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null); | |
2775 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); | |
2776 | $table->add_field('onebinary', XMLDB_TYPE_BINARY, 'big', null, null, null); | |
2777 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
2778 | $dbman->create_table($table); | |
2779 | ||
2780 | $DB->insert_record($tablename, array('course' => 1)); | |
2781 | ||
2782 | $this->assertTrue($DB->set_field_select($tablename, 'course', 2, 'id = ?', array(1))); | |
2783 | $this->assertEquals(2, $DB->get_field($tablename, 'course', array('id' => 1))); | |
2784 | ||
9d6d32b6 PS |
2785 | // Check nulls are set properly for all types. |
2786 | $DB->set_field_select($tablename, 'oneint', null, 'id = ?', array(1)); // Trues. | |
a3d5830a PS |
2787 | $DB->set_field_select($tablename, 'onenum', null, 'id = ?', array(1)); |
2788 | $DB->set_field_select($tablename, 'onechar', null, 'id = ?', array(1)); | |
2789 | $DB->set_field_select($tablename, 'onetext', null, 'id = ?', array(1)); | |
2790 | $DB->set_field_select($tablename, 'onebinary', null, 'id = ?', array(1)); | |
2791 | $this->assertNull($DB->get_field($tablename, 'oneint', array('id' => 1))); | |
2792 | $this->assertNull($DB->get_field($tablename, 'onenum', array('id' => 1))); | |
2793 | $this->assertNull($DB->get_field($tablename, 'onechar', array('id' => 1))); | |
2794 | $this->assertNull($DB->get_field($tablename, 'onetext', array('id' => 1))); | |
2795 | $this->assertNull($DB->get_field($tablename, 'onebinary', array('id' => 1))); | |
2796 | ||
9d6d32b6 | 2797 | // Check zeros are set properly for all types. |
a3d5830a PS |
2798 | $DB->set_field_select($tablename, 'oneint', 0, 'id = ?', array(1)); |
2799 | $DB->set_field_select($tablename, 'onenum', 0, 'id = ?', array(1)); | |
2800 | $this->assertEquals(0, $DB->get_field($tablename, 'oneint', array('id' => 1))); | |
2801 | $this->assertEquals(0, $DB->get_field($tablename, 'onenum', array('id' => 1))); | |
2802 | ||
9d6d32b6 PS |
2803 | // Check booleans are set properly for all types. |
2804 | $DB->set_field_select($tablename, 'oneint', true, 'id = ?', array(1)); // Trues. | |
a3d5830a PS |
2805 | $DB->set_field_select($tablename, 'onenum', true, 'id = ?', array(1)); |
2806 | $DB->set_field_select($tablename, 'onechar', true, 'id = ?', array(1)); | |
2807 | $DB->set_field_select($tablename, 'onetext', true, 'id = ?', array(1)); | |
2808 | $this->assertEquals(1, $DB->get_field($tablename, 'oneint', array('id' => 1))); | |
2809 | $this->assertEquals(1, $DB->get_field($tablename, 'onenum', array('id' => 1))); | |
2810 | $this->assertEquals(1, $DB->get_field($tablename, 'onechar', array('id' => 1))); | |
2811 | $this->assertEquals(1, $DB->get_field($tablename, 'onetext', array('id' => 1))); | |
2812 | ||
9d6d32b6 | 2813 | $DB->set_field_select($tablename, 'oneint', false, 'id = ?', array(1)); // Falses. |
a3d5830a PS |
2814 | $DB->set_field_select($tablename, 'onenum', false, 'id = ?', array(1)); |
2815 | $DB->set_field_select($tablename, 'onechar', false, 'id = ?', array(1)); | |
2816 | $DB->set_field_select($tablename, 'onetext', false, 'id = ?', array(1)); | |
2817 | $this->assertEquals(0, $DB->get_field($tablename, 'oneint', array('id' => 1))); | |
2818 | $this->assertEquals(0, $DB->get_field($tablename, 'onenum', array('id' => 1))); | |
2819 | $this->assertEquals(0, $DB->get_field($tablename, 'onechar', array('id' => 1))); | |
2820 | $this->assertEquals(0, $DB->get_field($tablename, 'onetext', array('id' => 1))); | |
2821 | ||
9d6d32b6 | 2822 | // Check string data causes exception in numeric types. |
a3d5830a PS |
2823 | try { |
2824 | $DB->set_field_select($tablename, 'oneint', 'onestring', 'id = ?', array(1)); | |
2825 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2826 | } catch (moodle_exception $e) { |
2827 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2828 | } |
2829 | try { | |
2830 | $DB->set_field_select($tablename, 'onenum', 'onestring', 'id = ?', array(1)); | |
2831 | $this->fail("Expecting an exception, none occurred"); | |
9d6d32b6 PS |
2832 | } catch (moodle_exception $e) { |
2833 | $this->assertInstanceOf('dml_exception', $e); | |
a3d5830a PS |
2834 | } |
2835 | ||
9d6d32b6 | 2836 | // Check empty string data is stored as 0 in numeric datatypes. |
a3d5830a PS |
2837 | $DB->set_field_select($tablename, 'oneint', '', 'id = ?', array(1)); |
2838 | $field = $DB->get_field($tablename, 'oneint', array('id' => 1)); | |
2839 | $this->assertTrue(is_numeric($field) && $field == 0); | |
2840 | ||
2841 | $DB->set_field_select($tablename, 'onenum', '', 'id = ?', array(1)); | |
2842 | $field = $DB->get_field($tablename, 'onenum', array('id' => 1)); | |
2843 | $this->assertTrue(is_numeric($field) && $field == 0); | |
2844 | ||
9d6d32b6 | 2845 | // Check empty strings are set properly in string types. |
a3d5830a PS |
2846 | $DB->set_field_select($tablename, 'onechar', '', 'id = ?', array(1)); |
2847 | $DB->set_field_select($tablename, 'onetext', '', 'id = ?', array(1)); | |
2848 | $this->assertTrue($DB->get_field($tablename, 'onechar', array('id' => 1)) === ''); | |
2849 | $this->assertTrue($DB->get_field($tablename, 'onetext', array('id' => 1)) === ''); | |
2850 | ||
9d6d32b6 | 2851 | // Check operation ((210.10 + 39.92) - 150.02) against numeric types. |
a3d5830a PS |
2852 | $DB->set_field_select($tablename, 'oneint', ((210.10 + 39.92) - 150.02), 'id = ?', array(1)); |
2853 | $DB->set_field_select($tablename, 'onenum', ((210.10 + 39.92) - 150.02), 'id = ?', array(1)); | |
2854 | $this->assertEquals(100, $DB->get_field($tablename, 'oneint', array('id' => 1))); | |
2855 | $this->assertEquals(100, $DB->get_field($tablename, 'onenum', array('id' => 1))); | |
2856 | ||
9d6d32b6 | 2857 | // Check various quotes/backslashes combinations in string types. |
a3d5830a PS |
2858 | $teststrings = array( |
2859 | 'backslashes and quotes alone (even): "" \'\' \\\\', | |
2860 | 'backslashes and quotes alone (odd): """ \'\'\' \\\\\\', | |
2861 | 'backslashes and quotes sequences (even): \\"\\" \\\'\\\'', | |
2862 | 'backslashes and quotes sequences (odd): \\"\\"\\" \\\'\\\'\\\''); | |
2863 | foreach ($teststrings as $teststring) { | |
2864 | $DB->set_field_select($tablename, 'onechar', $teststring, 'id = ?', array(1)); | |
2865 | $DB->set_field_select($tablename, 'onetext', $teststring, 'id = ?', array(1)); | |
2866 | $this->assertEquals($teststring, $DB->get_field($tablename, 'onechar', array('id' => 1))); | |
2867 | $this->assertEquals($teststring, $DB->get_field($tablename, 'onetext', array('id' => 1))); | |
2868 | } | |
2869 | ||
9d6d32b6 | 2870 | // Check LOBs in text/binary columns. |
a3d5830a PS |
2871 | $clob = file_get_contents(__DIR__ . '/fixtures/clob.txt'); |
2872 | $blob = file_get_contents(__DIR__ . '/fixtures/randombinary'); | |
2873 | $DB->set_field_select($tablename, 'onetext', $clob, 'id = ?', array(1)); | |
2874 | $DB->set_field_select($tablename, 'onebinary', $blob, 'id = ?', array(1)); | |
2875 | $this->assertEquals($clob, $DB->get_field($tablename, 'onetext', array('id' => 1)), 'Test CLOB set_field (full contents output disabled)'); | |
2876 | $this->assertEquals($blob, $DB->get_field($tablename, 'onebinary', array('id' => 1)), 'Test BLOB set_field (full contents output disabled)'); | |
2877 | ||
9d6d32b6 | 2878 | // And "small" LOBs too, just in case. |
a3d5830a PS |
2879 | $newclob = substr($clob, 0, 500); |
2880 | $newblob = substr($blob, 0, 250); | |
2881 | $DB->set_field_select($tablename, 'onetext', $newclob, 'id = ?', array(1)); | |
2882 | $DB->set_field_select($tablename, 'onebinary', $newblob, 'id = ?', array(1)); | |
2883 | $this->assertEquals($newclob, $DB->get_field($tablename, 'onetext', array('id' => 1)), 'Test "small" CLOB set_field (full contents output disabled)'); | |
2884 | $this->assertEquals($newblob, $DB->get_field($tablename, 'onebinary', array('id' => 1)), 'Test "small" BLOB set_field (full contents output disabled)'); | |
2885 | ||
2886 | // This is the failure from MDL-24863. This was giving an error on MSSQL, | |
2887 | // which converts the '1' to an integer, which cannot then be compared with | |
2888 | // onetext cast to a varchar. This should be fixed and working now. | |
2889 | $newchar = 'frog'; | |
9d6d32b6 | 2890 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
2891 | $params = array('onetext' => '1'); |
2892 | try { | |
2893 | $DB->set_field_select($tablename, 'onechar', $newchar, $DB->sql_compare_text('onetext') . ' = ?', $params); | |
2894 | $this->assertTrue(true, 'No exceptions thrown with numerical text param comparison for text field.'); | |
2895 | } catch (dml_exception $e) { | |
2896 | $this->assertFalse(true, 'We have an unexpected exception.'); | |
2897 | throw $e; | |
2898 | } | |
a3d5830a PS |
2899 | } |
2900 | ||
2901 | public function test_count_records() { | |
2902 | $DB = $this->tdb; | |
2903 | ||
2904 | $dbman = $DB->get_manager(); | |
2905 | ||
2906 | $table = $this->get_test_table(); | |
2907 | $tablename = $table->getName(); | |
2908 | ||
9d6d32b6 PS |
2909 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2910 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
2911 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); |
2912 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
2913 | $dbman->create_table($table); | |
2914 | ||
63224dee | 2915 | $this->assertSame(0, $DB->count_records($tablename)); |
a3d5830a PS |
2916 | |
2917 | $DB->insert_record($tablename, array('course' => 3)); | |
2918 | $DB->insert_record($tablename, array('course' => 4)); | |
2919 | $DB->insert_record($tablename, array('course' => 5)); | |
2920 | ||
63224dee | 2921 | $this->assertSame(3, $DB->count_records($tablename)); |
a3d5830a | 2922 | |
9d6d32b6 | 2923 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
2924 | $conditions = array('onetext' => '1'); |
2925 | try { | |
2926 | $DB->count_records($tablename, $conditions); | |
2927 | if (debugging()) { | |
9d6d32b6 | 2928 | // Only in debug mode - hopefully all devs test code in debug mode... |
a3d5830a PS |
2929 | $this->fail('An Exception is missing, expected due to equating of text fields'); |
2930 | } | |
9d6d32b6 PS |
2931 | } catch (moodle_exception $e) { |
2932 | $this->assertInstanceOf('dml_exception', $e); | |
2933 | $this->assertSame('textconditionsnotallowed', $e->errorcode); | |
a3d5830a PS |
2934 | } |
2935 | } | |
2936 | ||
2937 | public function test_count_records_select() { | |
2938 | $DB = $this->tdb; | |
2939 | ||
2940 | $dbman = $DB->get_manager(); | |
2941 | ||
2942 | $table = $this->get_test_table(); | |
2943 | $tablename = $table->getName(); | |
2944 | ||
9d6d32b6 PS |
2945 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2946 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
2947 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
2948 | $dbman->create_table($table); | |
2949 | ||
63224dee | 2950 | $this->assertSame(0, $DB->count_records($tablename)); |
a3d5830a PS |
2951 | |
2952 | $DB->insert_record($tablename, array('course' => 3)); | |
2953 | $DB->insert_record($tablename, array('course' => 4)); | |
2954 | $DB->insert_record($tablename, array('course' => 5)); | |
2955 | ||
63224dee | 2956 | $this->assertSame(2, $DB->count_records_select($tablename, 'course > ?', array(3))); |
a3d5830a PS |
2957 | } |
2958 | ||
2959 | public function test_count_records_sql() { | |
2960 | $DB = $this->tdb; | |
2961 | $dbman = $DB->get_manager(); | |
2962 | ||
2963 | $table = $this->get_test_table(); | |
2964 | $tablename = $table->getName(); | |
2965 | ||
9d6d32b6 PS |
2966 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
2967 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
63224dee | 2968 | $table->add_field('onechar', XMLDB_TYPE_CHAR, '100', null, null, null); |
a3d5830a PS |
2969 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
2970 | $dbman->create_table($table); | |
2971 | ||
63224dee | 2972 | $this->assertSame(0, $DB->count_records($tablename)); |
a3d5830a | 2973 | |
63224dee PS |
2974 | $DB->insert_record($tablename, array('course' => 3, 'onechar' => 'a')); |
2975 | $DB->insert_record($tablename, array('course' => 4, 'onechar' => 'b')); | |
2976 | $DB->insert_record($tablename, array('course' => 5, 'onechar' => 'c')); | |
2977 | ||
2978 | $this->assertSame(2, $DB->count_records_sql("SELECT COUNT(*) FROM {{$tablename}} WHERE course > ?", array(3))); | |
a3d5830a | 2979 | |
9d6d32b6 | 2980 | // Test invalid use. |
63224dee PS |
2981 | try { |
2982 | $DB->count_records_sql("SELECT onechar FROM {{$tablename}} WHERE course = ?", array(3)); | |
2983 | $this->fail('Exception expected when non-number field used in count_records_sql'); | |
9d6d32b6 | 2984 | } catch (moodle_exception $e) { |
63224dee PS |
2985 | $this->assertInstanceOf('coding_exception', $e); |
2986 | } | |
2987 | ||
2988 | try { | |
2989 | $DB->count_records_sql("SELECT course FROM {{$tablename}} WHERE 1 = 2"); | |
2990 | $this->fail('Exception expected when non-number field used in count_records_sql'); | |
9d6d32b6 | 2991 | } catch (moodle_exception $e) { |
63224dee PS |
2992 | $this->assertInstanceOf('coding_exception', $e); |
2993 | } | |
a3d5830a PS |
2994 | } |
2995 | ||
2996 | public function test_record_exists() { | |
2997 | $DB = $this->tdb; | |
2998 | $dbman = $DB->get_manager(); | |
2999 | ||
3000 | $table = $this->get_test_table(); | |
3001 | $tablename = $table->getName(); | |
3002 | ||
9d6d32b6 PS |
3003 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
3004 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
3005 | $table->add_field('onetext', XMLDB_TYPE_TEXT, 'big', null, null, null); |
3006 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); | |
3007 | $dbman->create_table($table); | |
3008 | ||
3009 | $this->assertEquals(0, $DB->count_records($tablename)); | |
3010 | ||
3011 | $this->assertFalse($DB->record_exists($tablename, array('course' => 3))); | |
3012 | $DB->insert_record($tablename, array('course' => 3)); | |
3013 | ||
3014 | $this->assertTrue($DB->record_exists($tablename, array('course' => 3))); | |
3015 | ||
9d6d32b6 | 3016 | // Test for exception throwing on text conditions being compared. (MDL-24863, unwanted auto conversion of param to int). |
a3d5830a PS |
3017 | $conditions = array('onetext' => '1'); |
3018 | try { | |
3019 | $DB->record_exists($tablename, $conditions); | |
3020 | if (debugging()) { | |
9d6d32b6 | 3021 | // Only in debug mode - hopefully all devs test code in debug mode... |
a3d5830a PS |
3022 | $this->fail('An Exception is missing, expected due to equating of text fields'); |
3023 | } | |
9d6d32b6 PS |
3024 | } catch (moodle_exception $e) { |
3025 | $this->assertInstanceOf('dml_exception', $e); | |
3026 | $this->assertSame('textconditionsnotallowed', $e->errorcode); | |
a3d5830a PS |
3027 | } |
3028 | } | |
3029 | ||
3030 | public function test_record_exists_select() { | |
3031 | $DB = $this->tdb; | |
3032 | $dbman = $DB->get_manager(); | |
3033 | ||
3034 | $table = $this->get_test_table(); | |
3035 | $tablename = $table->getName(); | |
3036 | ||
9d6d32b6 PS |
3037 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
3038 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
3039 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
3040 | $dbman->create_table($table); | |
3041 | ||
3042 | $this->assertEquals(0, $DB->count_records($tablename)); | |
3043 | ||
3044 | $this->assertFalse($DB->record_exists_select($tablename, "course = ?", array(3))); | |
3045 | $DB->insert_record($tablename, array('course' => 3)); | |
3046 | ||
3047 | $this->assertTrue($DB->record_exists_select($tablename, "course = ?", array(3))); | |
3048 | } | |
3049 | ||
3050 | public function test_record_exists_sql() { | |
3051 | $DB = $this->tdb; | |
3052 | $dbman = $DB->get_manager(); | |
3053 | ||
3054 | $table = $this->get_test_table(); | |
3055 | $tablename = $table->getName(); | |
3056 | ||
9d6d32b6 PS |
3057 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
3058 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
3059 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
3060 | $dbman->create_table($table); | |
3061 | ||
3062 | $this->assertEquals(0, $DB->count_records($tablename)); | |
3063 | ||
3064 | $this->assertFalse($DB->record_exists_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3))); | |
3065 | $DB->insert_record($tablename, array('course' => 3)); | |
3066 | ||
3067 | $this->assertTrue($DB->record_exists_sql("SELECT * FROM {{$tablename}} WHERE course = ?", array(3))); | |
3068 | } | |
3069 | ||
3070 | public function test_recordset_locks_delete() { | |
3071 | $DB = $this->tdb; | |
3072 | $dbman = $DB->get_manager(); | |
3073 | ||
9d6d32b6 | 3074 | // Setup. |
a3d5830a PS |
3075 | $table = $this->get_test_table(); |
3076 | $tablename = $table->getName(); | |
3077 | ||
9d6d32b6 PS |
3078 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
3079 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
3080 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
3081 | $dbman->create_table($table); | |
3082 | ||
3083 | $DB->insert_record($tablename, array('course' => 1)); | |
3084 | $DB->insert_record($tablename, array('course' => 2)); | |
3085 | $DB->insert_record($tablename, array('course' => 3)); | |
3086 | $DB->insert_record($tablename, array('course' => 4)); | |
3087 | $DB->insert_record($tablename, array('course' => 5)); | |
3088 | $DB->insert_record($tablename, array('course' => 6)); | |
3089 | ||
9d6d32b6 PS |
3090 | // Test against db write locking while on an open recordset. |
3091 | $rs = $DB->get_recordset($tablename, array(), null, 'course', 2, 2); // Get courses = {3,4}. | |
a3d5830a PS |
3092 | foreach ($rs as $record) { |
3093 | $cid = $record->course; | |
3094 | $DB->delete_records($tablename, array('course' => $cid)); | |
3095 | $this->assertFalse($DB->record_exists($tablename, array('course' => $cid))); | |
3096 | } | |
3097 | $rs->close(); | |
3098 | ||
3099 | $this->assertEquals(4, $DB->count_records($tablename, array())); | |
3100 | } | |
3101 | ||
3102 | public function test_recordset_locks_update() { | |
3103 | $DB = $this->tdb; | |
3104 | $dbman = $DB->get_manager(); | |
3105 | ||
9d6d32b6 | 3106 | // Setup. |
a3d5830a PS |
3107 | $table = $this->get_test_table(); |
3108 | $tablename = $table->getName(); | |
3109 | ||
9d6d32b6 PS |
3110 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); |
3111 | $table->add_field('course', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | |
a3d5830a PS |
3112 | $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); |
3113 | $dbman->create_table($table); | |
3114 | ||
3115 | $DB->insert_record($tablename, array('course' => 1)); | |
3116 | $DB->insert_record($tablename, array('course' => 2)); | |
3117 | $DB->insert_record($tablename, array('course' => 3)); | |
3118 | $DB->insert_record($tablename, array('course' => 4)); | |
3119 | $DB->insert_record($tablename, array('course' => 5)); | |
3120 | $DB->insert_record($tablename, array('course' => 6)); | |