Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Support for Model::findAllBy$Field w/autocreating views #3

Closed
wants to merge 1 commit into from

2 participants

@phishy

No description provided.

@gwoo gwoo commented on the diff
tests/integration/data/CrudExtendedTest.php
((11 lines not shown))
$company = Companies::find($company1->id);
$data = $company->data();
$this->assertEqual('Marine Store', $data['name']);
+ $company1->delete();
@gwoo Owner
gwoo added a note

this should probably be $company->delete() instead of $company1->delete()

@phishy
phishy added a note

It's the same thing.

@gwoo Owner
gwoo added a note

It may seem that way, but it is two different things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@gwoo gwoo commented on the diff
extensions/data/source/Couchbase.php
((11 lines not shown))
}
- if (!empty($conditions['view'])) {
+ if (empty($conditions)) {
@gwoo Owner
gwoo added a note

Could you move this logic to the conditions method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@phishy phishy closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 28, 2013
  1. @phishy
This page is out of date. Refresh to see the latest.
View
140 extensions/data/source/Couchbase.php
@@ -1,8 +1,8 @@
<?php
/**
- * li3_couchbase: A Couchbase datasource for Lithium.
+ * li3_couchbase: A Couchbase data source for Lithium.
*
- * @copyright Copyright 2012, Michael Nitschinger
+ * @copyright Copyright 2013, Union Of RAD
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
@@ -12,6 +12,7 @@
use lithium\core\NetworkException;
use lithium\core\Environment;
use lithium\util\Inflector;
+use lithium\util\String;
/**
* A data source adapter which allows you to connect to the Couchbase database engine.
@@ -74,7 +75,22 @@ class Couchbase extends \lithium\data\Source {
protected $_views = array();
/**
+ * Map of sources to classes
*
+ * @var array
+ */
+ protected $_classMap = array();
+
+ /**
+ * Design document prefix
+ *
+ * @var string
+ */
+ public $prefix = '';
+
+ /**
+ * Constructor.
+ * @param array $config
*/
public function __construct(array $config = array()) {
$defaults = array(
@@ -84,6 +100,7 @@ public function __construct(array $config = array()) {
'database' => 'default',
'persistent' => true
);
+ $this->prefix = (Environment::get() == 'production') ? '' : 'dev_';
parent::__construct($config + $defaults);
}
@@ -121,19 +138,35 @@ public function configureClass($class) {
$pieces = explode('\\', $class);
$model = array_pop($pieces);
$source = Inflector::tableize($model);
- $prefix = (Environment::get() == 'production') ? '' : 'dev_';
- $this->_views[$source] = json_decode($this->getDesignDoc("{$prefix}{$source}"), true);
- $this->_views[$source] = $this->_views[$source]['views'];
- if ($this->_views[$source]) {
- foreach ($this->_views[$source] as $k => $v) {
- $class::finder($k, array('conditions' => array('view' => $k)));
+ $this->_classMap[$source] = $class;
+ $this->registerViews($source);
+ return array('schema' => array(), 'meta' => array('key' => 'id', 'locked' => false));
+ }
+
+ /**
+ * Introspects Couchbase for views, and automatically registers Model finders
+ *
+ * @param $source Couchbase view name
+ */
+ public function registerViews($source) {
+ $class = $this->_classMap[$source];
+ $this->_views[$source] = json_decode($this->getDesignDoc("{$this->prefix}{$source}"),
+ true);
+ if (isset($this->_views[$source])) {
+ $this->_views[$source] = $this->_views[$source]['views'];
+ if ($this->_views[$source]) {
+ foreach ($this->_views[$source] as $k => $v) {
+ $class::finder($k, array('conditions' => array('view' => $k)));
+ }
}
}
- return array('schema' => array(), 'meta' => array('key' => 'id', 'locked' => false));
}
/**
+ * Connects to the database using the options provided to the class constructor.
*
+ * @return boolean Returns `true` if a database connection could be established, otherwise
+ * `false`.
*/
public function connect() {
$config = $this->_config;
@@ -148,7 +181,9 @@ public function connect() {
}
/**
+ * Disconnects the adapter from the database.
*
+ * @return boolean Returns `true` on success, else `false`.
*/
public function disconnect() {
$this->_isConnected = false;
@@ -157,14 +192,22 @@ public function disconnect() {
}
/**
+ * Returns an array of object types accessible through this database.
*
+ * @param object $class
+ * @return void
*/
public function sources($class = null) {
return array();
}
/**
+ * Describe database
*
+ * @param object $collection
+ * @param array $schema Any schema data pre-defined by the model.
+ * @param array $meta
+ * @return void
*/
public function describe($collection, $fields = array(), array $meta = array()) {
if (!$fields && ($func = $this->_schema)) {
@@ -189,13 +232,25 @@ public function calculation($type, $query, array $options = array()) {
return 0;
}
}
+
/**
+ * Defines or modifies the default settings of a relationship between two models.
*
+ * @param string $class the primary model of the relationship
+ * @param string $type the type of the relationship (hasMany, hasOne, belongsTo)
+ * @param string $name the name of the relationship
+ * @param array $config relationship options
+ * @return array Returns an array containing the configuration for a model relationship.
*/
public function relationship($class, $type, $name, array $options = array()) {}
/**
+ * Create new document.
*
+ * @param string $query
+ * @param array $options
+ * @return boolean
+ * @filter
*/
public function create($query, array $options = array()) {
$this->_checkConnection();
@@ -233,7 +288,38 @@ public function create($query, array $options = array()) {
}
/**
+ * Returns an array of views for a given source
+ *
+ * @param string $source
+ * @return array
+ */
+ public function views($source = '') {
+ return ($source) ? $this->_views[$source] : $this->_views;
+ }
+
+ /**
+ * Creates a new Couchbase view and re-registers Model finders
+ *
+ * @param string $source
+ * @param string $field
+ */
+ public function createView($source, $field) {
+ $views = json_decode($this->getDesignDoc("{$this->prefix}{$source}"), true);
+ $views['views']["by_{$field}"] = array(
+ 'map' =>
+ "function (doc, meta) { if(doc._source == '{$source}') { emit(doc.{$field}, doc) }}",
+ );
+ $this->setDesignDoc("{$this->prefix}{$source}", json_encode($views));
+ $this->registerViews($source);
+ }
+
+ /**
+ * Read from document.
*
+ * @param string $query
+ * @param array $options
+ * @return object
+ * @filter
*/
public function read($query, array $options = array()) {
$this->_checkConnection();
@@ -252,23 +338,37 @@ public function read($query, array $options = array()) {
$key = $model::key();
$viewName = '';
- $prefix = (Environment::get() == 'production') ? '' : 'dev_';
+ $viewOptions = array('stale' => false);
- if (!$conditions) {
- $viewName = 'all';
+ if (isset($conditions['view']) && $conditions['view'] == 'all') {
+ unset($conditions['view']);
}
- if (!empty($conditions['view'])) {
+ if (empty($conditions)) {
@gwoo Owner
gwoo added a note

Could you move this logic to the conditions method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $conditions['view'] = 'all';
+ }
+
+ if (!empty($conditions[$key])) {
+ // nada
+ } elseif (empty($conditions['view'])) {
+ $field = key($conditions);
+ $viewName = "by_{$field}";
+ $viewOptions['key'] = array_shift($conditions);
+ } else {
$viewName = $conditions['view'];
}
- $viewOptions = array('stale' => false);
+ if ($viewName && !array_key_exists($viewName, $self->views($source))) {
+ $self->createView($source, $field);
+ }
+
if (isset($conditions['key'])) {
$viewOptions['key'] = $conditions['key'];
}
if ($viewName) {
- $view = $self->connection->view($prefix . $source, $viewName, $viewOptions);
+ $view = $self->connection->view("{$self->prefix}{$source}", $viewName,
+ $viewOptions);
$records = array();
if (!empty($view['rows'])) {
foreach ($view['rows'] as $r) {
@@ -291,7 +391,12 @@ public function read($query, array $options = array()) {
}
/**
+ * Update document.
*
+ * @param string $query
+ * @param array $options
+ * @return boolean
+ * @filter
*/
public function update($query, array $options = array()) {
$this->_checkConnection();
@@ -323,7 +428,12 @@ public function update($query, array $options = array()) {
}
/**
+ * Delete document.
*
+ * @param string $query
+ * @param array $options
+ * @return boolean
+ * @filter
*/
public function delete($query, array $options = array()) {
$params = compact('query', 'options');
View
62 tests/integration/data/CrudExtendedTest.php
@@ -52,25 +52,6 @@ public function skip() {
* Creating the test database
*/
public function setUp() {
- $views = array(
- 'views' =>
- array(
- 'all' =>
- array(
- 'map' =>
- "function (doc, meta) { if(doc._source == 'companies') { emit(meta.id,
- doc) }}",
- ),
- 'by_active' =>
- array(
- 'map' =>
- "function (doc, meta) { if(doc._source == 'companies') { emit(doc.active, doc
- ) }}",
- ),
- ),
- );
- $result = $this->db->setDesignDoc('dev_companies', json_encode($views));
- $this->assertTrue($result);
//$this->db->connection->put($this->_database);
}
@@ -141,15 +122,31 @@ public function testFindAll() {
$this->assertTrue($company->delete());
}
- public function testFindByView() {
+ public function testFindById() {
$company1 = Companies::create($this->data[0]);
$company1->save();
- $company2 = Companies::create($this->data[1]);
- $company2->save();
-
$company = Companies::find($company1->id);
$data = $company->data();
$this->assertEqual('Marine Store', $data['name']);
+ $company1->delete();
@gwoo Owner
gwoo added a note

this should probably be $company->delete() instead of $company1->delete()

@phishy
phishy added a note

It's the same thing.

@gwoo Owner
gwoo added a note

It may seem that way, but it is two different things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+ public function testFindByStaticFinder() {
+ $company1 = Companies::create($this->data[0]);
+ $company1->save();
+ $company2 = Companies::create($this->data[1]);
+ $company2->save();
+ $company = Companies::by_active();
+ $this->assertEqual(2, count($company));
+ $company1->delete();
+ $company2->delete();
+ }
+
+ public function testFindByView() {
+ $company1 = Companies::create($this->data[0]);
+ $company1->save();
+ $company2 = Companies::create($this->data[1]);
+ $company2->save();
$companies = Companies::find('by_active');
$this->assertEqual(2, count($companies->data()));
@@ -157,10 +154,29 @@ public function testFindByView() {
$companies = Companies::find('all', array('conditions' => array('view' => 'by_active')));
$this->assertEqual(2, count($companies->data()));
+// $companies = Companies::find('first', array('conditions' => array('view' => 'by_active')));
+// $this->assertEqual(2, count($companies->data()));
+
$companies = Companies::find('by_active', array('conditions' => array('key' => false)));
$this->assertEqual(1, count($companies->data()));
$company1->delete();
$company2->delete();
}
+
+ public function testFindByViewAutocreate() {
+ $company1 = Companies::create($this->data[0]);
+ $company1->save();
+ $company2 = Companies::create($this->data[1]);
+ $company2->save();
+
+ $company = Companies::findAllByName('Marine Store');
+ $this->assertEqual(1, count($company->data()));
+
+ $company = Companies::findByName('Marine Store');
+ $this->assertEqual('Marine Store', $company['name']);
+
+ $company1->delete();
+ $company2->delete();
+ }
}
Something went wrong with that request. Please try again.