Insert_Batch(), ON DUPLICATE KEY UPDATE hack |
[eluser]a tired machine[/eluser]
I'm often running into the issue where I have a dataset that I need to sync into my db. For example, 50 results from a web services API call. With the current active record class it would seem that we have two options: 1. Mass delete followed by a batch insert, but then we lose any other field data we may have in the table (such as a 'created' timestamp). 2. Loop through each result, querying the database to see if the entry already exists, and then either inserting or updating accordingly, which in my example grows to be 100 database calls! The MySQL "ON DUPLICATE KEY UPDATE" clause is an elegant solution. Yet, due to portability concerns the functionality of the active record class doesn't contain functions such as this one. So here's how I hacked it into the code. In mysql_driver.php I added this function: Code: /** You can see I've simply copied the _Insert_Batch() function and appended the ON DUPLICATE UPDATE claus onto the end of the MySQL query it generates. Then I added this function to DB_active_rec.php, which again is simply a copy of the Insert_Bach() function modified to call the above modified function. Code: /** Presto, syncing data becomes as easy as one line of code in your model: Code: $this->db->insert_on_duplicate_update_batch('table',$data); It would be probably more elegant and provide more flexability if it could be called in this way: Code: $this->db I don't see the harm in including functions into the active record class that are not universally supported by every database. (CodeIgniter requires certain system configurations such mod_rewrite, GD, etc. for many of its features). Considering how immensely useful while simple to implement, I would love to see this feature included into the CodeIgniter core. It would of course be possible to code the (inefficient) equivalents for other database drivers. But in general it would be nice to have database-specific functions available.
[eluser]Unknown[/eluser]
My blog post should do this for you, http://nitmedia.tumblr.com/post/18132504...b-function
[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'); 2. Create MY_DB_mysql_driver.php in application/core/ (or mysqli, or whatever you use) Code: <?php That way you can also update the system folder when needed. Hope it helps someone. |
Welcome Guest, Not a member yet? Register Sign In |