Permalink
Cannot retrieve contributors at this time
Fetching contributors…

<?php | |
if (!defined('BASEPATH')) | |
exit('No direct script access allowed'); | |
require_once('Cimongo_cursor.php'); | |
require_once('Cimongo_extras.php'); | |
/** | |
* CodeIgniter MongoDB Library | |
* | |
* A library to interact with the NoSQL database MongoDB. | |
* For more information see http://www.mongodb.org | |
* | |
* @package CodeIgniter | |
* @author Alessandro Arnodo | a.arnodo@gmail.com | @vesparny | |
* @copyright Copyright (c) 2012, Alessandro Arnodo. | |
* @license http://www.opensource.org/licenses/mit-license.php | |
* @link | |
* @version Version 1.1.0 | |
* | |
*/ | |
/** | |
* Cimongo | |
* | |
* Provide CI active record like methods to interact with MongoDB | |
* @since v1.0 | |
*/ | |
class Cimongo extends Cimongo_extras { | |
private $_inserted_id = FALSE; | |
public $debug = FALSE; | |
/** | |
* Construct a new Cimongo | |
* | |
* @since v1.0.0 | |
*/ | |
public function __construct() { | |
parent::__construct(); | |
} | |
/** | |
* Fake close function so you can bind $this->db=$this->cimongo | |
* | |
*/ | |
public function close() { | |
} | |
/** | |
* Get the documents based upon the passed parameters | |
* | |
* @since v1.0.0 | |
*/ | |
public function get($collection = "", $limit = FALSE, $offset = FALSE) { | |
if (empty($collection)) { | |
//FIXME theow exception instead show error | |
show_error("In order to retreive documents from MongoDB, a collection name must be passed", 500); | |
} | |
$cursor = $this->db->selectCollection($collection)->find($this->wheres, $this->selects); | |
$cimongo_cursor = new Cimongo_cursor($cursor); | |
$this->limit = ($limit !== FALSE && is_numeric($limit)) ? $limit : $this->limit; | |
if ($this->limit !== FALSE) { | |
$cimongo_cursor->limit($this->limit); | |
} | |
$this->offset = ($offset !== FALSE && is_numeric($offset)) ? $offset : $this->offset; | |
if ($this->offset !== FALSE) { | |
$cimongo_cursor->skip($this->offset); | |
} | |
if (!empty($this->sorts) && count($this->sorts) > 0) { | |
$cimongo_cursor->sort($this->sorts); | |
} | |
$this->_clear(); | |
return $cimongo_cursor; | |
} | |
/** | |
* Get the documents based upon the passed parameters | |
* | |
* @since v1.0.0 | |
*/ | |
public function get_where($collection = "", $where = array(), $limit = FALSE, $offset = FALSE) { | |
return $this->where($where)->get($collection, $limit, $offset); | |
} | |
/** | |
* Determine which fields to include (_id is always returned) | |
* | |
* @since v1.0.0 | |
*/ | |
public function select($includes = array()) { | |
if (!is_array($includes)) { | |
$includes = array(); | |
} | |
if (!empty($includes)) { | |
foreach ($includes as $col) { | |
$this->selects[$col] = TRUE; | |
} | |
} | |
return $this; | |
} | |
/** | |
* where clause: | |
* | |
* Passa an array of field=>value, every condition will be merged in AND statement | |
* e.g.: | |
* $this->cimongo->where(array('foo'=> 'bar', 'user'=>'arny')->get("users") | |
* | |
* if you need more complex clause you can pass an array composed exactly like mongoDB needs, followed by a boolean TRUE parameter. | |
* e.g.: | |
* $where_clause = array( | |
* '$or'=>array( | |
* array("user"=>'arny'), | |
* array("facebook.id"=>array('$gt'=>1,'$lt'=>5000)), | |
* array('faceboo.usernamek'=>new MongoRegex("/^arny.$/")) | |
* ), | |
* email"=>"a.arnodo@gmail.com" | |
* ); | |
* | |
* | |
* $this->cimongo->where($where_clause, TRUE)->get("users") | |
* | |
* @since v1.0.0 | |
* | |
* | |
*/ | |
public function where($wheres = array(), $native = FALSE) { | |
if ($native === TRUE && is_array($wheres)) { | |
$this->wheres = $wheres; | |
} elseif (is_array($wheres)) { | |
foreach ($wheres as $where => $value) { | |
$this->_where_init($where); | |
$this->wheres[$where] = $value; | |
} | |
} | |
return $this; | |
} | |
/** | |
* Get the documents where the value of a $field may be something else | |
* | |
* @since v1.0.0 | |
*/ | |
public function or_where($wheres = array()) { | |
$this->_where_init('$or'); | |
if (is_array($wheres) && count($wheres) > 0) { | |
foreach ($wheres as $wh => $val) { | |
$this->wheres['$or'][] = array($wh => $val); | |
} | |
} | |
return $this; | |
} | |
/** | |
* Get the documents where the value of a $field is in a given $in array(). | |
* | |
* @since v1.0.0 | |
*/ | |
public function where_in($field = "", $in = array()) { | |
$this->_where_init($field); | |
$this->wheres[$field]['$in'] = $in; | |
return $this; | |
} | |
/** | |
* Get the documents where the value of a $field is not in a given $in array(). | |
* | |
* @since v1.0.0 | |
*/ | |
public function where_not_in($field = "", $in = array()) { | |
$this->_where_init($field); | |
$this->wheres[$field]['$nin'] = $in; | |
return $this; | |
} | |
/** | |
* | |
* Get the documents where the (string) value of a $field is like a value. The defaults | |
* allow for a case-insensitive search. | |
* | |
* @param $flags | |
* Allows for the typical regular expression flags: | |
* i = case insensitive | |
* m = multiline | |
* x = can contain comments | |
* l = locale | |
* s = dotall, "." matches everything, including newlines | |
* u = match unicode | |
* | |
* @param $enable_start_wildcard | |
* If set to anything other than TRUE, a starting line character "^" will be prepended | |
* to the search value, representing only searching for a value at the start of | |
* a new line. | |
* | |
* @param $enable_end_wildcard | |
* If set to anything other than TRUE, an ending line character "$" will be appended | |
* to the search value, representing only searching for a value at the end of | |
* a line. | |
* | |
* @usage : $this->cimongo->like('foo', 'bar', 'im', FALSE, TRUE); | |
* @since v1.0.0 | |
* | |
*/ | |
public function like($field = "", $value = "", $flags = "i", $enable_start_wildcard = TRUE, $enable_end_wildcard = TRUE) { | |
$field = (string) trim($field); | |
$this->_where_init($field); | |
$value = (string) trim($value); | |
$value = quotemeta($value); | |
if ($enable_start_wildcard !== TRUE) { | |
$value = "^" . $value; | |
} | |
if ($enable_end_wildcard !== TRUE) { | |
$value .= "$"; | |
} | |
$regex = "/$value/$flags"; | |
$this->wheres[$field] = new MongoRegex($regex); | |
return $this; | |
} | |
/** | |
* The same as the aboce but multiple instances are joined by OR: | |
* | |
* @since v1.0.0 | |
*/ | |
public function or_like($field, $like = array(),$flags = "i") { | |
$this->_where_init('$or'); | |
if (is_array($like) && count($like) > 0) { | |
foreach ($like as $admitted) { | |
$this->wheres['$or'][] = array($field => new MongoRegex("/$admitted/$flags")); | |
} | |
} else { | |
$this->wheres['$or'][] = array($field => new MongoRegex("/$like/$flags")); | |
} | |
return $this; | |
} | |
/** | |
* The same as the aboce but multiple instances are joined by NOT LIKE: | |
* | |
* @since v1.0.0 | |
*/ | |
public function not_like($field, $like = array()) { | |
$this->_where_init($field); | |
if (is_array($like) && count($like) > 0) { | |
foreach ($like as $admitted) { | |
$this->wheres[$field]['$nin'][] = new MongoRegex("/$admitted/"); | |
} | |
} | |
return $this; | |
} | |
/** | |
* | |
* Sort the documents based on the parameters passed. To set values to descending order, | |
* you must pass values of either -1, FALSE, 'desc', or 'DESC', else they will be | |
* set to 1 (ASC). | |
* | |
* @usage : $this->cimongo->order_by(array('name' => 'ASC'))->get('users'); | |
* @since v1.0.0 | |
*/ | |
public function order_by($fields = array()) { | |
foreach ($fields as $field => $val) { | |
if ($val === -1 || $val === FALSE || strtolower($val) === 'desc') { | |
$this->sorts[$field] = -1; | |
} | |
if ($val === 1 || $val === TRUE || strtolower($val) === 'asc') { | |
$this->sorts[$field] = 1; | |
} | |
} | |
return $this; | |
} | |
/** | |
* | |
* Count all the documents in a collection | |
* | |
* @usage : $this->cimongo->count_all('users'); | |
* @since v1.0.0 | |
*/ | |
public function count_all($collection = "") { | |
if (empty($collection)) { | |
show_error("In order to retreive a count of documents from MongoDB, a collection name must be passed", 500); | |
} | |
$cursor = $this->db->selectCollection($collection)->find(); | |
$cimongo_cursor = new Cimongo_cursor($cursor); | |
$count = $cimongo_cursor->count(TRUE); | |
$this->_clear(); | |
return $count; | |
} | |
/** | |
* | |
* Count the documents based upon the passed parameters | |
* | |
* @since v1.0.0 | |
*/ | |
public function count_all_results($collection = "") { | |
if (empty($collection)) { | |
show_error("In order to retreive a count of documents from MongoDB, a collection name must be passed", 500); | |
} | |
$cursor = $this->db->selectCollection($collection)->find($this->wheres); | |
$cimongo_cursor = new Cimongo_cursor($cursor); | |
if ($this->limit !== FALSE) { | |
$cimongo_cursor->limit($this->limit); | |
} | |
if ($this->offset !== FALSE) { | |
$cimongo_cursor->skip($this->offset); | |
} | |
$this->_clear(); | |
return $cimongo_cursor->count(TRUE); | |
} | |
/** | |
* | |
* Insert a new document into the passed collection | |
* | |
* @since v1.0.0 | |
*/ | |
public function insert($collection = "", $insert = array()) { | |
if (empty($collection)) { | |
show_error("No Mongo collection selected to insert into", 500); | |
} | |
if (count($insert) == 0) { | |
show_error("Nothing to insert into Mongo collection or insert is not an array", 500); | |
} | |
$this->_inserted_id = FALSE; | |
try { | |
$query = $this->db->selectCollection($collection)->insert($insert, array("w" => $this->query_safety)); | |
if (isset($insert['_id'])) { | |
$this->_inserted_id = $insert['_id']; | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} catch (MongoException $e) { | |
show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); | |
} catch (MongoCursorException $e) { | |
show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); | |
} | |
} | |
/** | |
* | |
* Insert a multiple new document into the passed collection | |
* | |
* @since v1.0.0 | |
*/ | |
public function insert_batch($collection = "", $insert = array()) { | |
if (empty($collection)) { | |
show_error("No Mongo collection selected to insert into", 500); | |
} | |
if (count($insert) == 0) { | |
show_error("Nothing to insert into Mongo collection or insert is not an array", 500); | |
} | |
try { | |
$query = $this->db->selectCollection($collection)->batchInsert($insert, array("w" => $this->query_safety)); | |
if (is_array($query)) { | |
return $query["err"] === NULL; | |
} else { | |
return $query; | |
} | |
} catch (MongoException $e) { | |
show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); | |
} catch (MongoCursorException $e) { | |
show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); | |
} catch (MongoCursorTimeoutException $e) { | |
show_error("Insert of data into MongoDB failed: {$e->getMessage()}", 500); | |
} | |
} | |
/** | |
* | |
* Sets a field to a value | |
* | |
* @usage: $this->cimongo->where(array('blog_id'=>123))->set(array('posted'=>1)->update('users'); | |
* @since v1.0.0 | |
*/ | |
public function set($fields = array()) { | |
if (is_array($fields)) { | |
$this->_update_init('$set'); | |
foreach ($fields as $field => $value) { | |
$this->updates['$set'][$field] = $value; | |
} | |
} | |
return $this; | |
} | |
/** | |
* | |
* Update a single document | |
* | |
* @since v1.0.0 | |
*/ | |
public function update($collection = "", $data = array(), $options = array()) { | |
if (empty($collection)) { | |
show_error("No Mongo collection selected to update", 500); | |
} | |
if (is_array($data) && count($data) > 0) { | |
$this->_update_init('$set'); | |
$this->updates['$set'] += $data; | |
} | |
if (count($this->updates) == 0) { | |
show_error("Nothing to update in Mongo collection or update is not an array", 500); | |
} | |
try { | |
$options = array_merge(array("w" => $this->query_safety, 'multiple' => FALSE), $options); | |
$this->db->selectCollection($collection)->update($this->wheres, $this->updates, $options); | |
$this->_clear(); | |
return TRUE; | |
} catch (MongoCursorException $e) { | |
show_error("Update of data into MongoDB failed: {$e->getMessage()}", 500); | |
} catch (MongoCursorException $e) { | |
show_error("Update of data into MongoDB failed: {$e->getMessage()}", 500); | |
} catch (MongoCursorTimeoutException $e) { | |
show_error("Update of data into MongoDB failed: {$e->getMessage()}", 500); | |
} | |
} | |
/** | |
* | |
* Update more than one document | |
* | |
* @since v1.0.0 | |
*/ | |
public function update_batch($collection = "", $data = array()) { | |
return $this->update($collection, $data, array('multiple' => TRUE)); | |
} | |
/** | |
* | |
* Delete document from the passed collection based upon certain criteria | |
* | |
* @since v1.0.0 | |
*/ | |
public function delete($collection = "", $options = array()) { | |
if (empty($collection)) { | |
show_error("No Mongo collection selected to delete from", 500); | |
} | |
try { | |
$options = array_merge(array("w" => $this->query_safety), $options); | |
$this->db->selectCollection($collection)->remove($this->wheres, $options); | |
$this->_clear(); | |
return TRUE; | |
} catch (MongoCursorException $e) { | |
show_error("Delete of data into MongoDB failed: {$e->getMessage()}", 500); | |
} catch (MongoCursorTimeoutException $e) { | |
show_error("Delete of data into MongoDB failed: {$e->getMessage()}", 500); | |
} | |
} | |
/** | |
* | |
* Delete more than one document | |
* | |
* @since v1.3.0 | |
*/ | |
public function delete_batch($collection = "", $options = array()) { | |
return $this->delete($collection, array('justOne' => FALSE)); | |
} | |
/** | |
* | |
* Limit results | |
* | |
* @since v1.1.0 | |
*/ | |
public function limit($limit = FALSE) { | |
if ($limit && is_numeric($limit)) { | |
$this->limit = $limit; | |
} | |
return $this; | |
} | |
/** | |
* | |
* Returns the last inserted document's id | |
* | |
* @since v1.1.0 | |
*/ | |
public function insert_id() { | |
return $this->_inserted_id; | |
} | |
} |