Commit 904654dc authored by Jens Segers's avatar Jens Segers

More features

parent 9d26ccb9
......@@ -41,7 +41,7 @@ class ConnectionResolver implements ConnectionResolverInterface {
* Get a database connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
* @return Connection
*/
public function connection($name = null)
{
......
......@@ -2,15 +2,9 @@
use Illuminate\Database\ConnectionResolverInterface as Resolver;
use Illuminate\Database\Eloquent\Collection;
use Jenssegers\Mongodb\Query as QueryBuilder;
abstract class Model extends \ArrayObject {
/**
* The connection name for the model.
*
* @var string
*/
protected $connection;
abstract class Model extends \Illuminate\Database\Eloquent\Model {
/**
* The collection associated with the model.
......@@ -27,225 +21,48 @@ abstract class Model extends \ArrayObject {
protected $primaryKey = '_id';
/**
* The connection resolver instance.
*
* @var Jenssegers\Mongodb\ConnectionResolverInterface
*/
protected static $resolver;
/**
* Get properties from internal array
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
return $this[$name];
}
/**
* Write all properties to internal array
*
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
$this[$name] = $value;
}
/**
* Handle dynamic method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
// Create a query
$query = $this->newQuery();
return call_user_func_array(array($query, $method), $parameters);
}
/**
* Handle dynamic static method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
$instance = new static;
return call_user_func_array(array($instance, $method), $parameters);
}
/**
* Get all of the models from the database.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function all($columns = array('*'))
{
$instance = new static;
return $instance->newQuery()->get($columns);
}
/**
* Find a model by its primary key.
*
* @param mixed $id
* @param array $columns
* @return \Jenssegers\Mongodb\Model|\Illuminate\Database\Eloquent\Collection
*/
public static function find($id, $columns = array('*'))
{
$instance = new static;
if (is_array($id))
{
$id = array_map(function($value)
{
return ($value instanceof MongoID) ? $value : new MongoID($value);
}, $id);
return $instance->newQuery()->whereIn($instance->getKeyName(), $id)->get($columns);
}
return $instance->newQuery()->find($id, $columns);
}
/**
* Create a new instance of the given model.
*
* @param array $attributes
* @param bool $exists
* @return \Jenssegers\Mongodb\Model
*/
public function newInstance($attributes = array(), $exists = false)
{
// This method just provides a convenient way for us to generate fresh model
// instances of this current model. It is particularly useful during the
// hydration of new objects via the Eloquent query builder instances.
$model = new static((array) $attributes);
$model->exists = $exists;
return $model;
}
/**
* Get a new query for the model's table.
*
* @return \Jenssegers\Mongodb\Query
*/
public function newQuery()
{
$query = new Query($this);
return $query;
}
/**
* Create a new Collection instance.
*
* @param array $models
* @return LMongo\Eloquent\Collection
*/
public function newCollection(array $models = array())
{
return new Collection($models);
}
/**
* Get the database collection for the model.
*
* @return \Jenssegers\Mongodb\Connection
*/
public function getCollection()
{
return $this->collection;
}
/**
* Get the database connection for the model.
* Perform a model insert operation.
*
* @return \Jenssegers\Mongodb\Connection
* @param \Illuminate\Database\Eloquent\Builder
* @return bool
*/
public function getConnection()
protected function performInsert($query)
{
return static::resolveConnection($this->connection);
}
if ($this->fireModelEvent('creating') === false) return false;
/**
* Get the current connection name for the model.
*
* @return string
*/
public function getConnectionName()
{
return $this->connection;
}
$attributes = $this->attributes;
/**
* Set the connection associated with the model.
*
* @param string $name
* @return void
*/
public function setConnection($name)
// If the model has an incrementing key, we can use the "insertGetId" method on
// the query builder, which will give us back the final inserted ID for this
// table from the database. Not all tables have to be incrementing though.
if ($this->incrementing)
{
$this->connection = $name;
$keyName = $this->getKeyName();
$this->setAttribute($keyName, $query->insert($attributes));
}
/**
* Get the primary key for the model.
*
* @return string
*/
public function getKeyName()
// If the table is not incrementing we'll simply insert this attributes as they
// are, as this attributes arrays must contain an "id" column already placed
// there by the developer as the manually determined key for these models.
else
{
return $this->primaryKey;
$query->insert($attributes);
}
/**
* Resolve a connection instance by name.
*
* @param string $connection
* @return \Jenssegers\Mongodb\Connection
*/
public static function resolveConnection($connection)
{
return static::$resolver->connection($connection);
}
$this->fireModelEvent('created', false);
/**
* Get the connection resolver instance.
*
* @return \Jenssegers\Mongodb\ConnectionResolverInterface
*/
public static function getConnectionResolver()
{
return static::$resolver;
return true;
}
/**
* Set the connection resolver instance.
* Get a new query builder instance for the connection.
*
* @param Jenssegers\Mongodb\ConnectionResolverInterface $resolver
* @return void
* @return Builder
*/
public static function setConnectionResolver(Resolver $resolver)
protected function newBaseQueryBuilder()
{
static::$resolver = $resolver;
$connection = $this->getConnection();
return new QueryBuilder($connection, $this->collection);
}
}
\ No newline at end of file
......@@ -2,63 +2,14 @@
use MongoID;
class Query {
class Query extends \Illuminate\Database\Query\Builder {
/**
* The model.
* The database collection
*
* @var Jenssegers\Mongodb\Model
* @var string
*/
protected $model;
/**
* The database connection instance.
*
* @var Jenssegers\Mongodb\Connection
*/
protected $connection;
/**
* The database collection used for the current query.
*
* @var string $collection
*/
protected $collection;
/**
* The where constraints for the query.
*
* @var array
*/
public $wheres = array();
/**
* The columns that should be returned.
*
* @var array
*/
public $columns = array();
/**
* The orderings for the query.
*
* @var array
*/
public $orders = array();
/**
* The maximum number of documents to return.
*
* @var int
*/
public $limit;
/**
* The number of records to skip.
*
* @var int
*/
public $offset;
public $collection;
/**
* All of the available operators.
......@@ -71,60 +22,20 @@ class Query {
'<' => '$lt',
'<=' => '$le',
'>' => '$gt',
'>=' => '$ge'
'>=' => '$ge',
'in' => '$in',
);
/**
* Create a new model query builder instance.
* Create a new query builder instance.
*
* @param Jenssegers\Mongodb\Connection $connection
* @param Connection $connection
* @return void
*/
public function __construct(Model $model)
public function __construct(Connection $connection, $collection)
{
$this->model = $model;
$this->connection = $model->getConnection();
$this->collection = $this->connection->getCollection($model->getCollection());
}
/**
* Set the "limit" value of the query.
*
* @param int $value
* @return \Jenssegers\Mongodb\Query
*/
public function take($value)
{
$this->limit = $value;
return $this;
}
/**
* Set the "offset" value of the query.
*
* @param int $value
* @return \Illuminate\Database\Query\Builder
*/
public function skip($value)
{
$this->offset = $value;
return $this;
}
/**
* Add an "order by" clause to the query.
*
* @param string $column
* @param string $direction
* @return \Illuminate\Database\Query\Builder
*/
public function orderBy($column, $direction = 'asc')
{
$this->orders[$column] = ($direction == 'asc' ? 1 : -1);
return $this;
$this->connection = $connection;
$this->collection = $connection->getCollection($collection);
}
/**
......@@ -136,69 +47,30 @@ class Query {
*/
public function find($id, $columns = array('*'))
{
$id = new MongoID((string) $id);
return $this->where($this->model->getKeyName(), '=', $id)->first($columns);
return $this->where('_id', '=', new MongoID((string) $id))->first($columns);
}
/**
* Execute the query and get the first result.
* Execute the query as a "select" statement.
*
* @param array $columns
* @return array
*/
public function first($columns = array())
{
return $this->take(1)->get($columns)->first();
}
/**
* Add a basic where clause to the query.
*
* @param string $column
* @param string $operator
* @param mixed $value
* @param string $boolean
* @return \Jenssegers\Mongodb\Query
*/
public function where($column, $operator = null, $value = null, $boolean = 'and')
public function get($columns = array('*'))
{
// If the given operator is not found in the list of valid operators we will
// assume that the developer is just short-cutting the '=' operators and
// we will set the operators to '=' and set the values appropriately.
if (!in_array(strtolower($operator), $this->operators, true))
// If no columns have been specified for the select statement, we will set them
// here to either the passed columns, or the standard default of retrieving
// all of the columns on the table using the "wildcard" column character.
if (is_null($this->columns))
{
list($value, $operator) = array($operator, '=');
}
if ($operator == '=')
{
$this->wheres[$column] = $value;
}
else
{
$this->wheres[$column] = array($this->operators[$operator] => $value);
}
return $this;
$this->columns = $columns;
}
/**
* Execute the query as a "select" statement.
*
* @param array $columns
* @return Collection
*/
public function get($columns = array())
{
// Merge with previous columns
$this->columns = array_merge($this->columns, $columns);
// Drop all columns if * is present
if (in_array('*', $this->columns)) $this->columns = array();
// Get Mongo cursor
$cursor = $this->collection->find($this->wheres, $this->columns);
$cursor = $this->collection->find($this->compileWheres(), $this->columns);
// Apply order
if ($this->orders)
......@@ -218,57 +90,50 @@ class Query {
$cursor->limit($this->limit);
}
// Return collection of models
return $this->toCollection($cursor);
return $cursor;
}
/**
* Insert a new document into the database.
* Add an "order by" clause to the query.
*
* @param array $data
* @return mixed
* @param string $column
* @param string $direction
* @return \Illuminate\Database\Query\Builder
*/
public function insert($data)
{
$result = $this->collection->insert($data);
if(1 == (int) $result['ok'])
public function orderBy($column, $direction = 'asc')
{
return $data['_id'];
}
$this->orders[$column] = ($direction == 'asc' ? 1 : -1);
return false;
return $this;
}
/**
* Save the document. Insert into the database if its not exists.
* Insert a new record into the database.
*
* @param array $data
* @return mixed
* @param array $values
* @return bool
*/
public function save($data)
public function insert(array $values)
{
$this->collection->save($data);
$result = $this->collection->insert($values);
if(isset($data['_id']))
if(1 == (int) $result['ok'])
{
return $data['_id'];
return $values['_id'];
}
return false;
}
/**
* Update a document in the database.
* Update a record in the database.
*
* @param array $data
* @param array $values
* @return int
*/
public function update(array $data)
public function update(array $values)
{
$update = array('$set' => $data);
$update = array('$set' => $values);
$result = $this->collection->update($this->wheres, $update, array('multiple' => true));
$result = $this->collection->update($this->compileWheres(), $update, array('multiple' => true));
if(1 == (int) $result['ok'])
{
......@@ -279,13 +144,15 @@ class Query {
}
/**
* Delete a document from the database.
* Delete a record from the database.
*
* @param mixed $id
* @return int
*/
public function delete()
public function delete($id = null)
{
$result = $this->collection->remove($this->wheres);
$query = $this->compileWheres($this);
$result = $this->collection->remove($query);
if(1 == (int) $result['ok'])
{
......@@ -296,20 +163,62 @@ class Query {
}
/**
* Transform to model collection.
* Compile the where array
*
* @param array $columns
* @return Collection
* @return array
*/
public function toCollection($results)
public function compileWheres()
{
if (!$this->wheres) return array();
$wheres = array();
foreach ($this->wheres as $where)
{
$models = array();
// Delegate
$method = "compileWhere{$where['type']}";
$compiled = $this->{$method}($where);
foreach ($compiled as $key=>$value)
$wheres[$key] = $value;
}
return $wheres;
}
foreach ($results as $result) {
$models[] = $this->model->newInstance($result);
public function compileWhereBasic($where)
{
extract($where);
// Convert id's
if ($column == '_id')
{
$value = ($value instanceof MongoID) ? $value : new MongoID($value);
}
// Convert operators
if (!isset($operator) || $operator == '=')
{
return array($column => $value);
}
else
{
return array($column => array($this->operators[$operator] => $value));
}
}
public function compileWhereIn($where)
{
extract($where);
// Convert id's
if ($column == '_id')
{
foreach ($values as &$value)
$value = ($value instanceof MongoID) ? $value : new MongoID($value);
}
return $this->model->newCollection($models);
return array($column => array($this->operators['in'] => $values));
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment