Welcome Guest, Not a member yet? Register   Sign In
file cache with its own library doesn't work
#1

When we turn file cache when using own library (custom_result_object) we don't get the result (empty array).
Reply
#2

(This post was last modified: 12-27-2015, 08:31 AM by Veygr.)

Solution.

In:
PHP Code:
system/databases/DB_result.php 

Find (line 186):
PHP Code:
elseif ( ! $this->result_id OR $this->num_rows === 0

Replace on:
PHP Code:
elseif ( /* ! $this->result_id OR */ $this->num_rows === 0
Reply
#3

In most cases editing core files is not the way to go. Instead you should extend that function in a seperate file. Otherwise you will run into upgrade issues.

Apart from that general remark there is a comment above the line you have altered:
Code:
// In the event that query caching is on, the result_id variable
// will not be a valid resource so we'll simply return an empty
// array.
Have you tried figuring out why your result_id does contain a valid result?
Reply
#4

This comment is from the line 242. See the method custom_result_object - line 178.

result_id is empty because file cache clear this field in:
PHP Code:
if ($this->cache_on === TRUE && $this->_cache_init())
{
    
// We'll create a new instance of the result object
    // only without the platform specific driver since
    // we can't use it with cached data (the query result
    // resource ID won't be any good once we've cached the
    // result object, so we'll have to compile the data
    // and save it)
    
$CR = new CI_DB_result($this);
    
$CR->result_object    $RES->result_object();
    
$CR->result_array    $RES->result_array();
    
$CR->num_rows        $RES->num_rows();

    
// Reset these since cached objects can not utilize resource IDs.
    
$CR->conn_id        NULL;
    
$CR->result_id        NULL;

    
$this->CACHE->write($sql$CR);



What if I extend DB_result, and the new version will not be compatible with this extension? It would be better verify and make changes again. I think this is a bug and it will be fixed.
Reply
#5

Despite the fact that the comment is from a different line, similar code is used in all 3 result methods, so the comment is still applicable. The only reason you're getting to line 186 is because the object you're looking for is not in the current DB_result object.

I don't particularly care for this behavior, but the DB_result class stores the result_array, result_object, or custom_result_object as separate properties (and different custom classes are stored separately within the custom_result_object property), and refuses to convert from one to another if they are retrieved from a cached result. On the other hand, if it's not a cached DB_result, it will happily convert a result_array or result_object into any of the other options, and in some (many? most?) cases this can be done without retrieving additional data from the database (in which case the result_id isn't needed).
Reply
#6

Would you have better solution to the above problem?
Reply
#7

(This post was last modified: 12-30-2015, 10:55 AM by mwhitney. Edit Reason: indentation in code block )

One of the reasons that it won't return data if you're dealing with a cached result and it can't find the result in the form you're requesting is that the result is usually fetched from the database in that form.

Your modification should work, assuming the result_array or result_object found in your cached result is actually the same result you would receive if you ran your query against the database, but it also depends on the default behavior of some of the methods called later in the custom_result_object() method if the data really isn't there. The assumption that the result is the same also leads to the question of why a cached result doesn't contain the custom result object in the first place, which implies that you may be caching a query in a situation which may not be appropriate for CI's approach to query caching.

To remove the reliance on the default behavior later in the method, I would replace the functionality you commented out in line 186 at a later point in the method. The easiest approach would probably be to add an additional elseif clause after line 200, like this:

PHP Code:
        if (($c count($this->result_array)) > 0)
        {
            
$_data 'result_array';
        }
        elseif ((
$c count($this->result_object)) > 0)
        {
            
$_data 'result_object';
        } 
// new code below:
        
elseif ( ! $this->result_id)
        {
            return array();
        } 

The lack of a custom result object for this class in the cached result indicates that something about your query has changed since the data was cached, though. In that case, it's questionable whether the data cached in the result_array or result_object is actually valid for the current query.

In general, I agree with Diederick's statement that you should extend the class rather than editing the core file directly. However, you can't actually extend the CI_DB_result class without also extending the CI_DB_driver to load the extended class, which would require a modified version of DB.php (because this file defines a function, not a class) to load the extended CI_DB_driver, and extending the CI_Loader to load the modified DB() function.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB