I am getting the error MysqlError: Duplicate entry '1-5' for key 'PRIMARY'
as shown below in the code. It only happened once (that I could detect, but it was random) and I couldn't find a cause (New Relic reported), but I cannot reproduce and I don't have much more information except the line number and the error given. The schema and code is below.
num_rows()
is somehow returning a value that is not 1 even though it shouldn't. If someone can give some insight on how to debug or fix that would be helpful.
Here is my schema for location_items:
CREATE TABLE `phppos_location_items` (
`location_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
`location` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`cost_price` decimal(23,10) DEFAULT NULL,
`unit_price` decimal(23,10) DEFAULT NULL,
`promo_price` decimal(23,10) DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`quantity` decimal(23,10) DEFAULT '0.0000000000',
`reorder_level` decimal(23,10) DEFAULT NULL,
`override_default_tax` int(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`location_id`,`item_id`),
KEY `phppos_location_items_ibfk_2` (`item_id`),
CONSTRAINT `phppos_location_items_ibfk_1` FOREIGN KEY (`location_id`) REFERENCES `phppos_locations` (`location_id`),
CONSTRAINT `phppos_location_items_ibfk_2` FOREIGN KEY (`item_id`) REFERENCES `phppos_items` (`item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
And the code:
//Lock tables involved in sale transaction so we do not have deadlock
$this->db->query('LOCK TABLES '.$this->db->dbprefix('customers').' WRITE, '.$this->db->dbprefix('receivings').' WRITE,
'.$this->db->dbprefix('store_accounts').' WRITE, '.$this->db->dbprefix('receivings_items').' WRITE,
'.$this->db->dbprefix('giftcards').' WRITE, '.$this->db->dbprefix('location_items').' WRITE,
'.$this->db->dbprefix('inventory').' WRITE,
'.$this->db->dbprefix('people').' READ,'.$this->db->dbprefix('items').' WRITE
,'.$this->db->dbprefix('employees_locations').' READ,'.$this->db->dbprefix('locations').' READ, '.$this->db->dbprefix('items_tier_prices').' READ
, '.$this->db->dbprefix('location_items_tier_prices').' READ, '.$this->db->dbprefix('items_taxes').' READ, '.$this->db->dbprefix('item_kits').' READ
, '.$this->db->dbprefix('location_item_kits').' READ, '.$this->db->dbprefix('item_kit_items').' READ, '.$this->db->dbprefix('employees').' READ , '.$this->db->dbprefix('item_kits_tier_prices').' READ
, '.$this->db->dbprefix('location_item_kits_tier_prices').' READ, '.$this->db->dbprefix('suppliers').' READ, '.$this->db->dbprefix('location_items_taxes').' READ
, '.$this->db->dbprefix('location_item_kits_taxes'). ' READ, '.$this->db->dbprefix('item_kits_taxes'). ' READ');
// other code for inserting data into other tables that are not relevant.
foreach($items as $line=>$item)
{
$cur_item_location_info->quantity = $cur_item_location_info->quantity !== NULL ? $cur_item_location_info->quantity : 0;
$quantity_data=array(
'quantity'=>$cur_item_location_info->quantity + $item['quantity'],
'location_id'=>$this->Employee->get_logged_in_employee_current_location_id(),
'item_id'=>$item['item_id']
);
$this->Item_location->save($quantity_data,$item['item_id']);
}
// other code for inserting data into other tables that are not relevant.
$this->db->query('UNLOCK TABLES');
class Item_location extends CI_Model
{
function exists($item_id,$location=false)
{
if(!$location)
{
$location= $this->Employee->get_logged_in_employee_current_location_id();
}
$this->db->from('location_items');
$this->db->where('item_id',$item_id);
$this->db->where('location_id',$location);
$query = $this->db->get();
return ($query->num_rows()==1);
}
function save($item_location_data,$item_id=-1,$location_id=false)
{
if(!$location_id)
{
$location_id= $this->Employee->get_logged_in_employee_current_location_id();
}
if (!$this->exists($item_id,$location_id))
{
$item_location_data['item_id'] = $item_id;
$item_location_data['location_id'] = $location_id;
//MysqlError: Duplicate entry '1-5' for key 'PRIMARY'
return $this->db->insert('location_items',$item_location_data);
}
$this->db->where('item_id',$item_id);
$this->db->where('location_id',$location_id);
return $this->db->update('location_items',$item_location_data);
}
}
function get_logged_in_employee_current_location_id()
{
if($this->is_logged_in())
{
//If we have a location in the session
if ($this->session->userdata('employee_current_location_id')!==FALSE)
{
return $this->session->userdata('employee_current_location_id');
}
//Return the first location user is authenticated for
return current($this->get_authenticated_location_ids($this->session->userdata('person_id')));
}
return FALSE;
}