4
4
5
5
use LogicException ;
6
6
use MongoDB \Client ;
7
- use MongoDB \Collection ;
8
7
use MongoDB \Database ;
9
8
use MongoDB \Driver \Manager ;
10
9
use MongoDB \Driver \ReadPreference ;
17
16
use function assertInternalType ;
18
17
use function assertNotEmpty ;
19
18
use function assertNotFalse ;
19
+ use function assertRegExp ;
20
20
use function assertStringStartsWith ;
21
21
use function count ;
22
22
use function current ;
23
23
use function explode ;
24
+ use function fopen ;
25
+ use function fwrite ;
26
+ use function hex2bin ;
24
27
use function implode ;
25
28
use function key ;
26
29
use function parse_url ;
30
+ use function rewind ;
27
31
use function strlen ;
28
32
use function strpos ;
29
33
use function substr_replace ;
@@ -77,15 +81,27 @@ public function createEntities(array $entities)
77
81
78
82
switch ($ type ) {
79
83
case 'client ' :
80
- $ this ->entityMap [ $ id] = $ this -> createClient ( $ def );
84
+ $ this ->createClient ( $ id, $ def );
81
85
break ;
82
86
83
87
case 'database ' :
84
- $ this ->entityMap [ $ id] = $ this -> createDatabase ( $ def );
88
+ $ this ->createDatabase ( $ id, $ def );
85
89
break ;
86
90
87
91
case 'collection ' :
88
- $ this ->entityMap [$ id ] = $ this ->createCollection ($ def );
92
+ $ this ->createCollection ($ id , $ def );
93
+ break ;
94
+
95
+ case 'session ' :
96
+ $ this ->createSession ($ id , $ def );
97
+ break ;
98
+
99
+ case 'bucket ' :
100
+ $ this ->createBucket ($ id , $ def );
101
+ break ;
102
+
103
+ case 'stream ' :
104
+ $ this ->createStream ($ id , $ def );
89
105
break ;
90
106
91
107
default :
@@ -104,6 +120,16 @@ public function getInternalClient() : Client
104
120
return $ this ->internalClient ;
105
121
}
106
122
123
+ public function isActiveClient (string $ clientId ) : bool
124
+ {
125
+ return $ this ->activeClient === $ clientId ;
126
+ }
127
+
128
+ public function setActiveClient (string $ clientId = null )
129
+ {
130
+ $ this ->activeClient = $ clientId ;
131
+ }
132
+
107
133
public function assertExpectedEventsForClients (array $ expectedEventsForClients )
108
134
{
109
135
assertNotEmpty ($ expectedEventsForClients );
@@ -144,7 +170,7 @@ public function getEventObserverForClient(string $id) : EventObserver
144
170
return $ this ->eventObserversByClient [$ id ];
145
171
}
146
172
147
- private function createClient (stdClass $ o ) : Client
173
+ private function createClient (string $ id , stdClass $ o )
148
174
{
149
175
Util::assertHasOnlyKeys ($ o , ['id ' , 'uriOptions ' , 'useMultipleMongoses ' , 'observeEvents ' , 'ignoreCommandMonitoringEvents ' ]);
150
176
@@ -178,23 +204,23 @@ private function createClient(stdClass $o) : Client
178
204
assertInternalType ('array ' , $ observeEvents );
179
205
assertInternalType ('array ' , $ ignoreCommandMonitoringEvents );
180
206
181
- $ this ->eventObserversByClient [$ o -> id ] = new EventObserver ($ observeEvents , $ ignoreCommandMonitoringEvents , $ o -> id , $ this -> entityMap );
207
+ $ this ->eventObserversByClient [$ id ] = new EventObserver ($ observeEvents , $ ignoreCommandMonitoringEvents , $ id , $ this );
182
208
}
183
209
184
- return new Client ($ uri , $ uriOptions );
210
+ $ this -> entityMap -> set ( $ id , new Client ($ uri , $ uriOptions) );
185
211
}
186
212
187
- private function createCollection (stdClass $ o ) : Collection
213
+ private function createCollection (string $ id , stdClass $ o )
188
214
{
189
215
Util::assertHasOnlyKeys ($ o , ['id ' , 'database ' , 'collectionName ' , 'collectionOptions ' ]);
190
216
191
217
$ collectionName = $ o ->collectionName ?? null ;
192
- $ database = $ o ->database ?? null ;
218
+ $ databaseId = $ o ->database ?? null ;
193
219
194
220
assertInternalType ('string ' , $ collectionName );
195
- assertInternalType ('string ' , $ database );
221
+ assertInternalType ('string ' , $ databaseId );
196
222
197
- $ database = $ this ->entityMap [$ database ];
223
+ $ database = $ this ->entityMap [$ databaseId ];
198
224
assertInstanceOf (Database::class, $ database );
199
225
200
226
$ options = [];
@@ -204,20 +230,20 @@ private function createCollection(stdClass $o) : Collection
204
230
$ options = self ::prepareCollectionOrDatabaseOptions ((array ) $ o ->collectionOptions );
205
231
}
206
232
207
- return $ database ->selectCollection ($ o ->collectionName , $ options );
233
+ $ this -> entityMap -> set ( $ id , $ database ->selectCollection ($ o ->collectionName , $ options), $ databaseId );
208
234
}
209
235
210
- private function createDatabase (stdClass $ o ) : Database
236
+ private function createDatabase (string $ id , stdClass $ o )
211
237
{
212
238
Util::assertHasOnlyKeys ($ o , ['id ' , 'client ' , 'databaseName ' , 'databaseOptions ' ]);
213
239
214
240
$ databaseName = $ o ->databaseName ?? null ;
215
- $ client = $ o ->client ?? null ;
241
+ $ clientId = $ o ->client ?? null ;
216
242
217
243
assertInternalType ('string ' , $ databaseName );
218
- assertInternalType ('string ' , $ client );
244
+ assertInternalType ('string ' , $ clientId );
219
245
220
- $ client = $ this ->entityMap [$ client ];
246
+ $ client = $ this ->entityMap [$ clientId ];
221
247
assertInstanceOf (Client::class, $ client );
222
248
223
249
$ options = [];
@@ -227,31 +253,115 @@ private function createDatabase(stdClass $o) : Database
227
253
$ options = self ::prepareCollectionOrDatabaseOptions ((array ) $ o ->databaseOptions );
228
254
}
229
255
230
- return $ client ->selectDatabase ($ databaseName , $ options );
256
+ $ this ->entityMap ->set ($ id , $ client ->selectDatabase ($ databaseName , $ options ), $ clientId );
257
+ }
258
+
259
+ private function createSession (string $ id , stdClass $ o )
260
+ {
261
+ Util::assertHasOnlyKeys ($ o , ['id ' , 'client ' , 'sessionOptions ' ]);
262
+
263
+ $ clientId = $ o ->client ?? null ;
264
+ assertInternalType ('string ' , $ clientId );
265
+ $ client = $ this ->entityMap [$ clientId ];
266
+ assertInstanceOf (Client::class, $ client );
267
+
268
+ $ options = [];
269
+
270
+ if (isset ($ o ->sessionOptions )) {
271
+ assertInternalType ('object ' , $ o ->sessionOptions );
272
+ $ options = self ::prepareSessionOptions ((array ) $ o ->sessionOptions );
273
+ }
274
+
275
+ $ this ->entityMap ->set ($ id , $ client ->startSession ($ options ), $ clientId );
276
+ }
277
+
278
+ private function createBucket (string $ id , stdClass $ o )
279
+ {
280
+ Util::assertHasOnlyKeys ($ o , ['id ' , 'database ' , 'bucketOptions ' ]);
281
+
282
+ $ databaseId = $ o ->database ?? null ;
283
+ assertInternalType ('string ' , $ databaseId );
284
+ $ database = $ this ->entityMap [$ databaseId ];
285
+ assertInstanceOf (Database::class, $ database );
286
+
287
+ $ options = [];
288
+
289
+ if (isset ($ o ->bucketOptions )) {
290
+ assertInternalType ('object ' , $ o ->bucketOptions );
291
+ $ options = self ::prepareBucketOptions ((array ) $ o ->bucketOptions );
292
+ }
293
+
294
+ $ this ->entityMap ->set ($ id , $ database ->selectGridFSBucket ($ options ), $ databaseId );
295
+ }
296
+
297
+ private function createStream (string $ id , stdClass $ o )
298
+ {
299
+ Util::assertHasOnlyKeys ($ o , ['id ' , 'hexBytes ' ]);
300
+
301
+ $ hexBytes = $ o ->hexBytes ?? null ;
302
+ assertInternalType ('string ' , $ hexBytes );
303
+ assertRegExp ('/^([0-9a-fA-F]{2})*$/ ' , $ hexBytes );
304
+
305
+ $ stream = fopen ('php://temp ' , 'w+b ' );
306
+ fwrite ($ stream , hex2bin ($ hexBytes ));
307
+ rewind ($ stream );
308
+
309
+ $ this ->entityMap ->set ($ id , $ stream );
231
310
}
232
311
233
312
private static function prepareCollectionOrDatabaseOptions (array $ options ) : array
234
313
{
235
314
Util::assertHasOnlyKeys ($ options , ['readConcern ' , 'readPreference ' , 'writeConcern ' ]);
236
315
237
- if (array_key_exists ('readConcern ' , $ options )) {
238
- assertInternalType ('object ' , $ options ['readConcern ' ]);
239
- $ options ['readConcern ' ] = Util::createReadConcern ($ options ['readConcern ' ]);
316
+ return Util::prepareCommonOptions ($ options );
317
+ }
318
+
319
+ private static function prepareBucketOptions (array $ options ) : array
320
+ {
321
+ Util::assertHasOnlyKeys ($ options , ['bucketName ' , 'chunkSizeBytes ' , 'disableMD5 ' , 'readConcern ' , 'readPreference ' , 'writeConcern ' ]);
322
+
323
+ if (array_key_exists ('bucketName ' , $ options )) {
324
+ assertInternalType ('string ' , $ options ['bucketName ' ]);
240
325
}
241
326
242
- if (array_key_exists ('readPreference ' , $ options )) {
243
- assertInternalType ('object ' , $ options ['readPreference ' ]);
244
- $ options ['readPreference ' ] = Util::createReadPreference ($ options ['readPreference ' ]);
327
+ if (array_key_exists ('chunkSizeBytes ' , $ options )) {
328
+ assertInternalType ('int ' , $ options ['chunkSizeBytes ' ]);
245
329
}
246
330
247
- if (array_key_exists ('writeConcern ' , $ options )) {
248
- assertInternalType ('object ' , $ options ['writeConcern ' ]);
249
- $ options ['writeConcern ' ] = Util::createWriteConcern ($ options ['writeConcern ' ]);
331
+ if (array_key_exists ('disableMD5 ' , $ options )) {
332
+ assertInternalType ('bool ' , $ options ['disableMD5 ' ]);
333
+ }
334
+
335
+ return Util::prepareCommonOptions ($ options );
336
+ }
337
+
338
+ private static function prepareSessionOptions (array $ options ) : array
339
+ {
340
+ Util::assertHasOnlyKeys ($ options , ['causalConsistency ' , 'defaultTransactionOptions ' ]);
341
+
342
+ if (array_key_exists ('causalConsistency ' , $ options )) {
343
+ assertInternalType ('bool ' , $ options ['causalConsistency ' ]);
344
+ }
345
+
346
+ if (array_key_exists ('defaultTransactionOptions ' , $ options )) {
347
+ assertInternalType ('object ' , $ options ['defaultTransactionOptions ' ]);
348
+ $ options ['defaultTransactionOptions ' ] = self ::prepareDefaultTransactionOptions ((array ) $ options ['defaultTransactionOptions ' ]);
250
349
}
251
350
252
351
return $ options ;
253
352
}
254
353
354
+ private static function prepareDefaultTransactionOptions (array $ options ) : array
355
+ {
356
+ Util::assertHasOnlyKeys ($ options , ['maxCommitTimeMS ' , 'readConcern ' , 'readPreference ' , 'writeConcern ' ]);
357
+
358
+ if (array_key_exists ('maxCommitTimeMS ' , $ options )) {
359
+ assertInternalType ('int ' , $ options ['maxCommitTimeMS ' ]);
360
+ }
361
+
362
+ return Util::prepareCommonOptions ($ options );
363
+ }
364
+
255
365
/**
256
366
* Removes mongos hosts beyond the first if the URI refers to a sharded
257
367
* cluster. Otherwise, the URI is returned as-is.
0 commit comments