├── README.md ├── config └── mongo_db.php └── libraries └── Mongo_db ├── Mongo_db.php └── drivers ├── Mongo_db_driver.php └── Mongo_db_result.php /README.md: -------------------------------------------------------------------------------- 1 | CodeIgniter-MongoDB 2 | =================== 3 | 4 | ActiveRecord-like driver to interact with the MongoDB database from CodeIgniter, mimicking the behavior of the SQL ActiveRecord driver that ships with the framework 5 | -------------------------------------------------------------------------------- /config/mongo_db.php: -------------------------------------------------------------------------------- 1 | 9 | * @author_url http://www.bitslice.net 10 | */ 11 | 12 | /* 13 | | ------------------------------------------------------------------- 14 | | MONGODB CONNECTIVITY SETTINGS 15 | | ------------------------------------------------------------------- 16 | | This file will contain the settings needed to access mongodb. 17 | | 18 | | ------------------------------------------------------------------- 19 | | EXPLANATION OF VARIABLES 20 | | ------------------------------------------------------------------- 21 | | 22 | | ['mongo_host'] The hostname of the database server 23 | | ['mongo_port'] The port of the database server 24 | | ['mongo_user'] The username used to connect to the database 25 | | ['mongo_pass'] The password used to connect to the database 26 | | ['mongo_db'] The name of the database you want to connect to 27 | | ['mongo_replicaset'] Wether the connection is being made to a replicaset or not 28 | | ['mongo_slave_ok'] Allow to run read queries on slave servers for performance 29 | | ['mongo_write_timeout'] The time to wait for the server in milliseconds 30 | | ['mongo_ensure_replicas'] The number of replicas to wait for when writing data 31 | | ['mongo_update_all'] Update all the docs matching a criteria or just the first one 32 | | ['mongo_remove_all'] Remove all the docs matching a criteria or just the first one 33 | | ['mongo_use_upsert'] Create a new document when updating a non-existent one 34 | | ['mongo_expand_dbrefs'] Decide to autamagically expand any DBRefs while running queries 35 | */ 36 | $config['mongo_host'] = 'localhost'; 37 | $config['mongo_port'] = 27017; 38 | $config['mongo_user'] = ''; 39 | $config['mongo_pass'] = ''; 40 | $config['mongo_db'] = 'billboard'; 41 | $config['mongo_replicaset'] = FALSE; 42 | $config['mongo_slave_ok'] = TRUE; 43 | $config['mongo_write_timeout'] = 5000; 44 | $config['mongo_ensure_replicas'] = 0; 45 | $config['mongo_update_all'] = TRUE; 46 | $config['mongo_remove_all'] = TRUE; 47 | $config['mongo_use_upsert'] = TRUE; 48 | $config['mongo_expand_dbrefs'] = TRUE; 49 | 50 | /* End of file mongodb.php */ 51 | /* Location: ./{APPLICATION}/config/mongodb.php */ -------------------------------------------------------------------------------- /libraries/Mongo_db/Mongo_db.php: -------------------------------------------------------------------------------- 1 | 13 | * @author_url http://www.bitslice.net 14 | */ 15 | class Mongo_db extends CI_Driver_Library { 16 | 17 | /** 18 | * Holder for the driver configuration options 19 | * 20 | * @var array 21 | * @access private 22 | */ 23 | private $_config = array (); 24 | 25 | /** 26 | * Constructor method 27 | * 28 | * @param array An array with the configuration options for the mongodb interaction, if nothing 29 | * is passed the library will try to use a mongo_db.php config file 30 | * @return void 31 | * @access public 32 | */ 33 | public function __construct( $config = array() ) { 34 | // List the drivers that this class will use 35 | $this->valid_drivers = array( 'mongo_db_driver', 'mongo_db_result' ); 36 | $CI =& get_instance(); 37 | 38 | if( empty( $config ) ) { 39 | $CI->config->load( 'mongo_db', TRUE ); 40 | $this->_config = $this->config->item( 'mongo_db' ); 41 | } else { 42 | $this->_config = $config; 43 | } 44 | 45 | // Connect to the mongodb database using the specified parameters 46 | if( ! $this->connect( $this->_config ) ) { 47 | show_error( 'Unable to connect to the MongoDB server', 500 ); 48 | } 49 | } 50 | 51 | /** 52 | * Method used to change the database to use in the active connection 53 | * 54 | * @param string The name of the database to switch to 55 | * @return boolean True on success, false otherwise 56 | * @access public 57 | */ 58 | public function change_db( $db ) { 59 | $this->driver->change_db( $db ); 60 | } 61 | 62 | /** 63 | * Return a configuration parameter 64 | * 65 | * @param string The configuration parameter to return 66 | * @return mixed If the required key exists, the value of it, false otherwise 67 | * @access protected 68 | */ 69 | public function config_item( $item ) { 70 | if ( array_key_exists( $item, $this->_config ) ) { 71 | return $this->_config[$item]; 72 | } else { 73 | return FALSE; 74 | } 75 | } 76 | 77 | /** 78 | * Method used to connect to a mongo database 79 | * 80 | * @param array An array with the options for the connection 81 | * @return boolean True on success, false otherwise 82 | * @access public 83 | */ 84 | public function connect( $config ) { 85 | return $this->driver->connect( $config ); 86 | } 87 | 88 | /** 89 | * Method used to terminate the active connection to the database 90 | * 91 | * @return void 92 | * @access public 93 | */ 94 | public function close() { 95 | return $this->driver->close(); 96 | } 97 | 98 | /** 99 | * Method used to specify the where part of the query to perform 100 | * 101 | * @param mixed This can be an array or a string depending on the circumstance 102 | * @param mixed If the previous param is a string this is the value to match the key to 103 | * @return void 104 | * @access public 105 | */ 106 | public function where( $key, $value = null ) { 107 | $this->driver->where( $key, $value ); 108 | } 109 | 110 | /** 111 | * Method used to set a OR clause to the where part of the query to perform 112 | * 113 | * @param Array An array containing the where clauses to set as conditionals 114 | * @return void 115 | * @access public 116 | */ 117 | public function or_where( $conds ) { 118 | $this->driver->where( '$or', $conds ); 119 | } 120 | 121 | /** 122 | * Method used to set a 'where less than' condition 123 | * 124 | * @param string The document field to use 125 | * @param mixed The value to use on the comparission 126 | * @return void 127 | * @access public 128 | */ 129 | public function where_lt( $key, $value ) { 130 | $this->driver->where( $key, array( '$lt' => $value ) ); 131 | } 132 | 133 | /** 134 | * Method used to set a 'where less than or equal' condition 135 | * 136 | * @param string The document field to use 137 | * @param mixed The value to use on the comparission 138 | * @return void 139 | * @access public 140 | */ 141 | public function where_lte( $key, $value ) { 142 | $this->driver->where( $key, array( '$lte' => $value ) ); 143 | } 144 | 145 | /** 146 | * Method used to set a 'where greater than' condition 147 | * 148 | * @param string The document field to use 149 | * @param mixed The value to use on the comparission 150 | * @return void 151 | * @access public 152 | */ 153 | public function where_gt( $key, $value ) { 154 | $this->driver->where( $key, array( '$gt' => $value ) ); 155 | } 156 | 157 | /** 158 | * Method used to set a 'where greater than or equal' condition 159 | * 160 | * @param string The document field to use 161 | * @param mixed The value to use on the comparission 162 | * @return void 163 | * @access public 164 | */ 165 | public function where_gte( $key, $value ) { 166 | $this->driver->where( $key, array( '$gte' => $value ) ); 167 | } 168 | 169 | /** 170 | * Method used to set a 'where not equal to' condition 171 | * 172 | * @param string The document field to use 173 | * @param mixed The value to use on the comparission 174 | * @return void 175 | * @access public 176 | */ 177 | public function where_ne( $key, $value ) { 178 | $this->driver->where( $key, array( '$ne' => $value ) ); 179 | } 180 | 181 | /** 182 | * Method used to set a 'where in' condition 183 | * 184 | * @param string The document field to use 185 | * @param array The array of values to use on the comparission 186 | * @return void 187 | * @access public 188 | */ 189 | public function where_in( $key, $values ) { 190 | $this->driver->where( $key, array( '$in' => $values ) ); 191 | } 192 | 193 | /** 194 | * Method used to set a 'where not in' condition 195 | * 196 | * @param string The document field to use 197 | * @param array The array of values to use on the comparission 198 | * @return void 199 | * @access public 200 | */ 201 | public function where_not_in( $key, $values ) { 202 | $this->driver->where( $key, array( '$nin' => $values ) ); 203 | } 204 | 205 | /** 206 | * Method used to set a 'where > $max and < $min' condition 207 | * 208 | * @param string The document field to use 209 | * @param mixed The minimum value to use on the comparission 210 | * @param mixed The maximum value to use on the comparission 211 | * @param boolean Whether to run the comparissions on inclusive mode or not 212 | * @return void 213 | * @access public 214 | */ 215 | public function where_between( $key, $min, $max, $inclusive = true ) { 216 | if( $inclusive ) { 217 | $this->driver->where( $key, array( '$gte' => $min, '$lte' => $max ) ); 218 | } else { 219 | $this->driver->where( $key, array( '$gt' => $min, '$lt' => $max ) ); 220 | } 221 | } 222 | 223 | /** 224 | * Method used to set a 'where like' condition 225 | * 226 | * @param string The document field to use 227 | * @param mixed The value to use on the comparission 228 | * @return void 229 | * @access public 230 | */ 231 | public function where_like( $key, $value ) { 232 | $regex = new MongoRegex( "/^".$value."/i" ); 233 | $this->driver->where( $key, array( '$regex' => $regex ) ); 234 | } 235 | 236 | /** 237 | * Method used to set the order info for the query to perform 238 | * 239 | * @param string The key to order the query from 240 | * @param string The type of the ordering, 'asc' or 'desc' 241 | * @return void 242 | * @access public 243 | */ 244 | public function order_by( $key, $dir ) { 245 | $this->driver->order_by( $key, $dir ); 246 | } 247 | 248 | /** 249 | * Method used to set the number of rows and the offset to be returned by the query 250 | * 251 | * @param int The number of rows to limit the query to 252 | * @return void 253 | * @access public 254 | */ 255 | public function limit( $limit, $offset = 0 ) { 256 | $this->driver->limit( $limit, $offset ); 257 | } 258 | 259 | /** 260 | * Method used to specify the selects for the query 261 | * 262 | * @param string A comma separated list of the fields to retrieve from the collection 263 | * @return void 264 | * @access public 265 | */ 266 | public function select( $select = '' ) { 267 | $this->driver->select( $select ); 268 | } 269 | 270 | /** 271 | * Method used to retrieve the documents from a given collection, if the where, select or 272 | * any other narrower method is called previously it will affect this method call, also 273 | * note that after calling this method the flush method is called so the mentioned limit 274 | * options no longer exists for other queries 275 | * 276 | * @param string The name of the collection to retrieve the documents from 277 | * @param int The number of results to limit the query to 278 | * @param int The number of rows to skip from the query 279 | * @return MongoCursor The cursor for the performed query 280 | * @access public 281 | */ 282 | public function get( $collection, $limit = null, $offset = null ) { 283 | return $this->_get( $collection, $limit, $offset ); 284 | } 285 | 286 | /** 287 | * Identical to the get method, only that adds a where array parameter 288 | * 289 | * @param string The name of the collection to retrieve the documents from 290 | * @param array An array with the where clauses for the query 291 | * @param int The number of results to limit the query to 292 | * @param int The number of rows to skip from the query 293 | * @return MongoCursor The cursor for the performed query 294 | * @access public 295 | */ 296 | public function get_where( $collection, $where, $limit = null, $offset = null ) { 297 | foreach( $where as $k => $v ) { 298 | $this->driver->where( $k, $v ); 299 | } 300 | 301 | return $this->_get( $collection, $limit, $offset ); 302 | } 303 | 304 | /** 305 | * Method used to manually set the data to insert into a collection 306 | * 307 | * @param string The key of the value to insert 308 | * @param mixed The data to insert into the collection 309 | * @return void 310 | * @access public 311 | */ 312 | public function set( $k, $v = null ) { 313 | $this->driver->set( $k, $v ); 314 | } 315 | 316 | /** 317 | * Method used to insert data into a database collection 318 | * 319 | * @param string The collection name to insert the data to 320 | * @param array An array containing the data to insert to the collection 321 | * @param array An array of options to perform the insert query with 322 | * @return stdClass An object containing the result of the insert query 323 | * @access public 324 | */ 325 | public function insert( $collection, $data = array(), $options = array() ) { 326 | return $this->driver->insert( $collection, $data, $options ); 327 | } 328 | 329 | /** 330 | * Method used to quickly insert multiple documents into a collection 331 | * 332 | * @param string The collection name to insert the data to 333 | * @param array An array containing the data to insert to the collection 334 | * @param array An array of options to perform the insert query with 335 | * @return stdClass An object containing the result of the insert query 336 | * @access public 337 | */ 338 | public function insert_batch( $collection, $data = null, $options = array() ) { 339 | return $this->driver->insert( $collection, $data, $options, TRUE ); 340 | } 341 | 342 | /** 343 | * Run an update operation with an implicit '$set' operator to avoid unintended replacements 344 | * 345 | * @param string The name of the collection to update 346 | * @param array An array containing the data to modify in the document 347 | * @param mixed An array or a string with the identifier for the document 348 | * @param array An array of options for the operation 349 | * @return stdClass An object with the information of the executed query 350 | * @access public 351 | */ 352 | public function update( $collection, $data, $where = null, $options = array() ) { 353 | return $this->driver->update( $collection, $data, $where, $options ); 354 | } 355 | 356 | /** 357 | * Method used to run an update operation with MongoDB operators like '$inc' and '$desc' 358 | * 359 | * @param string The name of the collection to update 360 | * @param array An array containing the data to modify in the document 361 | * @param mixed An array or a string with the identifier for the document 362 | * @param array An array of options for the operation 363 | * @return stdClass An object with the information of the executed query 364 | * @access public 365 | */ 366 | public function modify( $collection, $data, $where = null, $options = array() ) { 367 | return $this->driver->modify( $collection, $data, $where, $options ); 368 | } 369 | 370 | /** 371 | * Method used to remove a document from a given collection 372 | * 373 | * @param strin The collection name to remove the document from 374 | * @param array An array containing the document identifiers 375 | * @param array An array of options to perform the action with 376 | * @return stdClass An object with the information of the executed query 377 | * @access public 378 | */ 379 | public function remove( $collection, $where = null, $options = array() ) { 380 | return $this->driver->remove( $collection, $where, $options ); 381 | } 382 | 383 | /** 384 | * Return the number of documents in a given collection 385 | * 386 | * @param string The collection to count 387 | * @return int 388 | * @access public 389 | */ 390 | public function count_all( $collection ) { 391 | return $this->driver->count_all( $collection ); 392 | } 393 | 394 | /** 395 | * Utility function that returns the last ID generated from an insert operation 396 | * 397 | * @return string 398 | * @access public 399 | */ 400 | public function insert_id() { 401 | return $this->driver->insert_id(); 402 | } 403 | 404 | /** 405 | * Method used to drop a collection from the database 406 | * 407 | * @param string The collection name to empty 408 | * @return array The database server response, check the MongoDB docs for more information 409 | * @access public 410 | */ 411 | public function drop_collection( $collection ) { 412 | return $this->driver->drop_collection( $collection ); 413 | } 414 | 415 | /** 416 | * Utility function to generate a 'MongoDate' object for general purposes 417 | * 418 | * @param mixed Either a timestamp(int) or a string based date 419 | * @return MongoDate The date object, access the 'sec' property for the timestamp 420 | * @access public 421 | */ 422 | public function gen_date( $param = null ) { 423 | if( $param ) { 424 | is_string( $param ) ? $date = new MongoDate( strtotime( $param ) ) : $date = new MongoDate( $param ); 425 | } else { 426 | $date = new MongoDate(); 427 | } 428 | return $date; 429 | } 430 | 431 | /** 432 | * Utility function to generate a 'MongoBinData' object to store a file as part of a document 433 | * 434 | * @param string The content of the file to store 435 | * @return MongoBinData A ready-to-store representation of the binary data 436 | * @access public 437 | */ 438 | public function gen_bindata( $contents ) { 439 | if( empty( $contents ) ) { 440 | show_error( 'You must provide the contents a file to this function', 500 ); 441 | } 442 | return new MongoBinData( $contents ); 443 | } 444 | 445 | /** 446 | * Utility function that generate a 'MongoDBRef' ready for storage 447 | * 448 | * @param string The collection the referenced document is in 449 | * @param MongoID The '_id' of the referenced document 450 | * @param string Optionally you can reference documents of another database on the server 451 | * @return MongoDBRef 452 | * @access public 453 | */ 454 | public function gen_dbref( $collection, $id, $db = null ) { 455 | if( $db ) { 456 | return MongoDBRef::create( $collection, $id, $db ); 457 | } else { 458 | return MongoDBRef::create( $collection, $id ); 459 | } 460 | } 461 | 462 | /** 463 | * Utility function that generates a MongoID instance base on a string representation 464 | * 465 | * @param string The string representation of the desired ID object 466 | * @return MongoId 467 | * @access public 468 | */ 469 | public function gen_id( $id_string ) { 470 | return new MongoId( $id_string ); 471 | } 472 | 473 | /** 474 | * Method used to retrieve the cursor for the prepared query 475 | * 476 | * @param int The number of results to limit the query to 477 | * @param int The number of rows to skip from the query 478 | * @return MongoCursor The cursor for the performed query 479 | * @access private 480 | */ 481 | private function _get( $collection, $limit = false, $offset = false ) { 482 | if( $limit ) { 483 | $this->driver->limit( $limit ); 484 | } 485 | if( $offset ) { 486 | $this->driver->offset( $offset ); 487 | } 488 | 489 | $result = $this->driver->get( $collection ); 490 | return $this->result->get_result( $result, $this->driver->db() ); 491 | } 492 | } 493 | // END Mongo_db Class 494 | 495 | /* End of file Mongo_db.php */ 496 | /* Location: ./{APPLICATION}/libraries/Mongo_db/Mongo_db.php */ -------------------------------------------------------------------------------- /libraries/Mongo_db/drivers/Mongo_db_driver.php: -------------------------------------------------------------------------------- 1 | 11 | * @author_url http://www.bitslice.net 12 | */ 13 | class Mongo_db_driver extends CI_Driver { 14 | 15 | /** 16 | * Holder for the MongoDB connection object 17 | * 18 | * @var Mongo 19 | * @access private 20 | */ 21 | private $_conn = NULL; 22 | 23 | /** 24 | * Holder for the active database selected 25 | * 26 | * @var resource 27 | * @access private 28 | */ 29 | private $_db = NULL; 30 | 31 | /** 32 | * Holder for the wheres of the query to execute 33 | * 34 | * @var array 35 | * @access private 36 | */ 37 | private $_ws = array(); 38 | 39 | /** 40 | * Holder for the selects part of the query 41 | * 42 | * @var array 43 | * @access private 44 | */ 45 | private $_sls = array(); 46 | 47 | /** 48 | * Holder for the from part of the query 49 | * 50 | * @var string 51 | * @access private 52 | */ 53 | private $_from = ''; 54 | 55 | /** 56 | * Holder for the insertion data issued with the set method 57 | * 58 | * @var array 59 | * @access private 60 | */ 61 | private $_data = array(); 62 | 63 | /** 64 | * Holder for the limit of the query 65 | * 66 | * @var int 67 | * @access private 68 | */ 69 | private $_lmt = 99999; 70 | 71 | /** 72 | * Holder for the offset of the query 73 | * 74 | * @var int 75 | * @access private 76 | */ 77 | private $_ost = 0; 78 | 79 | /** 80 | * Holder for the sort query info 81 | * 82 | * @var array 83 | * @access private 84 | */ 85 | private $_st = array(); 86 | 87 | /** 88 | * Holder for the latest generated id on an insert operation 89 | * 90 | * @var string 91 | * @access private 92 | */ 93 | private $_insert_id = ''; 94 | 95 | /** 96 | * Constructor method 97 | * 98 | * @return void 99 | * @access public 100 | */ 101 | public function __construct() { 102 | // Check that the PHP MongoDB driver is installed 103 | if( ! class_exists( 'Mongo' ) ) { 104 | show_error( 'The MongoDB PECL extension isn\'t installed', 500 ); 105 | } 106 | } 107 | 108 | /** 109 | * Method used to change the database to use in the active connection 110 | * 111 | * @param string The name of the database to switch to 112 | * @return boolean True on success, false otherwise 113 | * @access public 114 | */ 115 | public function change_db( $db ) { 116 | if( empty( $db ) ) { 117 | show_error( 'The database name must be specified' ); 118 | return false; 119 | } 120 | try { 121 | $this->_db = $this->_conn->selectDB( $db ); 122 | return true; 123 | } catch( Exception $e ) { 124 | show_error( "Unable to use {$db} - {$e->getMessage()}", 500 ); 125 | return false; 126 | } 127 | } 128 | 129 | /** 130 | * Method used to connect to a mongo database 131 | * 132 | * @param array An array with the options for the connection 133 | * @return boolean True on success, false otherwise 134 | * @access public 135 | */ 136 | public function connect( $config ) { 137 | // Check the required configuration fields 138 | if( empty( $config['mongo_host'] ) ) { 139 | show_error( 'The host of the mongodb is required', 500 ); 140 | } 141 | 142 | // Set the connection string 143 | $conn = 'mongodb://'.$config['mongo_host']; 144 | 145 | // Check that a port is specified 146 | if( ! empty( $config['mongo_port'] ) ) { 147 | $conn .= ":{$config['mongo_port']}"; 148 | } 149 | 150 | // Check that a database is specified to use instead of admin 151 | if( ! empty( $config['mongo_db'] ) ) { 152 | $conn .= "/{$config['mongo_db']}"; 153 | } 154 | 155 | // Check if username/password is beign used 156 | $options = array(); 157 | if( ! empty( $config['mongo_user'] ) && ! empty( $config['mongo_pass'] ) ) { 158 | // Use the options method instead of passing the user and pass in the address directly 159 | // useful for the case the user includes ":" or "@" on the pass 160 | $options['username'] = $config['mongo_user']; 161 | $options['password'] = $config['mongo_pass']; 162 | } 163 | 164 | // Set the replicaset connection parameter 165 | $options['replicaSet'] = $config['mongo_replicaset']; 166 | 167 | // Connect to the database 168 | try { 169 | // Establish the connection to the server 170 | $this->_conn = new Mongo( $conn, $options ); 171 | if ( $config['mongo_slave_ok'] ) { 172 | // TODO - Update drive to set slave in MongoDB PHP new driver 173 | //$this->_conn->setSlaveOkay( $config['mongo_slave_ok'] ); 174 | } 175 | 176 | // Connect to the required database 177 | $this->_db = $this->_conn->selectDB( $config['mongo_db'] ); 178 | return true; 179 | } catch( MongoConnectionException $e ) { 180 | show_error( "Unable to connect to MongoDB - {$e->getMessage()}", 500 ); 181 | return false; 182 | } 183 | } 184 | 185 | /** 186 | * Return the number of documents in a given collection 187 | * 188 | * @param string The collection to count 189 | * @return int 190 | * @access public 191 | */ 192 | public function count_all( $collection ) { 193 | return $this->_db->{$collection}->count(); 194 | } 195 | 196 | /** 197 | * Method used to close de connection to the database 198 | * 199 | * @return boolean True on success, false otherwise 200 | * @access public 201 | */ 202 | public function close() { 203 | $this->_db = NULL; 204 | return $this->_conn->close(); 205 | } 206 | 207 | /** 208 | * Accesor method for the internally used database connection object 209 | * 210 | * @return MongoDB 211 | * @access public 212 | */ 213 | public function db() { 214 | return $this->_db; 215 | } 216 | 217 | /** 218 | * Method used to drop a collection from the database 219 | * 220 | * @param string The name of the collection to drop 221 | * @return array The response obtainined from the database 222 | * @access public 223 | */ 224 | public function drop_collection( $collection ) { 225 | if( empty( $collection ) ) { 226 | show_error( 'The collection name must be specified', 500 ); 227 | } 228 | 229 | return $this->_db->{$collection}->drop(); 230 | } 231 | 232 | /** 233 | * Method used to specify the from part for the query 234 | * 235 | * @param string The name of the collection to perform the query against 236 | * @return void 237 | * @access public 238 | */ 239 | public function from( $collection ) { 240 | if ( empty( $collection ) ) { 241 | show_error( 'The collection name must be specified', 500 ); 242 | } 243 | $this->_from = $collection; 244 | } 245 | 246 | /** 247 | * Method used to retrieve the documents from a given collection, if the where, select or 248 | * any other narrower method is called previously it will affect this method call, also 249 | * note that after calling this method the flush method is called so the mentioned limit 250 | * options no longer exists for other queries 251 | * 252 | * @param string The name of the collection to retrieve the documents from 253 | * @return MongoCursor The cursor for the performed query 254 | * @access public 255 | */ 256 | public function get( $col ) { 257 | if ( empty( $col ) ) { 258 | if ( empty( $this->_from ) ) { 259 | show_error( 'The collection name must be specified', 500 ); 260 | } 261 | $col = $this->_from; 262 | } 263 | 264 | $docs = $this->_db->{$col} 265 | ->find( $this->_ws, $this->_sls ) 266 | ->limit( $this->_lmt ) 267 | ->skip( $this->_ost ) 268 | ->sort( $this->_st ); 269 | $this->_flush(); 270 | 271 | return $docs; 272 | } 273 | 274 | /** 275 | * Method used to insert data into a collection 276 | * 277 | * @param string The collection name to insert the data to 278 | * @param array An array containing the data to insert to the collection 279 | * @param options An array of options to set to the MongoDB insert query 280 | * @param boolean Whether or not to use a batch insert 281 | * @return stdClass An object containing the result of the insert query 282 | * @access public 283 | */ 284 | public function insert( $collection, $data, $options, $batch = false ) { 285 | if( empty( $collection ) ) { 286 | show_error( 'The collection name must be specified', 500 ); 287 | } 288 | 289 | // Check if there's data from the set method 290 | $data = array_merge( $this->_data, $data ); 291 | if( empty( $data ) ) { 292 | show_error( 'No data provided to insert in the collection', 500 ); 293 | } 294 | 295 | // Adjust the method to use 296 | $batch ? $method = 'batchInsert' : $method = 'insert'; 297 | 298 | // Use the config values for keys not already set by the user 299 | if( ! array_key_exists( 'safe', $options ) ) { 300 | $options['safe'] = $this->config_item( 'mongo_ensure_replicas' ); 301 | } 302 | if( ! array_key_exists( 'timeout', $options) ) { 303 | $options['timeout'] = $this->config_item( 'mongo_write_timeout' ); 304 | } 305 | 306 | $action = new stdClass(); 307 | try { 308 | if ( $this->_db->{$collection}->{$method}( $data, $options ) ) { 309 | $action->result = TRUE; 310 | $action->id = $data['_id']->{'$id'}; 311 | $this->_insert_id = $data['_id']->{'$id'}; 312 | } else { 313 | $action->result = FALSE; 314 | } 315 | } catch( MongoCursorException $e ) { 316 | $action->error = $e->getMessage(); 317 | $action->result = FALSE; 318 | } 319 | $this->_flush(); 320 | 321 | return $action; 322 | } 323 | 324 | /** 325 | * Utility function that returns the last ID generated from an insert operation 326 | * 327 | * @return string 328 | * @access public 329 | */ 330 | public function insert_id() { 331 | return $this->_insert_id; 332 | } 333 | 334 | /** 335 | * Method used to set the limit of results for a given query 336 | * 337 | * @param int The number of rows to limit the query to 338 | * @param int The offset to use for the query 339 | * @return void 340 | * @access public 341 | */ 342 | public function limit( $limit, $offset = null ) { 343 | if ( $limit !== NULL && is_numeric( $limit ) && $limit >= 1 ) { 344 | $this->_lmt = $limit; 345 | } 346 | if ( $offset !== NULL && is_numeric( $offset ) && $offset >= 1 ) { 347 | $this->_ost = $offset; 348 | } 349 | } 350 | 351 | /** 352 | * Method used to run an update operation with MongoDB operators like '$inc' and '$desc' 353 | * 354 | * @param string The name of the collection to update 355 | * @param array An array containing the data to modify in the document 356 | * @param mixed An array or a string with the identifier for the document 357 | * @param array An array of options for the operation 358 | * @return stdClass An object with the information of the executed query 359 | * @access public 360 | */ 361 | public function modify( $collection, $data, $where, $options ) { 362 | if( empty( $collection ) ) { 363 | if( empty( $this->_from ) ) { 364 | show_error( 'The collection name must be specified', 500 ); 365 | } else { 366 | $collection = $this->_from; 367 | } 368 | } 369 | 370 | $data = array_merge( $this->_data, $data ); 371 | if( !$data || empty( $data ) ) { 372 | show_error( 'No data provided to insert to the collection', 500 ); 373 | } 374 | 375 | // Prepare the where statements whether from an array or a string 376 | $this->_set_where( $where ); 377 | 378 | // Use the config values for keys not already set by the user 379 | if ( ! array_key_exists( 'safe', $options ) ) { 380 | $options['safe'] = $this->config_item( 'mongo_ensure_replicas' ); 381 | } 382 | if ( ! array_key_exists( 'timeout', $options) ) { 383 | $options['timeout'] = $this->config_item( 'mongo_write_timeout' ); 384 | } 385 | if ( ! array_key_exists( 'upsert', $options ) ) { 386 | $options['upsert'] = $this->config_item( 'mongo_use_upsert' ); 387 | } 388 | if ( ! array_key_exists( 'multiple', $options ) ) { 389 | $options['multiple'] = $this->config_item( 'mongo_update_all' ); 390 | } 391 | 392 | $action = new stdClass(); 393 | try { 394 | if ( $this->_db->{$collection}->update( $this->_ws, $data, $options ) ) { 395 | $action->result = true; 396 | } else { 397 | $action->result = false; 398 | } 399 | } catch( MongoCursorException $e ) { 400 | $action->error = $e->getMessage(); 401 | $action->result = FALSE; 402 | } 403 | $this->_flush(); 404 | 405 | return $action; 406 | } 407 | 408 | /** 409 | * Method used to set the sorting options for the query 410 | * 411 | * @param string The key of the field to order the query from 412 | * @param string The direction of the sort, for the key 413 | * @return void 414 | * @access public 415 | */ 416 | public function order_by( $key, $dir ) { 417 | if( ! is_string( $key ) || empty( $key ) ) { 418 | show_error( 'The field name to sort with must set', 500 ); 419 | } 420 | 421 | if ( $dir == 'asc' ) { 422 | $this->_st[$key] = 1; 423 | } else if( $dir == 'desc' ) { 424 | $this->_st[$key] = -1; 425 | } 426 | } 427 | 428 | /** 429 | * Method used to remove a document from a selected collection 430 | * 431 | * @param string The name of the collection to remove the document from 432 | * @param array An array with the information to select the document to remove 433 | * @param array An array of options to perform the query with 434 | * @return stdClass An object with the query results information 435 | * @access public 436 | */ 437 | public function remove( $collection, $where, $options ) { 438 | if ( empty( $collection ) ) { 439 | if ( empty( $this->_from ) ) { 440 | show_error( 'The collection name must be specified', 500 ); 441 | } 442 | $collection = $this->_from; 443 | } 444 | 445 | if( is_array( $where ) ) { 446 | foreach( $where as $k => $v ) { 447 | $this->_ws[$k] = $v; 448 | } 449 | } 450 | 451 | // Set whether to delete all the matching documents or not 452 | if( ! array_key_exists( 'justOne', $options ) ) { 453 | $options['justOne'] = !( $this->config_item( 'mongo_remove_all' ) ); 454 | } 455 | 456 | $action = new stdClass(); 457 | try { 458 | if ( $this->_db->{$collection}->remove( $this->_ws, $options ) ) { 459 | $action->result = true; 460 | } else { 461 | $action->result = false; 462 | } 463 | } catch( MongoCursorException $e ) { 464 | $action->error = $e->getMessage(); 465 | $action->result = false; 466 | } 467 | $this->_flush(); 468 | 469 | return $action; 470 | } 471 | 472 | /** 473 | * Method used to specify the selects for the query 474 | * 475 | * @param string A comma separated list of the fields to retrieve 476 | * @return void 477 | * @access public 478 | */ 479 | public function select( $select = '' ) { 480 | // Check if at least a field is passed 481 | if( empty( $select ) ) { 482 | show_error( 'The fields to retrieve must be specified' ); 483 | } 484 | 485 | // Get the fields from the given string 486 | $fields = explode( ',', $select ); 487 | foreach( $fields as $field ) { 488 | $this->_sls[trim( $field )] = TRUE; 489 | } 490 | } 491 | 492 | /** 493 | * Method used to set the data to insert into a collection 494 | * 495 | * @param mixed The key for the data to insert or an array of data 496 | * @param mixed The value of the given key, if not value is passed null will be used 497 | * @return void 498 | * @access public 499 | */ 500 | public function set( $k, $v = null ) { 501 | if( is_array( $k ) ) { 502 | $this->_data = $k; 503 | } else if( is_object( $k ) ) { 504 | $this->_data = (array)$k; 505 | } else { 506 | if( !is_string( $k ) || empty( $k ) ) { 507 | show_error( 'The key for the data to insert must be a string', 500 ); 508 | } else { 509 | $this->_data[$k] = $v; 510 | } 511 | } 512 | } 513 | 514 | /** 515 | * Method used to update a document from a given collection 516 | * 517 | * @param string The name of the collection to update the document from 518 | * @param array An array containing the data to update the document with 519 | * @param mixed An array or string with the document identifier 520 | * @param array An array of options for the update 521 | * @return stdClass An object containing the update query result 522 | * @access public 523 | */ 524 | public function update( $collection, $data, $where, $options ) { 525 | if( empty( $collection ) ) { 526 | if ( empty( $this->_from ) ) { 527 | show_error( 'The collection name must be specified', 500 ); 528 | } 529 | $collection = $this->_from; 530 | } 531 | 532 | // Check if there's data from the set method 533 | $data = array_merge( $this->_data, $data ); 534 | if( empty( $data ) ) { 535 | show_error( 'No data provided to update the collection with', 500 ); 536 | } 537 | 538 | // Prepare the where statements whether from an array or a string 539 | $this->_set_where( $where ); 540 | 541 | // Use the config values for keys not already set by the user 542 | if ( ! array_key_exists( 'safe', $options ) ) { 543 | $options['safe'] = $this->config_item( 'mongo_ensure_replicas' ); 544 | } 545 | if ( ! array_key_exists( 'timeout', $options) ) { 546 | $options['timeout'] = $this->config_item( 'mongo_write_timeout' ); 547 | } 548 | if ( ! array_key_exists( 'upsert', $options ) ) { 549 | $options['upsert'] = $this->config_item( 'mongo_use_upsert' ); 550 | } 551 | if ( ! array_key_exists( 'multiple', $options ) ) { 552 | $options['multiple'] = $this->config_item( 'mongo_update_all' ); 553 | } 554 | 555 | // Automatically add a '$set' operator to avoid replacing the hole document 556 | if ( array_key_exists( '$inc', $data ) ) { 557 | $newdoc = $data; 558 | } else if ( array_key_exists( '$set', $data ) ) { 559 | $newdoc = $data; 560 | } else { 561 | $newdoc = array( '$set' => $data ); 562 | } 563 | 564 | $action = new stdClass(); 565 | try { 566 | if( $this->_db->{$collection}->update( $this->_ws, $newdoc, $options ) ) { 567 | $action->result = true; 568 | } else { 569 | $action->result = false; 570 | } 571 | } catch( MongoCursorException $e ) { 572 | $action->error = $e->getMessage(); 573 | $action->result = false; 574 | } 575 | $this->_flush(); 576 | 577 | return $action; 578 | } 579 | 580 | /** 581 | * Method used to specify the where part of the query to perform 582 | * 583 | * @param mixed This can be an array or a string depending on the circumstance 584 | * @param mixed If the previous param is a string this is the value to match that key to 585 | * @return void 586 | * @access public 587 | */ 588 | public function where( $key, $value = null ) { 589 | // Check if the method is being called with just a value, or an array 590 | if( is_array( $key ) ) { 591 | foreach( $key as $k => $v ) { 592 | $this->_ws[$k] = $v; 593 | } 594 | } else { 595 | if( ! $value ) { 596 | show_error( 'A value must be provided for the where statement' ); 597 | } else { 598 | $this->_ws[$key] = $value; 599 | } 600 | } 601 | } 602 | 603 | /** 604 | * Method used to reset all the delimiters for a query 605 | * 606 | * @return void 607 | * @access private 608 | */ 609 | private function _flush() { 610 | $this->_ws = array(); 611 | $this->_sls = array(); 612 | $this->_data = array(); 613 | $this->_from = ''; 614 | $this->_query = ''; 615 | } 616 | 617 | /** 618 | * Prepare the where statements whether from an array or a string 619 | * 620 | * @param mixed The "where" statements to process 621 | * @return void 622 | * @access private 623 | */ 624 | private function _set_where( $where = null ) { 625 | if ( isset( $where ) && $where !== null ) { 626 | if ( is_array( $where ) ) { 627 | foreach ( $where as $k => $v ) { 628 | $this->_ws[$k] = $v; 629 | } 630 | } else if( is_string( $where ) ) { 631 | $wheres = explode( ',', $where ); 632 | foreach ( $wheres as $wr ) { 633 | $pair = explode( '=', trim( $wr ) ); 634 | $this->_ws[trim( $pair[0] )] = trim( $pair[1] ); 635 | } 636 | } 637 | } 638 | } 639 | } 640 | // END Mongo_db_driver Class 641 | 642 | /* End of file Mongo_db_driver.php */ 643 | /* Location: ./{APPLICATION}/libraries/Mongo_db/drivers/Mongo_db_driver.php */ -------------------------------------------------------------------------------- /libraries/Mongo_db/drivers/Mongo_db_result.php: -------------------------------------------------------------------------------- 1 | 11 | * @author_url http://www.bitslice.net 12 | */ 13 | class Mongo_db_result extends CI_Driver { 14 | 15 | /** 16 | * Holder for the result of the query excuted 17 | * 18 | * @var resource 19 | * @access private 20 | */ 21 | private $_result = NULL; 22 | 23 | /** 24 | * Holder for the database connection 25 | * 26 | * @var resource 27 | * @access private 28 | */ 29 | private $_db = NULL; 30 | 31 | /** 32 | * Method used to create a result instance to perform the operations to the 33 | * MongoDB cursor 34 | * 35 | * @param MongoCursor The cursor obtained from the query executed 36 | * @param MongoDB The MongoDB connection used 37 | * @return Mongo_db_result The result object 38 | * @access public 39 | */ 40 | public function get_result( $cursor = NULL, &$db ) { 41 | $this->_result = $cursor; 42 | $this->_db = $db; 43 | 44 | // Move the cursor to the next location for the individual rows queries 45 | $this->_result->next(); 46 | return $this; 47 | } 48 | 49 | /** 50 | * Method used to get the results of the issued query as an array of objects 51 | * 52 | * @return array An array of the result objects 53 | * @access public 54 | */ 55 | public function result() { 56 | $result = array(); 57 | foreach( $this->_result as $row ) { 58 | if( $this->config_item( 'mongo_expand_dbrefs' ) ) 59 | $this->_deref( $row ); 60 | $result[] = (object) $row; 61 | } 62 | return $result; 63 | } 64 | 65 | /** 66 | * Method used to get the results of the query as an array of arrays 67 | * 68 | * @return array An array containing the results array 69 | * @access public 70 | */ 71 | public function result_array() { 72 | $result = array(); 73 | foreach( $this->_result as $row ) { 74 | if( $this->config_item( 'mongo_expand_dbrefs' ) ) { 75 | $this->_deref( $row ); 76 | } 77 | $result[] = $row; 78 | } 79 | return $result; 80 | } 81 | 82 | /** 83 | * Method used to get an object with a row of the performed query 84 | * 85 | * @param int The position of the required row to be returned 86 | * @return stdClass An object containing the first result of the query 87 | * @access public 88 | */ 89 | public function row( $row = NULL ) { 90 | return (object)$this->_row( $row ); 91 | } 92 | 93 | /** 94 | * Method used to get an array with a row of the performed query 95 | * 96 | * @param int The position of the required row to be returned 97 | * @return array An array containing the first result of the query 98 | * @access public 99 | */ 100 | public function row_array( $row = NULL ) { 101 | return $this->_row( $row ); 102 | } 103 | 104 | /** 105 | * Method used to retrieve the first row of the result of a query 106 | * 107 | * @param string Whether or not the result should be returned as an array 108 | * @return mixed An array or an object with the result of the first query result 109 | * @access public 110 | */ 111 | public function first_row( $array = '' ) { 112 | $this->_result->rewind(); 113 | 114 | $result = $this->_get_result(); 115 | return $this->_cast_result( $array, $result ); 116 | } 117 | 118 | /** 119 | * Method used to retrieve the last row from a query result 120 | * 121 | * @param string Whether or not the result should be returned as an array 122 | * @return mixed An array or an object with the result of the last query result 123 | * @access public 124 | */ 125 | public function last_row( $array = '' ) { 126 | // Advance the cursor to the last position 127 | for( $i = 1; $i < $this->_result->count(); $i++ ) { 128 | $this->_result->next(); 129 | } 130 | 131 | $result = $this->_get_result(); 132 | return $this->_cast_result( $array, $result ); 133 | } 134 | 135 | /** 136 | * Method used to retrieve the previous row from a query result 137 | * 138 | * @param string Whether or not the result should be returned as an array 139 | * @return mixed An array or an object with the result of the previous query result 140 | * @access public 141 | */ 142 | public function previous_row( $array = '' ) { 143 | $info = $this->_result->info(); 144 | $this->_result->rewind(); 145 | 146 | // Check that the cursor has started iterating 147 | if( isset( $info['at'] ) ) { 148 | // Move the cursor to the required position 149 | for( $i = 1; $i < ( $info['at'] - 1 ); $i++ ) { 150 | $this->_result->next(); 151 | } 152 | } 153 | 154 | $result = $this->_get_result(); 155 | return $this->_cast_result( $array, $result ); 156 | } 157 | 158 | /** 159 | * Method used to retrieve the next row from a query result 160 | * 161 | * @param string Whether or not the result should be returned as an array 162 | * @return mixed An array or an object with the result of the next query result 163 | * @access public 164 | */ 165 | public function next_row( $array = '' ) { 166 | $this->_result->next(); 167 | 168 | $result = $this->_get_result(); 169 | return $this->_cast_result( $array, $result ); 170 | } 171 | 172 | /** 173 | * Method used to get the number of rows returned by the query 174 | * 175 | * @return int The number of rows returned by the executed query 176 | * @access public 177 | */ 178 | public function num_rows() { 179 | return $this->_result->count(); 180 | } 181 | 182 | /** 183 | * Method used to retrieve the fields number in the current row 184 | * 185 | * @return int The number of the fields in the row 186 | * @access public 187 | */ 188 | public function num_fields() { 189 | return count( $this->_result->current() ); 190 | } 191 | 192 | /** 193 | * Returns information about the executed query, useful for debugging and optimization 194 | * 195 | * @return array 196 | * @access public 197 | */ 198 | public function explain_query() { 199 | return $this->_result->explain(); 200 | } 201 | 202 | /** 203 | * Method used to get a row resulting from the executed query 204 | * 205 | * @param int The index of the row to be returned 206 | * @return array An array containing the result of the query 207 | * @access private 208 | */ 209 | private function _row( $row ) { 210 | if( ! $row ) { 211 | return $this->_get_result(); 212 | } 213 | 214 | // Move the cursor to the required position 215 | for( $i = 1; $i < $row; $i++ ) { 216 | $this->_result->next(); 217 | } 218 | 219 | return $this->_get_result(); 220 | } 221 | 222 | /** 223 | * Method used to get a row from the executed query 224 | * 225 | * @return array An array containing the row data of the result 226 | * @access private 227 | */ 228 | private function _get_result() { 229 | if( $this->_result->valid() ) { 230 | $row = $this->_result->current(); 231 | if( $this->config_item( 'mongo_expand_dbrefs' ) ) { 232 | $this->_deref( $row ); 233 | } 234 | return $row; 235 | } else { 236 | return array(); 237 | } 238 | } 239 | 240 | /** 241 | * Method used to cast the result row to an object or an array 242 | * 243 | * @param string Whether or not the result should be returned as an array 244 | * @param array The array containing the result of the query 245 | * @return mixed An array or an object with the result of the last query result 246 | * @access private 247 | */ 248 | private function _cast_result( $array, $result ) { 249 | if( $array == 'array' ) { 250 | return $result; 251 | } else { 252 | return (object) $result; 253 | } 254 | } 255 | 256 | /** 257 | * Utility function to expand any DBRefs present in a document 258 | * 259 | * @param mixed The document to scan for DBRefs instances 260 | * @return void 261 | * @access private 262 | */ 263 | private function _deref( &$data ) { 264 | foreach( $data as $key => $value ) { 265 | if( is_object( $value ) || is_array( $value ) ) { 266 | if( is_object( $data ) ) { 267 | $data->{$key} = $this->_deref( $value ); 268 | } else { 269 | $data[ $key ] = $this->_deref( $value ); 270 | } 271 | } 272 | 273 | if( MongoDBRef::isRef( $value ) ) { 274 | if( is_object( $data ) ) { 275 | $data->{$key} = $this->_db->getDBRef( $value ); 276 | } else { 277 | $data[ $key ] = $this->_db->getDBRef( $value ); 278 | } 279 | } 280 | } 281 | return $data; 282 | } 283 | } 284 | // END Mongo_db_result.php Class 285 | 286 | /* End of file Mongo_db_result.php */ 287 | /* Location: ./{APPLICATION}/libraries/Mongo_db/drivers/Mongo_db_result.php */ --------------------------------------------------------------------------------