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