diff --git a/enrol/paypal/ipn.php b/enrol/paypal/ipn.php index 5d764403fca..750fc7ad3ab 100644 --- a/enrol/paypal/ipn.php +++ b/enrol/paypal/ipn.php @@ -184,7 +184,7 @@ } else if (strcmp ($result, "INVALID") == 0) { // ERROR - insert_record("enrol_paypal", $data); + insert_record("enrol_paypal", $data, false); email_paypal_error_to_admin("Received an invalid payment notification!! (Fake payment?)", $data); } } diff --git a/filter/algebra/filter.php b/filter/algebra/filter.php index 8558684ebfd..3cf0a7df479 100644 --- a/filter/algebra/filter.php +++ b/filter/algebra/filter.php @@ -220,7 +220,7 @@ function algebra_filter ($courseid, $text) { $texcache->md5key = $md5; $texcache->rawtext = addslashes($texexp); $texcache->timemodified = time(); - insert_record("cache_filters",$texcache); + insert_record("cache_filters",$texcache, false); $text = str_replace( $matches[0][$i], string_file_picture_algebra($filename, $texexp), $text); } else { $text = str_replace( $matches[0][$i],"Undetermined error: ",$text); diff --git a/filter/tex/filter.php b/filter/tex/filter.php index f3c69ce0649..9ac9ab15207 100644 --- a/filter/tex/filter.php +++ b/filter/tex/filter.php @@ -132,7 +132,7 @@ function tex_filter ($courseid, $text) { $texcache->md5key = $md5; $texcache->rawtext = addslashes($texexp); $texcache->timemodified = time(); - insert_record("cache_filters",$texcache); + insert_record("cache_filters",$texcache, false); } $filename = $md5 . ".gif"; $text = str_replace( $matches[0][$i], string_file_picture_tex($filename, $texexp), $text); diff --git a/lib/datalib.php b/lib/datalib.php index acb0345eede..646173a81f9 100644 --- a/lib/datalib.php +++ b/lib/datalib.php @@ -907,6 +907,19 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') { return false; } + /// Postgres doesn't have the concept of primary key built in + /// and will return the OID which isn't what we want. + /// The efficient and transaction-safe strategy is to + /// move the sequence forward first, and make the insert + /// with an explicit id. + if ( !isset($dataobject->{$primarykey}) + && $CFG->dbtype === 'postgres7' + && $returnid == true ) { + if ($nextval = get_field_sql("SELECT NEXTVAL('{$CFG->prefix}{$table}_{$primarykey}_seq')")) { + $dataobject->{$primarykey} = $nextval; + } + } + /// Get the correct SQL from adoDB if (!$insertSQL = $db->GetInsertSQL($rs, (array)$dataobject, true)) { return false; @@ -925,20 +938,32 @@ function insert_record($table, $dataobject, $returnid=true, $primarykey='id') { return true; } -/// Find the return ID of the newly inserted record - switch ($CFG->dbtype) { - case "postgres7": // Just loves to be special - $oid = $db->Insert_ID(); - if ($rs = $db->Execute("SELECT $primarykey FROM $CFG->prefix$table WHERE oid = $oid")) { - if ($rs->RecordCount() == 1) { - return (integer) $rs->fields[0]; - } - } - return false; - - default: - return $db->Insert_ID(); // Should work on most databases, but not all! +/// We already know the record PK +/// if it's been passed explicitly, +/// or if we've retrieved it from a +/// sequence (Postgres). + if (isset($dataobject->{$primarykey})) { + return $dataobject->{$primarykey}; } + +/// This only gets triggered with non-Postgres databases +/// however we have some postgres fallback in case we failed +/// to find the sequence. + $id = $db->Insert_ID(); + + if ($CFG->dbtype === 'postgres7') { + // try to get the primary key based on id + if ( ($rs = $db->Execute('SELECT '. $primarykey .' FROM '. $CFG->prefix . $table .' WHERE oid = '. $id)) + && ($rs->RecordCount() == 1) ) { + trigger_error("Retrieved $primarykey from oid on table $table because we could not find the sequence."); + return (integer)$rs->fields[0]; + } + trigger_error('Failed to retrieve primary key after insert: SELECT '. $primarykey .' FROM '. $CFG->prefix . $table .' WHERE oid = '. $id); + return false; + } + + return (integer)$id; + } diff --git a/mod/chat/chatd.php b/mod/chat/chatd.php index b78f5a69b22..9d9255a0d7f 100755 --- a/mod/chat/chatd.php +++ b/mod/chat/chatd.php @@ -321,7 +321,7 @@ class ChatDaemon { $msg->timestamp = time(); // Commit to DB - insert_record('chat_messages', $msg); + insert_record('chat_messages', $msg, false); // OK, now push it out to all users $this->message_broadcast($msg, $this->sets_info[$sessionid]['user']); @@ -415,7 +415,7 @@ class ChatDaemon { $msg->message = addslashes($msg->message); // Commit to DB - insert_record('chat_messages', $msg); + insert_record('chat_messages', $msg, false); // Undo the hack $msg->message = $origmsg; @@ -537,7 +537,7 @@ class ChatDaemon { $msg->message = 'enter'; $msg->timestamp = time(); - insert_record('chat_messages', $msg); + insert_record('chat_messages', $msg, false); $this->message_broadcast($msg, $this->sets_info[$sessionid]['user']); return true; @@ -740,7 +740,7 @@ class ChatDaemon { $msg->timestamp = time(); $this->trace('User has disconnected, destroying uid '.$info['userid'].' with SID '.$sessionid, E_USER_WARNING); - insert_record('chat_messages', $msg); + insert_record('chat_messages', $msg, false); // *************************** IMPORTANT // diff --git a/mod/glossary/edit.php b/mod/glossary/edit.php index 755d61a9b9a..ebdeffa01e7 100644 --- a/mod/glossary/edit.php +++ b/mod/glossary/edit.php @@ -176,7 +176,7 @@ if ( $confirm ) { foreach ($form->categories as $category) { if ( $category > 0 ) { $newcategory->categoryid = $category; - insert_record("glossary_entries_categories",$newcategory); + insert_record("glossary_entries_categories",$newcategory, false); } else { break; } @@ -190,7 +190,7 @@ if ( $confirm ) { unset($newalias); $newalias->entryid = $e; $newalias->alias = $alias; - insert_record("glossary_alias",$newalias); + insert_record("glossary_alias",$newalias, false); } } }