$dataobject in insert_record() and update_record() must be objects.
Added code to detect, fix and debug array situations. Related to MDL-9751.
This commit is contained in:
+59
-47
@@ -395,9 +395,9 @@ function count_records_sql($sql) {
|
||||
* @return mixed a fieldset object containing the first mathcing record, or false if none found.
|
||||
*/
|
||||
function get_record($table, $field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields='*') {
|
||||
|
||||
|
||||
global $CFG;
|
||||
|
||||
|
||||
// Check to see whether this record is eligible for caching (fields=*, only condition is id)
|
||||
$docache = false;
|
||||
if (!empty($CFG->rcache) && $CFG->rcache === true && $field1=='id' && !$field2 && !$field3 && $fields=='*') {
|
||||
@@ -408,11 +408,11 @@ function get_record($table, $field1, $value1, $field2='', $value2='', $field3=''
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$select = where_clause($field1, $value1, $field2, $value2, $field3, $value3);
|
||||
|
||||
$record = get_record_sql('SELECT '.$fields.' FROM '. $CFG->prefix . $table .' '. $select);
|
||||
|
||||
|
||||
// If we're caching records, store this one
|
||||
// (supposing we got something - we don't cache failures)
|
||||
if ($docache) {
|
||||
@@ -653,7 +653,7 @@ function get_recordset_sql($sql, $limitfrom=null, $limitnum=null) {
|
||||
|
||||
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
|
||||
if (!empty($CFG->rolesactive)) {
|
||||
if (strpos($sql, ' '.$CFG->prefix.'user_students ') ||
|
||||
if (strpos($sql, ' '.$CFG->prefix.'user_students ') ||
|
||||
strpos($sql, ' '.$CFG->prefix.'user_teachers ') ||
|
||||
strpos($sql, ' '.$CFG->prefix.'user_coursecreators ') ||
|
||||
strpos($sql, ' '.$CFG->prefix.'user_admins ')) {
|
||||
@@ -736,7 +736,7 @@ function recordset_to_array($rs) {
|
||||
|
||||
/**
|
||||
* This function is used to get the current record from the recordset. It
|
||||
* doesn't advance the recordset position. You'll need to do that by
|
||||
* doesn't advance the recordset position. You'll need to do that by
|
||||
* using the rs_next_record($recordset) function.
|
||||
* @param ADORecordSet the recordset to fetch current record from
|
||||
* @return ADOFetchObj the object containing the fetched information
|
||||
@@ -851,7 +851,7 @@ function onespace2empty(&$item, $key=null) {
|
||||
* @param string $field a field to check (optional).
|
||||
* @param string $value the value the field must have (requred if field1 is given, else optional).
|
||||
* @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
|
||||
* @param string $fields a comma separated list of fields to return (optional, by default
|
||||
* @param string $fields a comma separated list of fields to return (optional, by default
|
||||
* all fields are returned). The first field will be used as key for the
|
||||
* array so must be a unique field such as 'id'.
|
||||
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
||||
@@ -871,7 +871,7 @@ function get_records($table, $field='', $value='', $sort='', $fields='*', $limit
|
||||
* @param string $table the table to query.
|
||||
* @param string $select A fragment of SQL to be used in a where clause in the SQL call.
|
||||
* @param string $sort an order to sort the results in (optional, a valid SQL ORDER BY parameter).
|
||||
* @param string $fields a comma separated list of fields to return
|
||||
* @param string $fields a comma separated list of fields to return
|
||||
* (optional, by default all fields are returned). The first field will be used as key for the
|
||||
* array so must be a unique field such as 'id'.
|
||||
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
||||
@@ -907,8 +907,8 @@ function get_records_list($table, $field='', $values='', $sort='', $fields='*',
|
||||
*
|
||||
* Return value as for @see function get_records.
|
||||
*
|
||||
* @param string $sql the SQL select query to execute. The first column of this SELECT statement
|
||||
* must be a unique value (usually the 'id' field), as it will be used as the key of the
|
||||
* @param string $sql the SQL select query to execute. The first column of this SELECT statement
|
||||
* must be a unique value (usually the 'id' field), as it will be used as the key of the
|
||||
* returned array.
|
||||
* @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
|
||||
* @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
|
||||
@@ -1185,7 +1185,7 @@ function set_field_select($table, $newfield, $newvalue, $select, $localcall = fa
|
||||
if ($select) {
|
||||
$select = 'WHERE ' . $select;
|
||||
}
|
||||
|
||||
|
||||
// Clear record_cache based on the parameters passed
|
||||
// (individual record or whole table)
|
||||
if ($CFG->rcache === true) {
|
||||
@@ -1223,7 +1223,7 @@ function set_field_select($table, $newfield, $newvalue, $select, $localcall = fa
|
||||
}
|
||||
}
|
||||
|
||||
/// Arriving here, standard update
|
||||
/// Arriving here, standard update
|
||||
return $db->Execute('UPDATE '. $CFG->prefix . $table .' SET '. $newfield .' = \''. $newvalue .'\' '. $select);
|
||||
}
|
||||
|
||||
@@ -1303,7 +1303,7 @@ function delete_records_select($table, $select='') {
|
||||
* @uses $db
|
||||
* @uses $CFG
|
||||
* @param string $table The database table to be checked against.
|
||||
* @param array $dataobject A data object with values for one or more fields in the record
|
||||
* @param object $dataobject A data object with values for one or more fields in the record
|
||||
* @param bool $returnid Should the id of the newly created record entry be returned? If this option is not requested then true/false is returned.
|
||||
* @param string $primarykey The primary key of the table we are inserting into (almost always "id")
|
||||
*/
|
||||
@@ -1315,6 +1315,12 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Check we are handling a proper $dataobject
|
||||
if (is_array($dataobject)) {
|
||||
debugging('Warning. Wrong call to insert_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER);
|
||||
$dataobject = (object)$dataobject;
|
||||
}
|
||||
|
||||
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
|
||||
if (!empty($CFG->rolesactive)) {
|
||||
if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) {
|
||||
@@ -1408,7 +1414,7 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
|
||||
case 'mssql':
|
||||
$clobdefault = 'null'; //Value of empty default clobs for this DB (under mssql this won't be executed
|
||||
$blobdefault = 'null'; //Value of empty default blobs for this DB
|
||||
break;
|
||||
break;
|
||||
}
|
||||
$insertSQL = str_replace("'@#CLOB#@'", $clobdefault, $insertSQL);
|
||||
$insertSQL = str_replace("'@#BLOB#@'", $blobdefault, $insertSQL);
|
||||
@@ -1427,7 +1433,7 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
|
||||
/// Under Oracle, finally, Update all the Clobs and Blobs present in the record
|
||||
/// if we know we have some of them in the query
|
||||
if ($CFG->dbfamily == 'oracle' &&
|
||||
!empty($dataobject->{$primarykey}) &&
|
||||
!empty($dataobject->{$primarykey}) &&
|
||||
(!empty($foundclobs) || !empty($foundblobs))) {
|
||||
if (!db_update_lobs($table, $dataobject->{$primarykey}, $foundclobs, $foundblobs)) {
|
||||
return false; //Some error happened while updating LOBs
|
||||
@@ -1453,7 +1459,7 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
|
||||
/// Under MSSQL all the Clobs and Blobs (IMAGE) present in the record
|
||||
/// if we know we have some of them in the query
|
||||
if (($CFG->dbfamily == 'mssql') &&
|
||||
!empty($id) &&
|
||||
!empty($id) &&
|
||||
(!empty($foundclobs) || !empty($foundblobs))) {
|
||||
if (!db_update_lobs($table, $id, $foundclobs, $foundblobs)) {
|
||||
return false; //Some error happened while updating LOBs
|
||||
@@ -1485,7 +1491,7 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
|
||||
* @uses $CFG
|
||||
* @uses $db
|
||||
* @param string $table The database table to be checked against.
|
||||
* @param array $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified.
|
||||
* @param object $dataobject An object with contents equal to fieldname=>fieldvalue. Must have an entry for 'id' to map to the table specified.
|
||||
* @return bool
|
||||
*/
|
||||
function update_record($table, $dataobject) {
|
||||
@@ -1496,11 +1502,17 @@ function update_record($table, $dataobject) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Check we are handling a proper $dataobject
|
||||
if (is_array($dataobject)) {
|
||||
debugging('Warning. Wrong call to update_record(). $dataobject must be an object. array found instead', DEBUG_DEVELOPER);
|
||||
$dataobject = (object)$dataobject;
|
||||
}
|
||||
|
||||
// Remove this record from record cache since it will change
|
||||
if ($CFG->rcache === true) {
|
||||
rcache_unset($table, $dataobject->id);
|
||||
}
|
||||
|
||||
|
||||
/// Temporary hack as part of phasing out all access to obsolete user tables XXX
|
||||
if (!empty($CFG->rolesactive)) {
|
||||
if (in_array($table, array('user_students', 'user_teachers', 'user_coursecreators', 'user_admins'))) {
|
||||
@@ -1576,7 +1588,7 @@ function update_record($table, $dataobject) {
|
||||
/// Under Oracle AND MSSQL, finally, Update all the Clobs and Blobs present in the record
|
||||
/// if we know we have some of them in the query
|
||||
if (($CFG->dbfamily == 'oracle' || $CFG->dbfamily == 'mssql') &&
|
||||
!empty($dataobject->id) &&
|
||||
!empty($dataobject->id) &&
|
||||
(!empty($foundclobs) || !empty($foundblobs))) {
|
||||
if (!db_update_lobs($table, $dataobject->id, $foundclobs, $foundblobs)) {
|
||||
return false; //Some error happened while updating LOBs
|
||||
@@ -1614,10 +1626,10 @@ function sql_paging_limit($page, $recordsperpage) {
|
||||
/**
|
||||
* Returns the proper SQL to do LIKE in a case-insensitive way
|
||||
*
|
||||
* Note the LIKE are case sensitive for Oracle. Oracle 10g is required to use
|
||||
* Note the LIKE are case sensitive for Oracle. Oracle 10g is required to use
|
||||
* the caseinsensitive search using regexp_like() or NLS_COMP=LINGUISTIC :-(
|
||||
* See http://docs.moodle.org/en/XMLDB_Problems#Case-insensitive_searches
|
||||
*
|
||||
*
|
||||
* @uses $CFG
|
||||
* @return string
|
||||
*/
|
||||
@@ -1671,7 +1683,7 @@ function sql_concat() {
|
||||
*/
|
||||
function sql_concat_join($separator="' '", $elements=array()) {
|
||||
global $db;
|
||||
|
||||
|
||||
// copy to ensure pass by value
|
||||
$elem = $elements;
|
||||
|
||||
@@ -1791,12 +1803,12 @@ function sql_order_by_text($fieldname, $numchars=32) {
|
||||
|
||||
|
||||
/**
|
||||
* Returns SQL to be used as a subselect to find the primary role of users.
|
||||
* Returns SQL to be used as a subselect to find the primary role of users.
|
||||
* Geoff Cant <[email protected]> (the author) is very keen for this to
|
||||
* be implemented as a view in future versions.
|
||||
* be implemented as a view in future versions.
|
||||
*
|
||||
* eg if this function returns a string called $primaryroles, then you could:
|
||||
* $sql = 'SELECT COUNT(DISTINCT prs.userid) FROM ('.$primary_roles.') prs
|
||||
* $sql = 'SELECT COUNT(DISTINCT prs.userid) FROM ('.$primary_roles.') prs
|
||||
* WHERE prs.primary_roleid='.$role->id.' AND prs.courseid='.$course->id.
|
||||
* ' AND prs.contextlevel = '.CONTEXT_COURSE;
|
||||
*
|
||||
@@ -1820,8 +1832,8 @@ function sql_primary_role_subselect() {
|
||||
SELECT 1
|
||||
FROM '.$CFG->prefix.'role_assignments i_ra
|
||||
INNER JOIN '.$CFG->prefix.'role i_r ON i_ra.roleid = i_r.id
|
||||
WHERE ra.userid = i_ra.userid AND
|
||||
ra.contextid = i_ra.contextid AND
|
||||
WHERE ra.userid = i_ra.userid AND
|
||||
ra.contextid = i_ra.contextid AND
|
||||
i_r.sortorder < r.sortorder
|
||||
) ';
|
||||
}
|
||||
@@ -2091,7 +2103,7 @@ function db_detect_lobs ($table, &$dataobject, &$clobs, &$blobs, $unset = false,
|
||||
continue;
|
||||
}
|
||||
/// If the field is CLOB, update its value to '@#CLOB#@' and store it in the $clobs array
|
||||
if (strtoupper($columns[strtolower($fieldname)]->type) == $clobdbtype) {
|
||||
if (strtoupper($columns[strtolower($fieldname)]->type) == $clobdbtype) {
|
||||
/// Oracle optimization. CLOBs under 4000cc can be directly inserted (no need to apply 2-phases to them)
|
||||
if ($CFG->dbfamily == 'oracle' && strlen($dataobject->$fieldname) < 4000) {
|
||||
continue;
|
||||
@@ -2163,7 +2175,7 @@ function db_update_lobs ($table, $sqlcondition, &$clobs, &$blobs) {
|
||||
/// Update all the clobs
|
||||
if ($clobs) {
|
||||
foreach ($clobs as $key => $value) {
|
||||
|
||||
|
||||
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; }; /// Count the extra updates in PERF
|
||||
|
||||
if (!$db->UpdateClob($CFG->prefix.$table, $key, $value, $sqlcondition)) {
|
||||
@@ -2180,7 +2192,7 @@ function db_update_lobs ($table, $sqlcondition, &$clobs, &$blobs) {
|
||||
/// Update all the blobs
|
||||
if ($blobs) {
|
||||
foreach ($blobs as $key => $value) {
|
||||
|
||||
|
||||
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->dbqueries++; }; /// Count the extra updates in PERF
|
||||
|
||||
if(!$db->UpdateBlob($CFG->prefix.$table, $key, $value, $sqlcondition)) {
|
||||
@@ -2217,11 +2229,11 @@ function rcache_set($table, $id, $rec) {
|
||||
$rcache->data[$table][$id] = $rec;
|
||||
} else {
|
||||
$key = $table . '|' . $id;
|
||||
|
||||
|
||||
if (isset($MCACHE)) {
|
||||
// $table is a flag used to mark
|
||||
// a table as dirty & uncacheable
|
||||
// when an UPDATE or DELETE not bound by ID
|
||||
// a table as dirty & uncacheable
|
||||
// when an UPDATE or DELETE not bound by ID
|
||||
// is taking place
|
||||
if (!$MCACHE->get($table)) {
|
||||
// this will also release the _forfill lock
|
||||
@@ -2230,7 +2242,7 @@ function rcache_set($table, $id, $rec) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2261,9 +2273,9 @@ function rcache_unset($table, $id) {
|
||||
/**
|
||||
* Get cached record if available. ONLY use if you
|
||||
* are trying to get the cached record and will NOT
|
||||
* fetch it yourself if not cached.
|
||||
*
|
||||
* Use rcache_getforfill() if you are going to fetch
|
||||
* fetch it yourself if not cached.
|
||||
*
|
||||
* Use rcache_getforfill() if you are going to fetch
|
||||
* the record if not cached...
|
||||
*
|
||||
* This function is private and must not be used outside dmllib at all
|
||||
@@ -2282,14 +2294,14 @@ function rcache_get($table, $id) {
|
||||
} else {
|
||||
$rcache->misses++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($MCACHE)) {
|
||||
$key = $table . '|' . $id;
|
||||
// we set $table as a flag used to mark
|
||||
// a table as dirty & uncacheable
|
||||
// when an UPDATE or DELETE not bound by ID
|
||||
// a table as dirty & uncacheable
|
||||
// when an UPDATE or DELETE not bound by ID
|
||||
// is taking place
|
||||
if ($MCACHE->get($table)) {
|
||||
$rcache->misses++;
|
||||
@@ -2302,7 +2314,7 @@ function rcache_get($table, $id) {
|
||||
} else {
|
||||
$rcache->misses++;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -2310,12 +2322,12 @@ function rcache_get($table, $id) {
|
||||
|
||||
/**
|
||||
* Get cached record if available. In most cases you want
|
||||
* to use this function -- namely if you are trying to get
|
||||
* to use this function -- namely if you are trying to get
|
||||
* the cached record and will fetch it yourself if not cached.
|
||||
* (and set the cache ;-)
|
||||
*
|
||||
* Uses the getforfill caching mechanism. See lib/eaccelerator.class.php
|
||||
* for a detailed description of the technique.
|
||||
* for a detailed description of the technique.
|
||||
*
|
||||
* Note: if you call rcache_getforfill() you are making an implicit promise
|
||||
* that if the cache is empty, you will later populate it, or cancel the promise
|
||||
@@ -2346,7 +2358,7 @@ function rcache_getforfill($table, $id) {
|
||||
if (!empty($rec)) {
|
||||
$rcache->hits++;
|
||||
return $rec;
|
||||
}
|
||||
}
|
||||
$rcache->misses++;
|
||||
return false;
|
||||
}
|
||||
@@ -2354,7 +2366,7 @@ function rcache_getforfill($table, $id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the exclusive lock obtained by
|
||||
* Release the exclusive lock obtained by
|
||||
* rcache_getforfill(). See rcache_getforfill()
|
||||
* for more details.
|
||||
*
|
||||
@@ -2366,7 +2378,7 @@ function rcache_getforfill($table, $id) {
|
||||
*/
|
||||
function rcache_releaseforfill($table, $id) {
|
||||
global $CFG, $MCACHE;
|
||||
|
||||
|
||||
if (isset($MCACHE)) {
|
||||
$key = $table . '|' . $id;
|
||||
return $MCACHE->releaseforfill($key);
|
||||
@@ -2396,7 +2408,7 @@ function rcache_unset_table ($table) {
|
||||
|
||||
if (isset($MCACHE)) {
|
||||
// at least as long as content keys to ensure they expire
|
||||
// before the dirty flag
|
||||
// before the dirty flag
|
||||
$MCACHE->set($table, true, $CFG->rcachettl);
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user