├── .gitignore ├── README.markdown ├── docs ├── __filesource │ ├── fsource_mongodb_mongodb-models-behaviors_behaviorsschemaless.php.html │ └── fsource_mongodb_mongodb-models-behaviors_behaviorssql_compatible.php.html ├── blank.html ├── classtrees_mongodb.html ├── elementindex.html ├── elementindex_mongodb.html ├── errors.html ├── index.html ├── li_mongodb.html ├── media │ ├── banner.css │ └── stylesheet.css ├── mongodb │ ├── mongodb-models-behaviors │ │ ├── SchemalessBehavior.html │ │ ├── SqlCompatibleBehavior.html │ │ ├── _behaviors---schemaless.php.html │ │ └── _behaviors---sql_compatible.php.html │ └── mongodb-models-datasources │ │ ├── MongodbSource.html │ │ └── _datasources---mongodb_source.php.html └── packages.html ├── models ├── behaviors │ ├── schemaless.php │ └── sql_compatible.php └── datasources │ └── mongodb_source.php ├── samples ├── controllers │ ├── geos_controller.php │ ├── posts_controller.php │ └── subdocuments_controller.php ├── models │ ├── geo.php │ ├── post.php │ └── subdocument.php └── views │ ├── geos │ ├── add.ctp │ └── index.ctp │ ├── posts │ ├── add.ctp │ ├── createindex.ctp │ ├── edit.ctp │ └── index.ctp │ └── subdocuments │ ├── add.ctp │ ├── edit.ctp │ └── index.ctp └── tests └── cases ├── 1st └── first_mongodb_source.test.php ├── behaviors └── sql_compatible.test.php └── datasources └── mongodb_source.test.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # mongoDB datasource for CakePHP 2 | 3 | ## Requirements 4 | PHP5, 5 | pecl mongo (http://php.net/mongo) 6 | 7 | ## Installation 8 | 9 | this repository should be installed in the same way as any other plugin. 10 | 11 | To install the driver for use in a single application: 12 | 13 | cd my/app/plugins 14 | git clone git://github.com/ichikaway/cakephp-mongodb.git mongodb 15 | 16 | To install the driver for use in any/multiple application(s) 17 | 18 | # where ROOT is the name of the directory parent to the base index.php of CakePHP. 19 | cd ROOT/plugins 20 | git clone git://github.com/ichikaway/cakephp-mongodb.git mongodb 21 | 22 | ## Sample Code 23 | 24 | To use this DB driver, install (obviously) and define a db source such as follows: 25 | 26 | 'mongodb.mongodbSource', 32 | 'database' => 'driver', 33 | 'host' => 'localhost', 34 | 'port' => 27017, 35 | /* optional auth fields 36 | 'login' => 'mongo', 37 | 'password' => 'awesomeness', 38 | */ 39 | ); 40 | 41 | Model files need to have mongoSchema property - or make use of the schemaless behavior. 42 | 43 | Mongo uses a primary key named "\_id" (cannot be renamed). It can be any format you like but if you don't explicitly set it Mongo will use an automatic 24 character (uu)id. 44 | 45 | Before you start, you may find it useful to see [a model sample.](http://github.com/ichikaway/mongoDB-Datasource/blob/master/samples/models/post.php) 46 | There are also some sample [controller actions: find,save,delete,deleteAll,updateAll](http://github.com/ichikaway/mongoDB-Datasource/blob/master/samples/controllers/posts_controller.php) note that your controller code needs no specific code to use this datasource. 47 | 48 | ## Author 49 | Yasushi Ichikawa ([ichikaway](http://twitter.com/ichikaway)) 50 | 51 | Andy Dawson ([AD7six](http://twitter.com/AD7six)) 52 | 53 | 54 | ## Contributors 55 | [Predominant](http://github.com/predominant/) : Cleanup code, add documentation 56 | 57 | [Jrbasso](http://github.com/jrbasso/) : Cleanup code 58 | 59 | [tkyk](http://github.com/tkyk/) : Fix bug, Add some function. 60 | 61 | 62 | ## Reference 63 | Reference code, Thank you! 64 | 65 | [Nate Abele's lithium mongoDB datasource](http://li3.rad-dev.org/) 66 | 67 | [Joél Perras' divan](http://github.com/jperras/divan/) 68 | 69 | -------------------------------------------------------------------------------- /docs/__filesource/fsource_mongodb_mongodb-models-behaviors_behaviorsschemaless.php.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | File Source for schemaless.php 7 | 8 | 9 | 10 | 11 |

Source for file schemaless.php

12 |

Documentation is available at schemaless.php

13 |
14 |
  1. <?php
  2. 15 |
  3. /**
  4. 16 |
  5.  * Schemaless behavior.
  6. 17 |
  7.  *
  8. 18 |
  9.  * Adds functionality specific to MongoDB/schemaless dbs
  10. 19 |
  11.  * Allow /not/ specifying the model's schema, and derive it (for cake-compatibility) from the data
  12. 20 |
  13.  * being saved. Note that used carelessly this is a pretty dangerous thing to allow - means a user
  14. 21 |
  15.  * can modify input forms adding whatever fields they like (unless you'er using the security
  16. 22 |
  17.  * component) and fill your db with their junk.
  18. 23 |
  19.  *
  20. 24 |
  21.  * PHP version 5
  22. 25 |
  23.  *
  24. 26 |
  25.  * Copyright (c) 2010, Andy Dawson
  26. 27 |
  27.  *
  28. 28 |
  29.  * Licensed under The MIT License
  30. 29 |
  31.  * Redistributions of files must retain the above copyright notice.
  32. 30 |
  33.  *
  34. 31 |
  35.  * @filesource
  36. 32 |
  37.  * @copyright     Copyright (c) 2010, Andy Dawson
  38. 33 |
  39.  * @link          www.ad7six.com
  40. 34 |
  41.  * @package       mongodb
  42. 35 |
  43.  * @subpackage    mongodb.models.behaviors
  44. 36 |
  45.  * @since         v 1.0 (24-May-2010)
  46. 37 |
  47.  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
  48. 38 |
  49.  */
  50. 39 |
  51.  
  52. 40 |
  53. /**
  54. 41 |
  55.  * SchemalessBehavior class
  56. 42 |
  57.  *
  58. 43 |
  59.  * @uses          ModelBehavior
  60. 44 |
  61.  * @package       mongodb
  62. 45 |
  63.  * @subpackage    mongodb.models.behaviors
  64. 46 |
  65.  */
  66. 47 |
  67. class SchemalessBehavior extends ModelBehavior {
  68. 48 |
  69.  
  70. 49 |
  71. /**
  72. 50 |
  73.  * name property
  74. 51 |
  75.  *
  76. 52 |
  77.  * @var string 'Schemaless'
  78. 53 |
  79.  * @access public
  80. 54 |
  81.  */
  82. 55 |
  83.     public $name = 'Schemaless';
  84. 56 |
  85.  
  86. 57 |
  87. /**
  88. 58 |
  89.  * settings property
  90. 59 |
  91.  *
  92. 60 |
  93.  * @var array 
  94. 61 |
  95.  * @access public
  96. 62 |
  97.  */
  98. 63 |
  99.     public $settings = array();
  100. 64 |
  101.  
  102. 65 |
  103. /**
  104. 66 |
  105.  * defaultSettings property
  106. 67 |
  107.  *
  108. 68 |
  109.  * @var array 
  110. 69 |
  111.  * @access protected
  112. 70 |
  113.  */
  114. 71 |
  115.     protected $_defaultSettings = array(
  116. 72 |
  117.     );
  118. 73 |
  119.  
  120. 74 |
  121. /**
  122. 75 |
  123.  * setup method
  124. 76 |
  125.  *
  126. 77 |
  127.  * Don't currently have any settings at all - disabled
  128. 78 |
  129.  *
  130. 79 |
  131.  * @param mixed $Model 
  132. 80 |
  133.  * @param array $config array()
  134. 81 |
  135.  * @return void 
  136. 82 |
  137.  * @access public
  138. 83 |
  139.  */
  140. 84 |
  141.     public function setup(&$Model$config array()) {
  142. 85 |
  143.         //$this->settings[$Model->alias] = array_merge($this->_defaultSettings, $config);
  144. 86 |
  145.     }
  146. 87 |
  147.  
  148. 88 |
  149. /**
  150. 89 |
  151.  * beforeSave method
  152. 90 |
  153.  *
  154. 91 |
  155.  * Set the schema to allow saving whatever has been passed
  156. 92 |
  157.  *
  158. 93 |
  159.  * @param mixed $Model 
  160. 94 |
  161.  * @return void 
  162. 95 |
  163.  * @access public
  164. 96 |
  165.  */
  166. 97 |
  167.     public function beforeSave(&$Model{
  168. 98 |
  169.         $Model->cacheSources false;
  170. 99 |
  171.         $Model->schema(true);
  172. 100 |
  173.         return true;
  174. 101 |
  175.     }
  176. 102 |
  177. }
  178. 103 |
104 |
105 |

106 | Documentation generated on Thu, 21 Apr 2011 01:07:45 +0900 by phpDocumentor 1.4.3 107 |

108 | 109 | -------------------------------------------------------------------------------- /docs/blank.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Generated Documentation 4 | 5 | 6 | 7 | 8 |

Generated Documentation

9 | Welcome to mongodb!
10 |
11 | This documentation was generated by phpDocumentor v1.4.3
12 | 13 | -------------------------------------------------------------------------------- /docs/classtrees_mongodb.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 | 15 |

16 |

Root class DboSource

17 | 19 | 20 |

Root class ModelBehavior

21 | 23 | 24 |

25 | Documentation generated on Thu, 21 Apr 2011 01:07:44 +0900 by phpDocumentor 1.4.3 26 |

27 | 28 | -------------------------------------------------------------------------------- /docs/elementindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Full index

13 |

Package indexes

14 | 17 |
18 |
19 | a 20 | b 21 | c 22 | d 23 | e 24 | g 25 | i 26 | l 27 | m 28 | n 29 | q 30 | r 31 | s 32 | t 33 | u 34 | v 35 | _ 36 |
37 | 38 | 39 |
40 |
a
41 |
top
42 |
43 |
44 |
45 |
46 | afterFind 47 |
48 |
49 | 50 |
If requested, convert dates from MongoDate objects to standard date strings
51 |
52 |
53 | 54 |
55 |
b
56 |
top
57 |
58 |
59 |
60 |
61 | beforeFind 62 |
63 |
64 | 65 |
beforeFind method
66 |
67 |
68 | beforeSave 69 |
70 |
71 | 72 |
beforeSave method
73 |
74 |
75 | begin 76 |
77 |
78 |
MongodbSource::begin() in mongodb_source.php
79 |
begin method
80 |
81 |
82 | 83 |
84 |
c
85 |
top
86 |
87 |
88 |
89 |
90 | $columns 91 |
92 |
93 |
MongodbSource::$columns in mongodb_source.php
94 |
column definition
95 |
96 |
97 | $connected 98 |
99 |
100 |
MongodbSource::$connected in mongodb_source.php
101 |
Are we connected to the DataSource?
102 |
103 |
104 | calculate 105 |
106 |
107 |
MongodbSource::calculate() in mongodb_source.php
108 |
Calculate
109 |
110 |
111 | close 112 |
113 |
114 |
MongodbSource::close() in mongodb_source.php
115 |
Close database connection
116 |
117 |
118 | commit 119 |
120 |
121 |
MongodbSource::commit() in mongodb_source.php
122 |
commit method
123 |
124 |
125 | connect 126 |
127 |
128 |
MongodbSource::connect() in mongodb_source.php
129 |
Connect to the database
130 |
131 |
132 | convertDates 133 |
134 |
135 | 136 |
Convert MongoDate objects to strings for the purpose of view simplicity
137 |
138 |
139 | create 140 |
141 |
142 |
MongodbSource::create() in mongodb_source.php
143 |
Create Data
144 |
145 |
146 | createSchema 147 |
148 |
149 |
MongodbSource::createSchema() in mongodb_source.php
150 |
createSchema method
151 |
152 |
153 | 154 |
155 |
d
156 |
top
157 |
158 |
159 |
160 |
161 | delete 162 |
163 |
164 |
MongodbSource::delete() in mongodb_source.php
165 |
Delete Data
166 |
167 |
168 | deriveSchemaFromData 169 |
170 |
171 | 172 |
deriveSchemaFromData method
173 |
174 |
175 | describe 176 |
177 |
178 |
MongodbSource::describe() in mongodb_source.php
179 |
Describe
180 |
181 |
182 | disconnect 183 |
184 |
185 |
MongodbSource::disconnect() in mongodb_source.php
186 |
Disconnect from the database
187 |
188 |
189 | distinct 190 |
191 |
192 |
MongodbSource::distinct() in mongodb_source.php
193 |
distinct method
194 |
195 |
196 | dropSchema 197 |
198 |
199 |
MongodbSource::dropSchema() in mongodb_source.php
200 |
dropSchema method
201 |
202 |
203 | 204 |
205 |
e
206 |
top
207 |
208 |
209 |
210 |
211 | ensureIndex 212 |
213 |
214 |
MongodbSource::ensureIndex() in mongodb_source.php
215 |
ensureIndex method
216 |
217 |
218 | execute 219 |
220 |
221 |
MongodbSource::execute() in mongodb_source.php
222 |
execute method
223 |
224 |
225 | 226 |
227 |
g
228 |
top
229 |
230 |
231 |
232 |
233 | getMapReduceResults 234 |
235 |
236 | 237 |
getMapReduceResults
238 |
239 |
240 | getMongoCollection 241 |
242 |
243 | 244 |
get MongoDB Collection Object
245 |
246 |
247 | getMongoDb 248 |
249 |
250 |
MongodbSource::getMongoDb() in mongodb_source.php
251 |
get MongoDB Object
252 |
253 |
254 | group 255 |
256 |
257 |
MongodbSource::group() in mongodb_source.php
258 |
group method
259 |
260 |
261 | 262 |
263 |
i
264 |
top
265 |
266 |
267 |
268 |
269 | insertMulti 270 |
271 |
272 |
MongodbSource::insertMulti() in mongodb_source.php
273 |
Inserts multiple values into a table
274 |
275 |
276 | isConnected 277 |
278 |
279 |
MongodbSource::isConnected() in mongodb_source.php
280 |
check connection to the database
281 |
282 |
283 | isInterfaceSupported 284 |
285 |
286 | 287 |
isInterfaceSupported method
288 |
289 |
290 | 291 |
292 |
l
293 |
top
294 |
295 |
296 |
297 |
298 | listSources 299 |
300 |
301 |
MongodbSource::listSources() in mongodb_source.php
302 |
Get list of available Collections
303 |
304 |
305 | logQuery 306 |
307 |
308 |
MongodbSource::logQuery() in mongodb_source.php
309 |
logQuery method
310 |
311 |
312 | 313 |
314 |
m
315 |
top
316 |
317 |
318 |
319 |
320 | mongodb_source.php 321 |
322 |
323 |
mongodb_source.php in mongodb_source.php
324 |
325 |
326 | MongoDbDateFormatter 327 |
328 |
329 |
MongoDbDateFormatter() in mongodb_source.php
330 |
MongoDbDateFormatter method
331 |
332 |
333 | MongodbSource 334 |
335 |
336 |
MongodbSource in mongodb_source.php
337 |
MongoDB Source
338 |
339 |
340 | 341 |
342 |
n
343 |
top
344 |
345 |
346 |
347 |
348 | $name 349 |
350 |
351 |
SqlCompatibleBehavior::$name in sql_compatible.php
352 |
name property
353 |
354 |
355 | $name 356 |
357 |
358 |
SchemalessBehavior::$name in schemaless.php
359 |
name property
360 |
361 |
362 | name 363 |
364 |
365 |
MongodbSource::name() in mongodb_source.php
366 |
Quotes identifiers.
367 |
368 |
369 | 370 |
371 |
q
372 |
top
373 |
374 |
375 |
376 |
377 | query 378 |
379 |
380 |
MongodbSource::query() in mongodb_source.php
381 |
query method If call getMongoDb() from model, this method call getMongoDb().
382 |
383 |
384 | 385 |
386 |
r
387 |
top
388 |
389 |
390 |
391 |
392 | read 393 |
394 |
395 |
MongodbSource::read() in mongodb_source.php
396 |
Read Data
397 |
398 |
399 | rollback 400 |
401 |
402 |
MongodbSource::rollback() in mongodb_source.php
403 |
rollback method
404 |
405 |
406 | 407 |
408 |
s
409 |
top
410 |
411 |
412 |
413 |
414 | $settings 415 |
416 |
417 |
SqlCompatibleBehavior::$settings in sql_compatible.php
418 |
Runtime settings
419 |
420 |
421 | $settings 422 |
423 |
424 | 425 |
settings property
426 |
427 |
428 | schemaless.php 429 |
430 |
431 |
schemaless.php in schemaless.php
432 |
433 |
434 | sql_compatible.php 435 |
436 |
437 |
sql_compatible.php in sql_compatible.php
438 |
439 |
440 | SchemalessBehavior 441 |
442 |
443 |
SchemalessBehavior in schemaless.php
444 |
SchemalessBehavior class
445 |
446 |
447 | setup 448 |
449 |
450 |
SqlCompatibleBehavior::setup() in sql_compatible.php
451 |
setup method
452 |
453 |
454 | setup 455 |
456 |
457 |
SchemalessBehavior::setup() in schemaless.php
458 |
setup method
459 |
460 |
461 | SqlCompatibleBehavior 462 |
463 |
464 |
SqlCompatibleBehavior in sql_compatible.php
465 |
SqlCompatibleBehavior class
466 |
467 |
468 | 469 |
470 |
t
471 |
top
472 |
473 |
474 |
475 |
476 | truncate 477 |
478 |
479 |
MongodbSource::truncate() in mongodb_source.php
480 |
Deletes all the records in a table
481 |
482 |
483 | 484 |
485 |
u
486 |
top
487 |
488 |
489 |
490 |
491 | update 492 |
493 |
494 |
MongodbSource::update() in mongodb_source.php
495 |
Update Data
496 |
497 |
498 | updateAll 499 |
500 |
501 |
MongodbSource::updateAll() in mongodb_source.php
502 |
Update multiple Record
503 |
504 |
505 | 506 |
507 |
v
508 |
top
509 |
510 |
511 |
512 |
513 | value 514 |
515 |
516 |
MongodbSource::value() in mongodb_source.php
517 |
Prepares a value, or an array of values for database queries by quoting and escaping them.
518 |
519 |
520 | 521 |
522 |
_
523 |
top
524 |
525 |
526 |
527 |
528 | $_baseConfig 529 |
530 |
531 |
MongodbSource::$_baseConfig in mongodb_source.php
532 |
Base Config
533 |
534 |
535 | $_db 536 |
537 |
538 |
MongodbSource::$_db in mongodb_source.php
539 |
Database Instance
540 |
541 |
542 | $_defaultSchema 543 |
544 |
545 |
MongodbSource::$_defaultSchema in mongodb_source.php
546 |
Default schema for the mongo models
547 |
548 |
549 | $_defaultSettings 550 |
551 |
552 | 553 |
defaultSettings property
554 |
555 |
556 | $_defaultSettings 557 |
558 |
559 | 560 |
defaultSettings property
561 |
562 |
563 | $_driverVersion 564 |
565 |
566 |
MongodbSource::$_driverVersion in mongodb_source.php
567 |
Mongo Driver Version
568 |
569 |
570 | $_startTime 571 |
572 |
573 |
MongodbSource::$_startTime in mongodb_source.php
574 |
startTime property
575 |
576 |
577 | _convertId 578 |
579 |
580 |
MongodbSource::_convertId() in mongodb_source.php
581 |
convertId method
582 |
583 |
584 | _prepareLogQuery 585 |
586 |
587 |
MongodbSource::_prepareLogQuery() in mongodb_source.php
588 |
prepareLogQuery method
589 |
590 |
591 | _setEmptyValues 592 |
593 |
594 |
MongodbSource::_setEmptyValues() in mongodb_source.php
595 |
Set empty values, arrays or integers, for the variables Mongo uses
596 |
597 |
598 | _stringify 599 |
600 |
601 |
MongodbSource::_stringify() in mongodb_source.php
602 |
stringify method
603 |
604 |
605 | _stripAlias 606 |
607 |
608 |
MongodbSource::_stripAlias() in mongodb_source.php
609 |
Convert automatically array('Model.field' => 'foo') to array('field' => 'foo')
610 |
611 |
612 | _translateConditions 613 |
614 |
615 | 616 |
translateConditions method
617 |
618 |
619 | _translateOperator 620 |
621 |
622 | 623 |
translateOperator method
624 |
625 |
626 | __construct 627 |
628 |
629 |
MongodbSource::__construct() in mongodb_source.php
630 |
construct method
631 |
632 |
633 | __destruct 634 |
635 |
636 |
MongodbSource::__destruct() in mongodb_source.php
637 |
Destruct
638 |
639 |
640 | 641 |
642 | a 643 | b 644 | c 645 | d 646 | e 647 | g 648 | i 649 | l 650 | m 651 | n 652 | q 653 | r 654 | s 655 | t 656 | u 657 | v 658 | _ 659 |
660 | -------------------------------------------------------------------------------- /docs/elementindex_mongodb.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

[mongodb] element index

13 | All elements 14 |
15 |
16 | a 17 | b 18 | c 19 | d 20 | e 21 | g 22 | i 23 | l 24 | m 25 | n 26 | q 27 | r 28 | s 29 | t 30 | u 31 | v 32 | _ 33 |
34 | 35 | 36 |
37 |
_
38 |
top
39 |
40 |
41 |
42 |
43 | $_defaultSettings 44 |
45 |
46 | 47 |
defaultSettings property
48 |
49 |
50 | $_defaultSettings 51 |
52 |
53 | 54 |
defaultSettings property
55 |
56 |
57 | _translateConditions 58 |
59 |
60 | 61 |
translateConditions method
62 |
63 |
64 | _translateOperator 65 |
66 |
67 | 68 |
translateOperator method
69 |
70 |
71 | $_baseConfig 72 |
73 |
74 |
MongodbSource::$_baseConfig in mongodb_source.php
75 |
Base Config
76 |
77 |
78 | $_db 79 |
80 |
81 |
MongodbSource::$_db in mongodb_source.php
82 |
Database Instance
83 |
84 |
85 | $_defaultSchema 86 |
87 |
88 |
MongodbSource::$_defaultSchema in mongodb_source.php
89 |
Default schema for the mongo models
90 |
91 |
92 | $_driverVersion 93 |
94 |
95 |
MongodbSource::$_driverVersion in mongodb_source.php
96 |
Mongo Driver Version
97 |
98 |
99 | $_startTime 100 |
101 |
102 |
MongodbSource::$_startTime in mongodb_source.php
103 |
startTime property
104 |
105 |
106 | _convertId 107 |
108 |
109 |
MongodbSource::_convertId() in mongodb_source.php
110 |
convertId method
111 |
112 |
113 | _prepareLogQuery 114 |
115 |
116 |
MongodbSource::_prepareLogQuery() in mongodb_source.php
117 |
prepareLogQuery method
118 |
119 |
120 | _setEmptyValues 121 |
122 |
123 |
MongodbSource::_setEmptyValues() in mongodb_source.php
124 |
Set empty values, arrays or integers, for the variables Mongo uses
125 |
126 |
127 | _stringify 128 |
129 |
130 |
MongodbSource::_stringify() in mongodb_source.php
131 |
stringify method
132 |
133 |
134 | _stripAlias 135 |
136 |
137 |
MongodbSource::_stripAlias() in mongodb_source.php
138 |
Convert automatically array('Model.field' => 'foo') to array('field' => 'foo')
139 |
140 |
141 | __construct 142 |
143 |
144 |
MongodbSource::__construct() in mongodb_source.php
145 |
construct method
146 |
147 |
148 | __destruct 149 |
150 |
151 |
MongodbSource::__destruct() in mongodb_source.php
152 |
Destruct
153 |
154 |
155 | 156 |
157 |
a
158 |
top
159 |
160 |
161 |
162 |
163 | afterFind 164 |
165 |
166 | 167 |
If requested, convert dates from MongoDate objects to standard date strings
168 |
169 |
170 | 171 |
172 |
b
173 |
top
174 |
175 |
176 |
177 |
178 | beforeFind 179 |
180 |
181 | 182 |
beforeFind method
183 |
184 |
185 | beforeSave 186 |
187 |
188 | 189 |
beforeSave method
190 |
191 |
192 | begin 193 |
194 |
195 |
MongodbSource::begin() in mongodb_source.php
196 |
begin method
197 |
198 |
199 | 200 |
201 |
c
202 |
top
203 |
204 |
205 |
206 |
207 | convertDates 208 |
209 |
210 | 211 |
Convert MongoDate objects to strings for the purpose of view simplicity
212 |
213 |
214 | $columns 215 |
216 |
217 |
MongodbSource::$columns in mongodb_source.php
218 |
column definition
219 |
220 |
221 | $connected 222 |
223 |
224 |
MongodbSource::$connected in mongodb_source.php
225 |
Are we connected to the DataSource?
226 |
227 |
228 | calculate 229 |
230 |
231 |
MongodbSource::calculate() in mongodb_source.php
232 |
Calculate
233 |
234 |
235 | close 236 |
237 |
238 |
MongodbSource::close() in mongodb_source.php
239 |
Close database connection
240 |
241 |
242 | commit 243 |
244 |
245 |
MongodbSource::commit() in mongodb_source.php
246 |
commit method
247 |
248 |
249 | connect 250 |
251 |
252 |
MongodbSource::connect() in mongodb_source.php
253 |
Connect to the database
254 |
255 |
256 | create 257 |
258 |
259 |
MongodbSource::create() in mongodb_source.php
260 |
Create Data
261 |
262 |
263 | createSchema 264 |
265 |
266 |
MongodbSource::createSchema() in mongodb_source.php
267 |
createSchema method
268 |
269 |
270 | 271 |
272 |
d
273 |
top
274 |
275 |
276 |
277 |
278 | delete 279 |
280 |
281 |
MongodbSource::delete() in mongodb_source.php
282 |
Delete Data
283 |
284 |
285 | deriveSchemaFromData 286 |
287 |
288 | 289 |
deriveSchemaFromData method
290 |
291 |
292 | describe 293 |
294 |
295 |
MongodbSource::describe() in mongodb_source.php
296 |
Describe
297 |
298 |
299 | disconnect 300 |
301 |
302 |
MongodbSource::disconnect() in mongodb_source.php
303 |
Disconnect from the database
304 |
305 |
306 | distinct 307 |
308 |
309 |
MongodbSource::distinct() in mongodb_source.php
310 |
distinct method
311 |
312 |
313 | dropSchema 314 |
315 |
316 |
MongodbSource::dropSchema() in mongodb_source.php
317 |
dropSchema method
318 |
319 |
320 | 321 |
322 |
e
323 |
top
324 |
325 |
326 |
327 |
328 | ensureIndex 329 |
330 |
331 |
MongodbSource::ensureIndex() in mongodb_source.php
332 |
ensureIndex method
333 |
334 |
335 | execute 336 |
337 |
338 |
MongodbSource::execute() in mongodb_source.php
339 |
execute method
340 |
341 |
342 | 343 |
344 |
g
345 |
top
346 |
347 |
348 |
349 |
350 | getMapReduceResults 351 |
352 |
353 | 354 |
getMapReduceResults
355 |
356 |
357 | getMongoCollection 358 |
359 |
360 | 361 |
get MongoDB Collection Object
362 |
363 |
364 | getMongoDb 365 |
366 |
367 |
MongodbSource::getMongoDb() in mongodb_source.php
368 |
get MongoDB Object
369 |
370 |
371 | group 372 |
373 |
374 |
MongodbSource::group() in mongodb_source.php
375 |
group method
376 |
377 |
378 | 379 |
380 |
i
381 |
top
382 |
383 |
384 |
385 |
386 | insertMulti 387 |
388 |
389 |
MongodbSource::insertMulti() in mongodb_source.php
390 |
Inserts multiple values into a table
391 |
392 |
393 | isConnected 394 |
395 |
396 |
MongodbSource::isConnected() in mongodb_source.php
397 |
check connection to the database
398 |
399 |
400 | isInterfaceSupported 401 |
402 |
403 | 404 |
isInterfaceSupported method
405 |
406 |
407 | 408 |
409 |
l
410 |
top
411 |
412 |
413 |
414 |
415 | listSources 416 |
417 |
418 |
MongodbSource::listSources() in mongodb_source.php
419 |
Get list of available Collections
420 |
421 |
422 | logQuery 423 |
424 |
425 |
MongodbSource::logQuery() in mongodb_source.php
426 |
logQuery method
427 |
428 |
429 | 430 |
431 |
m
432 |
top
433 |
434 |
435 |
436 |
437 | mongodb_source.php 438 |
439 |
440 |
mongodb_source.php in mongodb_source.php
441 |
442 |
443 | MongoDbDateFormatter 444 |
445 |
446 |
MongoDbDateFormatter() in mongodb_source.php
447 |
MongoDbDateFormatter method
448 |
449 |
450 | MongodbSource 451 |
452 |
453 |
MongodbSource in mongodb_source.php
454 |
MongoDB Source
455 |
456 |
457 | 458 |
459 |
n
460 |
top
461 |
462 |
463 |
464 |
465 | $name 466 |
467 |
468 |
SqlCompatibleBehavior::$name in sql_compatible.php
469 |
name property
470 |
471 |
472 | $name 473 |
474 |
475 |
SchemalessBehavior::$name in schemaless.php
476 |
name property
477 |
478 |
479 | name 480 |
481 |
482 |
MongodbSource::name() in mongodb_source.php
483 |
Quotes identifiers.
484 |
485 |
486 | 487 |
488 |
q
489 |
top
490 |
491 |
492 |
493 |
494 | query 495 |
496 |
497 |
MongodbSource::query() in mongodb_source.php
498 |
query method If call getMongoDb() from model, this method call getMongoDb().
499 |
500 |
501 | 502 |
503 |
r
504 |
top
505 |
506 |
507 |
508 |
509 | read 510 |
511 |
512 |
MongodbSource::read() in mongodb_source.php
513 |
Read Data
514 |
515 |
516 | rollback 517 |
518 |
519 |
MongodbSource::rollback() in mongodb_source.php
520 |
rollback method
521 |
522 |
523 | 524 |
525 |
s
526 |
top
527 |
528 |
529 |
530 |
531 | $settings 532 |
533 |
534 |
SqlCompatibleBehavior::$settings in sql_compatible.php
535 |
Runtime settings
536 |
537 |
538 | $settings 539 |
540 |
541 | 542 |
settings property
543 |
544 |
545 | schemaless.php 546 |
547 |
548 |
schemaless.php in schemaless.php
549 |
550 |
551 | sql_compatible.php 552 |
553 |
554 |
sql_compatible.php in sql_compatible.php
555 |
556 |
557 | SchemalessBehavior 558 |
559 |
560 |
SchemalessBehavior in schemaless.php
561 |
SchemalessBehavior class
562 |
563 |
564 | setup 565 |
566 |
567 |
SqlCompatibleBehavior::setup() in sql_compatible.php
568 |
setup method
569 |
570 |
571 | setup 572 |
573 |
574 |
SchemalessBehavior::setup() in schemaless.php
575 |
setup method
576 |
577 |
578 | SqlCompatibleBehavior 579 |
580 |
581 |
SqlCompatibleBehavior in sql_compatible.php
582 |
SqlCompatibleBehavior class
583 |
584 |
585 | 586 |
587 |
t
588 |
top
589 |
590 |
591 |
592 |
593 | truncate 594 |
595 |
596 |
MongodbSource::truncate() in mongodb_source.php
597 |
Deletes all the records in a table
598 |
599 |
600 | 601 |
602 |
u
603 |
top
604 |
605 |
606 |
607 |
608 | update 609 |
610 |
611 |
MongodbSource::update() in mongodb_source.php
612 |
Update Data
613 |
614 |
615 | updateAll 616 |
617 |
618 |
MongodbSource::updateAll() in mongodb_source.php
619 |
Update multiple Record
620 |
621 |
622 | 623 |
624 |
v
625 |
top
626 |
627 |
628 |
629 |
630 | value 631 |
632 |
633 |
MongodbSource::value() in mongodb_source.php
634 |
Prepares a value, or an array of values for database queries by quoting and escaping them.
635 |
636 |
637 | 638 |
639 | a 640 | b 641 | c 642 | d 643 | e 644 | g 645 | i 646 | l 647 | m 648 | n 649 | q 650 | r 651 | s 652 | t 653 | u 654 | v 655 | _ 656 |
657 | -------------------------------------------------------------------------------- /docs/errors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | phpDocumentor Parser Errors and Warnings 7 | 8 | 9 | 10 | 11 | Post-parsing
12 | 13 |

Post-parsing

14 |

Warnings:


15 | Warning - Class SchemalessBehavior parent ModelBehavior not found
16 | Warning - Class SqlCompatibleBehavior parent ModelBehavior not found
17 | Warning - Class MongodbSource parent DboSource not found
18 |

19 | Documentation generated on Thu, 21 Apr 2011 01:07:46 +0900 by phpDocumentor 1.4.3 20 |

21 | 22 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | Generated Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <H2>Frame Alert</H2> 20 | <P>This document is designed to be viewed using the frames feature. 21 | If you see this message, you are using a non-frame-capable web client.</P> 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/li_mongodb.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
mongodb
12 |
13 | 14 |
15 | 16 |
Description
17 |
18 | Class trees
19 | Index of elements
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
mongodb-models-behaviors
29 |
30 |
31 |
Classes
32 |
SchemalessBehavior
33 |
SqlCompatibleBehavior
34 |
Files
35 |
schemaless.php
36 |
sql_compatible.php
37 |
38 |
39 | 40 | 41 | 42 | 43 |
mongodb-models-datasources
44 |
45 |
46 |
Classes
47 |
MongodbSource
48 |
Functions
49 |
MongoDbDateFormatter
50 |
Files
51 |
mongodb_source.php
52 |
53 |
54 | 55 | 56 |
57 |
58 |

phpDocumentor v 1.4.3

59 | 60 | -------------------------------------------------------------------------------- /docs/media/banner.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | background-color: #DDDDDD; 4 | margin: 0px; 5 | padding: 0px; 6 | } 7 | 8 | /* Banner (top bar) classes */ 9 | 10 | .banner { } 11 | 12 | .banner-menu 13 | { 14 | clear: both; 15 | padding: .5em; 16 | border-top: 2px solid #999999; 17 | } 18 | 19 | .banner-title 20 | { 21 | text-align: right; 22 | font-size: 20pt; 23 | font-weight: bold; 24 | margin: .2em; 25 | } 26 | 27 | .package-selector 28 | { 29 | background-color: #CCCCCC; 30 | border: 1px solid black; 31 | color: blue; 32 | } 33 | -------------------------------------------------------------------------------- /docs/media/stylesheet.css: -------------------------------------------------------------------------------- 1 | a { color: #0000FF; text-decoration: none; } 2 | a:hover { color: #FF0000; text-decoration: underline; } 3 | a:active { color: #FF0000; text-decoration: underline; } 4 | 5 | body { background-color: #EEEEEE; font-family: Verdana, Arial, sans-serif } 6 | body, table { font-size: 10pt } 7 | a img { border: 0px; } 8 | dd { margin-left: 0px; padding-left: 1em; } 9 | 10 | /* Page layout/boxes */ 11 | 12 | .info-box {} 13 | .info-box-title { margin: 1em 0em 0em 0em; padding: .25em; font-weight: normal; font-size: 14pt; border: 2px solid #999999; background-color: #DDDDDD } 14 | .info-box-body { border: 1px solid #999999; padding: .5em; background-color: #F8F8F8; } 15 | .nav-bar { font-size: 8pt; white-space: nowrap; text-align: right; padding: .2em; margin: 0em 0em 1em 0em; } 16 | 17 | .oddrow { background-color: #DDDDDD; border: 1px solid #999999; padding: .5em; margin-bottom: 1em} 18 | .evenrow { background-color: #DDDDDD; border: 1px solid #999999; padding: .5em; margin-bottom: 1em} 19 | 20 | .page-body { max-width: 800px; margin: auto; } 21 | .tree dl { margin: 0px } 22 | 23 | /* Index formatting classes */ 24 | 25 | .index-item-body { margin-top: .5em; margin-bottom: .5em} 26 | .index-item-description { margin-top: .25em } 27 | .index-item-details { font-weight: normal; font-style: italic; font-size: 8pt } 28 | .index-letter-section { background-color: #EEEEEE; border: 1px dotted #999999; padding: .5em; margin-bottom: 1em} 29 | .index-letter-title { font-size: 12pt; font-weight: bold } 30 | .index-letter-menu { text-align: center; margin: 1em } 31 | .index-letter { font-size: 12pt } 32 | 33 | /* Docbook classes */ 34 | 35 | .description {} 36 | .short-description { font-weight: bold; color: #666666; } 37 | .tags { padding-left: 0em; margin-left: 3em; color: #666666; list-style-type: square; } 38 | .parameters { padding-left: 0em; margin-left: 3em; font-style: italic; list-style-type: square; } 39 | .redefinitions { font-size: 8pt; padding-left: 0em; margin-left: 2em; } 40 | .package { } 41 | .package-title { font-weight: bold; font-size: 14pt; border-bottom: 1px solid black } 42 | .package-details { font-size: 85%; } 43 | .sub-package { font-weight: bold; font-size: 120% } 44 | .tutorial { border-width: thin; border-color: #0066ff } 45 | .tutorial-nav-box { width: 100%; border: 2px solid #999999; background-color: #DDDDDD } 46 | .nav-button-disabled { color: #999999; } 47 | .nav-button:active, 48 | .nav-button:focus, 49 | .nav-button:hover { background-color: #AAAAAA; outline: 1px solid #666666; text-decoration: none } 50 | .folder-title { font-style: italic } 51 | 52 | /* Generic formatting */ 53 | 54 | .field { font-weight: bold; } 55 | .detail { font-size: 8pt; } 56 | .notes { font-style: italic; font-size: 8pt; } 57 | .separator { background-color: #999999; height: 2px; } 58 | .warning { color: #FF6600; } 59 | .disabled { font-style: italic; color: #999999; } 60 | 61 | /* Code elements */ 62 | 63 | .line-number { } 64 | 65 | .class-table { width: 100%; } 66 | .class-table-header { border-bottom: 1px dotted #666666; text-align: left} 67 | .class-name { color: #000000; font-weight: bold; } 68 | 69 | .method-summary { padding-left: 1em; font-size: 8pt } 70 | .method-header { } 71 | .method-definition { margin-bottom: .3em } 72 | .method-title { font-weight: bold; } 73 | .method-name { font-weight: bold; } 74 | .method-signature { font-size: 85%; color: #0066BB; margin: .5em 0em } 75 | .method-result { font-style: italic; } 76 | 77 | .var-summary { padding-left: 1em; font-size: 8pt; } 78 | .var-header { } 79 | .var-title { margin-bottom: .3em } 80 | .var-type { color: red; font-weight: bold } 81 | .var-name { font-weight: bold; } 82 | .var-default {} 83 | .var-description { font-weight: normal; color: #000000; } 84 | 85 | .include-title { } 86 | .include-type { font-style: italic; } 87 | .include-name { font-weight: bold; } 88 | 89 | .const-title { } 90 | .const-name { font-weight: bold; } 91 | 92 | /* Syntax highlighting */ 93 | 94 | .src-code { border: 1px solid #336699; padding: 1em; background-color: #EEEEEE; 95 | font-family: 'Courier New', Courier, monospace; font-weight: normal; } 96 | .src-line { font-family: 'Courier New', Courier, monospace; font-weight: normal; } 97 | 98 | .src-comm { color: #666666; } 99 | .src-id { } 100 | .src-inc { color: #0000FF; } 101 | .src-key { color: #0000FF; } 102 | .src-num { color: #CC0000; } 103 | .src-str { color: #66cccc; } 104 | .src-sym { font-weight: bold; } 105 | .src-var { } 106 | 107 | .src-php { font-weight: bold; } 108 | 109 | .src-doc { color: #009999 } 110 | .src-doc-close-template { color: #0000FF } 111 | .src-doc-coretag { color: #0099FF; font-weight: bold } 112 | .src-doc-inlinetag { color: #0099FF } 113 | .src-doc-internal { color: #6699cc } 114 | .src-doc-tag { color: #0080CC } 115 | .src-doc-template { color: #0000FF } 116 | .src-doc-type { font-style: italic } 117 | .src-doc-var { font-style: italic } 118 | 119 | .tute-tag { color: #009999 } 120 | .tute-attribute-name { color: #0000FF } 121 | .tute-attribute-value { color: #0099FF } 122 | .tute-entity { font-weight: bold; } 123 | .tute-comment { font-style: italic } 124 | .tute-inline-tag { color: #636311; font-weight: bold } 125 | 126 | /* tutorial */ 127 | 128 | .authors { } 129 | .author { font-style: italic; font-weight: bold } 130 | .author-blurb { margin: .5em 0em .5em 2em; font-size: 85%; font-weight: normal; font-style: normal } 131 | .example { background-color: #DDDDDD; border: 1px solid #999999; padding: .5em; } 132 | .listing { background-color: #DDDDDD; border: 1px solid #999999; padding: .5em; white-space: nowrap; } 133 | .release-info { font-size: 85%; font-style: italic; margin: 1em 0em } 134 | .ref-title-box { } 135 | .ref-title { } 136 | .ref-purpose { font-style: italic; color: #666666 } 137 | .ref-synopsis { } 138 | .title { font-weight: bold; border-bottom: 1px solid #888888; color: #888888; } 139 | .cmd-synopsis { margin: 1em 0em } 140 | .cmd-title { font-weight: bold } 141 | .toc { margin-left: 2em; padding-left: 0em } 142 | 143 | -------------------------------------------------------------------------------- /docs/mongodb/mongodb-models-behaviors/SchemalessBehavior.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Docs For Class SchemalessBehavior 7 | 8 | 9 | 10 | 11 |
12 |

Class SchemalessBehavior

13 | 14 | 15 |
16 |
Description
17 | 23 |
24 | 25 |

SchemalessBehavior class

26 |
    27 |
  • uses: ModelBehavior
  • 28 |
29 |

30 | Located in /behaviors/schemaless.php (line 34) 31 |

32 | 33 | 34 |
ModelBehavior
 35 |    |
 36 |    --SchemalessBehavior
37 | 38 |
39 |
40 | 41 | 42 | 43 | 44 |
45 |
Variable Summary
46 | 53 |
54 |
55 |
56 | string 57 | $name 58 |
59 |
60 | array 61 | $settings 62 |
63 |
64 | array 65 | $_defaultSettings 66 |
67 |
68 |
69 |
70 | 71 | 72 |
73 |
Method Summary
74 | 81 |
82 |
83 | 84 |
85 | void 86 | beforeSave 87 | ( &$Model, mixed $Model) 88 |
89 | 90 |
91 | void 92 | setup 93 | ( &$Model, [array $config = array()], mixed $Model) 94 |
95 |
96 |
97 |
98 | 99 | 100 |
101 |
Variables
102 | 111 |
112 | 113 | 114 |
115 | 116 |
117 | 118 | string 119 | $name 120 | = 'Schemaless' (line 42) 121 | 122 |
123 | 124 | 125 |

name property

126 |
    127 |
  • var: 'Schemaless'
  • 128 |
  • access: public
  • 129 |
130 | 131 | 132 | 133 | 134 | 135 |
136 | 137 |
138 | 139 |
140 | 141 | array 142 | $settings 143 | = array() (line 50) 144 | 145 |
146 | 147 | 148 |

settings property

149 |
    150 |
  • access: public
  • 151 |
152 | 153 | 154 | 155 | 156 | 157 |
158 | 159 |
160 | 161 |
162 | 163 | array 164 | $_defaultSettings 165 | = array(
)
(line 58) 166 |
167 |
168 | 169 | 170 |

defaultSettings property

171 |
    172 |
  • access: protected
  • 173 |
174 | 175 | 176 | 177 | 178 | 179 |
180 | 181 |
182 |
183 | 184 | 185 |
186 |
Methods
187 | 193 |
194 | 195 | 196 |
197 | 198 |
199 | beforeSave (line 84) 200 |
201 | 202 | 203 |

beforeSave method

204 |

Set the schema to allow saving whatever has been passed

205 |
    206 |
  • access: public
  • 207 |
208 | 209 |
210 | void 211 | 212 | beforeSave 213 | 214 | ( &$Model, mixed $Model) 215 |
216 | 217 |
    218 |
  • 219 | mixed 220 | $Model
  • 221 |
  • 222 | 223 | &$Model
  • 224 |
225 | 226 | 227 |
228 | 229 |
230 | 231 |
232 | setup (line 71) 233 |
234 | 235 | 236 |

setup method

237 |

Don't currently have any settings at all - disabled

238 |
    239 |
  • access: public
  • 240 |
241 | 242 |
243 | void 244 | 245 | setup 246 | 247 | ( &$Model, [array $config = array()], mixed $Model) 248 |
249 | 250 |
    251 |
  • 252 | mixed 253 | $Model
  • 254 |
  • 255 | array 256 | $config: array()
  • 257 |
  • 258 | 259 | &$Model
  • 260 |
261 | 262 | 263 |
264 | 265 |
266 |
267 | 268 | 269 |

270 | Documentation generated on Thu, 21 Apr 2011 01:07:45 +0900 by phpDocumentor 1.4.3 271 |

272 |
273 | -------------------------------------------------------------------------------- /docs/mongodb/mongodb-models-behaviors/SqlCompatibleBehavior.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Docs For Class SqlCompatibleBehavior 7 | 8 | 9 | 10 | 11 |
12 |

Class SqlCompatibleBehavior

13 | 14 | 15 |
16 |
Description
17 | 23 |
24 | 25 |

SqlCompatibleBehavior class

26 |
    27 |
  • uses: ModelBehavior
  • 28 |
29 |

30 | Located in /behaviors/sql_compatible.php (line 31) 31 |

32 | 33 | 34 |
ModelBehavior
 35 |    |
 36 |    --SqlCompatibleBehavior
37 | 38 |
39 |
40 | 41 | 42 | 43 | 44 |
45 |
Variable Summary
46 | 53 |
54 |
55 |
56 | string 57 | $name 58 |
59 |
60 | array 61 | $settings 62 |
63 |
64 | array 65 | $_defaultSettings 66 |
67 |
68 |
69 |
70 | 71 | 72 |
73 |
Method Summary
74 | 81 |
82 |
83 | 84 |
85 | void 86 | afterFind 87 | ( &$Model, mixed $results, mixed $primary, mixed $Model) 88 |
89 | 90 |
91 | void 92 | beforeFind 93 | ( &$Model, mixed $query, mixed $Model) 94 |
95 | 96 |
97 | void 98 | convertDates 99 | ( &$results, mixed $results) 100 |
101 | 102 |
103 | void 104 | setup 105 | ( &$Model, [array $config = array()], mixed $Model) 106 |
107 | 108 |
109 | void 110 | _translateConditions 111 | ( &$Model,  &$conditions, mixed $Model, mixed $conditions) 112 |
113 | 114 |
115 | string 116 | _translateOperator 117 | (mixed $Model, mixed $operator) 118 |
119 |
120 |
121 |
122 | 123 | 124 |
125 |
Variables
126 | 135 |
136 | 137 | 138 |
139 | 140 |
141 | 142 | string 143 | $name 144 | = 'SqlCompatible' (line 39) 145 | 146 |
147 | 148 | 149 |

name property

150 |
    151 |
  • var: 'SqlCompatible'
  • 152 |
  • access: public
  • 153 |
154 | 155 | 156 | 157 | 158 | 159 |
160 | 161 |
162 | 163 |
164 | 165 | array 166 | $settings 167 | = array() (line 49) 168 | 169 |
170 | 171 | 172 |

Runtime settings

173 |

Keyed on model alias

174 |
    175 |
  • access: public
  • 176 |
177 | 178 | 179 | 180 | 181 | 182 |
183 | 184 |
185 | 186 |
187 | 188 | array 189 | $_defaultSettings 190 | = array(
'convertDates' => true,
'operators' => array(
'!=' => '$ne',
'>' => '$gt',
'>=' => '$gte',
'<' => '$lt',
'<=' => '$lte',
'IN' => '$in',
'NOT' => '$not',
'NOT IN' => '$nin'
))
(line 57) 191 |
192 |
193 | 194 | 195 |

defaultSettings property

196 |
    197 |
  • access: protected
  • 198 |
199 | 200 | 201 | 202 | 203 | 204 |
205 | 206 |
207 |
208 | 209 | 210 |
211 |
Methods
212 | 218 |
219 | 220 | 221 |
222 | 223 |
224 | afterFind (line 94) 225 |
226 | 227 | 228 |

If requested, convert dates from MongoDate objects to standard date strings

229 |
    230 |
  • access: public
  • 231 |
232 | 233 |
234 | void 235 | 236 | afterFind 237 | 238 | ( &$Model, mixed $results, mixed $primary, mixed $Model) 239 |
240 | 241 |
    242 |
  • 243 | mixed 244 | $Model
  • 245 |
  • 246 | mixed 247 | $results
  • 248 |
  • 249 | mixed 250 | $primary
  • 251 |
  • 252 | 253 | &$Model
  • 254 |
255 | 256 | 257 |
258 | 259 |
260 | 261 |
262 | beforeFind (line 111) 263 |
264 | 265 | 266 |

beforeFind method

267 |

If conditions are an array ensure they are mongified

268 |
    269 |
  • access: public
  • 270 |
271 | 272 |
273 | void 274 | 275 | beforeFind 276 | 277 | ( &$Model, mixed $query, mixed $Model) 278 |
279 | 280 |
    281 |
  • 282 | mixed 283 | $Model
  • 284 |
  • 285 | mixed 286 | $query
  • 287 |
  • 288 | 289 | &$Model
  • 290 |
291 | 292 | 293 |
294 | 295 |
296 | 297 |
298 | convertDates (line 125) 299 |
300 | 301 | 302 |

Convert MongoDate objects to strings for the purpose of view simplicity

303 |
    304 |
  • access: public
  • 305 |
306 | 307 |
308 | void 309 | 310 | convertDates 311 | 312 | ( &$results, mixed $results) 313 |
314 | 315 |
    316 |
  • 317 | mixed 318 | $results
  • 319 |
  • 320 | 321 | &$results
  • 322 |
323 | 324 | 325 |
326 | 327 |
328 | 329 |
330 | setup (line 81) 331 |
332 | 333 | 334 |

setup method

335 |

Allow overriding the operator map

336 |
    337 |
  • access: public
  • 338 |
339 | 340 |
341 | void 342 | 343 | setup 344 | 345 | ( &$Model, [array $config = array()], mixed $Model) 346 |
347 | 348 |
    349 |
  • 350 | mixed 351 | $Model
  • 352 |
  • 353 | array 354 | $config: array()
  • 355 |
  • 356 | 357 | &$Model
  • 358 |
359 | 360 | 361 |
362 | 363 |
364 | 365 |
366 | _translateConditions (line 145) 367 |
368 | 369 | 370 |

translateConditions method

371 |

Loop on conditions and desqlify them

372 |
    373 |
  • access: protected
  • 374 |
375 | 376 |
377 | void 378 | 379 | _translateConditions 380 | 381 | ( &$Model,  &$conditions, mixed $Model, mixed $conditions) 382 |
383 | 384 |
    385 |
  • 386 | mixed 387 | $Model
  • 388 |
  • 389 | mixed 390 | $conditions
  • 391 |
  • 392 | 393 | &$Model
  • 394 |
  • 395 | 396 | &$conditions
  • 397 |
398 | 399 | 400 |
401 | 402 |
403 | 404 |
405 | _translateOperator (line 247) 406 |
407 | 408 | 409 |

translateOperator method

410 |

Use the operator map for the model and return what the db really wants to hear

411 |
    412 |
  • access: protected
  • 413 |
414 | 415 |
416 | string 417 | 418 | _translateOperator 419 | 420 | (mixed $Model, mixed $operator) 421 |
422 | 423 |
    424 |
  • 425 | mixed 426 | $Model
  • 427 |
  • 428 | mixed 429 | $operator
  • 430 |
431 | 432 | 433 |
434 | 435 |
436 |
437 | 438 | 439 |

440 | Documentation generated on Thu, 21 Apr 2011 01:07:46 +0900 by phpDocumentor 1.4.3 441 |

442 |
443 | -------------------------------------------------------------------------------- /docs/mongodb/mongodb-models-behaviors/_behaviors---schemaless.php.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Docs for page schemaless.php 7 | 8 | 9 | 10 | 11 |
12 |

/behaviors/schemaless.php

13 | 14 | 15 |
16 |
Description
17 | 21 |
22 | 23 |

Schemaless behavior.

24 |

Adds functionality specific to MongoDB/schemaless dbs Allow /not/ specifying the model's schema, and derive it (for cake-compatibility) from the data being saved. Note that used carelessly this is a pretty dangerous thing to allow - means a user can modify input forms adding whatever fields they like (unless you'er using the security component) and fill your db with their junk.

PHP version 5

Copyright (c) 2010, Andy Dawson

Licensed under The MIT License Redistributions of files must retain the above copyright notice.

25 | 32 | 33 |
34 |
35 | 36 | 37 |
38 |
Classes
39 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 56 | 57 |
ClassDescription
51 | SchemalessBehavior 52 | 54 | SchemalessBehavior class 55 |
58 |
59 |
60 | 61 | 62 | 63 | 64 | 65 |

66 | Documentation generated on Thu, 21 Apr 2011 01:07:44 +0900 by phpDocumentor 1.4.3 67 |

68 |
69 | -------------------------------------------------------------------------------- /docs/mongodb/mongodb-models-behaviors/_behaviors---sql_compatible.php.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Docs for page sql_compatible.php 7 | 8 | 9 | 10 | 11 |
12 |

/behaviors/sql_compatible.php

13 | 14 | 15 |
16 |
Description
17 | 21 |
22 | 23 |

Sql Compatible.

24 |

Attach this behavior to be able to query mongo DBs without using mongo specific syntax. If you don't need this behavior don't attach it and save a few cycles

PHP version 5

Copyright (c) 2010, Andy Dawson

Licensed under The MIT License Redistributions of files must retain the above copyright notice.

25 | 32 | 33 |
34 |
35 | 36 | 37 |
38 |
Classes
39 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 53 | 56 | 57 |
ClassDescription
51 | SqlCompatibleBehavior 52 | 54 | SqlCompatibleBehavior class 55 |
58 |
59 |
60 | 61 | 62 | 63 | 64 | 65 |

66 | Documentation generated on Thu, 21 Apr 2011 01:07:45 +0900 by phpDocumentor 1.4.3 67 |

68 |
69 | -------------------------------------------------------------------------------- /docs/mongodb/mongodb-models-datasources/_datasources---mongodb_source.php.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Docs for page mongodb_source.php 7 | 8 | 9 | 10 | 11 |
12 |

/datasources/mongodb_source.php

13 | 14 | 15 |
16 |
Description
17 | 22 |
23 | 24 |

A CakePHP datasource for the mongoDB (http://www.mongodb.org/) document-oriented database.

25 |

This datasource uses Pecl Mongo (http://php.net/mongo) and is thus dependent on PHP 5.0 and greater.

Original implementation by ichikaway(Yasushi Ichikawa) http://github.com/ichikaway/

Reference: Nate Abele's lithium mongoDB datasource (http://li3.rad-dev.org/) Joél Perras' divan(http://github.com/jperras/divan/)

Copyright 2010, Yasushi Ichikawa http://github.com/ichikaway/

Contributors: Predominant, Jrbasso, tkyk, AD7six

Licensed under The MIT License Redistributions of files must retain the above copyright notice.

26 |
    27 |
  • copyright: Copyright 2010, Yasushi Ichikawa http://github.com/ichikaway/
  • 28 |
  • license: The MIT License
  • 29 |
30 | 31 |
32 |
33 | 34 | 35 |
36 |
Classes
37 | 42 |
43 | 44 | 45 | 46 | 47 | 48 | 49 | 52 | 55 | 56 |
ClassDescription
50 | MongodbSource 51 | 53 | MongoDB Source 54 |
57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 |
65 |
Functions
66 | 71 |
72 | 73 |
74 | 75 |
76 | MongoDbDateFormatter (line 1317) 77 |
78 | 79 | 80 |

MongoDbDateFormatter method

81 |

This function cannot be in the class because of the way model save is written

82 |
    83 |
  • access: public
  • 84 |
85 | 86 |
87 | void 88 | 89 | MongoDbDateFormatter 90 | 91 | ([mixed $date = null]) 92 |
93 | 94 |
    95 |
  • 96 | mixed 97 | $date: null
  • 98 |
99 | 100 | 101 |
102 |
103 |
104 | 105 |

106 | Documentation generated on Thu, 21 Apr 2011 01:07:44 +0900 by phpDocumentor 1.4.3 107 |

108 |
109 | -------------------------------------------------------------------------------- /docs/packages.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 28 | 29 | -------------------------------------------------------------------------------- /models/behaviors/schemaless.php: -------------------------------------------------------------------------------- 1 | settings[$Model->alias] = array_merge($this->_defaultSettings, $config); 73 | } 74 | 75 | /** 76 | * beforeSave method 77 | * 78 | * Set the schema to allow saving whatever has been passed 79 | * 80 | * @param mixed $Model 81 | * @return void 82 | * @access public 83 | */ 84 | public function beforeSave(&$Model) { 85 | $Model->cacheSources = false; 86 | $Model->schema(true); 87 | return true; 88 | } 89 | } -------------------------------------------------------------------------------- /models/behaviors/sql_compatible.php: -------------------------------------------------------------------------------- 1 | true, 59 | 'operators' => array( 60 | '!=' => '$ne', 61 | '>' => '$gt', 62 | '>=' => '$gte', 63 | '<' => '$lt', 64 | '<=' => '$lte', 65 | 'IN' => '$in', 66 | 'NOT' => '$not', 67 | 'NOT IN' => '$nin' 68 | ) 69 | ); 70 | 71 | /** 72 | * setup method 73 | * 74 | * Allow overriding the operator map 75 | * 76 | * @param mixed $Model 77 | * @param array $config array() 78 | * @return void 79 | * @access public 80 | */ 81 | public function setup(&$Model, $config = array()) { 82 | $this->settings[$Model->alias] = array_merge($this->_defaultSettings, $config); 83 | } 84 | 85 | /** 86 | * If requested, convert dates from MongoDate objects to standard date strings 87 | * 88 | * @param mixed $Model 89 | * @param mixed $results 90 | * @param mixed $primary 91 | * @return void 92 | * @access public 93 | */ 94 | public function afterFind(&$Model, $results, $primary) { 95 | if ($this->settings[$Model->alias]['convertDates']) { 96 | $this->convertDates($results); 97 | } 98 | return $results; 99 | } 100 | 101 | /** 102 | * beforeFind method 103 | * 104 | * If conditions are an array ensure they are mongified 105 | * 106 | * @param mixed $Model 107 | * @param mixed $query 108 | * @return void 109 | * @access public 110 | */ 111 | public function beforeFind(&$Model, $query) { 112 | if (is_array($query['conditions']) && $this->_translateConditions($Model, $query['conditions'])) { 113 | return $query; 114 | } 115 | return true; 116 | } 117 | 118 | /** 119 | * Convert MongoDate objects to strings for the purpose of view simplicity 120 | * 121 | * @param mixed $results 122 | * @return void 123 | * @access public 124 | */ 125 | public function convertDates(&$results) { 126 | if (is_array($results)) { 127 | foreach($results as &$row) { 128 | $this->convertDates($row); 129 | } 130 | } elseif (is_a($results, 'MongoDate')) { 131 | $results = date('Y-M-d h:i:s', $results->sec); 132 | } 133 | } 134 | 135 | /** 136 | * translateConditions method 137 | * 138 | * Loop on conditions and desqlify them 139 | * 140 | * @param mixed $Model 141 | * @param mixed $conditions 142 | * @return void 143 | * @access protected 144 | */ 145 | protected function _translateConditions(&$Model, &$conditions) { 146 | $return = false; 147 | foreach($conditions as $key => &$value) { 148 | $uKey = strtoupper($key); 149 | if (substr($uKey, -5) === 'NOT IN') { 150 | // 'Special' case because it has a space in it, and it's the whole key 151 | $conditions[substr($key, 0, -5)]['$nin'] = $value; 152 | unset($conditions[$key]); 153 | $return = true; 154 | continue; 155 | } 156 | if ($uKey === 'OR') { 157 | unset($conditions[$key]); 158 | foreach($value as $key => $part) { 159 | $part = array($key => $part); 160 | $this->_translateConditions($Model, $part); 161 | $conditions['$or'][] = $part; 162 | } 163 | $return = true; 164 | continue; 165 | } 166 | if (substr($uKey, -3) === 'NOT') { 167 | // 'Special' case because it's awkward 168 | $childKey = key($value); 169 | $childValue = current($value); 170 | 171 | if (in_array(substr($childKey, -1), array('>', '<', '='))) { 172 | $parts = explode(' ', $childKey); 173 | $operator = array_pop($parts); 174 | if ($operator = $this->_translateOperator($Model, $operator)) { 175 | $childKey = implode(' ', $parts); 176 | } 177 | } else { 178 | $conditions[$childKey]['$nin'] = (array)$childValue; 179 | unset($conditions['NOT']); 180 | $return = true; 181 | continue; 182 | } 183 | 184 | $conditions[$childKey]['$not'][$operator] = $childValue; 185 | unset($conditions['NOT']); 186 | $return = true; 187 | continue; 188 | } 189 | if (substr($uKey, -5) === ' LIKE') { 190 | // 'Special' case because it's awkward 191 | if ($value[0] === '%') { 192 | $value = substr($value, 1); 193 | } else { 194 | $value = '^' . $value; 195 | } 196 | if (substr($value, -1) === '%') { 197 | $value = substr($value, 0, -1); 198 | } else { 199 | $value .= '$'; 200 | } 201 | $value = str_replace('%', '.*', $value); 202 | 203 | $conditions[substr($key, 0, -5)] = new MongoRegex("/$value/i"); 204 | unset($conditions[$key]); 205 | $return = true; 206 | continue; 207 | } 208 | 209 | if (!in_array(substr($key, -1), array('>', '<', '='))) { 210 | $return = true; 211 | continue; 212 | } 213 | if (is_numeric($key && is_array($value))) { 214 | if ($this->_translateConditions($Model, $value)) { 215 | $return = true; 216 | continue; 217 | } 218 | } 219 | $parts = explode(' ', $key); 220 | $operator = array_pop($parts); 221 | if ($operator = $this->_translateOperator($Model, $operator)) { 222 | $newKey = implode(' ', $parts); 223 | $conditions[$newKey][$operator] = $value; 224 | unset($conditions[$key]); 225 | $return = true; 226 | } 227 | if (is_array($value)) { 228 | if ($this->_translateConditions($Model, $value)) { 229 | $return = true; 230 | continue; 231 | } 232 | } 233 | } 234 | return $return; 235 | } 236 | 237 | /** 238 | * translateOperator method 239 | * 240 | * Use the operator map for the model and return what the db really wants to hear 241 | * 242 | * @param mixed $Model 243 | * @param mixed $operator 244 | * @return string 245 | * @access protected 246 | */ 247 | protected function _translateOperator($Model, $operator) { 248 | if (!empty($this->settings[$Model->alias]['operators'][$operator])) { 249 | return $this->settings[$Model->alias]['operators'][$operator]; 250 | } 251 | return ''; 252 | } 253 | } -------------------------------------------------------------------------------- /models/datasources/mongodb_source.php: -------------------------------------------------------------------------------- 1 | true, 88 | 'persistent' => false, 89 | 'host' => 'localhost', 90 | 'database' => '', 91 | 'port' => '27017', 92 | 'login' => '', 93 | 'password' => '' 94 | ); 95 | 96 | /** 97 | * column definition 98 | * 99 | * @var array 100 | */ 101 | public $columns = array( 102 | 'boolean' => array('name' => 'boolean'), 103 | 'string' => array('name' => 'varchar'), 104 | 'text' => array('name' => 'text'), 105 | 'integer' => array('name' => 'integer', 'format' => null, 'formatter' => 'intval'), 106 | 'float' => array('name' => 'float', 'format' => null, 'formatter' => 'floatval'), 107 | 'datetime' => array('name' => 'datetime', 'format' => null, 'formatter' => 'MongodbDateFormatter'), 108 | 'timestamp' => array('name' => 'timestamp', 'format' => null, 'formatter' => 'MongodbDateFormatter'), 109 | 'time' => array('name' => 'time', 'format' => null, 'formatter' => 'MongodbDateFormatter'), 110 | 'date' => array('name' => 'date', 'format' => null, 'formatter' => 'MongodbDateFormatter'), 111 | ); 112 | 113 | /** 114 | * Default schema for the mongo models 115 | * 116 | * @var array 117 | * @access protected 118 | */ 119 | protected $_defaultSchema = array( 120 | '_id' => array('type' => 'string', 'length' => 24, 'key' => 'primary'), 121 | 'created' => array('type' => 'datetime', 'default' => null) 122 | ); 123 | 124 | /** 125 | * construct method 126 | * 127 | * By default don't try to connect until you need to 128 | * 129 | * @param array $config Configuration array 130 | * @param bool $autoConnect false 131 | * @return void 132 | * @access public 133 | */ 134 | function __construct($config = array(), $autoConnect = false) { 135 | return parent::__construct($config, $autoConnect); 136 | } 137 | 138 | /** 139 | * Destruct 140 | * 141 | * @access public 142 | */ 143 | public function __destruct() { 144 | if ($this->connected) { 145 | $this->disconnect(); 146 | } 147 | } 148 | 149 | /** 150 | * commit method 151 | * 152 | * MongoDB doesn't support transactions 153 | * 154 | * @return void 155 | * @access public 156 | */ 157 | public function commit() { 158 | return false; 159 | } 160 | 161 | /** 162 | * Connect to the database 163 | * 164 | * If using 1.0.2 or above use the mongodb:// format to connect 165 | * The connect syntax changed in version 1.0.2 - so check for that too 166 | * 167 | * If authentication information in present then authenticate the connection 168 | * 169 | * @return boolean Connected 170 | * @access public 171 | */ 172 | public function connect() { 173 | $this->connected = false; 174 | 175 | try{ 176 | if (false && $this->_driverVersion >= '1.0.2' && $this->config['host'] != 'localhost') { 177 | $host = "mongodb://"; 178 | } else { 179 | $host = ''; 180 | } 181 | $host .= $this->config['host'] . ':' . $this->config['port']; 182 | 183 | if (false && $this->_driverVersion >= '1.0.2') { 184 | $this->connection = new Mongo($host, array("persist" => $this->config['persistent'])); 185 | } else { 186 | $this->connection = new Mongo($host, true, $this->config['persistent']); 187 | } 188 | 189 | if ($this->_db = $this->connection->selectDB($this->config['database'])) { 190 | if (!empty($this->config['login'])) { 191 | $return = $this->_db->authenticate($this->config['login'], $this->config['password']); 192 | if (!$return || !$return['ok']) { 193 | trigger_error('MongodbSource::connect ' . $return['errmsg']); 194 | return false; 195 | } 196 | } 197 | $this->connected = true; 198 | } 199 | } catch(MongoException $e) { 200 | $this->error = $e->getMessage(); 201 | trigger_error($this->error); 202 | } 203 | return $this->connected; 204 | } 205 | 206 | /** 207 | * Inserts multiple values into a table 208 | * 209 | * @param string $table 210 | * @param string $fields 211 | * @param array $values 212 | * @access public 213 | */ 214 | public function insertMulti($table, $fields, $values) { 215 | $table = $this->fullTableName($table); 216 | 217 | if (!is_array($fields) || !is_array($values)) { 218 | return false; 219 | } 220 | $data = array(); 221 | foreach($values as $row) { 222 | if (is_string($row)) { 223 | $row = explode(', ', substr($row, 1, -1)); 224 | } 225 | $data[] = array_combine($fields, $row); 226 | } 227 | $this->_prepareLogQuery($table); // just sets a timer 228 | try{ 229 | $return = $this->_db 230 | ->selectCollection($table) 231 | ->batchInsert($data, array('safe' => true)); 232 | } catch (MongoException $e) { 233 | $this->error = $e->getMessage(); 234 | trigger_error($this->error); 235 | } 236 | if ($this->fullDebug) { 237 | $this->logQuery("db.{$table}.insertMulti( :data , array('safe' => true))", compact('data')); 238 | } 239 | } 240 | 241 | /** 242 | * check connection to the database 243 | * 244 | * @return boolean Connected 245 | * @access public 246 | */ 247 | public function isConnected() { 248 | if ($this->connected === false) { 249 | return false; 250 | } 251 | return $this->connect(); 252 | } 253 | 254 | /** 255 | * get MongoDB Object 256 | * 257 | * @return mixed MongoDB Object 258 | * @access public 259 | */ 260 | public function getMongoDb() { 261 | if ($this->connected === false) { 262 | return false; 263 | } 264 | return $this->_db; 265 | } 266 | 267 | /** 268 | * get MongoDB Collection Object 269 | * 270 | * @return mixed MongoDB Collection Object 271 | * @access public 272 | */ 273 | public function getMongoCollection(&$Model) { 274 | if ($this->connected === false) { 275 | return false; 276 | } 277 | 278 | $collection = $this->_db 279 | ->selectCollection($Model->table); 280 | return $collection; 281 | } 282 | 283 | /** 284 | * isInterfaceSupported method 285 | * 286 | * listSources is infact supported, however: cake expects it to return a complete list of all 287 | * possible sources in the selected db - the possible list of collections is infinte, so it's 288 | * faster and simpler to tell cake that the interface is /not/ supported so it assumes that 289 | * exist 290 | * 291 | * @param mixed $interface 292 | * @return void 293 | * @access public 294 | */ 295 | public function isInterfaceSupported($interface) { 296 | if ($interface === 'listSources') { 297 | return false; 298 | } 299 | return parent::isInterfaceSupported($interface); 300 | } 301 | 302 | /** 303 | * Close database connection 304 | * 305 | * @return boolean Connected 306 | * @access public 307 | */ 308 | public function close() { 309 | return $this->disconnect(); 310 | } 311 | 312 | /** 313 | * Disconnect from the database 314 | * 315 | * @return boolean Connected 316 | * @access public 317 | */ 318 | public function disconnect() { 319 | if ($this->connected) { 320 | $this->connected = !$this->connection->close(); 321 | unset($this->_db, $this->connection); 322 | return !$this->connected; 323 | } 324 | return true; 325 | } 326 | 327 | /** 328 | * Get list of available Collections 329 | * 330 | * @param array $data 331 | * @return array Collections 332 | * @access public 333 | */ 334 | public function listSources($data = null) { 335 | if (!$this->isConnected()) { 336 | return false; 337 | } 338 | 339 | $collections = $this->_db->listCollections(); 340 | $sources = array(); 341 | 342 | if(!empty($collections)){ 343 | foreach($collections as $collection){ 344 | $sources[] = $collection->getName(); 345 | } 346 | } 347 | 348 | return $sources; 349 | } 350 | 351 | /** 352 | * Describe 353 | * 354 | * Automatically bind the schemaless behavior if there is no explicit mongo schema. 355 | * When called, if there is model data it will be used to derive a schema. a row is plucked 356 | * out of the db and the data obtained used to derive the schema. 357 | * 358 | * @param Model $Model 359 | * @return array if model instance has mongoSchema, return it. 360 | * @access public 361 | */ 362 | public function describe(&$Model, $field = null) { 363 | $Model->primaryKey = '_id'; 364 | $schema = array(); 365 | if (!empty($Model->mongoSchema) && is_array($Model->mongoSchema)) { 366 | $schema = $Model->mongoSchema; 367 | return $schema + $this->_defaultSchema; 368 | } elseif ($this->isConnected() && is_a($Model, 'Model') && !empty($Model->Behaviors)) { 369 | $Model->Behaviors->attach('Mongodb.Schemaless'); 370 | if (!$Model->data) { 371 | if ($this->_db->selectCollection($Model->table)->count()) { 372 | return $this->deriveSchemaFromData($Model, $this->_db->selectCollection($Model->table)->findOne()); 373 | } 374 | } 375 | } 376 | return $this->deriveSchemaFromData($Model); 377 | } 378 | 379 | /** 380 | * begin method 381 | * 382 | * Mongo doesn't support transactions 383 | * 384 | * @return void 385 | * @access public 386 | */ 387 | public function begin() { 388 | return false; 389 | } 390 | 391 | /** 392 | * Calculate 393 | * 394 | * @param Model $Model 395 | * @return array 396 | * @access public 397 | */ 398 | public function calculate(&$Model) { 399 | return array('count' => true); 400 | } 401 | 402 | /** 403 | * Quotes identifiers. 404 | * 405 | * MongoDb does not need identifiers quoted, so this method simply returns the identifier. 406 | * 407 | * @param string $name The identifier to quote. 408 | * @return string The quoted identifier. 409 | */ 410 | public function name($name) { 411 | return $name; 412 | } 413 | 414 | /** 415 | * Create Data 416 | * 417 | * @param Model $Model Model Instance 418 | * @param array $fields Field data 419 | * @param array $values Save data 420 | * @return boolean Insert result 421 | * @access public 422 | */ 423 | public function create(&$Model, $fields = null, $values = null) { 424 | if (!$this->isConnected()) { 425 | return false; 426 | } 427 | 428 | if ($fields !== null && $values !== null) { 429 | $data = array_combine($fields, $values); 430 | } else { 431 | $data = $Model->data; 432 | } 433 | if (!empty($data['_id'])) { 434 | $this->_convertId($data['_id']); 435 | } 436 | 437 | $this->_prepareLogQuery($Model); // just sets a timer 438 | try{ 439 | $return = $this->_db 440 | ->selectCollection($Model->table) 441 | ->insert($data, true); 442 | } catch (MongoException $e) { 443 | $this->error = $e->getMessage(); 444 | trigger_error($this->error); 445 | } 446 | if ($this->fullDebug) { 447 | $this->logQuery("db.{$Model->useTable}.insert( :data , true)", compact('data')); 448 | } 449 | 450 | if (!empty($return) && $return['ok']) { 451 | $id = is_object($data['_id']) ? $data['_id']->__toString() : null; 452 | $Model->setInsertID($id); 453 | $Model->id = $id; 454 | return true; 455 | } 456 | return false; 457 | } 458 | 459 | /** 460 | * createSchema method 461 | * 462 | * Mongo no care for creating schema. Mongo work with no schema. 463 | * 464 | * @param mixed $schema 465 | * @param mixed $tableName null 466 | * @return void 467 | * @access public 468 | */ 469 | public function createSchema($schema, $tableName = null) { 470 | return true; 471 | } 472 | 473 | /** 474 | * dropSchema method 475 | * 476 | * Return a command to drop each table 477 | * 478 | * @param mixed $schema 479 | * @param mixed $tableName null 480 | * @return void 481 | * @access public 482 | */ 483 | public function dropSchema($schema, $tableName = null) { 484 | if (!$this->isConnected()) { 485 | return false; 486 | } 487 | 488 | if (!is_a($schema, 'CakeSchema')) { 489 | trigger_error(__('Invalid schema object', true), E_USER_WARNING); 490 | return null; 491 | } 492 | if ($tableName) { 493 | return "db.{$tableName}.drop();"; 494 | } 495 | 496 | $toDrop = array(); 497 | foreach ($schema->tables as $curTable => $columns) { 498 | if ($tableName === $curTable) { 499 | $toDrop[] = $curTable; 500 | } 501 | } 502 | 503 | if (count($toDrop) === 1) { 504 | return "db.{$toDrop[0]}.drop();"; 505 | } 506 | 507 | $return = "toDrop = :tables;\nfor( i = 0; i < toDrop.length; i++ ) {\n\tdb[toDrop[i]].drop();\n}"; 508 | $tables = '["' . implode($toDrop, '", "') . '"]'; 509 | 510 | return String::insert($return, compact('tables')); 511 | } 512 | 513 | /** 514 | * distinct method 515 | * 516 | * @param mixed $Model 517 | * @param array $keys array() 518 | * @param array $params array() 519 | * @return void 520 | * @access public 521 | */ 522 | public function distinct(&$Model, $keys = array(), $params = array()) { 523 | if (!$this->isConnected()) { 524 | return false; 525 | } 526 | 527 | $this->_prepareLogQuery($Model); // just sets a timer 528 | 529 | if (array_key_exists('conditions', $params)) { 530 | $params = $params['conditions']; 531 | } 532 | try{ 533 | $return = $this->_db 534 | ->selectCollection($Model->table) 535 | ->distinct($keys, $params); 536 | } catch (MongoException $e) { 537 | $this->error = $e->getMessage(); 538 | trigger_error($this->error); 539 | } 540 | if ($this->fullDebug) { 541 | $this->logQuery("db.{$Model->useTable}.distinct( :keys, :params )", compact('keys', 'params')); 542 | } 543 | 544 | return $return; 545 | } 546 | 547 | 548 | /** 549 | * group method 550 | * 551 | * @param mixed $Model 552 | * @param array $params array() 553 | * Set params same as MongoCollection::group() 554 | * key,initial, reduce, options(conditions, finalize) 555 | * 556 | * Ex. $params = array( 557 | * 'key' => array('field' => true), 558 | * 'initial' => array('csum' => 0), 559 | * 'reduce' => 'function(obj, prev){prev.csum += 1;}', 560 | * 'options' => array( 561 | * 'condition' => array('age' => array('$gt' => 20)), 562 | * 'finalize' => array(), 563 | * ), 564 | * ); 565 | * @return void 566 | * @access public 567 | */ 568 | public function group(&$Model, $params = array()) { 569 | 570 | if (!$this->isConnected() || count($params) === 0 ) { 571 | return false; 572 | } 573 | 574 | $this->_prepareLogQuery($Model); // just sets a timer 575 | 576 | $key = (empty($params['key'])) ? array() : $params['key']; 577 | $initial = (empty($params['initial'])) ? array() : $params['initial']; 578 | $reduce = (empty($params['reduce'])) ? array() : $params['reduce']; 579 | $options = (empty($params['options'])) ? array() : $params['options']; 580 | 581 | try{ 582 | $return = $this->_db 583 | ->selectCollection($Model->table) 584 | ->group($key, $initial, $reduce, $options); 585 | } catch (MongoException $e) { 586 | $this->error = $e->getMessage(); 587 | trigger_error($this->error); 588 | } 589 | if ($this->fullDebug) { 590 | $this->logQuery("db.{$Model->useTable}.group( :key, :initial, :reduce, :options )", $params); 591 | } 592 | 593 | 594 | return $return; 595 | } 596 | 597 | 598 | /** 599 | * ensureIndex method 600 | * 601 | * @param mixed $Model 602 | * @param array $keys array() 603 | * @param array $params array() 604 | * @return void 605 | * @access public 606 | */ 607 | public function ensureIndex(&$Model, $keys = array(), $params = array()) { 608 | if (!$this->isConnected()) { 609 | return false; 610 | } 611 | 612 | $this->_prepareLogQuery($Model); // just sets a timer 613 | 614 | try{ 615 | $return = $this->_db 616 | ->selectCollection($Model->table) 617 | ->ensureIndex($keys, $params); 618 | } catch (MongoException $e) { 619 | $this->error = $e->getMessage(); 620 | trigger_error($this->error); 621 | } 622 | if ($this->fullDebug) { 623 | $this->logQuery("db.{$Model->useTable}.ensureIndex( :keys, :params )", compact('keys', 'params')); 624 | } 625 | 626 | return $return; 627 | } 628 | 629 | /** 630 | * Update Data 631 | * 632 | * This method uses $set operator automatically with MongoCollection::update(). 633 | * If you don't want to use $set operator, you can chose any one as follw. 634 | * 1. Set TRUE in Model::mongoNoSetOperator property. 635 | * 2. Set a mongodb operator in a key of save data as follow. 636 | * Model->save(array('_id' => $id, '$inc' => array('count' => 1))); 637 | * Don't use Model::mongoSchema property, 638 | * CakePHP delete '$inc' data in Model::Save(). 639 | * 3. Set a Mongo operator in Model::mongoNoSetOperator property. 640 | * Model->mongoNoSetOperator = '$inc'; 641 | * Model->save(array('_id' => $id, array('count' => 1))); 642 | * 643 | * @param Model $Model Model Instance 644 | * @param array $fields Field data 645 | * @param array $values Save data 646 | * @return boolean Update result 647 | * @access public 648 | */ 649 | public function update(&$Model, $fields = null, $values = null, $conditions = null) { 650 | 651 | if (!$this->isConnected()) { 652 | return false; 653 | } 654 | 655 | if ($fields !== null && $values !== null) { 656 | $data = array_combine($fields, $values); 657 | } elseif($fields !== null && $conditions !== null) { 658 | return $this->updateAll($Model, $fields, $conditions); 659 | } else{ 660 | $data = $Model->data; 661 | } 662 | 663 | if (empty($data['_id'])) { 664 | $data['_id'] = $Model->id; 665 | } 666 | $this->_convertId($data['_id']); 667 | 668 | try{ 669 | $mongoCollectionObj = $this->_db 670 | ->selectCollection($Model->table); 671 | } catch (MongoException $e) { 672 | $this->error = $e->getMessage(); 673 | trigger_error($this->error); 674 | return false; 675 | } 676 | 677 | $this->_prepareLogQuery($Model); // just sets a timer 678 | if (!empty($data['_id'])) { 679 | $this->_convertId($data['_id']); 680 | $cond = array('_id' => $data['_id']); 681 | unset($data['_id']); 682 | 683 | //setting Mongo operator 684 | if(empty($Model->mongoNoSetOperator)) { 685 | $keys = array_keys($data); 686 | if(substr($keys[0],0,1) !== '$') { 687 | $data = array('$set' => $data); 688 | } 689 | } elseif(substr($Model->mongoNoSetOperator,0,1) === '$') { 690 | if(!empty($data['modified'])) { 691 | $modified = $data['modified']; 692 | unset($data['modified']); 693 | $data = array($Model->mongoNoSetOperator => $data, '$set' => array('modified' => $modified)); 694 | } else { 695 | $data = array($Model->mongoNoSetOperator => $data); 696 | 697 | } 698 | } 699 | 700 | 701 | try{ 702 | $return = $mongoCollectionObj->update($cond, $data, array("multiple" => false)); 703 | } catch (MongoException $e) { 704 | $this->error = $e->getMessage(); 705 | trigger_error($this->error); 706 | } 707 | if ($this->fullDebug) { 708 | $this->logQuery("db.{$Model->useTable}.update( :conditions, :data, :params )", 709 | array('conditions' => $cond, 'data' => $data, 'params' => array("multiple" => false)) 710 | ); 711 | } 712 | } else { 713 | try{ 714 | $return = $mongoCollectionObj->save($data); 715 | } catch (MongoException $e) { 716 | $this->error = $e->getMessage(); 717 | trigger_error($this->error); 718 | } 719 | if ($this->fullDebug) { 720 | $this->logQuery("db.{$Model->useTable}.save( :data )", compact('data')); 721 | } 722 | } 723 | return $return; 724 | } 725 | 726 | /** 727 | * Update multiple Record 728 | * 729 | * @param Model $Model Model Instance 730 | * @param array $fields Field data 731 | * @param array $conditions 732 | * @return boolean Update result 733 | * @access public 734 | */ 735 | public function updateAll(&$Model, $fields = null, $conditions = null) { 736 | if (!$this->isConnected()) { 737 | return false; 738 | } 739 | 740 | $fields = array('$set' => $fields); 741 | 742 | $this->_stripAlias($conditions, $Model->alias); 743 | $this->_stripAlias($fields, $Model->alias, false, 'value'); 744 | 745 | $this->_prepareLogQuery($Model); // just sets a timer 746 | try{ 747 | $return = $this->_db 748 | ->selectCollection($Model->table) 749 | ->update($conditions, $fields, array("multiple" => true)); 750 | } catch (MongoException $e) { 751 | $this->error = $e->getMessage(); 752 | trigger_error($this->error); 753 | } 754 | 755 | if ($this->fullDebug) { 756 | $this->logQuery("db.{$Model->useTable}.update( :fields, :params )", 757 | array('fields' => $fields, 'params' => array("multiple" => true)) 758 | ); 759 | } 760 | return $return; 761 | } 762 | 763 | /** 764 | * deriveSchemaFromData method 765 | * 766 | * @param mixed $Model 767 | * @param array $data array() 768 | * @return void 769 | * @access public 770 | */ 771 | public function deriveSchemaFromData($Model, $data = array()) { 772 | if (!$data) { 773 | $data = $Model->data; 774 | if ($data && array_key_exists($Model->alias, $data)) { 775 | $data = $data[$Model->alias]; 776 | } 777 | } 778 | 779 | $return = $this->_defaultSchema; 780 | 781 | if ($data) { 782 | $fields = array_keys($data); 783 | foreach($fields as $field) { 784 | if (in_array($field, array('created', 'modified', 'updated'))) { 785 | $return[$field] = array('type' => 'datetime', 'null' => true); 786 | } else { 787 | $return[$field] = array('type' => 'string', 'length' => 2000); 788 | } 789 | } 790 | } 791 | 792 | return $return; 793 | } 794 | 795 | /** 796 | * Delete Data 797 | * 798 | * For deleteAll(true, false) calls - conditions will arrive here as true - account for that and 799 | * convert to an empty array 800 | * For deleteAll(array('some conditions')) calls - conditions will arrive here as: 801 | * array( 802 | * Alias._id => array(1, 2, 3, ...) 803 | * ) 804 | * 805 | * This format won't be understood by mongodb, it'll find 0 rows. convert to: 806 | * 807 | * array( 808 | * Alias._id => array('$in' => array(1, 2, 3, ...)) 809 | * ) 810 | * 811 | * @TODO bench remove() v drop. if it's faster to drop - just drop the collection taking into 812 | * account existing indexes (recreate just the indexes) 813 | * @param Model $Model Model Instance 814 | * @param array $conditions 815 | * @return boolean Update result 816 | * @access public 817 | */ 818 | public function delete(&$Model, $conditions = null) { 819 | if (!$this->isConnected()) { 820 | return false; 821 | } 822 | 823 | $id = null; 824 | 825 | $this->_stripAlias($conditions, $Model->alias); 826 | 827 | if ($conditions === true) { 828 | $conditions = array(); 829 | } elseif (empty($conditions)) { 830 | $id = $Model->id; 831 | } elseif (!empty($conditions) && !is_array($conditions)) { 832 | $id = $conditions; 833 | $conditions = array(); 834 | } 835 | 836 | $mongoCollectionObj = $this->_db 837 | ->selectCollection($Model->table); 838 | 839 | $this->_stripAlias($conditions, $Model->alias); 840 | if (!empty($id)) { 841 | $conditions['_id'] = $id; 842 | } 843 | if (!empty($conditions['_id'])) { 844 | $this->_convertId($conditions['_id'], true); 845 | } 846 | 847 | $return = false; 848 | $r = false; 849 | try{ 850 | $this->_prepareLogQuery($Model); // just sets a timer 851 | $return = $mongoCollectionObj->remove($conditions); 852 | if ($this->fullDebug) { 853 | $this->logQuery("db.{$Model->useTable}.remove( :conditions )", 854 | compact('conditions') 855 | ); 856 | } 857 | $return = true; 858 | } catch (MongoException $e) { 859 | $this->error = $e->getMessage(); 860 | trigger_error($this->error); 861 | } 862 | return $return; 863 | } 864 | 865 | /** 866 | * Read Data 867 | * 868 | * For deleteAll(true) calls - the conditions will arrive here as true - account for that and switch to an empty array 869 | * 870 | * @param Model $Model Model Instance 871 | * @param array $query Query data 872 | * @return array Results 873 | * @access public 874 | */ 875 | public function read(&$Model, $query = array()) { 876 | if (!$this->isConnected()) { 877 | return false; 878 | } 879 | 880 | $this->_setEmptyValues($query); 881 | extract($query); 882 | 883 | if (!empty($order[0])) { 884 | $order = array_shift($order); 885 | } 886 | $this->_stripAlias($conditions, $Model->alias); 887 | $this->_stripAlias($fields, $Model->alias, false, 'value'); 888 | $this->_stripAlias($order, $Model->alias, false, 'both'); 889 | 890 | if (!empty($conditions['_id'])) { 891 | $this->_convertId($conditions['_id']); 892 | } 893 | 894 | $fields = (is_array($fields)) ? $fields : array($fields => 1); 895 | if ($conditions === true) { 896 | $conditions = array(); 897 | } elseif (!is_array($conditions)) { 898 | $conditions = array($conditions); 899 | } 900 | $order = (is_array($order)) ? $order : array($order); 901 | 902 | if (is_array($order)) { 903 | foreach($order as $field => &$dir) { 904 | if (is_numeric($field) || is_null($dir)) { 905 | unset ($order[$field]); 906 | continue; 907 | } 908 | if ($dir && strtoupper($dir) === 'ASC') { 909 | $dir = 1; 910 | continue; 911 | } elseif (!$dir || strtoupper($dir) === 'DESC') { 912 | $dir = -1; 913 | continue; 914 | } 915 | $dir = (int)$dir; 916 | } 917 | } 918 | 919 | if (empty($offset) && $page && $limit) { 920 | $offset = ($page - 1) * $limit; 921 | } 922 | 923 | $return = array(); 924 | 925 | $this->_prepareLogQuery($Model); // just sets a timer 926 | if (empty($modify)) { 927 | if ($Model->findQueryType === 'count' && $fields == array('count' => true)) { 928 | $count = $this->_db 929 | ->selectCollection($Model->table) 930 | ->count($conditions); 931 | if ($this->fullDebug) { 932 | $this->logQuery("db.{$Model->useTable}.count( :conditions )", 933 | compact('conditions', 'count') 934 | ); 935 | } 936 | return array(array($Model->alias => array('count' => $count))); 937 | } 938 | 939 | $return = $this->_db 940 | ->selectCollection($Model->table) 941 | ->find($conditions, $fields) 942 | ->sort($order) 943 | ->limit($limit) 944 | ->skip($offset); 945 | if ($this->fullDebug) { 946 | $count = $return->count(); 947 | $this->logQuery("db.{$Model->useTable}.find( :conditions, :fields ).sort( :order ).limit( :limit ).skip( :offset )", 948 | compact('conditions', 'fields', 'order', 'limit', 'offset', 'count') 949 | ); 950 | } 951 | } else { 952 | $options = array_filter(array( 953 | 'findandmodify' => $Model->table, 954 | 'query' => $conditions, 955 | 'sort' => $order, 956 | 'remove' => !empty($remove), 957 | 'update' => array('$set' => $modify), 958 | 'new' => !empty($new), 959 | 'fields' => $fields, 960 | 'upsert' => !empty($upsert) 961 | )); 962 | $return = $this->_db 963 | ->command($options); 964 | if ($this->fullDebug) { 965 | if ($return['ok']) { 966 | $count = 1; 967 | if ($this->config['set_string_id'] && !empty($return['value']['_id']) && is_object($return['value']['_id'])) { 968 | $return['value']['_id'] = $return['value']['_id']->__toString(); 969 | } 970 | $return[][$Model->alias] = $return['value']; 971 | } else { 972 | $count = 0; 973 | } 974 | $this->logQuery("db.runCommand( :options )", 975 | array('options' => array_filter($options), 'count' => $count) 976 | ); 977 | } 978 | } 979 | 980 | if ($Model->findQueryType === 'count') { 981 | return array(array($Model->alias => array('count' => $return->count()))); 982 | } 983 | 984 | if (is_object($return)) { 985 | $_return = array(); 986 | while ($return->hasNext()) { 987 | $mongodata = $return->getNext(); 988 | if ($this->config['set_string_id'] && !empty($mongodata['_id']) && is_object($mongodata['_id'])) { 989 | $mongodata['_id'] = $mongodata['_id']->__toString(); 990 | } 991 | $_return[][$Model->alias] = $mongodata; 992 | } 993 | return $_return; 994 | } 995 | return $return; 996 | } 997 | 998 | /** 999 | * rollback method 1000 | * 1001 | * MongoDB doesn't support transactions 1002 | * 1003 | * @return void 1004 | * @access public 1005 | */ 1006 | public function rollback() { 1007 | return false; 1008 | } 1009 | 1010 | /** 1011 | * Deletes all the records in a table 1012 | * 1013 | * @param mixed $table A string or model class representing the table to be truncated 1014 | * @return boolean 1015 | * @access public 1016 | */ 1017 | public function truncate($table) { 1018 | if (!$this->isConnected()) { 1019 | return false; 1020 | } 1021 | 1022 | return $this->execute('db.' . $this->fullTableName($table) . '.remove();'); 1023 | } 1024 | 1025 | /** 1026 | * query method 1027 | * If call getMongoDb() from model, this method call getMongoDb(). 1028 | * 1029 | * @param mixed $query 1030 | * @param array $params array() 1031 | * @return void 1032 | * @access public 1033 | */ 1034 | public function query($query, $params = array()) { 1035 | if (!$this->isConnected()) { 1036 | return false; 1037 | } 1038 | 1039 | if($query === 'getMongoDb') { 1040 | return $this->getMongoDb(); 1041 | } 1042 | 1043 | $this->_prepareLogQuery($Model); // just sets a timer 1044 | $return = $this->_db 1045 | ->command($query); 1046 | if ($this->fullDebug) { 1047 | $this->logQuery("db.runCommand( :query )", compact('query')); 1048 | } 1049 | 1050 | return $return; 1051 | } 1052 | 1053 | /** 1054 | * getMapReduceResults 1055 | * 1056 | * @param mixed $query 1057 | * @return void 1058 | * @access public 1059 | */ 1060 | public function getMapReduceResults($query) { 1061 | 1062 | $result = $this->query($query); 1063 | if($result['ok']) { 1064 | $data = $this->_db->selectCollection($result['result'])->find(); 1065 | return $data; 1066 | } 1067 | return false; 1068 | } 1069 | 1070 | 1071 | 1072 | /** 1073 | * Prepares a value, or an array of values for database queries by quoting and escaping them. 1074 | * 1075 | * @param mixed $data A value or an array of values to prepare. 1076 | * @param string $column The column into which this data will be inserted 1077 | * @param boolean $read Value to be used in READ or WRITE context 1078 | * @return mixed Prepared value or array of values. 1079 | * @access public 1080 | */ 1081 | public function value($data, $column = null, $read = true) { 1082 | $return = parent::value($data, $column, $read); 1083 | if ($return === null && $data !== null) { 1084 | return $data; 1085 | } 1086 | return $return; 1087 | } 1088 | 1089 | /** 1090 | * execute method 1091 | * 1092 | * If there is no query or the query is true, execute has probably been called as part of a 1093 | * db-agnostic process which does not have a mongo equivalent, don't do anything. 1094 | * 1095 | * @param mixed $query 1096 | * @param array $params array() 1097 | * @return void 1098 | * @access public 1099 | */ 1100 | public function execute($query, $params = array()) { 1101 | if (!$this->isConnected()) { 1102 | return false; 1103 | } 1104 | 1105 | if (!$query || $query === true) { 1106 | return; 1107 | } 1108 | $this->_prepareLogQuery($Model); // just sets a timer 1109 | $return = $this->_db 1110 | ->execute($query, $params); 1111 | if ($this->fullDebug) { 1112 | if ($params) { 1113 | $this->logQuery(":query, :params", 1114 | compact('query', 'params') 1115 | ); 1116 | } else { 1117 | $this->logQuery($query); 1118 | } 1119 | } 1120 | if ($return['ok']) { 1121 | return $return['retval']; 1122 | } 1123 | return $return; 1124 | } 1125 | 1126 | /** 1127 | * Set empty values, arrays or integers, for the variables Mongo uses 1128 | * 1129 | * @param mixed $data 1130 | * @param array $integers array('limit', 'offset') 1131 | * @return void 1132 | * @access protected 1133 | */ 1134 | protected function _setEmptyValues(&$data, $integers = array('limit', 'offset')) { 1135 | if (!is_array($data)) { 1136 | return; 1137 | } 1138 | foreach($data as $key => $value) { 1139 | if (empty($value)) { 1140 | if (in_array($key, $integers)) { 1141 | $data[$key] = 0; 1142 | } else { 1143 | $data[$key] = array(); 1144 | } 1145 | } 1146 | } 1147 | } 1148 | 1149 | /** 1150 | * prepareLogQuery method 1151 | * 1152 | * Any prep work to log a query 1153 | * 1154 | * @param mixed $Model 1155 | * @return void 1156 | * @access protected 1157 | */ 1158 | protected function _prepareLogQuery(&$Model) { 1159 | if (!$this->fullDebug) { 1160 | return false; 1161 | } 1162 | $this->_startTime = microtime(true); 1163 | $this->took = null; 1164 | $this->affected = null; 1165 | $this->error = null; 1166 | $this->numRows = null; 1167 | return true; 1168 | } 1169 | 1170 | /** 1171 | * logQuery method 1172 | * 1173 | * Set timers, errors and refer to the parent 1174 | * If there are arguments passed - inject them into the query 1175 | * Show MongoIds in a copy-and-paste-into-mongo format 1176 | * 1177 | * 1178 | * @param mixed $query 1179 | * @param array $args array() 1180 | * @return void 1181 | * @access public 1182 | */ 1183 | public function logQuery($query, $args = array()) { 1184 | if ($args) { 1185 | $this->_stringify($args); 1186 | $query = String::insert($query, $args); 1187 | } 1188 | $this->took = round((microtime(true) - $this->_startTime) * 1000, 0); 1189 | $this->affected = null; 1190 | if (empty($this->error['err'])) { 1191 | $this->error = $this->_db->lastError(); 1192 | if (!is_scalar($this->error)) { 1193 | $this->error = json_encode($this->error); 1194 | } 1195 | } 1196 | $this->numRows = !empty($args['count'])?$args['count']:null; 1197 | 1198 | $query = preg_replace('@"ObjectId\((.*?)\)"@', 'ObjectId ("\1")', $query); 1199 | return parent::logQuery($query); 1200 | } 1201 | 1202 | /** 1203 | * convertId method 1204 | * 1205 | * $conditions is used to determine if it should try to auto correct _id => array() queries 1206 | * it only appies to conditions, hence the param name 1207 | * 1208 | * @param mixed $mixed 1209 | * @param bool $conditions false 1210 | * @return void 1211 | * @access protected 1212 | */ 1213 | protected function _convertId(&$mixed, $conditions = false) { 1214 | if (is_string($mixed)) { 1215 | if (strlen($mixed) !== 24) { 1216 | return; 1217 | } 1218 | $mixed = new MongoId($mixed); 1219 | } 1220 | if (is_array($mixed)) { 1221 | foreach($mixed as &$row) { 1222 | $this->_convertId($row, false); 1223 | } 1224 | if (!empty($mixed[0]) && $conditions) { 1225 | $mixed = array('$in' => $mixed); 1226 | } 1227 | } 1228 | } 1229 | 1230 | /** 1231 | * stringify method 1232 | * 1233 | * Takes an array of args as an input and returns an array of json-encoded strings. Takes care of 1234 | * any objects the arrays might be holding (MongoID); 1235 | * 1236 | * @param array $args array() 1237 | * @param int $level 0 internal recursion counter 1238 | * @return array 1239 | * @access protected 1240 | */ 1241 | protected function _stringify(&$args = array(), $level = 0) { 1242 | foreach($args as &$arg) { 1243 | if (is_array($arg)) { 1244 | $this->_stringify($arg, $level + 1); 1245 | } elseif (is_object($arg) && is_callable(array($arg, '__toString'))) { 1246 | $class = get_class($arg); 1247 | if ($class === 'MongoId') { 1248 | $arg = 'ObjectId(' . $arg->__toString() . ')'; 1249 | } elseif ($class === 'MongoRegex') { 1250 | $arg = '_regexstart_' . $arg->__toString() . '_regexend_'; 1251 | } else { 1252 | $arg = $class . '(' . $arg->__toString() . ')'; 1253 | } 1254 | } 1255 | if ($level === 0) { 1256 | $arg = json_encode($arg); 1257 | if (strpos($arg, '_regexstart_')) { 1258 | preg_match_all('@"_regexstart_(.*?)_regexend_"@', $arg, $matches); 1259 | foreach($matches[0] as $i => $whole) { 1260 | $replace = stripslashes($matches[1][$i]); 1261 | $arg = str_replace($whole, $replace, $arg); 1262 | } 1263 | } 1264 | } 1265 | } 1266 | } 1267 | 1268 | /** 1269 | * Convert automatically array('Model.field' => 'foo') to array('field' => 'foo') 1270 | * 1271 | * This introduces the limitation that you can't have a (nested) field with the same name as the model 1272 | * But it's a small price to pay to be able to use other behaviors/functionality with mongoDB 1273 | * 1274 | * @param array $args array() 1275 | * @param string $alias 'Model' 1276 | * @param bool $recurse true 1277 | * @param string $check 'key', 'value' or 'both' 1278 | * @return void 1279 | * @access protected 1280 | */ 1281 | protected function _stripAlias(&$args = array(), $alias = 'Model', $recurse = true, $check = 'key') { 1282 | if (!is_array($args)) { 1283 | return; 1284 | } 1285 | $checkKey = ($check === 'key' || $check === 'both'); 1286 | $checkValue = ($check === 'value' || $check === 'both'); 1287 | 1288 | foreach($args as $key => &$val) { 1289 | if ($checkKey) { 1290 | if (strpos($key, $alias . '.') === 0) { 1291 | unset($args[$key]); 1292 | $key = substr($key, strlen($alias) + 1); 1293 | $args[$key] = $val; 1294 | } 1295 | } 1296 | if ($checkValue) { 1297 | if (is_string($val) && strpos($val, $alias . '.') === 0) { 1298 | $val = substr($val, strlen($alias) + 1); 1299 | } 1300 | } 1301 | if ($recurse && is_array($val)) { 1302 | $this->_stripAlias($val, $alias, true, $check); 1303 | } 1304 | } 1305 | } 1306 | } 1307 | 1308 | /** 1309 | * MongoDbDateFormatter method 1310 | * 1311 | * This function cannot be in the class because of the way model save is written 1312 | * 1313 | * @param mixed $date null 1314 | * @return void 1315 | * @access public 1316 | */ 1317 | function MongoDbDateFormatter($date = null) { 1318 | if ($date) { 1319 | return new MongoDate($date); 1320 | } 1321 | return new MongoDate(); 1322 | } 1323 | -------------------------------------------------------------------------------- /samples/controllers/geos_controller.php: -------------------------------------------------------------------------------- 1 | 35, 29 | 'page' => 1, 30 | ); 31 | 32 | if(!empty($type) && !empty($lat) && !empty($long)) { 33 | $lat = floatval($lat); 34 | $long = floatval($long); 35 | $opt1 = floatval($opt1); 36 | $opt2 = floatval($opt2); 37 | 38 | switch($type) { 39 | case('near'): 40 | if(!empty($opt1)){ 41 | $cond = array('loc' => array('$near' => array($lat, $long), '$maxDistance' => $opt1)); 42 | } else { 43 | $cond = array('loc' => array('$near' => array($lat, $long))); 44 | } 45 | break; 46 | case('box'): 47 | $lowerLeft = array($lat, $long); 48 | $upperRight = array($opt1, $opt2); 49 | $cond = array('loc' => array('$within' => array('$box' => array($lowerLeft, $upperRight)))); 50 | break; 51 | case('circle'): 52 | $center = array($lat, $long); 53 | $radius = $opt1; 54 | $cond = array('loc' => array('$within' => array('$center' => array($center, $radius)))); 55 | break; 56 | } 57 | $params['conditions'] = $cond; 58 | 59 | } else { 60 | $params['order'] = array('_id' => -1); 61 | } 62 | 63 | $results = $this->Geo->find('all', $params); 64 | $this->set(compact('results')); 65 | } 66 | 67 | /** 68 | * add method 69 | * 70 | * @return void 71 | * @access public 72 | */ 73 | public function add() { 74 | if (!empty($this->data)) { 75 | 76 | $this->Geo->create(); 77 | if ($this->Geo->save($this->data)) { 78 | $this->flash(__('Geo saved.', true), array('action' => 'index')); 79 | } else { 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * delete method 86 | * 87 | * @param mixed $id null 88 | * @return void 89 | * @access public 90 | */ 91 | public function delete($id = null) { 92 | if (!$id) { 93 | $this->flash(__('Invalid Geo', true), array('action' => 'index')); 94 | } 95 | if ($this->Geo->delete($id)) { 96 | $this->flash(__('Geo deleted', true), array('action' => 'index')); 97 | } else { 98 | $this->flash(__('Geo deleted Fail', true), array('action' => 'index')); 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /samples/controllers/posts_controller.php: -------------------------------------------------------------------------------- 1 | array('title', 'body', 'hoge'), 30 | //'fields' => array('Post.title', ), 31 | //'conditions' => array('title' => 'hehe'), 32 | //'conditions' => array('hoge' => array('$gt' => '10', '$lt' => '34')), 33 | //'order' => array('title' => 1, 'body' => 1), 34 | 'order' => array('_id' => -1), 35 | 'limit' => 35, 36 | 'page' => 1, 37 | ); 38 | $results = $this->Post->find('all', $params); 39 | //$result = $this->Post->find('count', $params); 40 | $this->set(compact('results')); 41 | } 42 | 43 | /** 44 | * add method 45 | * 46 | * @return void 47 | * @access public 48 | */ 49 | public function add() { 50 | if (!empty($this->data)) { 51 | 52 | $this->Post->create(); 53 | if ($this->Post->save($this->data)) { 54 | $this->flash(__('Post saved.', true), array('action' => 'index')); 55 | } else { 56 | } 57 | } 58 | } 59 | 60 | /** 61 | * edit method 62 | * 63 | * @param mixed $id null 64 | * @return void 65 | * @access public 66 | */ 67 | public function edit($id = null) { 68 | if (!$id && empty($this->data)) { 69 | $this->flash(__('Invalid Post', true), array('action' => 'index')); 70 | } 71 | if (!empty($this->data)) { 72 | 73 | if ($this->Post->save($this->data)) { 74 | $this->flash(__('The Post has been saved.', true), array('action' => 'index')); 75 | } else { 76 | } 77 | } 78 | if (empty($this->data)) { 79 | $this->data = $this->Post->read(null, $id); 80 | //$this->data = $this->Post->find('first', array('conditions' => array('_id' => $id))); 81 | } 82 | } 83 | 84 | /** 85 | * delete method 86 | * 87 | * @param mixed $id null 88 | * @return void 89 | * @access public 90 | */ 91 | public function delete($id = null) { 92 | if (!$id) { 93 | $this->flash(__('Invalid Post', true), array('action' => 'index')); 94 | } 95 | if ($this->Post->delete($id)) { 96 | $this->flash(__('Post deleted', true), array('action' => 'index')); 97 | } else { 98 | $this->flash(__('Post deleted Fail', true), array('action' => 'index')); 99 | } 100 | } 101 | 102 | /** 103 | * deleteall method 104 | * 105 | * @return void 106 | * @access public 107 | */ 108 | public function deleteall() { 109 | $conditions = array('title' => 'aa'); 110 | if ($this->Post->deleteAll($conditions)) { 111 | $this->flash(__('Post deleteAll success', true), array('action' => 'index')); 112 | 113 | } else { 114 | $this->flash(__('Post deleteAll Fail', true), array('action' => 'index')); 115 | } 116 | } 117 | 118 | /** 119 | * updateall method 120 | * 121 | * @return void 122 | * @access public 123 | */ 124 | public function updateall() { 125 | $conditions = array('title' => 'ichi2' ); 126 | 127 | $field = array('title' => 'ichi' ); 128 | 129 | if ($this->Post->updateAll($field, $conditions)) { 130 | $this->flash(__('Post updateAll success', true), array('action' => 'index')); 131 | 132 | } else { 133 | $this->flash(__('Post updateAll Fail', true), array('action' => 'index')); 134 | } 135 | } 136 | 137 | public function createindex() { 138 | $mongo = ConnectionManager::getDataSource($this->Post->useDbConfig); 139 | $mongo->ensureIndex($this->Post, array('title' => 1)); 140 | 141 | } 142 | } -------------------------------------------------------------------------------- /samples/controllers/subdocuments_controller.php: -------------------------------------------------------------------------------- 1 | array('_id' => -1), 28 | 'limit' => 35, 29 | 'page' => 1, 30 | ); 31 | $results = $this->Subdocument->find('all', $params); 32 | $this->set(compact('results')); 33 | } 34 | 35 | /** 36 | * add method 37 | * 38 | * @return void 39 | * @access public 40 | */ 41 | public function add() { 42 | if (!empty($this->data)) { 43 | $this->Subdocument->create(); 44 | if ($this->Subdocument->save($this->data)) { 45 | $this->flash(__('Subdocument saved.', true), array('action' => 'index')); 46 | } else { 47 | } 48 | } 49 | } 50 | 51 | /** 52 | * edit method 53 | * 54 | * @param mixed $id null 55 | * @return void 56 | * @access public 57 | */ 58 | public function edit($id = null) { 59 | if (!$id && empty($this->data)) { 60 | $this->flash(__('Invalid Subdocument', true), array('action' => 'index')); 61 | } 62 | if (!empty($this->data)) { 63 | 64 | if ($this->Subdocument->save($this->data)) { 65 | $this->flash(__('The Subdocument has been saved.', true), array('action' => 'index')); 66 | } else { 67 | } 68 | } 69 | if (empty($this->data)) { 70 | $this->data = $this->Subdocument->read(null, $id); 71 | } 72 | } 73 | 74 | /** 75 | * delete method 76 | * 77 | * @param mixed $id null 78 | * @return void 79 | * @access public 80 | */ 81 | public function delete($id = null) { 82 | if (!$id) { 83 | $this->flash(__('Invalid Subdocument', true), array('action' => 'index')); 84 | } 85 | if ($this->Subdocument->delete($id)) { 86 | $this->flash(__('Subdocument deleted', true), array('action' => 'index')); 87 | } else { 88 | $this->flash(__('Subdocument deleted Fail', true), array('action' => 'index')); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /samples/models/geo.php: -------------------------------------------------------------------------------- 1 | array('type'=>'string'), 7 | 'body'=>array('type'=>'string'), 8 | 'loc'=>array( 9 | 'lat' => array('type'=>'float'), 10 | 'long' => array('type'=>'float'), 11 | ), 12 | 'created'=>array('type'=>'datetime'), 13 | 'modified'=>array('type'=>'datetime'), 14 | ); 15 | */ 16 | 17 | function beforeSave() { 18 | if(!empty($this->data[$this->alias]['loc'])) { 19 | //convert location info from string to float 20 | $this->data[$this->alias]['loc']['lat'] = floatval($this->data[$this->alias]['loc']['lat']); 21 | $this->data[$this->alias]['loc']['long'] = floatval($this->data[$this->alias]['loc']['long']); 22 | } 23 | return true; 24 | } 25 | 26 | 27 | function afterSave($created) { 28 | //create Gespatial Index 29 | $mongo = $this->getDataSource(); 30 | $mongo->ensureIndex($this, array('loc' => "2d")); 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /samples/models/post.php: -------------------------------------------------------------------------------- 1 | array('type'=>'string'), 8 | 'body'=>array('type'=>'string'), 9 | 'hoge'=>array('type'=>'string'), 10 | 'created'=>array('type'=>'datetime'), 11 | 'modified'=>array('type'=>'datetime'), 12 | ); 13 | */ 14 | } -------------------------------------------------------------------------------- /samples/models/subdocument.php: -------------------------------------------------------------------------------- 1 | array('type'=>'string'), 6 | 'body'=>array('type'=>'string'), 7 | 'subdoc'=>array( 8 | 'name' => array('type'=>'string'), 9 | 'age' => array('type'=>'integer') 10 | ), 11 | 'created'=>array('type'=>'datetime'), 12 | 'modified'=>array('type'=>'datetime'), 13 | ); 14 | */ 15 | } -------------------------------------------------------------------------------- /samples/views/geos/add.ctp: -------------------------------------------------------------------------------- 1 |
2 | Form->create('Geo' , array( 'type' => 'post' ));?> 3 |
4 | 5 | Form->input('title'); 7 | echo $this->Form->input('body'); 8 | echo $this->Form->input('Geo.loc.lat', array('label' => 'latitude')); 9 | echo $this->Form->input('Geo.loc.long', array('label' => 'longitude')); 10 | ?> 11 |
12 | Form->end('Submit');?> 13 |
14 |
15 | 18 |
19 | 20 | 21 | Form->end('Submit');?> 22 | 23 |
24 | 27 |
28 | -------------------------------------------------------------------------------- /samples/views/geos/index.ctp: -------------------------------------------------------------------------------- 1 | Html->link('Add data', 'add'); ?> 2 |
3 |
4 | 5 | 6 | id: 7 | [Html->link('delete','delete/'.$result['Geo']['_id']); ?>] 8 | [ 'index', 'near', $result['Geo']['loc']['lat'], $result['Geo']['loc']['long']); 10 | echo $this->Html->link('near here', $url); 11 | ?>] 12 | [ 'index', 'circle', $result['Geo']['loc']['lat'], $result['Geo']['loc']['long'], 10); 14 | echo $this->Html->link('around here', $url); 15 | ?>] 16 |
17 | title:
18 | body:
19 | latitude:
20 | longitude:
21 | 22 |
23 | 24 | -------------------------------------------------------------------------------- /samples/views/posts/add.ctp: -------------------------------------------------------------------------------- 1 |
2 | Form->create('Post' , array( 'type' => 'post' ));?> 3 |
4 | 5 | Form->input('title'); 7 | echo $this->Form->input('body'); 8 | echo $this->Form->input('hoge'); 9 | ?> 10 |
11 | Form->end('Submit');?> 12 |
13 |
14 | 17 |
18 | -------------------------------------------------------------------------------- /samples/views/posts/createindex.ctp: -------------------------------------------------------------------------------- 1 |

Sample of create index in MongoDB

2 |
3 |
4 | 5 | Creating index.... -------------------------------------------------------------------------------- /samples/views/posts/edit.ctp: -------------------------------------------------------------------------------- 1 |
2 | Form->create('Post' , array( 'type' => 'post' ));?> 3 |
4 | 5 | Form->hidden('_id'); 7 | echo $this->Form->input('title'); 8 | echo $this->Form->input('body'); 9 | echo $this->Form->input('hoge'); 10 | ?> 11 |
12 | Form->end('Submit');?> 13 |
14 |
15 | 18 |
19 | -------------------------------------------------------------------------------- /samples/views/posts/index.ctp: -------------------------------------------------------------------------------- 1 | Html->link('Add data', 'add'); ?> 2 |
3 |
4 | 5 | 6 | id: [Html->link('edit','edit/'.$result['Post']['_id']); ?>] [Html->link('delete','delete/'.$result['Post']['_id']); ?>]
7 | title:
8 | body:
9 | hoge:
10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /samples/views/subdocuments/add.ctp: -------------------------------------------------------------------------------- 1 |
2 | Form->create('Subdocument' , array( 'type' => 'post' ));?> 3 |
4 | 5 | Form->input('title'); 7 | echo $this->Form->input('body'); 8 | //echo $this->Form->input('subdoc.name'); 9 | //echo $this->Form->input('subdoc.age'); 10 | echo $this->Form->input('Subdocument.subdoc.0.name'); 11 | echo $this->Form->input('Subdocument.subdoc.0.age'); 12 | echo $this->Form->input('Subdocument.subdoc.1.name'); 13 | echo $this->Form->input('Subdocument.subdoc.1.age'); 14 | ?> 15 |
16 | Form->end('Submit');?> 17 |
18 |
19 | 22 |
23 | 24 | 25 | Form->end('Submit');?> 26 | 27 |
28 | 31 |
32 | -------------------------------------------------------------------------------- /samples/views/subdocuments/edit.ctp: -------------------------------------------------------------------------------- 1 |
2 | Form->create('Subdocument' , array( 'type' => 'post' ));?> 3 |
4 | 5 | Form->hidden('_id'); 7 | echo $this->Form->input('title'); 8 | echo $this->Form->input('body'); 9 | echo $this->Form->input('Subdocument.subdoc.0.name'); 10 | echo $this->Form->input('Subdocument.subdoc.0.age'); 11 | echo $this->Form->input('Subdocument.subdoc.1.name'); 12 | echo $this->Form->input('Subdocument.subdoc.1.age'); 13 | ?> 14 |
15 | Form->end('Submit');?> 16 |
17 |
18 | 21 |
22 | -------------------------------------------------------------------------------- /samples/views/subdocuments/index.ctp: -------------------------------------------------------------------------------- 1 | Html->link('Add data', 'add'); ?> 2 |
3 |
4 | 5 | 6 | id: [Html->link('edit','edit/'.$result['Subdocument']['_id']); ?>] [Html->link('delete','delete/'.$result['Subdocument']['_id']); ?>]
7 | title:
8 | body:
9 | $val): ?> 10 | subdoc_name:
11 | subdoc_age:
12 | 13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /tests/cases/1st/first_mongodb_source.test.php: -------------------------------------------------------------------------------- 1 | 'mongodb', 61 | 'host' => 'localhost', 62 | 'login' => '', 63 | 'password' => '', 64 | 'database' => 'test_mongo', 65 | 'port' => 27017, 66 | 'prefix' => '', 67 | 'persistent' => false, 68 | ); 69 | 70 | /** 71 | * Sets up the environment for each test method 72 | * 73 | * @return void 74 | * @access public 75 | */ 76 | public function startTest() { 77 | $connections = ConnectionManager::enumConnectionObjects(); 78 | 79 | if (!empty($connections['test']['classname']) && $connections['test']['classname'] === 'mongodbSource') { 80 | $config = new DATABASE_CONFIG(); 81 | $this->_config = $config->test; 82 | } 83 | 84 | ConnectionManager::create('mongo_test', $this->_config); 85 | 86 | } 87 | 88 | /** 89 | * Destroys the environment after each test method is run 90 | * 91 | * @return void 92 | * @access public 93 | */ 94 | public function endTest() { 95 | $this->mongodb = new MongodbSource($this->_config); 96 | $this->mongodb->connect(); 97 | $this->dropData(); 98 | unset($this->mongodb); 99 | } 100 | 101 | 102 | /** 103 | * Drop database 104 | * 105 | * @return void 106 | * @access public 107 | */ 108 | public function dropData() { 109 | try { 110 | $db = $this->mongodb 111 | ->connection 112 | ->selectDB($this->_config['database']); 113 | 114 | foreach($db->listCollections() as $collection) { 115 | $collection->drop(); 116 | } 117 | } catch (MongoException $e) { 118 | trigger_error($e->getMessage()); 119 | } 120 | } 121 | 122 | 123 | /** 124 | * testSchemaless method 125 | * 126 | * Test you can save to a model without specifying mongodb. 127 | * 128 | * @return void 129 | * @access public 130 | */ 131 | public function testSchemaless() { 132 | $toSave = array( 133 | 'title' => 'A test article', 134 | 'body' => str_repeat('Lorum ipsum ', 100), 135 | 'tags' => array( 136 | 'one', 137 | 'two', 138 | 'three' 139 | ), 140 | 'modified' => null, 141 | 'created' => null 142 | ); 143 | 144 | $MongoArticle = ClassRegistry::init('MongoArticleSchemafree'); 145 | $MongoArticle->create(); 146 | $this->assertTrue($MongoArticle->save($toSave), 'Saving with no defined schema failed'); 147 | 148 | $expected = array_intersect_key($toSave, array_flip(array('title', 'body', 'tags'))); 149 | $result = $MongoArticle->read(array('title', 'body', 'tags')); 150 | unset ($result['MongoArticleSchemafree']['_id']); // prevent auto added field from screwing things up 151 | $this->assertEqual($expected, $result['MongoArticleSchemafree']); 152 | 153 | $toSave = array( 154 | 'title' => 'Another test article', 155 | 'body' => str_repeat('Lorum pipsum ', 100), 156 | 'tags' => array( 157 | 'four', 158 | 'five', 159 | 'six' 160 | ), 161 | 'starts' => date('Y-M-d H:i:s'), 162 | 'modified' => null, 163 | 'created' => null 164 | ); 165 | $MongoArticle->create(); 166 | $this->assertTrue($MongoArticle->save($toSave), 'Saving with no defined schema failed'); 167 | $starts = $MongoArticle->field('starts'); 168 | $this->assertEqual($toSave['starts'], $starts); 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /tests/cases/behaviors/sql_compatible.test.php: -------------------------------------------------------------------------------- 1 | lastQuery = $query; 57 | return $query; 58 | } 59 | } 60 | 61 | /** 62 | * SqlCompatibleTest class 63 | * 64 | * @uses CakeTestCase 65 | * @package mongodb 66 | * @subpackage mongodb.tests.cases.behaviors 67 | */ 68 | class SqlCompatibleTest extends CakeTestCase { 69 | 70 | /** 71 | * Default db config. overriden by test db connection if present 72 | * 73 | * @var array 74 | * @access protected 75 | */ 76 | protected $_config = array( 77 | 'datasource' => 'mongodb', 78 | 'host' => 'localhost', 79 | 'login' => '', 80 | 'password' => '', 81 | 'database' => 'test_mongo', 82 | 'port' => 27017, 83 | 'prefix' => '', 84 | 'persistent' => false, 85 | ); 86 | 87 | /** 88 | * Sets up the environment for each test method 89 | * 90 | * @return void 91 | * @access public 92 | */ 93 | public function startTest() { 94 | $connections = ConnectionManager::enumConnectionObjects(); 95 | 96 | if (!empty($connections['test']['classname']) && $connections['test']['classname'] === 'mongodbSource') { 97 | $config = new DATABASE_CONFIG(); 98 | $this->_config = $config->test; 99 | } 100 | 101 | ConnectionManager::create('mongo_test', $this->_config); 102 | $this->Mongo = new MongodbSource($this->_config); 103 | 104 | $this->Post = ClassRegistry::init(array('class' => 'SqlCompatiblePost', 'alias' => 'Post', 'ds' => 'mongo_test')); 105 | 106 | $this->_setupData(); 107 | } 108 | 109 | /** 110 | * Destroys the environment after each test method is run 111 | * 112 | * @return void 113 | * @access public 114 | */ 115 | public function endTest() { 116 | $this->Post->deleteAll(true); 117 | unset($this->Post); 118 | } 119 | 120 | /** 121 | * testNOT method 122 | * 123 | * @return void 124 | * @access public 125 | */ 126 | public function testNOT() { 127 | $expected = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); 128 | $result = $this->Post->find('all', array( 129 | 'conditions' => array( 130 | 'title !=' => 10, 131 | ), 132 | 'fields' => array('_id', 'title', 'number'), 133 | 'order' => array('number' => 'ASC') 134 | )); 135 | $result = Set::extract($result, '/Post/title'); 136 | $this->assertEqual($expected, $result); 137 | 138 | $conditions = array( 139 | 'title' => array('$ne' => 10) 140 | ); 141 | $this->assertEqual($conditions, $this->Post->lastQuery['conditions']); 142 | 143 | $result = $this->Post->find('all', array( 144 | 'conditions' => array( 145 | 'NOT' => array( 146 | 'title' => 10 147 | ), 148 | ), 149 | 'fields' => array('_id', 'title', 'number'), 150 | 'order' => array('number' => 'ASC') 151 | )); 152 | $result = Set::extract($result, '/Post/title'); 153 | $this->assertEqual($expected, $result); 154 | 155 | $conditions = array( 156 | 'title' => array('$nin' => array(10)) 157 | ); 158 | $this->assertEqual($conditions, $this->Post->lastQuery['conditions']); 159 | } 160 | 161 | /** 162 | * testGTLT method 163 | * 164 | * @return void 165 | * @access public 166 | */ 167 | public function testGTLT() { 168 | $expected = array(8, 9, 10, 11, 12, 13); 169 | $result = $this->Post->find('all', array( 170 | 'conditions' => array( 171 | 'title >' => 7, 172 | 'title <' => 14, 173 | ), 174 | 'fields' => array('_id', 'title', 'number'), 175 | 'order' => array('number' => 'ASC') 176 | )); 177 | $result = Set::extract($result, '/Post/title'); 178 | $this->assertEqual($expected, $result); 179 | 180 | $conditions = array( 181 | 'title' => array( 182 | '$gt' => 7, 183 | '$lt' => 14 184 | ) 185 | ); 186 | $this->assertEqual($conditions, $this->Post->lastQuery['conditions']); 187 | } 188 | 189 | /** 190 | * testGTE method 191 | * 192 | * @return void 193 | * @access public 194 | */ 195 | public function testGTE() { 196 | $expected = array(19, 20); 197 | $result = $this->Post->find('all', array( 198 | 'conditions' => array( 199 | 'title >=' => 19, 200 | ), 201 | 'fields' => array('_id', 'title', 'number'), 202 | 'order' => array('number' => 'ASC') 203 | )); 204 | $result = Set::extract($result, '/Post/title'); 205 | $this->assertEqual($expected, $result); 206 | 207 | $conditions = array( 208 | 'title' => array('$gte' => 19) 209 | ); 210 | $this->assertEqual($conditions, $this->Post->lastQuery['conditions']); 211 | } 212 | 213 | /** 214 | * testOR method 215 | * 216 | * @return void 217 | * @access public 218 | */ 219 | public function testOR() { 220 | $expected = array(1, 2, 19, 20); 221 | $result = $this->Post->find('all', array( 222 | 'conditions' => array( 223 | 'OR' => array( 224 | 'title <=' => 2, 225 | 'title >=' => 19, 226 | ) 227 | ), 228 | 'fields' => array('_id', 'title', 'number'), 229 | 'order' => array('number' => 'ASC') 230 | )); 231 | $result = Set::extract($result, '/Post/title'); 232 | $this->assertEqual($expected, $result); 233 | 234 | $conditions = array( 235 | '$or' => array( 236 | array('title' => array('$lte' => 2)), 237 | array('title' => array('$gte' => 19)) 238 | ) 239 | ); 240 | $this->assertEqual($conditions, $this->Post->lastQuery['conditions']); 241 | } 242 | 243 | /** 244 | * setupData method 245 | * 246 | * @return void 247 | * @access protected 248 | */ 249 | protected function _setupData() { 250 | $this->Post->deleteAll(true); 251 | for ($i = 1; $i <= 20; $i++) { 252 | $data = array( 253 | 'title' => $i, 254 | ); 255 | $saveData['Post'] = $data; 256 | $this->Post->create(); 257 | $this->Post->save($saveData); 258 | } 259 | } 260 | } --------------------------------------------------------------------------------