Skip to content

Commit

Permalink
Added update_batch() support for PostgreSQL (issue #356)
Browse files Browse the repository at this point in the history
  • Loading branch information
narfbg committed May 24, 2012
1 parent 846acc7 commit d06acd8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
4 changes: 2 additions & 2 deletions system/database/DB_utility.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosur
$out = rtrim($out).$newline;

// Next blast through the result array and build out the rows
foreach ($query->result_array() as $row)
while ($row = $query->unbuffered_row('array'))
{
foreach ($row as $item)
{
Expand Down Expand Up @@ -258,7 +258,7 @@ public function xml_from_result($query, $params = array())

// Generate the result
$xml = '<'.$root.'>'.$newline;
foreach ($query->result_array() as $row)
while ($row = $query->unbuffered_row())
{
$xml .= $tab.'<'.$element.'>'.$newline;
foreach ($row as $key => $val)
Expand Down
41 changes: 41 additions & 0 deletions system/database/drivers/postgre/postgre_driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,47 @@ protected function _update($table, $values, $where, $orderby = array(), $limit =

// --------------------------------------------------------------------

/**
* Update_Batch statement
*
* Generates a platform-specific batch update string from the supplied data
*
* @param string the table name
* @param array the update data
* @param array the where clause
* @return string
*/
protected function _update_batch($table, $values, $index, $where = NULL)
{
$ids = array();
foreach ($values as $key => $val)
{
$ids[] = $val[$index];

foreach (array_keys($val) as $field)
{
if ($field != $index)
{
$final[$field][] = 'WHEN '.$val[$index].' THEN '.$val[$field];
}
}
}

$cases = '';
foreach ($final as $k => $v)
{

This comment has been minimized.

Copy link
@wcoppens

wcoppens Aug 29, 2012

The second variable $k should be $index, otherwise it will filter down the index on a wrong column.

$cases .= $k.' = (CASE '.$k."\n"
.implode("\n", $v)."\n"
.'ELSE '.$k.' END), ';
}

return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
.' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
.$index.' IN('.implode(',', $ids).')';
}

// --------------------------------------------------------------------

/**
* Delete statement
*
Expand Down
2 changes: 2 additions & 0 deletions user_guide_src/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Release Date: Not Released
- Added db_set_charset() support.
- Added _optimize_table() support for the :doc:`Database Utility Class <database/utilities>` (rebuilds table indexes).
- Added boolean data type support in escape().
- Added update_batch() support.
- Added a constructor to the DB_result class and moved all driver-specific properties and logic out of the base DB_driver class to allow better abstraction.
- Removed limit() and order_by() support for UPDATE and DELETE queries in PostgreSQL driver. Postgres does not support those features.
- Removed protect_identifiers() and renamed internal method _protect_identifiers() to it instead - it was just an alias.
Expand Down Expand Up @@ -218,6 +219,7 @@ Bug fixes for 3.0
- Fixed a bug (#44, #110) - :doc:`Upload library <libraries/file_uploading>`'s clean_file_name() method didn't clear '!' and '#' characters.
- Fixed a bug (#121) - ``CI_DB_result::row()`` returned an array when there's no actual result to be returned.
- Fixed a bug (#319) - SQLSRV's affected_rows() method failed due to a scrollable cursor being created for write-type queries.
- Fixed a bug (#356) - PostgreSQL driver didn't have an _update_batch() method, which resulted in fatal error being triggered when update_batch() is used with it.

Version 2.1.1
=============
Expand Down

2 comments on commit d06acd8

@jsanmarb
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based upon the update_batch method described above, I modified it slightly since in my case it not worked. After that, it worked.

So, this method I put on the system/database/drivers/postgre/postgre_driver.php:

    // --------------------------------------------------------------------

    /**
     * Update_Batch statement
     *
     * Generates a platform-specific batch update string from the supplied data
     *
     * @param   string  the table name
     * @param   array   the update data
     * @param   array   the where clause
     * @return  string
     */
    protected function _update_batch($table, $values, $index, $where = NULL)
    {
        $ids = array();
        foreach ($values as $key => $val)
        {
            $ids[] = $val[$index];

            foreach (array_keys($val) as $field)
            {
                if ($field != $index)
                {
                    $final[$field][] =  'WHEN '. $index . ' = ' .$val[$index].' THEN '.$val[$field];
                }
            }
        }

        $cases = '';
        foreach ($final as $k => $v)
        {
            $cases .= $k .' = (CASE '. "\n"
                .implode("\n", $v)."\n"
                .'ELSE '.$k.' END), ';
        }

        return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
            .' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
            .$index.' IN ('.implode(',', $ids).')';
    }

Until now, I have not needed to update the other two files.

Thank you.

@narfbg
Copy link
Contributor Author

@narfbg narfbg commented on d06acd8 Jan 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsanmarb

This is a really old commit, the current version of this code looks a lot more different. You should be updating to the latest CI version, not patching stock files by hand.

Also, comments on commits are really unfriendly - hard to find and easy to lose track of, and just pasting an entire function only makes it worse ... One has to spend minutes searching for the tiny differences (on 3 lines out of 28 here, and only 2 are relevant); a diff is way, way better.

Please sign in to comment.