ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

A new Challenge (someone mentioned they missed them)

November 03, 2008 1:05pm

Subscribe [5]
  • #1 / Nov 03, 2008 1:05pm

    Randy Casburn

    997 posts

    Title: Find the (potential) CI Bug

    Setup:

    A coder opens a custom mysql db connection within a hook. Records a record and then closes the db. Later on in the code he discovers he has issued $this->recordVisit(); again as shown.  Something like this:

    $this->_openDBConn();
    $this->recordVisit();
    $this->_closeDBConn();
      :
    $this->recordVisit();

    The problem is that the second record is written to the database even though the database connection has been closed and the connection id has been set to NULL.  Both of these facts are confirmed.

    The database class is manually loaded and configured properly. 

    Here are the basic methods:

    public function recordVisit() {
    
            $aData = array( 'remote_addr'  => $_SERVER['REMOTE_ADDR']
                          , 'http_referer' => isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : 'NOT SET');
        
            $this->oDB->insert( 'visitor', $aData );
        }
    
    
        protected function _openDBConn() {
            
            require_once( BASEPATH.'database/DB'.EXT );
            
            if( !isset( $this->oDB ) ) {
                
                $this->oDB = DB();
            }
        }
        
        protected function _closeDBConn() {
    
            $this->oDB->close();
        }

    Challenge: Why does the second record get written to the database after the connection has been closed?

    ———-

    Have fun. (and yes, I know the answer)

    Randy

  • #2 / Nov 03, 2008 4:02pm

    Adam Griffiths

    316 posts

    You could have at least used maths, I’d have more chance getting it then. Lol.

  • #3 / Nov 03, 2008 4:09pm

    Randy Casburn

    997 posts

    You could have at least used maths, I’d have more chance getting it then. Lol.

    OK…for Adam, he must identify the attached formula that I had to recon with while building an application about three years ago…  :lol:

    Everyone else can stick to the original challenge…

    Randy

  • #4 / Nov 03, 2008 4:18pm

    Adam Griffiths

    316 posts

    You could have at least used maths, I’d have more chance getting it then. Lol.

    OK…for Adam, he must identify the attached formula that I had to recon with while building an application about three years ago…  :lol:

    Everyone else can stick to the original challenge…

    Randy

    I’ll have a crack at it but, I don’t do A level maths so how the hell?! lol. Good ol’ Randy 😛

  • #5 / Nov 03, 2008 4:34pm

    James Gifford

    77 posts

    Is it because there is no public close() method in the mysql_driver class? The close method is private (_close()) so when you call $this->oDB->close() nothing happens and the connection is still open.

  • #6 / Nov 03, 2008 4:47pm

    Randy Casburn

    997 posts

    That’s what I thought at first too.  But since the the DB_driver class is extended by the mysql driver class, the DB_driver->close() method is the public method that gets called in this case.  It then calls the private _close() method inside the mysql driver.

    Nice try though!

  • #7 / Nov 03, 2008 4:48pm

    Randy Casburn

    997 posts

    OH…and the connection is, in fact, confirmed to be closed after issuing the first call to $this->_closeDBConn();

    Randy

  • #8 / Nov 03, 2008 4:48pm

    Randy Casburn

    997 posts

    I’ll have a crack at it but, I don’t do A level maths so how the hell?! lol. Good ol’ Randy 😛

    I was just joking man…you guys take me waaaaaay too seriously…hahahahehheeheeheh

  • #9 / Nov 03, 2008 4:52pm

    Adam Griffiths

    316 posts

    I’ll have a crack at it but, I don’t do A level maths so how the hell?! lol. Good ol’ Randy 😛

    I was just joking man…you guys take me waaaaaay too seriously…hahahahehheeheeheh

    Lol, fair enough. The big “E” looking thing is a Sigma, and means the sum of. Does that count?! 😛

  • #10 / Nov 03, 2008 4:53pm

    Frank Berger

    46 posts

    the insert method in the object DB() returns calls CI_DB_driver::query which calls CI_DB_driver::simple_query which calls CI_DB_driver::initialize if no connection is defined which re-initializes the connection, happy now?

    I wouldn’t call this a bug, just a fail-safe so you wont loose any data. And you want your code to deny such a violent act, how about changing your _closeDBConn method to this:

    protected function _closeDBConn() {
            $this->oDB->close();
            $this->oDB = NULL;
     }

    cheers
    Frank

  • #11 / Nov 03, 2008 4:58pm

    Xeoncross

    350 posts

    Is it because of the nasty internet gnomes always killing data packets?

  • #12 / Nov 03, 2008 5:07pm

    Randy Casburn

    997 posts

    the insert method in the object DB() returns calls CI_DB_driver::query which calls CI_DB_driver::simple_query which calls CI_DB_driver::initialize if no connection is defined which re-initializes the connection, happy now?

    I wouldn’t call this a bug, just a fail-safe so you wont loose any data. And you want your code to deny such a violent act, how about changing your _closeDBConn method to this:

    protected function _closeDBConn() {
            $this->oDB->close();
            $this->oDB = NULL;
     }

    cheers
    Frank


    Now Frank…this seems much “happier” than what that other thing you posted! 😛

    WHOO HOO everyone Frank wins!

    ————
    Congratulations Frank!
    ————

    Frank’s explanation is exactly right and doesn’t need anything further.  In the next post I’ll attempt to explain the sequence of events to see if this means “bug” or “fail safe”.

    Then we can see what the Dereks say.

    Randy


    So, even when we tell CodeIgniter to close our database connection, the obstinate little beast holds on to the

  • #13 / Nov 03, 2008 5:16pm

    Randy Casburn

    997 posts

    If you attempt to send a query to a database using CI you’ll get an error.

    If you instantiate a DB using a properly configured database group in CI and run a valid query it will work.

    —-

    Now, enter the challeng.  If you invoke the close() method CI literally does indeed close the connection and indeed does literally NULLify the connection id.

    What CI does not do, as Frank points out in a vague way above, is do a thing with the DB object.  CI preserves the object so you can use the DB methods to access the previous query and other meta-data available within the object.  We may not want to destroy something that valuable…after all, we are supposed to be doing the OOP thing right?

    So, at any time in the future, if you simply send the DB object any properly form query, it tests to see if a connection exists and if it does not, it re-creates the connection based upon your database group settings.

    Hence, you thought you connection was destroyed, but CI will re-create it on the fly.

    ——

    So the question is:

    1) Is this the expected behavior? (a fail safe)

    2) If the developer purposefully invokes the close() method, should CI honor that request and not (somewhat blindly) re-open a connection the develop thought he/she had closed?

    ——

    Food for thought.

    —-

    Comments?

    Randy

  • #14 / Nov 03, 2008 5:17pm

    Randy Casburn

    997 posts

    Is it because of the nasty internet gnomes always killing data packets?

    Dogonit Xeon!  You were so close too… 😛

  • #15 / Nov 03, 2008 5:21pm

    Randy Casburn

    997 posts

    I’ll have a crack at it but, I don’t do A level maths so how the hell?! lol. Good ol’ Randy 😛

    I was just joking man…you guys take me waaaaaay too seriously…hahahahehheeheeheh

    Lol, fair enough. The big “E” looking thing is a Sigma, and means the sum of. Does that count?! 😛

    Ok…you can win too then!


    Randy

    p.s.  The formula is a continuous variance of a standard deviation - I used this in a Monte Carlo simulation engine that calculated all kinds of financial derivatives and performance statistics - I didn’t have a clue about most of it!!  :cheese:

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases