ConnectionManager getDataSource undefined method
Asked Answered
H

1

0

Using cakephp 2.3.8 I am attempting to setup a connection to a custom couchbase datasource I have made within another datasource. The datasource I am attempting to load functions properly on the rest of the site when being loaded via a model. I want to use the connection manager to load this datasource. This is what I have so far:

database.php file:

public $queriesCB = array(  
    'datasource' => 'CouchbaseSource',
    'username'      => 'queries',
    'password'   => '',
    'bucket'        => 'queries', 
    'prefix'    => 'q_',
    'expiry'    => '1814400', //3 Weeks
    'autoConnect' => true, 
    'database'      => NULL , 
    'persistent' => false
    );

Within my other datasource trying to load couchbase datasource

$db = ConnectionManager::getDataSource("queriesCB"); 

When I debug $db I get this:

object(CouchbaseSource) {
        description => 'Couchbase DataSource'
        conObject => object(Couchbase) {
                [private] _handle => resource
        }
        config => array(
                'password' => '*****',
                'database' => '*****',
                'prefix' => '*****',
                'datasource' => 'CouchbaseSource',
                'username' => 'queries',
                'bucket' => 'queries',
                'expiry' => '1814400',
                'autoConnect' => true,
                'persistent' => false
        )
        prefix => 'q__'
        connected => false
        cacheSources => true
        configKeyName => 'queriesCB'
        [protected] _baseConfig => array()
        [protected] _descriptions => array()
        [protected] _sources => null
        [protected] _transactionStarted => false
}

Now when I try to call this I get a error:

$db = ConnectionManager::getDataSource("queriesCB"); 
$db->Get('test');

Error: Call to undefined method CouchbaseSource::Get().

This is a custom method, the datasource is all custom to work best with couchbase and the Get method does function properly. How am I setting up this connection wrong in cakephp?

Edit:

I just tested it with the default database config to a mysql database, it fails as well. The question now would be what would be the best way to initialize a new datasource? should I have to load a model with that datasource attached? Example: have a couchbase model with the datasource as couchbase?

Edit: Here is some of the datasource

class CouchbaseSource extends DataSource { 
    public $description = 'Couchbase DataSource';
    public $conObject = NULL;
    public $config = NULL;
    public $prefix = NULL;


public function __construct($config = array()){

    // If no configuration is set we use the default
    $this->config = $config; 

    // Setup the cache string that is used when building the string
    $this->prefix = (isset($this->config['prefix']) ? $this->config['prefix']."_" : "");

    if ($this->config['autoConnect']) {
        $this->connect();
    }

}


public function connect() {
    if ($this->conObject !== true) {
        try {
            $this->conObject = new Couchbase("127.0.0.1:8091", $this->config['username'], $this->config['password'], $this->config['bucket'], $this->config['persistent']);
        } catch (Exception $e) {
            throw new MissingConnectionException(array('class' => $e->getMessage()));
        }
    }
    return $this->conObject;
}


public function query($method, $params, $object) {

    // If not connected... reconnect!
    if(!$this->conObject) {
        $this->connect();
    }

    $apiMethod = $this->__methodToClass($method);
    if (!method_exists($this, $apiMethod)) {
        throw new NotFoundException("Class '{$apiMethod}' was not found");
    } else {
        return call_user_func_array(array($this, $apiMethod), $params);
    }  
}


private function __methodToClass($method) {
    return 'CB' . strtolower(Inflector::camelize($method));
}


public function describe(&$Model) {
    return $this->description;
}

/////////////////////////////////////////////////
// Query Methods
/////////////////////////////////////////////////

public function CBadd($key = NULL, $value = NULL, $expiry = NULL, $persisto = NULL, $replicateto = NULL) {
    return $this->conObject->add($key, $value, $expiry, $persisto, $replicateto);
}
Homologous answered 10/8, 2013 at 15:15 Comment(7)
Please show the CouchbaseSource class source, or provide an example datasource that causes the same behaviour.Diploid
A test using the default datasource failed. I suspect that this is due to not calling a datasource from a model? My datasource I am using isn't exactly to the same conventions as cakephp guildelines.Homologous
It doesn't matter from where you invoke something on a datasource object, whether it's directly or indirectly through a model, it should work either way. Retrieving a DS using ConnectionManager::getDataSource() and then invoking methods on the DS is totally ok and should work just fine (it does for me). I'm not sure what conventions you are referring to, but if you are talking about implementing the CRUD API, that's only necessary in case the DS is ment to be connected to a model.Diploid
yes my DS wouldn't be considered a crud api, after looking at my output from $db above, I am wondering if conObject is really setup right? It doesn't appear to have any of my methods from my datasource availableHomologous
I took a look at my default datasource through mysql, doesn't appear to have anything significantly different. Still giving me the PHP Fatal error: Call to undefined method CouchbaseSource::Get()Homologous
I think a model will automatcally map the call to "query" in this case I will need to call query myself?Homologous
So essentially you were trying to call a method on the conObject property, since there is no get method on the datasource, only a CBget method (judging from your code snippet). It's always a good idea to include such information in the question, since it's crucial for the problem.Diploid
H
2

The solution is to directly call the query method from the couchbasesource. Given the way that I setup the datasource, unlike linking it through a model, the query information was not automatically passed. My go around was to simple use this.

App::uses('ConnectionManager', 'Model');
$db = ConnectionManager::getDataSource("queriesCB");
debug($db->query('Get', array('test')));
Homologous answered 11/8, 2013 at 2:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.