Moodle

new dml (moodle_recordset particularly) break backwards compatiblity with keys

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: 2.0
  • Fix Version/s: 2.0
  • Component/s: Database SQL/XMLDB
  • Labels:
    None
  • Affected Branches:
    MOODLE_20_STABLE
  • Fixed Branches:
    MOODLE_20_STABLE

Description

In order to fully support backwards compatibility with the new moodle_recordset objects, we must change the implementation of key (as mandated by the Iterator interface) to return the first column of the current row. Currently it is returning the rowcount.

This means that

$records = $DB->get_records('foo'); and $records[$someid] do not behave as they used to.

Activity

Hide
Petr Škoda (skodak) added a comment -

oopps!

Show
Petr Škoda (skodak) added a comment - oopps!
Hide
Eloy Lafuente (stronk7) added a comment -

re-oopps!

Show
Eloy Lafuente (stronk7) added a comment - re-oopps!
Hide
Eloy Lafuente (stronk7) added a comment -

Could we add one test for this too?

Show
Eloy Lafuente (stronk7) added a comment - Could we add one test for this too?
Hide
Eloy Lafuente (stronk7) added a comment -

Err.. why oopps?

We convert all the recordsets to associative array with the adodb_recordset_to_array() method, not relying in key() at all. So:

1) the get_records_xxx() functions, using that function, return proper associative arrays.
2) the get_recordset_xxx() functions, return 1 record in each iteration, not using the key() for anything (AFAIK).

So... why $DB->get_records('foo') do not behave as they used to?

Show
Eloy Lafuente (stronk7) added a comment - Err.. why oopps? We convert all the recordsets to associative array with the adodb_recordset_to_array() method, not relying in key() at all. So: 1) the get_records_xxx() functions, using that function, return proper associative arrays. 2) the get_recordset_xxx() functions, return 1 record in each iteration, not using the key() for anything (AFAIK). So... why $DB->get_records('foo') do not behave as they used to?
Hide
Penny Leach added a comment - - edited

Because they don't end up as array at all, they end up as php objects that implement Iterator (which makes them behave like an array).

This means you can iterate over them by implementing a few functions, next, prev, key etc.

next is implemented (what is making foreach($DB->get_records('foo')) work, but key isn't, which means that

$foo = $DB->get_records('foo'); works, but $foo[$presetidweexpect] doesn't.

See http://nz2.php.net/Iterator for more info

Show
Penny Leach added a comment - - edited Because they don't end up as array at all, they end up as php objects that implement Iterator (which makes them behave like an array). This means you can iterate over them by implementing a few functions, next, prev, key etc. next is implemented (what is making foreach($DB->get_records('foo')) work, but key isn't, which means that $foo = $DB->get_records('foo'); works, but $foo[$presetidweexpect] doesn't. See http://nz2.php.net/Iterator for more info
Hide
Eloy Lafuente (stronk7) added a comment -

Err..

but $foo[$presetidweexpect] doesn't.

What's $foo there? One recordset (get_recordset_xxx) or one record array (get_record_xxx)?

If recordset, it cannot be accessed as array at all! It's an (forward) iterator! Born to iterate!

The only change I think we can make is to, effectively, return proper keys with 1st field in current record, in order to allow:

foreach ($recordset as $key => $record) {
}

iterations to be used. Instead of current "order" (record counter).

I'll post here one patch for adodb and pdo iterator implementations in order to provide that $key properly.

Ciao

Show
Eloy Lafuente (stronk7) added a comment - Err.. but $foo[$presetidweexpect] doesn't. What's $foo there? One recordset (get_recordset_xxx) or one record array (get_record_xxx)? If recordset, it cannot be accessed as array at all! It's an (forward) iterator! Born to iterate! The only change I think we can make is to, effectively, return proper keys with 1st field in current record, in order to allow: foreach ($recordset as $key => $record) { } iterations to be used. Instead of current "order" (record counter). I'll post here one patch for adodb and pdo iterator implementations in order to provide that $key properly. Ciao
Hide
Eloy Lafuente (stronk7) added a comment -

Ah, just rereading:

"next is implemented (what is making foreach($DB->get_records('foo')) "

That's incorrect! get_recordsXXX() is able to iterate because it's one array. No iterator there at all.

Only get_recordsetXXX() are able to iterate (sequentially forward to be cross-db) because we have one iterator for them.

Ciao

Show
Eloy Lafuente (stronk7) added a comment - Ah, just rereading: "next is implemented (what is making foreach($DB->get_records('foo')) " That's incorrect! get_recordsXXX() is able to iterate because it's one array. No iterator there at all. Only get_recordsetXXX() are able to iterate (sequentially forward to be cross-db) because we have one iterator for them. Ciao
Hide
Eloy Lafuente (stronk7) added a comment -

One reset over fields seems to be enough to return first column value as key, both in adodb and pdo. Pretty simple.

Show
Eloy Lafuente (stronk7) added a comment - One reset over fields seems to be enough to return first column value as key, both in adodb and pdo. Pretty simple.
Hide
Petr Škoda (skodak) added a comment -

+1 for commit

Show
Petr Škoda (skodak) added a comment - +1 for commit
Hide
Eloy Lafuente (stronk7) added a comment -

Committed with some functional tests.

Resolving as fixed. Ciao

Show
Eloy Lafuente (stronk7) added a comment - Committed with some functional tests. Resolving as fixed. Ciao
Hide
Petr Škoda (skodak) added a comment -

thanks

Show
Petr Škoda (skodak) added a comment - thanks

People

Dates

  • Created:
    Updated:
    Resolved: