[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);
}
}
?>
That way you can also update the system folder when needed. Hope it helps someone.