• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
weird bug on database model [ci 1.6.2]

#1
[eluser]adwin[/eluser]
Hi .. I found a bug that not always happened in my model

i use ci 1.6.2

here is my code
Code:
function save()
        {
            $this->db->set('measureid',$this->measureid);
            $this->db->set('goodsid',$this->goodsid);
            $this->db->set('poid',$this->poid);
            $this->db->set('qty',$this->qty);
            $this->db->set('qty0',$this->qty0);
            
            $this->db->set('unitprice',$this->unitprice);
            $this->db->set('discount',$this->discount);
            $this->db->set('total', $this->calculatetotal());
            
            $this->db->trans_begin();
            $status = '';  
            if($this->id != 0)
            {
                $this->db->where('id',$this->id);
                $status = $this->db->update($this->_table);
            }else
            {
                $status = $this->db->insert($this->_table);
                $this->id = $this->db->insert_id() ;
            }
            
            if(!$this->checkstatus($status,$this->_table)){
                echo $this->goodsid.' <br/>';
                echo $this->db->last_query();
                return false;
            }

            if(!$this->updateHeader($this->poid))
                return false;      

            if ($this->db->trans_status()===FALSE){
              return $this->rolllback();
            } else {
              $this->db->trans_commit();
              return true;
            }
        }

as you can see, there is
Code:
$this->db->set('measureid',$this->measureid);
$this->db->set('goodsid',$this->goodsid);
on the top of the db->set();

measureid and goodsid is linked with other table (foreign keys)

when I did insert it produce the error because measureid or goodsid not included into the insert sql.

here is the error:
Code:
Cannot add or update a child row: a foreign key constraint fails (`ci/podt`, CONSTRAINT `podt_ibfk_2` FOREIGN KEY (`goodsid`) REFERENCES `mtgoods` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
SQL : INSERT INTO `podt` (`measureid`, `qty`, `unitprice`, `discount`, `total`) VALUES ('1', 20, '30000', '300', 599700)

as you can see on my code, i have set the goodsid and measureid right ?

#2
[eluser]Pascal Kriete[/eluser]
That is quite odd, and I have no idea what could be causing it. Even if the variables aren't defined the fields should still get set.

What type of database are you using?
And can you try it without the transaction, just to whittle away at the possible causes and get a reduced version.

#3
[eluser]adwin[/eluser]
I did a research on this

Code:
$this->db->set('measureid',$this->measureid);
            $this->db->set('goodsid',$this->goodsid);
            $this->db->set('poid',$this->poid);
            $this->db->set('qty',$this->qty);
            $this->db->set('qty0',$this->qty0);
            $this->db->set('unitprice',$this->unitprice);
            $this->db->set('discount',$this->discount);
            $this->db->set('total', $this->calculatetotal());
            
            echo 'goodsid:'.$this->goodsid ;
            print_r($this->db->ar_set);
            return false;

it produce this code:
Code:
goodsid:1Array ( [`measureid`] => '1' [`qty`] => 20 [`unitprice`] => '30000' [`discount`] => '300' [`total`] => 599700 )

and something even weird than this Smile
if I change the goodsid into something other that 1 it will produce a correct result:
Code:
goodsid:6Array ( [`measureid`] => '1' [`goodsid`] => '6' [`qty`] => 20 [`unitprice`] => '30000' [`discount`] => '300' [`total`] => 599700 )

... and this one will make you confuse a lot ...
I change the code into this (just changing the place of measureid and goodsid
Code:
$this->db->set('goodsid',$this->goodsid);
            $this->db->set('measureid',$this->measureid);
            $this->db->set('poid',$this->poid);
            $this->db->set('qty',$this->qty);
            $this->db->set('qty0',$this->qty0);
            $this->db->set('unitprice',$this->unitprice);
            $this->db->set('discount',$this->discount);
            $this->db->set('total', $this->calculatetotal());

            echo ' goodsid: ' .$this->goodsid;  
            echo ' measureid :' .$this->measureid;  
            print_r($this->db->ar_set);
            return false;

if the goodsid and measureid = 1 the result : (no measureid in the ar_set)
Code:
goodsid: 1 measureid :1 Array ( [`goodsid`] => '1' [`qty`] => 20 [`unitprice`] => '30000' [`discount`] => '300' [`total`] => 599700 )

if the goodsid changed to other than 1 result
Code:
goodsid: 10 measureid :1 Array ( [`goodsid`] => '10' [`measureid`] => '1' [`qty`] => 20 [`unitprice`] => '30000' [`discount`] => '300' [`total`] => 599700 )

I will check on active record set() function after this Big Grin
so weird ... so true ... Big Grin

#4
[eluser]adwin[/eluser]
[quote author="inparo" date="1213011231"]That is quite odd, and I have no idea what could be causing it. Even if the variables aren't defined the fields should still get set.

What type of database are you using?
And can you try it without the transaction, just to whittle away at the possible causes and get a reduced version.[/quote]

I did without transaction ... look at my 2nd post. i just doing db->set() ...
I use mysql database ... before i used to use array instead of using db->set() and it works well ... now i want to make my code looks better so I use set.

any idea hahahaha ...

#5
[eluser]adwin[/eluser]
I make a deeper research on this
I did a modification on system\database\DB_active_rec.php

Code:
function set($key, $value = '', $escape = TRUE)
    {
        $key = $this->_object_to_array($key);
    
        if ( ! is_array($key))
        {
            $key = array($key => $value);
        }    

        foreach ($key as $k => $v)
        {
            if ($escape === FALSE)
            {
                $this->ar_set[$this->_protect_identifiers($k)] = $v;
                if ($this->ar_caching === TRUE)
                {
                    $this->ar_cache_offset[$this->_protect_identifiers($k)] = $v;
                }
            }
            else
            {
                            $this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);
                if ($this->ar_caching === TRUE)
                {
                    $this->ar_cache_offset[$this->_protect_identifiers($k)] = $this->escape($v);
                }
            }
                }
                print_r($this->ar_set); echo '<br/>';
        
        return $this;
    }

I just add print_r($this->ar_set); echo '<br/>'; to see what the happens in arr_set[] array ...

and when the code (my 2nd post) was runned it produce
Code:
Array ( [`goodsid`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '1' [`poid`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '1' [`poid`] => '1' [`qty`] => 20 )
Array ( [`goodsid`] => '1' [`measureid`] => '1' [`poid`] => '1' [`qty`] => 20 [`qty0`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '1' [`poid`] => '1' [`qty`] => 20 [`qty0`] => '1' [`unitprice`] => '30000' )
Array ( [`goodsid`] => '1' [`measureid`] => '1' [`poid`] => '1' [`qty`] => 20 [`qty0`] => '1' [`unitprice`] => '30000' [`discount`] => '300' )
Array ( [`goodsid`] => '1' [`qty`] => 20 [`unitprice`] => '30000' [`discount`] => '300' [`total`] => 599700 )

but if I change the measureid into something else
Code:
Array ( [`goodsid`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '7' )
Array ( [`goodsid`] => '1' [`measureid`] => '7' [`poid`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '7' [`poid`] => '1' [`qty`] => 1 )
Array ( [`goodsid`] => '1' [`measureid`] => '7' [`poid`] => '1' [`qty`] => 1 [`qty0`] => '1' )
Array ( [`goodsid`] => '1' [`measureid`] => '7' [`poid`] => '1' [`qty`] => 1 [`qty0`] => '1' [`unitprice`] => '30000' )
Array ( [`goodsid`] => '1' [`measureid`] => '7' [`poid`] => '1' [`qty`] => 1 [`qty0`] => '1' [`unitprice`] => '30000' [`discount`] => '300' )
Array ( [`goodsid`] => '1' [`measureid`] => '7' [`qty`] => 1 [`unitprice`] => '30000' [`discount`] => '300' [`total`] => 29700 )
it produce correct result ... sigh ... any idea ?

so weird ... Sad

ps: I use PHP Version 5.2.5

#6
[eluser]adwin[/eluser]
I found the problem but don't know which one is the error ... and i think it is not logic at all .. Sad
I found that the problem was caused by calculatetotal() function ... but that function dont have anything to do with db->ar_set()
Code:
function calculatetotal(){
            $measure = $this->mtconversions->get($this->measureid);
            $this->qty = $this->qty0 * $measure->value ;
            $total = ($this->qty * $this->unitprice) - $this->discount ;  
            $this->total = $total ;
            return $total ;
        }

        function save()
        {
            $this->calculatetotal();  

            $this->db->set('goodsid',$this->goodsid);
            $this->db->set('poid',$this->poid);
            $this->db->set('measureid',$this->measureid);
            $this->db->set('qty',$this->qty);
            $this->db->set('qty0',$this->qty0);
            $this->db->set('unitprice',$this->unitprice);
            $this->db->set('discount',$this->discount);
            $this->db->set('total', $this->total);
            // bug will be triggered the above with
            // $this->db->set('total', $this->calculatetotal());
            
            print_r($this->db->ar_set);
            return false;
        }

let me know if someone knows about this incident Big Grin.. i am still curious ...


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.