PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/moodle/lib/dmllib.php

https://bitbucket.org/geek745/moodle-db2
PHP | 2868 lines | 1368 code | 338 blank | 1162 comment | 418 complexity | 4ddce1df93c3545681376329f37cbbf4 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause, LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php // $Id: dmllib.php,v 1.116.2.33 2009/09/26 11:55:57 skodak Exp $
  2. ///////////////////////////////////////////////////////////////////////////
  3. // //
  4. // NOTICE OF COPYRIGHT //
  5. // //
  6. // Moodle - Modular Object-Oriented Dynamic Learning Environment //
  7. // http://moodle.com //
  8. // //
  9. // Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
  10. // //
  11. // This program is free software; you can redistribute it and/or modify //
  12. // it under the terms of the GNU General Public License as published by //
  13. // the Free Software Foundation; either version 2 of the License, or //
  14. // (at your option) any later version. //
  15. // //
  16. // This program is distributed in the hope that it will be useful, //
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of //
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
  19. // GNU General Public License for more details: //
  20. // //
  21. // http://www.gnu.org/copyleft/gpl.html //
  22. // //
  23. ///////////////////////////////////////////////////////////////////////////
  24. /// This library contains all the Data Manipulation Language (DML) functions
  25. /// used to interact with the DB. All the dunctions in this library must be
  26. /// generic and work against the major number of RDBMS possible. This is the
  27. /// list of currently supported and tested DBs: mysql, postresql, mssql, oracle
  28. /// This library is automatically included by Moodle core so you never need to
  29. /// include it yourself.
  30. /// For more info about the functions available in this library, please visit:
  31. /// http://docs.moodle.org/en/DML_functions
  32. /// (feel free to modify, improve and document such page, thanks!)
  33. /// GLOBAL CONSTANTS /////////////////////////////////////////////////////////
  34. $empty_rs_cache = array(); // Keeps copies of the recordsets used in one invocation
  35. $metadata_cache = array(); // Kereeps copies of the MetaColumns() for each table used in one invocations
  36. $rcache = new StdClass; // Cache simple get_record results
  37. $rcache->data = array();
  38. $rcache->hits = 0;
  39. $rcache->misses = 0;
  40. /// FUNCTIONS FOR DATABASE HANDLING ////////////////////////////////
  41. /**
  42. * Execute a given sql command string
  43. *
  44. * Completely general function - it just runs some SQL and reports success.
  45. *
  46. * @uses $db
  47. * @param string $command The sql string you wish to be executed.
  48. * @param bool $feedback Set this argument to true if the results generated should be printed. Default is true.
  49. * @return bool success
  50. */
  51. function execute_sql($command, $feedback=true) {
  52. /// Completely general function - it just runs some SQL and reports success.
  53. global $db, $CFG;
  54. $olddebug = $db->debug;
  55. if (!$feedback) {
  56. $db->debug = false;
  57. }
  58. if ($CFG->version >= 2006101007) { //Look for trailing ; from Moodle 1.7.0
  59. $command = trim($command);
  60. /// If the trailing ; is there, fix and warn!
  61. if (substr($command, strlen($command)-1, 1) == ';') {
  62. /// One noticeable exception, Oracle PL/SQL blocks require ending in ";"
  63. if ($CFG->dbfamily == 'oracle' && substr($command, -4) == 'END;') {
  64. /// Nothing to fix/warn. The command is one PL/SQL block, so it's ok.
  65. } else {
  66. $command = trim($command, ';');
  67. debugging('Warning. Avoid to end your SQL commands with a trailing ";".', DEBUG_DEVELOPER);
  68. }
  69. }
  70. }
  71. $empty_rs_cache = array(); // Clear out the cache, just in case changes were made to table structures
  72. if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
  73. $rs = $db->Execute($command);
  74. $db->debug = $olddebug;
  75. if ($rs) {
  76. if ($feedback) {
  77. notify(get_string('success'), 'notifysuccess');
  78. }
  79. return true;
  80. } else {
  81. if ($feedback) {
  82. notify('<strong>' . get_string('error') . '</strong>');
  83. }
  84. // these two may go to difference places
  85. debugging($db->ErrorMsg() .'<br /><br />'. s($command));
  86. if (!empty($CFG->dblogerror)) {
  87. $debug=array_shift(debug_backtrace());
  88. error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $command");
  89. }
  90. return false;
  91. }
  92. }
  93. /**
  94. * on DBs that support it, switch to transaction mode and begin a transaction
  95. * you'll need to ensure you call commit_sql() or your changes *will* be lost.
  96. *
  97. * Now using ADOdb standard transactions. Some day, we should switch to
  98. * Smart Transactions (http://phplens.com/adodb/tutorial.smart.transactions.html)
  99. * as they autodetect errors and are nestable and easier to write
  100. *
  101. * this is _very_ useful for massive updates
  102. */
  103. function begin_sql() {
  104. global $db;
  105. $db->BeginTrans();
  106. return true;
  107. }
  108. /**
  109. * on DBs that support it, commit the transaction
  110. *
  111. * Now using ADOdb standard transactions. Some day, we should switch to
  112. * Smart Transactions (http://phplens.com/adodb/tutorial.smart.transactions.html)
  113. * as they autodetect errors and are nestable and easier to write
  114. */
  115. function commit_sql() {
  116. global $db;
  117. $db->CommitTrans();
  118. return true;
  119. }
  120. /**
  121. * on DBs that support it, rollback the transaction
  122. *
  123. * Now using ADOdb standard transactions. Some day, we should switch to
  124. * Smart Transactions (http://phplens.com/adodb/tutorial.smart.transactions.html)
  125. * as they autodetect errors and are nestable and easier to write
  126. */
  127. function rollback_sql() {
  128. global $db;
  129. $db->RollbackTrans();
  130. return true;
  131. }
  132. /**
  133. * returns db specific uppercase function
  134. * @deprecated Moodle 1.7 because all the RDBMS use upper()
  135. */
  136. function db_uppercase() {
  137. return "upper";
  138. }
  139. /**
  140. * returns db specific lowercase function
  141. * @deprecated Moodle 1.7 because all the RDBMS use lower()
  142. */
  143. function db_lowercase() {
  144. return "lower";
  145. }
  146. /**
  147. * Run an arbitrary sequence of semicolon-delimited SQL commands
  148. *
  149. * Assumes that the input text (file or string) consists of
  150. * a number of SQL statements ENDING WITH SEMICOLONS. The
  151. * semicolons MUST be the last character in a line.
  152. * Lines that are blank or that start with "#" or "--" (postgres) are ignored.
  153. * Only tested with mysql dump files (mysqldump -p -d moodle)
  154. *
  155. * @uses $CFG
  156. *
  157. * @deprecated Moodle 1.7 use the new XMLDB stuff in lib/ddllib.php
  158. *
  159. * @param string $sqlfile The path where a file with sql commands can be found on the server.
  160. * @param string $sqlstring If no path is supplied then a string with semicolon delimited sql
  161. * commands can be supplied in this argument.
  162. * @return bool Returns true if databse was modified successfully.
  163. */
  164. function modify_database($sqlfile='', $sqlstring='') {
  165. global $CFG;
  166. if ($CFG->version > 2006101007) {
  167. debugging('Function modify_database() is deprecated. Replace it with the new XMLDB stuff.', DEBUG_DEVELOPER);
  168. }
  169. $success = true; // Let's be optimistic
  170. if (!empty($sqlfile)) {
  171. if (!is_readable($sqlfile)) {
  172. $success = false;
  173. echo '<p>Tried to modify database, but "'. $sqlfile .'" doesn\'t exist!</p>';
  174. return $success;
  175. } else {
  176. $lines = file($sqlfile);
  177. }
  178. } else {
  179. $sqlstring = trim($sqlstring);
  180. if ($sqlstring{strlen($sqlstring)-1} != ";") {
  181. $sqlstring .= ";"; // add it in if it's not there.
  182. }
  183. $lines[] = $sqlstring;
  184. }
  185. $command = '';
  186. foreach ($lines as $line) {
  187. $line = rtrim($line);
  188. $length = strlen($line);
  189. if ($length and $line[0] <> '#' and $line[0].$line[1] <> '--') {
  190. if (substr($line, $length-1, 1) == ';') {
  191. $line = substr($line, 0, $length-1); // strip ;
  192. $command .= $line;
  193. $command = str_replace('prefix_', $CFG->prefix, $command); // Table prefixes
  194. if (! execute_sql($command)) {
  195. $success = false;
  196. }
  197. $command = '';
  198. } else {
  199. $command .= $line;
  200. }
  201. }
  202. }
  203. return $success;
  204. }
  205. /// GENERIC FUNCTIONS TO CHECK AND COUNT RECORDS ////////////////////////////////////////
  206. /**
  207. * Test whether a record exists in a table where all the given fields match the given values.
  208. *
  209. * The record to test is specified by giving up to three fields that must
  210. * equal the corresponding values.
  211. *
  212. * @uses $CFG
  213. * @param string $table The table to check.
  214. * @param string $field1 the first field to check (optional).
  215. * @param string $value1 the value field1 must have (requred if field1 is given, else optional).
  216. * @param string $field2 the second field to check (optional).
  217. * @param string $value2 the value field2 must have (requred if field2 is given, else optional).
  218. * @param string $field3 the third field to check (optional).
  219. * @param string $value3 the value field3 must have (requred if field3 is given, else optional).
  220. * @return bool true if a matching record exists, else false.
  221. */
  222. function record_exists($table, $field1='', $value1='', $field2='', $value2='', $field3='', $value3='') {
  223. global $CFG;
  224. $select = where_clause($field1, $value1, $field2, $value2, $field3, $value3);
  225. return record_exists_sql('SELECT * FROM '. $CFG->prefix . $table .' '. $select);
  226. }
  227. /**
  228. * Test whether any records exists in a table which match a particular WHERE clause.
  229. *
  230. * @uses $CFG
  231. * @param string $table The database table to be checked against.
  232. * @param string $select A fragment of SQL to be used in a WHERE clause in the SQL call.
  233. * @return bool true if a matching record exists, else false.
  234. */
  235. function record_exists_select($table, $select='') {
  236. global $CFG;
  237. if ($select) {
  238. $select = 'WHERE '.$select;
  239. }
  240. return record_exists_sql('SELECT * FROM '. $CFG->prefix . $table . ' ' . $select);
  241. }
  242. /**
  243. * Test whether a SQL SELECT statement returns any records.
  244. *
  245. * This function returns true if the SQL statement executes
  246. * without any errors and returns at least one record.
  247. *
  248. * @param string $sql The SQL statement to execute.
  249. * @return bool true if the SQL executes without errors and returns at least one record.
  250. */
  251. function record_exists_sql($sql) {
  252. $limitfrom = 0; /// Number of records to skip
  253. $limitnum = 1; /// Number of records to retrieve
  254. if (!$rs = get_recordset_sql($sql, $limitfrom, $limitnum)) {
  255. return false;
  256. }
  257. if (rs_EOF($rs)) {
  258. $result = false;
  259. } else {
  260. $result = true;
  261. }
  262. rs_close($rs);
  263. return $result;
  264. }
  265. /**
  266. * Count the records in a table where all the given fields match the given values.
  267. *
  268. * @uses $CFG
  269. * @param string $table The table to query.
  270. * @param string $field1 the first field to check (optional).
  271. * @param string $value1 the value field1 must have (requred if field1 is given, else optional).
  272. * @param string $field2 the second field to check (optional).
  273. * @param string $value2 the value field2 must have (requred if field2 is given, else optional).
  274. * @param string $field3 the third field to check (optional).
  275. * @param string $value3 the value field3 must have (requred if field3 is given, else optional).
  276. * @return int The count of records returned from the specified criteria.
  277. */
  278. function count_records($table, $field1='', $value1='', $field2='', $value2='', $field3='', $value3='') {
  279. global $CFG;
  280. $select = where_clause($field1, $value1, $field2, $value2, $field3, $value3);
  281. return count_records_sql('SELECT COUNT(*) FROM '. $CFG->prefix . $table .' '. $select);
  282. }
  283. /**
  284. * Count the records in a table which match a particular WHERE clause.
  285. *
  286. * @uses $CFG
  287. * @param string $table The database table to be checked against.
  288. * @param string $select A fragment of SQL to be used in a WHERE clause in the SQL call.
  289. * @param string $countitem The count string to be used in the SQL call. Default is COUNT(*).
  290. * @return int The count of records returned from the specified criteria.
  291. */
  292. function count_records_select($table, $select='', $countitem='COUNT(*)') {
  293. global $CFG;
  294. if ($select) {
  295. $select = 'WHERE '.$select;
  296. }
  297. return count_records_sql('SELECT '. $countitem .' FROM '. $CFG->prefix . $table .' '. $select);
  298. }
  299. /**
  300. * Get the result of a SQL SELECT COUNT(...) query.
  301. *
  302. * Given a query that counts rows, return that count. (In fact,
  303. * given any query, return the first field of the first record
  304. * returned. However, this method should only be used for the
  305. * intended purpose.) If an error occurrs, 0 is returned.
  306. *
  307. * @uses $CFG
  308. * @uses $db
  309. * @param string $sql The SQL string you wish to be executed.
  310. * @return int the count. If an error occurrs, 0 is returned.
  311. */
  312. function count_records_sql($sql) {
  313. $rs = get_recordset_sql($sql);
  314. if (is_object($rs) and is_array($rs->fields)) {
  315. return reset($rs->fields);
  316. } else {
  317. return 0;
  318. }
  319. }
  320. /// GENERIC FUNCTIONS TO GET, INSERT, OR UPDATE DATA ///////////////////////////////////
  321. /**
  322. * Get a single record as an object
  323. *
  324. * @uses $CFG
  325. * @param string $table The table to select from.
  326. * @param string $field1 the first field to check (optional).
  327. * @param string $value1 the value field1 must have (requred if field1 is given, else optional).
  328. * @param string $field2 the second field to check (optional).
  329. * @param string $value2 the value field2 must have (requred if field2 is given, else optional).
  330. * @param string $field3 the third field to check (optional).
  331. * @param string $value3 the value field3 must have (requred if field3 is given, else optional).
  332. * @return mixed a fieldset object containing the first mathcing record, or false if none found.
  333. */
  334. function get_record($table, $field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields='*') {
  335. global $CFG;
  336. // Check to see whether this record is eligible for caching (fields=*, only condition is id)
  337. $docache = false;
  338. if (!empty($CFG->rcache) && $CFG->rcache === true && $field1=='id' && !$field2 && !$field3 && $fields=='*') {
  339. $docache = true;
  340. // If it's in the cache, return it
  341. $cached = rcache_getforfill($table, $value1);
  342. if (!empty($cached)) {
  343. return $cached;
  344. }
  345. }
  346. $select = where_clause($field1, $value1, $field2, $value2, $field3, $value3);
  347. $record = get_record_sql('SELECT '.$fields.' FROM '. $CFG->prefix . $table .' '. $select);
  348. // If we're caching records, store this one
  349. // (supposing we got something - we don't cache failures)
  350. if ($docache) {
  351. if ($record !== false) {
  352. rcache_set($table, $value1, $record);
  353. } else {
  354. rcache_releaseforfill($table, $value1);
  355. }
  356. }
  357. return $record;
  358. }
  359. /**
  360. * Get a single record as an object using an SQL statement
  361. *
  362. * The SQL statement should normally only return one record. In debug mode
  363. * you will get a warning if more record is returned (unless you
  364. * set $expectmultiple to true). In non-debug mode, it just returns
  365. * the first record.
  366. *
  367. * @uses $CFG
  368. * @uses $db
  369. * @param string $sql The SQL string you wish to be executed, should normally only return one record.
  370. * @param bool $expectmultiple If the SQL cannot be written to conveniently return just one record,
  371. * set this to true to hide the debug message.
  372. * @param bool $nolimit sometimes appending ' LIMIT 1' to the SQL causes an error. Set this to true
  373. * to stop your SQL being modified. This argument should probably be deprecated.
  374. * @return Found record as object. False if not found or error
  375. */
  376. function get_record_sql($sql, $expectmultiple=false, $nolimit=false) {
  377. global $CFG;
  378. /// Default situation
  379. $limitfrom = 0; /// Number of records to skip
  380. $limitnum = 1; /// Number of records to retrieve
  381. /// Only a few uses of the 2nd and 3rd parameter have been found
  382. /// I think that we should avoid to use them completely, one
  383. /// record is one record, and everything else should return error.
  384. /// So the proposal is to change all the uses, (4-5 inside Moodle
  385. /// Core), drop them from the definition and delete the next two
  386. /// "if" sentences. (eloy, 2006-08-19)
  387. if ($nolimit) {
  388. $limitfrom = 0;
  389. $limitnum = 0;
  390. } else if ($expectmultiple) {
  391. $limitfrom = 0;
  392. $limitnum = 1;
  393. } else if (debugging('', DEBUG_DEVELOPER)) {
  394. // Debugging mode - don't use a limit of 1, but do change the SQL, because sometimes that
  395. // causes errors, and in non-debug mode you don't see the error message and it is
  396. // impossible to know what's wrong.
  397. $limitfrom = 0;
  398. $limitnum = 100;
  399. }
  400. if (!$rs = get_recordset_sql($sql, $limitfrom, $limitnum)) {
  401. return false;
  402. }
  403. $recordcount = $rs->RecordCount();
  404. if ($recordcount == 0) { // Found no records
  405. return false;
  406. } else if ($recordcount == 1) { // Found one record
  407. /// DIRTY HACK to retrieve all the ' ' (1 space) fields converted back
  408. /// to '' (empty string) for Oracle. It's the only way to work with
  409. /// all those NOT NULL DEFAULT '' fields until we definitively delete them
  410. if ($CFG->dbfamily == 'oracle') {
  411. array_walk($rs->fields, 'onespace2empty');
  412. }
  413. /// End of DIRTY HACK
  414. return (object)$rs->fields;
  415. } else { // Error: found more than one record
  416. notify('Error: Turn off debugging to hide this error.');
  417. notify($sql . '(with limits ' . $limitfrom . ', ' . $limitnum . ')');
  418. if ($records = $rs->GetAssoc(true)) {
  419. notify('Found more than one record in get_record_sql !');
  420. print_object($records);
  421. } else {
  422. notify('Very strange error in get_record_sql !');
  423. print_object($rs);
  424. }
  425. print_continue("$CFG->wwwroot/$CFG->admin/config.php");
  426. }
  427. }
  428. /**
  429. * Gets one record from a table, as an object
  430. *
  431. * @uses $CFG
  432. * @param string $table The database table to be checked against.
  433. * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
  434. * @param string $fields A comma separated list of fields to be returned from the chosen table.
  435. * @return object|false Returns an array of found records (as objects) or false if no records or error occured.
  436. */
  437. function get_record_select($table, $select='', $fields='*') {
  438. global $CFG;
  439. if ($select) {
  440. $select = 'WHERE '. $select;
  441. }
  442. return get_record_sql('SELECT '. $fields .' FROM '. $CFG->prefix . $table .' '. $select);
  443. }
  444. /**
  445. * Get a number of records as an ADODB RecordSet.
  446. *
  447. * Selects records from the table $table.
  448. *
  449. * If specified, only records where the field $field has value $value are retured.
  450. *
  451. * If specified, the results will be sorted as specified by $sort. This
  452. * is added to the SQL as "ORDER BY $sort". Example values of $sort
  453. * mightbe "time ASC" or "time DESC".
  454. *
  455. * If $fields is specified, only those fields are returned.
  456. *
  457. * Since this method is a little less readable, use of it should be restricted to
  458. * code where it's possible there might be large datasets being returned. For known
  459. * small datasets use get_records - it leads to simpler code.
  460. *
  461. * If you only want some of the records, specify $limitfrom and $limitnum.
  462. * The query will skip the first $limitfrom records (according to the sort
  463. * order) and then return the next $limitnum records. If either of $limitfrom
  464. * or $limitnum is specified, both must be present.
  465. *
  466. * The return value is an ADODB RecordSet object
  467. * @link http://phplens.com/adodb/reference.functions.adorecordset.html
  468. * if the query succeeds. If an error occurrs, false is returned.
  469. *
  470. * @param string $table the table to query.
  471. * @param string $field a field to check (optional).
  472. * @param string $value the value the field must have (requred if field1 is given, else optional).
  473. * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
  474. * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned).
  475. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  476. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  477. * @return mixed an ADODB RecordSet object, or false if an error occured.
  478. */
  479. function get_recordset($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  480. if ($field) {
  481. $select = "$field = '$value'";
  482. } else {
  483. $select = '';
  484. }
  485. return get_recordset_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
  486. }
  487. /**
  488. * Get a number of records as an ADODB RecordSet.
  489. *
  490. * If given, $select is used as the SELECT parameter in the SQL query,
  491. * otherwise all records from the table are returned.
  492. *
  493. * Other arguments and the return type as for @see function get_recordset.
  494. *
  495. * @uses $CFG
  496. * @param string $table the table to query.
  497. * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
  498. * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
  499. * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned).
  500. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  501. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  502. * @return mixed an ADODB RecordSet object, or false if an error occured.
  503. */
  504. function get_recordset_select($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  505. global $CFG;
  506. if ($select) {
  507. $select = ' WHERE '. $select;
  508. }
  509. if ($sort) {
  510. $sort = ' ORDER BY '. $sort;
  511. }
  512. return get_recordset_sql('SELECT '. $fields .' FROM '. $CFG->prefix . $table . $select . $sort, $limitfrom, $limitnum);
  513. }
  514. /**
  515. * Get a number of records as an ADODB RecordSet.
  516. *
  517. * Only records where $field takes one of the values $values are returned.
  518. * $values should be a comma-separated list of values, for example "4,5,6,10"
  519. * or "'foo','bar','baz'".
  520. *
  521. * Other arguments and the return type as for @see function get_recordset.
  522. *
  523. * @param string $table the table to query.
  524. * @param string $field a field to check (optional).
  525. * @param string $values comma separated list of values the field must have (requred if field is given, else optional).
  526. * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
  527. * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned).
  528. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  529. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  530. * @return mixed an ADODB RecordSet object, or false if an error occured.
  531. */
  532. function get_recordset_list($table, $field='', $values='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  533. if ($field) {
  534. $select = "$field IN ($values)";
  535. } else {
  536. $select = '';
  537. }
  538. return get_recordset_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
  539. }
  540. /**
  541. * Get a number of records as an ADODB RecordSet. $sql must be a complete SQL query.
  542. * Since this method is a little less readable, use of it should be restricted to
  543. * code where it's possible there might be large datasets being returned. For known
  544. * small datasets use get_records_sql - it leads to simpler code.
  545. *
  546. * The return type is as for @see function get_recordset.
  547. *
  548. * @uses $CFG
  549. * @uses $db
  550. * @param string $sql the SQL select query to execute.
  551. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  552. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  553. * @return mixed an ADODB RecordSet object, or false if an error occured.
  554. */
  555. function get_recordset_sql($sql, $limitfrom=null, $limitnum=null) {
  556. global $CFG, $db;
  557. if (empty($db)) {
  558. return false;
  559. }
  560. /// Temporary hack as part of phasing out all access to obsolete user tables XXX
  561. if (!empty($CFG->rolesactive)) {
  562. if (strpos($sql, ' '.$CFG->prefix.'user_students ') ||
  563. strpos($sql, ' '.$CFG->prefix.'user_teachers ') ||
  564. strpos($sql, ' '.$CFG->prefix.'user_coursecreators ') ||
  565. strpos($sql, ' '.$CFG->prefix.'user_admins ')) {
  566. if (debugging()) { var_dump(debug_backtrace()); }
  567. error('This SQL relies on obsolete tables! Your code must be fixed by a developer.');
  568. }
  569. }
  570. if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
  571. if ($limitfrom || $limitnum) {
  572. ///Special case, 0 must be -1 for ADOdb
  573. $limitfrom = empty($limitfrom) ? -1 : $limitfrom;
  574. $limitnum = empty($limitnum) ? -1 : $limitnum;
  575. $rs = $db->SelectLimit($sql, $limitnum, $limitfrom);
  576. } else {
  577. $rs = $db->Execute($sql);
  578. }
  579. if (!$rs) {
  580. debugging($db->ErrorMsg() .'<br /><br />'. s($sql));
  581. if (!empty($CFG->dblogerror)) {
  582. $debug=array_shift(debug_backtrace());
  583. error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $sql with limits ($limitfrom, $limitnum)");
  584. }
  585. return false;
  586. }
  587. return $rs;
  588. }
  589. /**
  590. * Utility function used by the following 4 methods. Note that for this to work, the first column
  591. * in the recordset must contain unique values, as it is used as the key to the associative array.
  592. *
  593. * @param object an ADODB RecordSet object.
  594. * @return mixed mixed an array of objects, or false if an error occured or the RecordSet was empty.
  595. */
  596. function recordset_to_array($rs) {
  597. global $CFG;
  598. $debugging = debugging('', DEBUG_DEVELOPER);
  599. if ($rs && !rs_EOF($rs)) {
  600. $objects = array();
  601. /// First of all, we are going to get the name of the first column
  602. /// to introduce it back after transforming the recordset to assoc array
  603. /// See http://docs.moodle.org/en/XMLDB_Problems, fetch mode problem.
  604. $firstcolumn = $rs->FetchField(0);
  605. /// Get the whole associative array
  606. if ($records = $rs->GetAssoc(true)) {
  607. foreach ($records as $key => $record) {
  608. /// Really DIRTY HACK for Oracle, but it's the only way to make it work
  609. /// until we got all those NOT NULL DEFAULT '' out from Moodle
  610. if ($CFG->dbfamily == 'oracle') {
  611. array_walk($record, 'onespace2empty');
  612. }
  613. /// End of DIRTY HACK
  614. $record[$firstcolumn->name] = $key;/// Re-add the assoc field
  615. if ($debugging && array_key_exists($key, $objects)) {
  616. debugging("Did you remember to make the first column something unique in your call to get_records? Duplicate value '$key' found in column '".$firstcolumn->name."'.", DEBUG_DEVELOPER);
  617. }
  618. $objects[$key] = (object) $record; /// To object
  619. }
  620. return $objects;
  621. /// Fallback in case we only have 1 field in the recordset. MDL-5877
  622. } else if ($rs->_numOfFields == 1 && $records = $rs->GetRows()) {
  623. foreach ($records as $key => $record) {
  624. /// Really DIRTY HACK for Oracle, but it's the only way to make it work
  625. /// until we got all those NOT NULL DEFAULT '' out from Moodle
  626. if ($CFG->dbfamily == 'oracle') {
  627. array_walk($record, 'onespace2empty');
  628. }
  629. /// End of DIRTY HACK
  630. if ($debugging && array_key_exists($record[$firstcolumn->name], $objects)) {
  631. debugging("Did you remember to make the first column something unique in your call to get_records? Duplicate value '".$record[$firstcolumn->name]."' found in column '".$firstcolumn->name."'.", DEBUG_DEVELOPER);
  632. }
  633. $objects[$record[$firstcolumn->name]] = (object) $record; /// The key is the first column value (like Assoc)
  634. }
  635. return $objects;
  636. } else {
  637. return false;
  638. }
  639. } else {
  640. return false;
  641. }
  642. }
  643. /**
  644. * This function is used to get the current record from the recordset. It
  645. * doesn't advance the recordset position. You'll need to do that by
  646. * using the rs_next_record($recordset) function.
  647. * @param ADORecordSet the recordset to fetch current record from
  648. * @return ADOFetchObj the object containing the fetched information
  649. */
  650. function rs_fetch_record(&$rs) {
  651. global $CFG;
  652. if (!$rs) {
  653. debugging('Incorrect $rs used!', DEBUG_DEVELOPER);
  654. return false;
  655. }
  656. $rec = $rs->FetchObj(); //Retrieve record as object without advance the pointer
  657. if ($rs->EOF) { //FetchObj requires manual checking of EOF to detect if it's the last record
  658. $rec = false;
  659. } else {
  660. /// DIRTY HACK to retrieve all the ' ' (1 space) fields converted back
  661. /// to '' (empty string) for Oracle. It's the only way to work with
  662. /// all those NOT NULL DEFAULT '' fields until we definetively delete them
  663. if ($CFG->dbfamily == 'oracle') {
  664. $recarr = (array)$rec; /// Cast to array
  665. array_walk($recarr, 'onespace2empty');
  666. $rec = (object)$recarr;/// Cast back to object
  667. }
  668. /// End DIRTY HACK
  669. }
  670. return $rec;
  671. }
  672. /**
  673. * This function is used to advance the pointer of the recordset
  674. * to its next position/record.
  675. * @param ADORecordSet the recordset to be moved to the next record
  676. * @return boolean true if the movement was successful and false if not (end of recordset)
  677. */
  678. function rs_next_record(&$rs) {
  679. if (!$rs) {
  680. debugging('Incorrect $rs used!', DEBUG_DEVELOPER);
  681. return false;
  682. }
  683. return $rs->MoveNext(); //Move the pointer to the next record
  684. }
  685. /**
  686. * This function is used to get the current record from the recordset. It
  687. * does advance the recordset position.
  688. * This is the prefered way to iterate over recordsets with code blocks like this:
  689. *
  690. * $rs = get_recordset('SELECT .....');
  691. * while ($rec = rs_fetch_next_record($rs)) {
  692. * /// Perform actions with the $rec record here
  693. * }
  694. * rs_close($rs); /// Close the recordset if not used anymore. Saves memory (optional but recommended).
  695. *
  696. * @param ADORecordSet the recordset to fetch current record from
  697. * @return mixed ADOFetchObj the object containing the fetched information or boolean false if no record (end of recordset)
  698. */
  699. function rs_fetch_next_record(&$rs) {
  700. global $CFG;
  701. if (!$rs) {
  702. debugging('Incorrect $rs used!', DEBUG_DEVELOPER);
  703. return false;
  704. }
  705. $rec = false;
  706. $recarr = $rs->FetchRow(); //Retrieve record as object without advance the pointer. It's quicker that FetchNextObj()
  707. if ($recarr) {
  708. /// DIRTY HACK to retrieve all the ' ' (1 space) fields converted back
  709. /// to '' (empty string) for Oracle. It's the only way to work with
  710. /// all those NOT NULL DEFAULT '' fields until we definetively delete them
  711. if ($CFG->dbfamily == 'oracle') {
  712. array_walk($recarr, 'onespace2empty');
  713. }
  714. /// End DIRTY HACK
  715. /// Cast array to object
  716. $rec = (object)$recarr;
  717. }
  718. return $rec;
  719. }
  720. /**
  721. * Returns true if no more records found
  722. * @param ADORecordSet the recordset
  723. * @return bool
  724. */
  725. function rs_EOF($rs) {
  726. if (!$rs) {
  727. debugging('Incorrect $rs used!', DEBUG_DEVELOPER);
  728. return true;
  729. }
  730. return $rs->EOF;
  731. }
  732. /**
  733. * This function closes the recordset, freeing all the memory and associated resources.
  734. * Note that, once closed, the recordset must not be used anymore along the request.
  735. * Saves memory (optional but recommended).
  736. * @param ADORecordSet the recordset to be closed
  737. * @return void
  738. */
  739. function rs_close(&$rs) {
  740. if (!$rs) {
  741. debugging('Incorrect $rs used!', DEBUG_DEVELOPER);
  742. return;
  743. }
  744. $rs->Close();
  745. }
  746. /**
  747. * This function is used to convert all the Oracle 1-space defaults to the empty string
  748. * like a really DIRTY HACK to allow it to work better until all those NOT NULL DEFAULT ''
  749. * fields will be out from Moodle.
  750. * @param string the string to be converted to '' (empty string) if it's ' ' (one space)
  751. * @param mixed the key of the array in case we are using this function from array_walk,
  752. * defaults to null for other (direct) uses
  753. * @return boolean always true (the converted variable is returned by reference)
  754. */
  755. function onespace2empty(&$item, $key=null) {
  756. $item = $item == ' ' ? '' : $item;
  757. return true;
  758. }
  759. ///End DIRTY HACK
  760. /**
  761. * Get a number of records as an array of objects.
  762. *
  763. * If the query succeeds and returns at least one record, the
  764. * return value is an array of objects, one object for each
  765. * record found. The array key is the value from the first
  766. * column of the result set. The object associated with that key
  767. * has a member variable for each column of the results.
  768. *
  769. * @param string $table the table to query.
  770. * @param string $field a field to check (optional).
  771. * @param string $value the value the field must have (requred if field1 is given, else optional).
  772. * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
  773. * @param string $fields a comma separated list of fields to return (optional, by default
  774. * all fields are returned). The first field will be used as key for the
  775. * array so must be a unique field such as 'id'.
  776. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  777. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  778. * @return mixed an array of objects, or false if no records were found or an error occured.
  779. */
  780. function get_records($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  781. $rs = get_recordset($table, $field, $value, $sort, $fields, $limitfrom, $limitnum);
  782. return recordset_to_array($rs);
  783. }
  784. /**
  785. * Get a number of records as an array of objects.
  786. *
  787. * Return value as for @see function get_records.
  788. *
  789. * @param string $table the table to query.
  790. * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
  791. * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
  792. * @param string $fields a comma separated list of fields to return
  793. * (optional, by default all fields are returned). The first field will be used as key for the
  794. * array so must be a unique field such as 'id'.
  795. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  796. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  797. * @return mixed an array of objects, or false if no records were found or an error occured.
  798. */
  799. function get_records_select($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  800. $rs = get_recordset_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
  801. return recordset_to_array($rs);
  802. }
  803. /**
  804. * Get a number of records as an array of objects.
  805. *
  806. * Return value as for @see function get_records.
  807. *
  808. * @param string $table The database table to be checked against.
  809. * @param string $field The field to search
  810. * @param string $values Comma separated list of possible value
  811. * @param string $sort Sort order (as valid SQL sort parameter)
  812. * @param string $fields A comma separated list of fields to be returned from the chosen table. If specified,
  813. * the first field should be a unique one such as 'id' since it will be used as a key in the associative
  814. * array.
  815. * @return mixed an array of objects, or false if no records were found or an error occured.
  816. */
  817. function get_records_list($table, $field='', $values='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  818. $rs = get_recordset_list($table, $field, $values, $sort, $fields, $limitfrom, $limitnum);
  819. return recordset_to_array($rs);
  820. }
  821. /**
  822. * Get a number of records as an array of objects.
  823. *
  824. * Return value as for @see function get_records.
  825. *
  826. * @param string $sql the SQL select query to execute. The first column of this SELECT statement
  827. * must be a unique value (usually the 'id' field), as it will be used as the key of the
  828. * returned array.
  829. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  830. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  831. * @return mixed an array of objects, or false if no records were found or an error occured.
  832. */
  833. function get_records_sql($sql, $limitfrom='', $limitnum='') {
  834. $rs = get_recordset_sql($sql, $limitfrom, $limitnum);
  835. return recordset_to_array($rs);
  836. }
  837. /**
  838. * Utility function used by the following 3 methods.
  839. *
  840. * @param object an ADODB RecordSet object with two columns.
  841. * @return mixed an associative array, or false if an error occured or the RecordSet was empty.
  842. */
  843. function recordset_to_menu($rs) {
  844. global $CFG;
  845. $menu = array();
  846. if ($rs && !rs_EOF($rs)) {
  847. $keys = array_keys($rs->fields);
  848. $key0=$keys[0];
  849. $key1=$keys[1];
  850. while (!$rs->EOF) {
  851. $menu[$rs->fields[$key0]] = $rs->fields[$key1];
  852. $rs->MoveNext();
  853. }
  854. /// Really DIRTY HACK for Oracle, but it's the only way to make it work
  855. /// until we got all those NOT NULL DEFAULT '' out from Moodle
  856. if ($CFG->dbfamily == 'oracle') {
  857. array_walk($menu, 'onespace2empty');
  858. }
  859. /// End of DIRTY HACK
  860. return $menu;
  861. } else {
  862. return false;
  863. }
  864. }
  865. /**
  866. * Utility function
  867. * Similar to recordset_to_menu
  868. *
  869. * field1, field2 is needed because the order from get_records_sql is not reliable
  870. * @param records - records from get_records_sql() or get_records()
  871. * @param field1 - field to be used as menu index
  872. * @param field2 - feild to be used as coresponding menu value
  873. * @return mixed an associative array, or false if an error occured or the RecordSet was empty.
  874. */
  875. function records_to_menu($records, $field1, $field2) {
  876. $menu = array();
  877. foreach ($records as $record) {
  878. $menu[$record->$field1] = $record->$field2;
  879. }
  880. if (!empty($menu)) {
  881. return $menu;
  882. } else {
  883. return false;
  884. }
  885. }
  886. /**
  887. * Get the first two columns from a number of records as an associative array.
  888. *
  889. * Arguments as for @see function get_recordset.
  890. *
  891. * If no errors occur, and at least one records is found, the return value
  892. * is an associative whose keys come from the first field of each record,
  893. * and whose values are the corresponding second fields. If no records are found,
  894. * or an error occurs, false is returned.
  895. *
  896. * @param string $table the table to query.
  897. * @param string $field a field to check (optional).
  898. * @param string $value the value the field must have (requred if field1 is given, else optional).
  899. * @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
  900. * @param string $fields a comma separated list of fields to return (optional, by default all fields are returned).
  901. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  902. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  903. * @return mixed an associative array, or false if no records were found or an error occured.
  904. */
  905. function get_records_menu($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  906. $rs = get_recordset($table, $field, $value, $sort, $fields, $limitfrom, $limitnum);
  907. return recordset_to_menu($rs);
  908. }
  909. /**
  910. * Get the first two columns from a number of records as an associative array.
  911. *
  912. * Arguments as for @see function get_recordset_select.
  913. * Return value as for @see function get_records_menu.
  914. *
  915. * @param string $table The database table to be checked against.
  916. * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
  917. * @param string $sort Sort order (optional) - a valid SQL order parameter
  918. * @param string $fields A comma separated list of fields to be returned from the chosen table.
  919. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  920. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  921. * @return mixed an associative array, or false if no records were found or an error occured.
  922. */
  923. function get_records_select_menu($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
  924. $rs = get_recordset_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
  925. return recordset_to_menu($rs);
  926. }
  927. /**
  928. * Get the first two columns from a number of records as an associative array.
  929. *
  930. * Arguments as for @see function get_recordset_sql.
  931. * Return value as for @see function get_records_menu.
  932. *
  933. * @param string $sql The SQL string you wish to be executed.
  934. * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
  935. * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
  936. * @return mixed an associative array, or false if no records were found or an error occured.
  937. */
  938. function get_records_sql_menu($sql, $limitfrom='', $limitnum='') {
  939. $rs = get_recordset_sql($sql, $limitfrom, $limitnum);
  940. return recordset_to_menu($rs);
  941. }
  942. /**
  943. * Get a single value from a table row where all the given fields match the given values.
  944. *
  945. * @param string $table the table to query.
  946. * @param string $return the field to return the value of.
  947. * @param string $field1 the first field to check (optional).
  948. * @param string $value1 the value field1 must have (requred if field1 is given, else optional).
  949. * @param string $field2 the second field to check (optional).
  950. * @param string $value2 the value field2 must have (requred if field2 is given, else optional).
  951. * @param string $field3 the third field to check (optional).
  952. * @param string $value3 the value field3 must have (requred if field3 is given, else optional).
  953. * @return mixed the specified value, or false if an error occured.
  954. */
  955. function get_field($table, $return, $field1, $value1, $field2='', $value2='', $field3='', $value3='') {
  956. global $CFG;
  957. $select = where_clause($field1, $value1, $field2, $value2, $field3, $value3);
  958. return get_field_sql('SELECT ' . $return . ' FROM ' . $CFG->prefix . $table . ' ' . $select);
  959. }
  960. /**
  961. * Get a single value from a table row where a particular select clause is true.
  962. *
  963. * @uses $CFG
  964. * @param string $table the table to query.
  965. * @param string $return the field to return the value of.
  966. * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
  967. * @return mixed the specified value, or false if an error occured.
  968. */
  969. function get_field_select($table, $return, $select) {
  970. global $CFG;
  971. if ($select) {
  972. $select = 'WHERE '. $select;
  973. }
  974. return get_field_sql('SELECT ' . $return . ' FROM ' . $CFG->prefix . $table . ' ' . $select);
  975. }
  976. /**
  977. * Get a single value from a table.
  978. *
  979. * @param string $sql an SQL statement expected to return a single value.
  980. * @return mixed the specified value, or false if an error occured.
  981. */
  982. function get_field_sql($sql) {
  983. global $CFG;
  984. /// Strip potential LIMIT uses arriving here, debugging them (MDL-7173)
  985. $newsql = preg_replace('/ LIMIT [0-9, ]+$/is', '', $sql);
  986. if ($newsql != $sql) {
  987. debugging('Incorrect use of LIMIT clause (not cross-db) in call to get_field_sql(): ' . s($sql), DEBUG_DEVELOPER);
  988. $sql = $newsql;
  989. }
  990. $rs = get_recordset_sql($sql, 0, 1);
  991. if ($rs && $rs->RecordCount() == 1) {
  992. /// DIRTY HACK to retrieve all the ' ' (1 space) fields converted back
  993. /// to '' (empty string) for Oracle. It's the only way to work with
  994. /// all those NOT NULL DEFAULT '' fields until we definetively delete them
  995. if ($CFG->dbfamily == 'oracle') {
  996. $value = reset($rs->fields);
  997. onespace2empty($value);
  998. return $value;
  999. }
  1000. /// End of DIRTY HACK
  1001. return reset($rs->fields);
  1002. } else {
  1003. return false;
  1004. }
  1005. }
  1006. /**
  1007. * Get a single value from a table row where a particular select clause is true.
  1008. *
  1009. * @uses $CFG
  1010. * @param string $table the table to query.
  1011. * @param string $return the field to return the value of.
  1012. * @param string $select A fragment of SQL to be used in a where clause in the SQL call.
  1013. * @return mixed|false Returns the value return from the SQL statment or false if an error occured.
  1014. */
  1015. function get_fieldset_select($table, $return, $select) {
  1016. global $CFG;
  1017. if ($select) {
  1018. $select = ' WHERE '. $select;
  1019. }
  1020. return get_fieldset_sql('SELECT ' . $return . ' FROM ' . $CFG->prefix . $table . $select);
  1021. }
  1022. /**
  1023. * Get an array of data from one or more fields from a database
  1024. * use to get a column, or a series of distinct values
  1025. *
  1026. * @uses $CFG
  1027. * @uses $db
  1028. * @param string $sql The SQL string you wish to be executed.
  1029. * @return mixed|false Returns the value return from the SQL statment or false if an error occured.
  1030. * @todo Finish documenting this function
  1031. */
  1032. function get_fieldset_sql($sql) {
  1033. global $db, $CFG;
  1034. if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
  1035. $rs = $db->Execute($sql);
  1036. if (!$rs) {
  1037. debugging($db->ErrorMsg() .'<br /><br />'. s($sql));
  1038. if (!empty($CFG->dblogerror)) {
  1039. $debug=array_shift(debug_backtrace());
  1040. error_log("SQL ".$db->ErrorMsg()." in {$debug['file']} on line {$debug['line']}. STATEMENT: $sql");
  1041. }
  1042. return false;
  1043. }
  1044. if ( !rs_EOF($rs) ) {
  1045. $keys = array_keys($rs->fields);
  1046. $key0 = $keys[0];
  1047. $results = array();
  1048. while (!$rs->EOF) {
  1049. array_push($results, $rs->fields[$key0]);
  1050. $rs->MoveNext();
  1051. }
  1052. /// DIRTY HACK to retrieve all the ' ' (1 space) fields converted back
  1053. /// to '' (empty string) for Oracle. It's the only way to work with
  1054. /// all those NOT NULL DEFAULT '' fields until we definetively delete them
  1055. if ($CFG->dbfamily == 'oracle') {
  1056. array_walk($results, 'onespace2empty');
  1057. }
  1058. /// End of DIRTY HACK
  1059. rs_close($rs);
  1060. return $results;
  1061. } else {
  1062. rs_close($rs);
  1063. return false;
  1064. }
  1065. }
  1066. /**
  1067. * Set a single field in every table row where all the given fields match the given values.
  1068. *
  1069. * @uses $CFG
  1070. * @uses $db
  1071. * @param string $table The database table to be checked against.
  1072. * @param string $newfield the field to set.
  1073. * @param string $newvalue the value to set the field to.
  1074. * @param string $field1 the first field to check (optional).
  1075. * @param string $value1 the value field1 must have (requred if field1 is given, else optional).
  1076. * @param string $field2 the second field to check (optional).
  1077. * @param string $value2 the value field2 must have (requred if field2 is given, else optional).
  1078. * @param string $field3 the third field to check (optional).
  1079. * @param string $value3 the value field3 must have (requred if field3 is given, else optional).
  1080. * @return mixed An ADODB RecordSet object with the results from the SQL call or false.
  1081. */
  1082. function set_field($table, $newfield, $newvalue, $field1, $value1, $field2='', $value2='', $field3='', $value3='') {
  1083. global $CFG;
  1084. // Clear record_cache based on the parameters passed
  1085. // (individual record or whole table)
  1086. if ($CFG->rcache === true) {
  1087. if ($field1 == 'id') {
  1088. rcache_unset($table, $value1);
  1089. } else if ($field2 == 'id') {
  1090. rcache_unset($table, $value2);
  1091. } else if ($field3 == 'id') {
  1092. rcache_unset($table, $value3);
  1093. } else {
  1094. rcache_unset_table($table);
  1095. }
  1096. }
  1097. $select = where_clause($field1, $value1, $field2, $value2, $field3, $value3);
  1098. return set_field_select($table, $newfield, $newvalue, $select, true);
  1099. }
  1100. /**
  1101. * Set a single field in every table row where the select statement evaluates to true.
  1102. *
  1103. * @uses $CFG
  1104. * @uses $db
  1105. * @param string $table The database table to be checked against.
  1106. * @param string $newfield the field to set.
  1107. * @param string $newvalue the value to set the field to.
  1108. * @param string $select a fragment of SQL to be used in a where clause in the SQL call.
  1109. * @param boolean $localcall Leave this set to false. (Should only be set to true by set_field.)
  1110. * @return mixed An ADODB RecordSet object with the results from the SQL call or false.
  1111. */
  1112. function set_field_select($table, $newfield, $newvalue, $select, $localcall = false) {
  1113. global $db, $CFG;
  1114. if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; };
  1115. if (!$localcall) {
  1116. if ($select) {

Large files files are truncated, but you can click here to view the full file