Commit 7effee85 authored by Jens Segers's avatar Jens Segers

First commit

parents
.DS_Store
Laravel Eloquent MongoDB
========================
This is an alternative Eloquent model that supports MongoDB. The code structure is not great, and there is little functionality at this moment.
Some code is based on https://github.com/navruzm/lmongo, that has way more complete features, but works a bit different than Eloquent.
Usage
-----
Tell your model to use the MongoDB model and a MongoDB collection:
use Jenssegers\Mongodb\Model as Eloquent
class MyModel extends Eloquent {
protected $collection = 'mycollection';
}
Configuration
-------------
The model will automatically check the Laravel database configuration array for a 'mongodb' item.
'mongodb' => array(
'host' => 'localhost',
'port' => 27017,
'database' => 'database',
),
You can also specify the connection name in the model:
class MyModel extends Eloquent {
protected $connection = 'mongodb2';
}
\ No newline at end of file
{
"name": "jenssegers/mongodb",
"authors": [
{
"name": "Jens Segers",
"email": "hello@jenssegers.be"
}
],
"license" : "MIT",
"require": {
"php": ">=5.3.0",
"illuminate/support": "4.0.x"
},
"autoload": {
"psr-0": {
"Jenssegers\\Mongodb": "src/"
}
},
"minimum-stability": "dev"
}
\ No newline at end of file
<?php namespace Jenssegers\Mongodb;
class Connection {
/**
* The MongoDB database handler.
*
* @var resource
*/
protected $db;
/**
* The MongoClient connection handler.
*
* @var resource
*/
protected $connection;
/**
* The database connection configuration options.
*
* @var string
*/
protected $config = array();
/**
* Create a new database connection instance.
*
* @param array $config
* @return void
*/
public function __construct(array $config)
{
if (!is_null($this->connection)) return;
// Store configuration
$this->config = $config;
// Check for connection options
$options = array_get($config, 'options', array());
// Create connection
$this->connection = new \MongoClient($this->getDsn($config), $options);
// Select database
$this->db = $this->connection->{$config['database']};
return $this;
}
/**
* Get a mongodb collection.
*
* @param string $name
*/
public function getCollection($name) {
return $this->db->{$name};
}
/**
* Create a DSN string from a configuration.
*
* @param array $config
* @return string
*/
protected function getDsn(array $config)
{
// First we will create the basic DSN setup as well as the port if it is in
// in the configuration options. This will give us the basic DSN we will
// need to establish the MongoClient and return them back for use.
extract($config);
$dsn = "mongodb://";
if (isset($config['username']) and isset($config['password']))
{
$dsn .= "{$username}:{$password}@";
}
$dsn.= "{$host}";
if (isset($config['port']))
{
$dsn .= ":{$port}";
}
$dsn.= "/{$database}";
return $dsn;
}
}
\ No newline at end of file
<?php namespace Jenssegers\Mongodb;
use Illuminate\Database\ConnectionResolverInterface;
use Jenssegers\Mongodb\Connection;
class ConnectionResolver implements ConnectionResolverInterface {
/**
* The application instance.
*
* @var Illuminate\Foundation\Application
*/
protected $app;
/**
* All of the registered connections.
*
* @var array
*/
protected $connections = array();
/**
* The default connection name.
*
* @var string
*/
protected $default = 'mongodb';
/**
* Create a new database manager instance.
*
* @param Illuminate\Foundation\Application $app
* @return void
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Get a database connection instance.
*
* @param string $name
* @return \Illuminate\Database\Connection
*/
public function connection($name = null)
{
if (is_null($name)) $name = $this->getDefaultConnection();
// If we haven't created this connection, we'll create it based on the config
// provided in the application.
if (!isset($this->connections[$name]))
{
// Get connection configuration
$connections = $this->app['config']['database']['connections'];
if (is_null($config = array_get($connections, $name)))
{
throw new \InvalidArgumentException("MongoDB [$name] not configured.");
}
// Make connection
$this->connections[$name] = $this->makeConnection($connections[$name]);
}
return $this->connections[$name];
}
/**
* Create a connection.
*
* @param array $config
*/
public function makeConnection($config) {
return new Connection($config);
}
/**
* Get the default connection name.
*
* @return string
*/
public function getDefaultConnection()
{
return $this->default;
}
/**
* Set the default connection name.
*
* @param string $name
* @return void
*/
public function setDefaultConnection($name)
{
$this->default = $name;
}
}
\ No newline at end of file
<?php namespace Jenssegers\Mongodb;
use Illuminate\Database\ConnectionResolverInterface as Resolver;
use Illuminate\Database\Eloquent\Collection;
abstract class Model extends \ArrayObject {
/**
* The connection name for the model.
*
* @var string
*/
protected $connection;
/**
* The collection associated with the model.
*
* @var string
*/
protected $collection;
/**
* The primary key for the model.
*
* @var string
*/
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.
*
* @return \Jenssegers\Mongodb\Connection
*/
public function getConnection()
{
return static::resolveConnection($this->connection);
}
/**
* Get the current connection name for the model.
*
* @return string
*/
public function getConnectionName()
{
return $this->connection;
}
/**
* Set the connection associated with the model.
*
* @param string $name
* @return void
*/
public function setConnection($name)
{
$this->connection = $name;
}
/**
* Get the primary key for the model.
*
* @return string
*/
public function getKeyName()
{
return $this->primaryKey;
}
/**
* Resolve a connection instance by name.
*
* @param string $connection
* @return \Jenssegers\Mongodb\Connection
*/
public static function resolveConnection($connection)
{
return static::$resolver->connection($connection);
}
/**
* Get the connection resolver instance.
*
* @return \Jenssegers\Mongodb\ConnectionResolverInterface
*/
public static function getConnectionResolver()
{
return static::$resolver;
}
/**
* Set the connection resolver instance.
*
* @param Jenssegers\Mongodb\ConnectionResolverInterface $resolver
* @return void
*/
public static function setConnectionResolver(Resolver $resolver)
{
static::$resolver = $resolver;
}
}
\ No newline at end of file
<?php namespace Jenssegers\Mongodb;
use Jenssegers\Mongodb\Model;
use Jenssegers\Mongodb\ConnectionResolver;
use Illuminate\Support\ServiceProvider;
class MongodbServiceProvider extends ServiceProvider {
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
Model::setConnectionResolver($this->app['db.mongodb']);
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// The database manager is used to resolve various connections, since multiple
// connections might be managed. It also implements the connection resolver
// interface which may be used by other components requiring connections.
$this->app['db.mongodb'] = $this->app->share(function($app)
{
return new ConnectionResolver($app);
});
}
}
\ No newline at end of file
<?php namespace Jenssegers\Mongodb;
use MongoID;
class Query {
/**
* The model.
*
* @var Jenssegers\Mongodb\Model
*/
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;
/**
* All of the available operators.
*
* @var array
*/
protected $operators = array(
'=' => '=',
'!=' => '!=',
'<' => '$lt',
'<=' => '$le',
'>' => '$gt',
'>=' => '$ge'
);
/**
* Create a new model query builder instance.
*
* @param Jenssegers\Mongodb\Connection $connection
* @return void
*/
public function __construct(Model $model)
{
$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;
}
/**
* 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;
}
/**
* Execute a query for a single record by ID.
*
* @param int $id
* @param array $columns
* @return mixed
*/
public function find($id, $columns = array('*'))
{
$id = new MongoID((string) $id);
return $this->where($this->model->getKeyName(), '=', $id)->first($columns);
}
/**
* Execute the query and get the first result.
*
* @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')
{
// 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))
{
list($value, $operator) = array($operator, '=');
}
if ($operator == '=')
{
$this->wheres[$column] = $value;
}
else
{
$this->wheres[$column] = array($this->operators[$operator] => $value);
}
return $this;
}
/**
* 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);
// Apply order
if ($this->orders)
{
$cursor->sort($this->orders);
}
// Apply limit
if ($this->limit)
{
$cursor->limit($this->limit);
}
// Return collection of models
return $this->toCollection($cursor);
}
/**
* Transform to model collection.
*
* @param array $columns
* @return Collection
*/
public function toCollection($results)
{
$models = array();
foreach ($results as $result) {
$models[] = $this->model->newInstance($result);
}
return $this->model->newCollection($models);
}
}
\ 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