Welcome Guest, Not a member yet? Register   Sign In
Insert_Batch(), ON DUPLICATE KEY UPDATE hack
#3

[eluser]Unknown[/eluser]
Awesome, thank you for your solution.

But instead of hacking your way at the system code, extend it. It's the proper way to do it.
Tested on CodeIgniter 2.1.3:

1. Create MY_Loader.php in application/core/
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Loader extends CI_Loader {

public function database($params = '', $return = FALSE, $active_record = NULL)
{
  // Grab the super object
  $CI =& get_instance();

  // Do we even need to load the database class?
  if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db))
  {
   return FALSE;
  }

  require_once(BASEPATH.'database/DB.php');

  $db = DB($params, $active_record);

  // Load extended DB driver
  $custom_db_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_driver';
  $custom_db_driver_file = APPPATH.'core/'.$custom_db_driver.'.php';

  if (file_exists($custom_db_driver_file))
  {
   require_once($custom_db_driver_file);

   $db = new $custom_db_driver(get_object_vars($db));
  }

  // Return DB instance
  if ($return === TRUE)
  {
   return $db;
  }

  // Initialize the db variable. Needed to prevent reference errors with some configurations
  $CI->db = '';
  $CI->db =& $db;
}
}

/* End of file MY_Loader.php */
/* Location: ./application/core/MY_Loader.php */


2. Create MY_DB_mysql_driver.php in application/core/ (or mysqli, or whatever you use)
Code:
<?php
class MY_DB_mysql_driver extends CI_DB_mysql_driver {

   final public function __construct($params)
{
  parent::__construct($params);
}

  /**
   * Insert_On_Duplicate_Update_Batch
   *
   * Compiles batch insert strings and runs the queries
   * MODIFIED to do a MySQL 'ON DUPLICATE KEY UPDATE'
   *
   * @access public
   * @param string the table to retrieve the results from
   * @param array an associative array of insert values
   * @return object
   */
  function insert_on_duplicate_update_batch($table = '', $set = NULL)
  {
    if ( ! is_null($set))
    {
     $this->set_insert_batch($set);
    }

    if (count($this->ar_set) == 0)
    {
     if ($this->db_debug)
     {
      //No valid data array.  Folds in cases where keys and values did not match up
      return $this->display_error('db_must_use_set');
     }
     return FALSE;
    }

    if ($table == '')
    {
     if ( ! isset($this->ar_from[0]))
     {
      if ($this->db_debug)
      {
       return $this->display_error('db_must_set_table');
      }
      return FALSE;
     }

     $table = $this->ar_from[0];
    }

    // Batch this baby
    for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
    {

     $sql = $this->_insert_on_duplicate_update_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));

     // echo $sql;

     $this->query($sql);
    }

    $this->_reset_write();


    return TRUE;
  }

  /**
   * Insert_on_duplicate_update_batch statement
   *
   * Generates a platform-specific insert string from the supplied data
   * MODIFIED to include ON DUPLICATE UPDATE
   *
   * @access public
   * @param string the table name
   * @param array the insert keys
   * @param array the insert values
   * @return string
   */
  private function _insert_on_duplicate_update_batch($table, $keys, $values)
  {
    foreach($keys as $key)
     $update_fields[] = $key.'=VALUES('.$key.')';

    return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values)." ON DUPLICATE KEY UPDATE ".implode(', ', $update_fields);
  }

}
?&gt;

That way you can also update the system folder when needed. Hope it helps someone.


Messages In This Thread
Insert_Batch(), ON DUPLICATE KEY UPDATE hack - by El Forum - 11-04-2011, 07:36 AM
Insert_Batch(), ON DUPLICATE KEY UPDATE hack - by El Forum - 02-23-2012, 10:06 AM
Insert_Batch(), ON DUPLICATE KEY UPDATE hack - by El Forum - 11-21-2012, 04:36 AM



Theme © iAndrew 2016 - Forum software by © MyBB