Welcome Guest, Not a member yet? Register   Sign In
DB_Cache ignores queryvars [PATCH]
#1

[eluser]mark17[/eluser]
L.S.

Using DB_Cache at least in CI 1.6.2 will never work properly when using prepared statements including variables.

Code:
/**
     * Retrieve a cached query
     *
     * The URI being requested will become the name of the cache sub-folder.
     * An MD5 hash of the SQL statement will become the cache file name
     *
     * @access    public
     * @return    string
     */
    function read($sql)
    {
print "$sql\n";
        if ( ! $this->check_path())
        {
            return $this->db->cache_off();
        }

At any time it will result in creating identical cachefilenames for e.g.
SELECT * FROM table WHERE field = ?; (? = 1)
SELECT * FROM table WHERE field = ?; (? = 2)

The system does _not_ pass parsed SQL statements to the cachesystem, therefore reading previously written cachefiles for the same query will result in yet another write since it cannot be read.

Writing cachefiles, however, does not suffer from this problem.


The calling code:
Code:
if (FALSE !== ($cache = $this->CACHE->read($sql)))
in DB_Driver clearly passes an unparsed query.


Regards,
#2

[eluser]mark17[/eluser]
A quick patch for this problem is switching two sequentiel codeblocks in DB_Driver.php starting at line #270;

OLD CODE:
Code:
// Is query caching enabled?  If the query is a "read type"

        // we will load the caching class and return the previously

        // cached query if it exists

        if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))

        {

            if ($this->_cache_init())

            {

                $this->load_rdriver();

                if (FALSE !== ($cache = $this->CACHE->read($sql)))

                {

                    return $cache;

                }

            }

        }

        

        // Compile binds if needed

        if ($binds !== FALSE)

        {

            $sql = $this->compile_binds($sql, $binds);

        }


PATCH CODE:
Code:
// Compile binds if needed

        if ($binds !== FALSE)

        {

            $sql = $this->compile_binds($sql, $binds);

        }


        // Is query caching enabled?  If the query is a "read type"

        // we will load the caching class and return the previously

        // cached query if it exists

        if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))

        {

            if ($this->_cache_init())

            {

                $this->load_rdriver();

                if (FALSE !== ($cache = $this->CACHE->read($sql)))

                {

                    return $cache;

                }

            }

        }

This will parse the prepared statement _before_ attempting to compile a filename in DB_Cache itself. I cannot understand that this has been around for quite some time without anyone noticing. Of course, this old behaviour will never surface in altering the state of the data but will result in loss in performance when relying on it.

Please submit this patch in future versions.
#3

[eluser]mark17[/eluser]
L.S.


The problem above was reported over a month ago with no form of recognision of whatsoever. Is this, as it's not uncommon, be dismissed yet again?


Regards,




Theme © iAndrew 2016 - Forum software by © MyBB