Fork me on GitHub

How to get ID of object inserted with DBUtil::insertObject  Bottom

  • According to the documentation for DBUtil::insertObject

    Quote


    Code

    // simple insert
        // create an array object containing the field names on the left as defined in **pntabled.php**, and the values on the right
        $obj = array('name'    => 'fred',
                     'address' => 'bloggs',
                     'phone'   => '555-123-4321');

        // do the insert
        $result = DBUtil::insertObject($obj, 'customers');

    $result will contain the ADODB recordset object or false on fail.

    Assuming the insert is successful $obj will have been automatically been updated with the id of the insert


    1) What is an "ADODB recordset object", and what would I do with it ? These aren't mentioned previously in the documentation.

    2) Even though DBUtil::insertObject takes $obj by reference (the prototype has &$obj), I as far as I can tell it is not in fact updated with the id.

    So, how do I find out the id of what was just inserted ?
  • $obj will contain the ID $obj['id'] after the query AFAIK.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • Nope, it does not. At least in 1.2.5, and when an id other than id is passed as the fourth param.

    This is from porting FormExpress from direct SQL to using DBUtil. This debug code:

    Code

    $h = fopen("/tmp/cxc.txt", "a");
    fwrite ($h, "Before: ~$formObj[form_id]~\n" );
        $result = DBUtil::insertObject($formObj, 'FormExpress', false, 'form_id');
    fwrite ($h, "After: ~$formObj[form_id]~   ~$formObj[id]~\n<" );
    fwrite ($h, "Result: ~$result[form_id]~   ~$result[id]~\n" );
    fclose($h);


    returns

    Quote


    Before: ~~
    After: ~~ ~~
    Result: ~~ ~~
  • I think your parameter order is incorrect. Given the function signature of

    Code

    insertObject(&$object, $tablename, $idcolumn = 'id', $preserve = false, $force = false)

    your code should be:

    Code

    $result = DBUtil::insertObject($formObj, 'FormExpress', 'form_id');


    Give that a try.

    On a sidenote, I'm a big fan of having all lowercase tablenames and typically that's what all Zikula modules do. Please consider renaming your tables to form_express ...

    Greetings
    R
  • Did I mention the documentation is wrong in so many places it's driving me batty ? icon_smile
    Of course, your way works. However, the Wiki documentation currently says:

    Quote


    insertObject

    All tables in a database should have an ID field which is unique. DBUtil always assumes the default idcolumn is called 'id' unless otherwise told. By default, DBUtil::insertObject will also allocate a unique ID for the record.

    DBUtil::insertObject($obj, $tablename, $force, $idcolumn)


    I've been updating the problems as I find them, but it's still hard to wrap my brain around the fact that these DBUtil docs are -- wrong, and, essentially, until someone goes through and edits them they can't be relied on. I wonder if this isn't why we haven't seen more people port things over ?

    I'm going to leave it wrong so at least one of you can see it and confirm I'm not making things up. icon_smile I have suggested this before on the dev list, but I really think someone who knows it well should go through and make sure the docs reflect reality. It would also be a good idea if all the doc pages references the same example table structure, so you could compare the "insert" example to the "create" example.

    As for the table names, there are a lot of things I would like to change. I'm doing the porting first to understand the structure that is here, then I'll do all the name changes as a separate task.



    Edited by ccandreva on Mar 01, 2011 - 12:05 PM.
  • Quote

    I've been updating the problems as I find them, but it's still hard to wrap my brain around the fact that these DBUtil docs are -- wrong, and, essentially, until someone goes through and edits them they can't be relied on. I wonder if this isn't why we haven't seen more people port things over ?

    Quite honestly, I don't know. The truth is that I never even look at the docs and just look in the code if I need to find something. Please, if you find something that's wrong, just fix it in the docs; people will sing your praises in generations to come icon_smile

    Quote

    As for the table names, there are a lot of things I would like to change. I'm doing the porting first to understand the structure that is here, then I'll do all the name changes as a separate task.

    I'm not sure what your plans are with FormExpress, but I've recently had the pleasure of working on a large site which uses FormExpress together with feproc to automate some things and I must admit, that even though I'm generally not dumb, decyphering how things work took a long time and was anything but easy; as a matter of fact, I'm still shaky as to how some things work even though I've spent a large amount of time looking at that code.

    So if you want to go in that direction, maybe we should talk as I have some ideas on how to make building such systems easier and more transparent.

    Greetings/Thanks
    Robert
  • I've been relying on the docs.

    Here's another problem: I just went to make the update, however there is also a discrepancy as to what the force parameter means. The docs have 'force' as third, and say:

    Quote

    If we need to chose the value for the ID field, we can do so by using the $force = true


    In fact I've written several modules with this assumption, where I insert objects that each user can only have one of using their uid as the object id. They are happily running in production passing 'false' as the third parameter. However, DBUtil.class.php itself says something completely different:

    Quote


    * @param object The object we wish to insert
    * @param tablename The tablename key for the PNTables structure
    * @param idcolumn The column which stores the primary key (optional) (default='id')
    * @param preserve whether or not to preserve existing/set standard fields (optional) (default=false)
    * @param force whether or not to insert empty values as NULL (optional) (default=false)


    "Force" is not only in a different place, but means something completely different !

    Now I can make a wild leap of logic, and say that if you pass false as the idcolum, then DBUtil will assume there is no id column, which is why everything I wrote works. Or, if it sees a value it knows what to do. Or, the whole problem is passed off to SQL which knows enough not to assign something if you pass a value in. Or, it's a bug that just happens to work for Mysql, but will break in something else.

    I don't know which scares me more: Writing DBUtil docs with my limited knowledge that someone else might rely on, or the thought that I might be an expert in DBUtil ! icon_smile
  • HI, I must admit I also always look at the DBUtil functions in the code and examples from other modules where necessary. I dont look that much at the docs to be honest.

    --
    campertoday.nl, Module development, Dutch Zikula Community

This list is based on users active over the last 60 minutes.