1<?php
2
3namespace Elgg\Database;
4
5use Elgg\Database\Clauses\AccessWhereClause;
6use Elgg\Database\Clauses\AnnotationWhereClause;
7use Elgg\Database\Clauses\JoinClause;
8use Elgg\Database\Clauses\MetadataWhereClause;
9use Elgg\Database\Clauses\OrderByClause;
10use Elgg\Database\Clauses\PrivateSettingWhereClause;
11use Elgg\Database\Clauses\RelationshipWhereClause;
12use Elgg\Integration\OrderByClauseTest;
13use Elgg\Mocks\Database;
14use Elgg\UnitTestCase;
15
16/**
17 * @group Entities
18 * @group QueryBuilder
19 * @group Repository
20 */
21class EntitiesRepositoryTest extends UnitTestCase {
22
23	public function up() {
24
25	}
26
27	public function down() {
28
29	}
30
31	public function testCanExecuteCount() {
32		$select = Select::fromTable('entities', 'e');
33		$select->select('COUNT(DISTINCT e.guid) AS total');
34
35		$select->addClause(new AccessWhereClause());
36
37		$spec = _elgg_services()->db->addQuerySpec([
38			'sql' => $select->getSQL(),
39			'params' => $select->getParameters(),
40			'results' => [
41				(object) [
42					'total' => 10,
43				]
44			]
45		]);
46
47		$options = [
48			'count' => true,
49		];
50
51		$find = Entities::find($options);
52		$count = Entities::with($options)->count();
53
54		$this->assertEquals(10, $find);
55		$this->assertEquals(10, $count);
56
57		_elgg_services()->db->removeQuerySpec($spec);
58	}
59
60	public function testCanExecuteCountWithBadDataFormat() {
61		$options = [
62			'count' => true,
63			'guids' => 'abc',
64		];
65
66		$find = Entities::find($options);
67		$this->assertEquals(0, $find);
68	}
69
70	public function testCanExecuteGet() {
71		$select = Select::fromTable('entities', 'e');
72		$select->select('DISTINCT e.*');
73
74		$select->addClause(new AccessWhereClause());
75
76		$select->setMaxResults(5);
77		$select->setFirstResult(5);
78		$select->addOrderBy('e.guid', 'asc');
79
80		$rows = $this->getRows(5);
81
82		$spec = _elgg_services()->db->addQuerySpec([
83			'sql' => $select->getSQL(),
84			'params' => $select->getParameters(),
85			'results' => $rows,
86		]);
87
88		$options = [
89			'limit' => 5,
90			'offset' => 5,
91			'callback' => false,
92			'order_by' => [
93				new OrderByClause('e.guid', 'ASC'),
94			]
95		];
96
97		$find = Entities::find($options);
98		$get = Entities::with($options)->get(5, 5, false);
99
100		$this->assertEquals($rows, $find);
101		$this->assertEquals($rows, $get);
102
103		_elgg_services()->db->removeQuerySpec($spec);
104	}
105
106	public function testCanExecuteGetWithClauses() {
107		$select = Select::fromTable('entities', 'e');
108		$select->select('DISTINCT e.*');
109		$select->addSelect('max(e.time_created) AS newest');
110		$select->groupBy('e.time_created');
111		$select->join('e', 'metadata', 'n_table', 'e.guid = n_table.entity_guid');
112		$alias = $select->joinMetadataTable('e', 'guid', 'status');
113		$select->where($select->compare("$alias.value", 'IN', ['draft'], ELGG_VALUE_STRING));
114		$select->having($select->compare('e.time_updated', 'IS NOT NULL'));
115		$select->addClause(new AccessWhereClause());
116
117		$select->setMaxResults(5);
118		$select->setFirstResult(5);
119		$select->addOrderBy('e.guid', 'asc');
120
121		$rows = $this->getRows(5);
122
123		$spec = _elgg_services()->db->addQuerySpec([
124			'sql' => $select->getSQL(),
125			'params' => $select->getParameters(),
126			'results' => $rows,
127		]);
128
129		$options = [
130			'limit' => 5,
131			'offset' => 5,
132			'callback' => false,
133			'order_by' => [
134				new OrderByClause('e.guid', 'ASC'),
135			],
136			'selects' => [
137				'max(e.time_created) AS newest',
138			],
139			'group_by' => [
140				'e.time_created',
141			],
142			'having' => [
143				function(QueryBuilder $qb) {
144				return $qb->compare('e.time_updated', 'IS NOT NULL');
145			}
146			],
147			'joins' => [
148				new JoinClause('metadata', 'n_table', 'e.guid = n_table.entity_guid'),
149			],
150			'wheres' =>[
151				function(QueryBuilder $qb) {
152					$alias = $qb->joinMetadataTable('e', 'guid', 'status');
153					return $qb->compare("$alias.value", 'IN', ['draft'], ELGG_VALUE_STRING);
154				}
155			]
156		];
157
158		$find = Entities::find($options);
159		$get = Entities::with($options)->get(5, 5, false);
160
161		$this->assertEquals($rows, $find);
162		$this->assertEquals($rows, $get);
163
164		_elgg_services()->db->removeQuerySpec($spec);
165	}
166
167	public function testCanExecuteGetWithBadDataFormat() {
168		$options = [
169			'limit' => 5,
170			'offset' => 5,
171			'callback' => false,
172			'guids' => 'abc',
173		];
174
175		$find = Entities::find($options);
176		$this->assertEquals(false, $find);
177	}
178
179	public function testCanExecuteBatchGet() {
180		$select = Select::fromTable('entities', 'e');
181		$select->select('DISTINCT e.*');
182
183		$access = new AccessWhereClause();
184		$access_where = $access->prepare($select, 'e');
185		$select->andWhere($access_where);
186
187		$select->setMaxResults(5);
188		$select->setFirstResult(5);
189		$select->addOrderBy('e.guid', 'asc');
190
191		$rows = $this->getRows(5);
192
193		$spec = _elgg_services()->db->addQuerySpec([
194			'sql' => $select->getSQL(),
195			'params' => $select->getParameters(),
196			'results' => $rows,
197		]);
198
199		$options = [
200			'limit' => 5,
201			'offset' => 5,
202			'callback' => false,
203			'order_by' => [
204				new OrderByClause('e.guid', 'ASC'),
205			],
206			'batch' => true,
207		];
208
209		$find = Entities::find($options);
210		$batch = Entities::with($options)->batch(5, 5, false);
211
212		$this->assertInstanceOf(\ElggBatch::class, $find);
213		$this->assertInstanceOf(\ElggBatch::class, $batch);
214
215		foreach ($find as $i => $row) {
216			$this->assertEquals($rows[$i], $row);
217		}
218
219		foreach ($batch as $i => $row) {
220			$this->assertEquals($rows[$i], $row);
221		}
222
223		_elgg_services()->db->removeQuerySpec($spec);
224	}
225
226	public function testCanExecuteMetadataCalculation() {
227
228		$metadata_names = ['foo'];
229
230		$select = Select::fromTable('entities', 'e');
231		$select->joinMetadataTable('e', 'guid', $metadata_names, 'inner', 'n_table');
232		$select->select("min(n_table.value) AS calculation");
233
234		$select->addClause(new AccessWhereClause());
235
236		$metadata = new MetadataWhereClause();
237		$metadata->names = $metadata_names;
238		$select->addClause($metadata, 'n_table');
239
240		$spec = _elgg_services()->db->addQuerySpec([
241			'sql' => $select->getSQL(),
242			'params' => $select->getParameters(),
243			'results' => [
244				(object) [
245					'calculation' => 10,
246				]
247			]
248		]);
249
250		$options = [
251			'metadata_calculation' => 'min',
252			'metadata_names' => $metadata_names,
253		];
254
255		$find = Entities::find($options);
256		$calculate = Entities::with($options)->calculate('min', $metadata_names, 'metadata');
257
258		$this->assertEquals(10, $find);
259		$this->assertEquals(10, $calculate);
260
261		_elgg_services()->db->removeQuerySpec($spec);
262	}
263
264	public function testCanExecuteMetadataCalculationWithoutPropertyType() {
265
266		$metadata_name = 'foo';
267
268		$select = Select::fromTable('entities', 'e');
269		$select->joinMetadataTable('e', 'guid', $metadata_name, 'inner', 'n_table');
270		$select->select("min(n_table.value) AS calculation");
271
272		$select->addClause(new AccessWhereClause());
273
274		$spec = _elgg_services()->db->addQuerySpec([
275			'sql' => $select->getSQL(),
276			'params' => $select->getParameters(),
277			'results' => [
278				(object) [
279					'calculation' => 10,
280				]
281			]
282		]);
283
284		$calculate = Entities::with([])->calculate('min', $metadata_name);
285
286		$this->assertEquals(10, $calculate);
287
288		_elgg_services()->db->removeQuerySpec($spec);
289	}
290
291	public function testCanExecuteAnnotationCalculation() {
292
293		$annotation_names = ['foo'];
294
295		$select = Select::fromTable('entities', 'e');
296		$select->joinAnnotationTable('e', 'guid', $annotation_names, 'inner', 'n_table');
297		$select->select("avg(n_table.value) AS calculation");
298
299		$select->addClause(new AccessWhereClause());
300
301		$annotation = new AnnotationWhereClause();
302		$annotation->names = $annotation_names;
303		$select->addClause($annotation, 'n_table');
304
305		$spec = _elgg_services()->db->addQuerySpec([
306			'sql' => $select->getSQL(),
307			'params' => $select->getParameters(),
308			'results' => [
309				(object) [
310					'calculation' => 10,
311				]
312			]
313		]);
314
315		$options = [
316			'annotation_calculation' => 'avg',
317			'annotation_names' => $annotation_names,
318		];
319
320		$find = Entities::find($options);
321		$calculate = Entities::with($options)->calculate('avg', $annotation_names, 'annotation');
322
323		$this->assertEquals(10, $find);
324		$this->assertEquals(10, $calculate);
325
326		_elgg_services()->db->removeQuerySpec($spec);
327	}
328
329	public function testThrowsOnInvalidCalculation() {
330		$this->expectException(\InvalidArgumentException::class);
331		Entities::with([])->calculate('invalid', 'guid', 'attribute');
332	}
333
334	public function testCanExecuteAttributeCalculation() {
335
336		$select = Select::fromTable('entities', 'e');
337		$select->select("max(e.guid) AS calculation");
338
339		$select->addClause(new AccessWhereClause());
340
341		$spec = _elgg_services()->db->addQuerySpec([
342			'sql' => $select->getSQL(),
343			'params' => $select->getParameters(),
344			'results' => [
345				(object) [
346					'calculation' => 10,
347				]
348			]
349		]);
350
351		$calculate = Entities::with([])->calculate('max', 'guid', 'attribute');
352
353		$this->assertEquals(10, $calculate);
354
355		_elgg_services()->db->removeQuerySpec($spec);
356	}
357
358	public function testCanExecuteAttributeCalculationWithoutPropertyType() {
359
360		$select = Select::fromTable('entities', 'e');
361		$select->select("max(e.guid) AS calculation");
362
363		$select->addClause(new AccessWhereClause());
364
365		$spec = _elgg_services()->db->addQuerySpec([
366			'sql' => $select->getSQL(),
367			'params' => $select->getParameters(),
368			'results' => [
369				(object) [
370					'calculation' => 10,
371				]
372			]
373		]);
374
375		$calculate = Entities::with([])->calculate('max', 'guid');
376
377		$this->assertEquals(10, $calculate);
378
379		_elgg_services()->db->removeQuerySpec($spec);
380	}
381
382	public function testThrowsOnInvalidAttributeCalculation() {
383		$this->expectException(\InvalidParameterException::class);
384		Entities::with([])->calculate('max', 'invalid', 'attribute');
385	}
386
387	public function testCanExecutePrivateSettingCalculation() {
388
389		$private_setting_names = ['foo'];
390
391		$select = Select::fromTable('entities', 'e');
392		$select->joinPrivateSettingsTable('e', 'guid', $private_setting_names, 'inner', 'ps');
393		$select->select("sum(ps.value) AS calculation");
394
395		$select->addClause(new AccessWhereClause());
396
397		$private_setting = new PrivateSettingWhereClause();
398		$private_setting->names = $private_setting_names;
399		$select->addClause($private_setting, 'ps');
400
401		$spec = _elgg_services()->db->addQuerySpec([
402			'sql' => $select->getSQL(),
403			'params' => $select->getParameters(),
404			'results' => [
405				(object) [
406					'calculation' => 10,
407				]
408			]
409		]);
410
411		$options = [
412			'private_setting_names' => $private_setting_names,
413		];
414
415		$calculate = Entities::with($options)->calculate('sum', $private_setting_names, 'private_setting');
416
417		$this->assertEquals(10, $calculate);
418
419		_elgg_services()->db->removeQuerySpec($spec);
420	}
421
422	public function testThrowsOnMetadataCalculationWithMultipleAndPairs() {
423
424		$options = [
425			'metadata_calculation' => 'min',
426			'metadata_name_value_pairs' => [
427				[
428					'name' => 'status',
429					'value' => 'draft',
430				],
431				[
432					'name' => 'category',
433					'value' => 'blogs',
434				]
435			]
436		];
437
438		$this->expectException(\LogicException::class);
439		Entities::find($options);
440	}
441
442	public function testThrowsOnAnnotationCalculationWithMultipleAndPairs() {
443
444		$options = [
445			'annotation_calculation' => 'min',
446			'annotation_name_value_pairs' => [
447				[
448					'name' => 'status',
449					'value' => 'draft',
450				],
451				[
452					'name' => 'category',
453					'value' => 'blogs',
454				]
455			]
456		];
457
458		$this->expectException(\LogicException::class);
459		Entities::find($options);
460	}
461
462	public function testCanExecuteQueryWithMetadataNameValuePairs() {
463
464		$select = Select::fromTable('entities', 'e');
465		$select->select('DISTINCT e.*');
466
467		$wheres = [];
468
469		$select->addClause(new AccessWhereClause());
470
471		$alias1 = $select->joinMetadataTable('e', 'guid', ['foo1']);
472		$metadata = new MetadataWhereClause();
473		$metadata->names = ['foo1'];
474		$metadata->values = ['bar1'];
475		$wheres[] = $metadata->prepare($select, $alias1);
476
477		$alias2 = $select->joinMetadataTable('e', 'guid', ['foo2']);
478		$metadata = new MetadataWhereClause();
479		$metadata->names = ['foo2'];
480		$metadata->values = ['bar2'];
481		$wheres[] = $metadata->prepare($select, $alias2);
482
483		$select->andWhere($select->merge($wheres));
484
485		$select->setMaxResults(10);
486		$select->setFirstResult(0);
487
488		$select->orderBy('e.guid', 'asc');
489
490		$rows = $this->getRows(5);
491		$spec = _elgg_services()->db->addQuerySpec([
492			'sql' => $select->getSQL(),
493			'params' => $select->getParameters(),
494			'results' => $rows,
495		]);
496
497		$options = [
498			'callback' => false,
499			'metadata_name_value_pairs' => [
500				'foo1' => 'bar1',
501				'foo2' => 'bar2',
502			],
503			'order_by' => [
504				new OrderByClause('e.guid', 'asc'),
505			],
506		];
507
508		$find = Entities::find($options);
509
510		$this->assertEquals($rows, $find);
511
512		_elgg_services()->db->removeQuerySpec($spec);
513	}
514
515	public function testCanExecuteQueryWithMetadataNameValuePairsJoinedByOr() {
516
517		$select = Select::fromTable('entities', 'e');
518		$select->select('DISTINCT e.*');
519
520		$wheres = [];
521
522		$select->addClause(new AccessWhereClause());
523
524		$select->joinMetadataTable('e', 'guid', null, 'inner','n_table');
525
526		$metadata = new MetadataWhereClause();
527		$metadata->names = ['foo1'];
528		$metadata->values = ['bar1'];
529		$wheres[] = $metadata->prepare($select, 'n_table');
530
531		$metadata = new MetadataWhereClause();
532		$metadata->names = ['foo2'];
533		$metadata->values = ['bar2'];
534		$wheres[] = $metadata->prepare($select, 'n_table');
535
536		$select->andWhere($select->merge($wheres, 'OR'));
537
538		$select->setMaxResults(10);
539		$select->setFirstResult(0);
540
541		$select->orderBy('e.guid', 'asc');
542
543		$rows = $this->getRows(5);
544		$spec = _elgg_services()->db->addQuerySpec([
545			'sql' => $select->getSQL(),
546			'params' => $select->getParameters(),
547			'results' => $rows,
548		]);
549
550		$options = [
551			'callback' => false,
552			'metadata_name_value_pairs' => [
553				'foo1' => 'bar1',
554				'foo2' => 'bar2',
555			],
556			'metadata_name_value_pairs_operator' => 'OR',
557			'order_by' => [
558				new OrderByClause('e.guid', 'asc'),
559			],
560		];
561
562		$find = Entities::find($options);
563
564		$this->assertEquals($rows, $find);
565
566		_elgg_services()->db->removeQuerySpec($spec);
567	}
568
569	public function testCanExecuteQueryWithAnnotationNameValuePairs() {
570
571		$select = Select::fromTable('entities', 'e');
572		$select->select('DISTINCT e.*');
573
574		$wheres = [];
575
576		$select->addClause(new AccessWhereClause());
577
578		$alias1 = $select->joinAnnotationTable('e', 'guid', ['foo1']);
579		$annotation = new AnnotationWhereClause();
580		$annotation->names = ['foo1'];
581		$annotation->values = ['bar1'];
582		$wheres[] = $annotation->prepare($select, $alias1);
583
584		$alias2 = $select->joinAnnotationTable('e', 'guid', ['foo2']);
585		$annotation = new AnnotationWhereClause();
586		$annotation->names = ['foo2'];
587		$annotation->values = ['bar2'];
588		$wheres[] = $annotation->prepare($select, $alias2);
589
590		$select->andWhere($select->merge($wheres));
591
592		$select->setMaxResults(10);
593		$select->setFirstResult(0);
594
595		$select->orderBy('e.guid', 'asc');
596
597		$rows = $this->getRows(5);
598		$spec = _elgg_services()->db->addQuerySpec([
599			'sql' => $select->getSQL(),
600			'params' => $select->getParameters(),
601			'results' => $rows,
602		]);
603
604		$options = [
605			'callback' => false,
606			'annotation_name_value_pairs' => [
607				'foo1' => 'bar1',
608				'foo2' => 'bar2',
609			],
610			'order_by' => [
611				new OrderByClause('e.guid', 'asc'),
612			],
613		];
614
615		$find = Entities::find($options);
616
617		$this->assertEquals($rows, $find);
618
619		_elgg_services()->db->removeQuerySpec($spec);
620	}
621
622	public function testCanExecuteQueryWithAnnotationNameValuePairsJoinedByOr() {
623
624		$select = Select::fromTable('entities', 'e');
625		$select->select('DISTINCT e.*');
626
627		$wheres = [];
628
629		$select->addClause(new AccessWhereClause());
630
631		$select->joinAnnotationTable('e', 'guid', null, 'inner','n_table');
632
633		$annotation = new AnnotationWhereClause();
634		$annotation->names = ['foo1'];
635		$annotation->values = ['bar1'];
636		$wheres[] = $annotation->prepare($select, 'n_table');
637
638		$annotation = new AnnotationWhereClause();
639		$annotation->names = ['foo2'];
640		$annotation->values = ['bar2'];
641		$wheres[] = $annotation->prepare($select, 'n_table');
642
643		$select->andWhere($select->merge($wheres, 'OR'));
644
645		$select->setMaxResults(10);
646		$select->setFirstResult(0);
647
648		$select->orderBy('e.guid', 'asc');
649
650		$rows = $this->getRows(5);
651		$spec = _elgg_services()->db->addQuerySpec([
652			'sql' => $select->getSQL(),
653			'params' => $select->getParameters(),
654			'results' => $rows,
655		]);
656
657		$options = [
658			'callback' => false,
659			'annotation_name_value_pairs' => [
660				'foo1' => 'bar1',
661				'foo2' => 'bar2',
662			],
663			'annotation_name_value_pairs_operator' => 'OR',
664			'order_by' => [
665				new OrderByClause('e.guid', 'asc'),
666			],
667		];
668
669		$find = Entities::find($options);
670
671		$this->assertEquals($rows, $find);
672
673		_elgg_services()->db->removeQuerySpec($spec);
674	}
675
676	public function testCanExecuteQueryWithPrivateSettingsNameValuePairs() {
677
678		$select = Select::fromTable('entities', 'e');
679		$select->select('DISTINCT e.*');
680
681		$wheres = [];
682
683		$select->addClause(new AccessWhereClause());
684
685		$alias1 = $select->joinPrivateSettingsTable('e', 'guid', 'foo1');
686		$private_setting = new PrivateSettingWhereClause();
687		$private_setting->names = ['foo1'];
688		$private_setting->values = ['bar1'];
689		$wheres[] = $private_setting->prepare($select, $alias1);
690
691		$alias2 = $select->joinPrivateSettingsTable('e', 'guid', 'foo2');
692		$private_setting = new PrivateSettingWhereClause();
693		$private_setting->names = ['foo2'];
694		$private_setting->values = ['bar2'];
695		$wheres[] = $private_setting->prepare($select, $alias2);
696
697		$select->andWhere($select->expr()->andX()->addMultiple($wheres));
698
699		$select->setMaxResults(10);
700		$select->setFirstResult(0);
701
702		$select->orderBy('e.guid', 'asc');
703
704		$rows = $this->getRows(5);
705		$spec = _elgg_services()->db->addQuerySpec([
706			'sql' => $select->getSQL(),
707			'params' => $select->getParameters(),
708			'results' => $rows,
709		]);
710
711		$options = [
712			'callback' => false,
713			'private_setting_name_value_pairs' => [
714				'foo1' => 'bar1',
715				'foo2' => 'bar2',
716			],
717			'order_by' => [
718				new OrderByClause('e.guid', 'asc'),
719			],
720		];
721
722		$find = Entities::find($options);
723
724		$this->assertEquals($rows, $find);
725
726		_elgg_services()->db->removeQuerySpec($spec);
727	}
728
729	public function testCanExecuteQueryWithPrivateSettingsNameValuePairsJoinedByOr() {
730
731		$select = Select::fromTable('entities', 'e');
732		$select->select('DISTINCT e.*');
733
734		$wheres = [];
735
736		$select->addClause(new AccessWhereClause());
737
738		$select->joinPrivateSettingsTable('e', 'guid', null, 'inner','ps');
739
740		$private_setting = new PrivateSettingWhereClause();
741		$private_setting->names = ['foo1'];
742		$private_setting->values = ['bar1'];
743		$wheres[] = $private_setting->prepare($select, 'ps');
744
745		$private_setting = new PrivateSettingWhereClause();
746		$private_setting->names = ['foo2'];
747		$private_setting->values = ['bar2'];
748		$wheres[] = $private_setting->prepare($select, 'ps');
749
750		$select->andWhere($select->merge($wheres, 'OR'));
751
752		$select->setMaxResults(10);
753		$select->setFirstResult(0);
754
755		$select->orderBy('e.guid', 'asc');
756
757		$rows = $this->getRows(5);
758		$spec = _elgg_services()->db->addQuerySpec([
759			'sql' => $select->getSQL(),
760			'params' => $select->getParameters(),
761			'results' => $rows,
762		]);
763
764		$options = [
765			'callback' => false,
766			'private_setting_name_value_pairs' => [
767				'foo1' => 'bar1',
768				'foo2' => 'bar2',
769			],
770			'private_setting_name_value_pairs_operator' => 'OR',
771			'order_by' => [
772				new OrderByClause('e.guid', 'asc'),
773			],
774		];
775
776		$find = Entities::find($options);
777
778		$this->assertEquals($rows, $find);
779
780		_elgg_services()->db->removeQuerySpec($spec);
781	}
782
783	/**
784	 * @group RepositoryPairs
785	 */
786	public function testCanExecuteQueryWithRelationshipPairs() {
787
788		$select = Select::fromTable('entities', 'e');
789		$select->select('DISTINCT e.*');
790
791		$wheres = [];
792
793		$select->addClause(new AccessWhereClause());
794
795		$alias1 = $select->joinRelationshipTable('e', 'guid', ['foo1']);
796		$private_setting = new RelationshipWhereClause();
797		$private_setting->names = ['foo1'];
798		$private_setting->subject_guids = [1, 2, 3];
799		$wheres[] = $private_setting->prepare($select, $alias1);
800
801		$alias2 = $select->joinRelationshipTable('e', 'guid', ['foo2'], true);
802		$private_setting = new RelationshipWhereClause();
803		$private_setting->names = ['foo2'];
804		$private_setting->object_guids = [4, 5, 6];
805		$wheres[] = $private_setting->prepare($select, $alias2);
806
807		$select->andWhere($select->expr()->andX()->addMultiple($wheres));
808
809		$select->setMaxResults(10);
810		$select->setFirstResult(0);
811
812		$select->orderBy('e.guid', 'asc');
813
814		$rows = $this->getRows(5);
815		$spec = _elgg_services()->db->addQuerySpec([
816			'sql' => $select->getSQL(),
817			'params' => $select->getParameters(),
818			'results' => $rows,
819		]);
820
821		$options = [
822			'callback' => false,
823			'relationship_pairs' => [
824				[
825					'relationship' => 'foo1',
826					'relationship_guid' => [1, 2, 3],
827				],
828				[
829					'relationship' => 'foo2',
830					'relationship_guid' => [4, 5, 6],
831					'inverse_relationship' => true,
832				]
833			],
834			'order_by' => [
835				new OrderByClause('e.guid', 'asc'),
836			],
837		];
838
839		$find = Entities::find($options);
840
841		$this->assertEquals($rows, $find);
842
843		_elgg_services()->db->removeQuerySpec($spec);
844	}
845
846	public function testCanExecuteQueryWithRelationship() {
847
848		$select = Select::fromTable('entities', 'e');
849		$select->select('DISTINCT e.*');
850
851		$wheres = [];
852
853		$select->addClause(new AccessWhereClause());
854
855		$select->joinRelationshipTable('e', 'guid', null, false, 'inner','r');
856
857		$private_setting = new RelationshipWhereClause();
858		$private_setting->names = ['foo1'];
859		$private_setting->subject_guids = [1, 2, 3];
860		$wheres[] = $private_setting->prepare($select, 'r');
861
862		$select->andWhere($select->merge($wheres, 'OR'));
863
864		$select->setMaxResults(10);
865		$select->setFirstResult(0);
866
867		$select->orderBy('e.guid', 'asc');
868
869		$rows = $this->getRows(5);
870		$spec = _elgg_services()->db->addQuerySpec([
871			'sql' => $select->getSQL(),
872			'params' => $select->getParameters(),
873			'results' => $rows,
874		]);
875
876		$options = [
877			'callback' => false,
878			'relationship_guid' => [1, 2, 3],
879			'relationship' => ['foo1'],
880			'inverse_relationship' => false,
881			'order_by' => [
882				new OrderByClause('e.guid', 'asc'),
883			],
884		];
885
886		$find = Entities::find($options);
887
888		$this->assertEquals($rows, $find);
889
890		_elgg_services()->db->removeQuerySpec($spec);
891	}
892
893	public function getRows($limit = 10) {
894		$rows = [];
895		for ($i = 0; $i < $limit; $i++) {
896			$row = (object) [
897				'guid' => $i,
898				'owner_guid' => rand(100, 999),
899				'container_guid' => rand(100, 999),
900				'enabled' => 'yes',
901				'type' => 'object',
902				'subtype' => 'foo',
903				'access_id' => ACCESS_PUBLIC,
904				'time_created' => time(),
905				'time_updated' => null,
906				'last_action' => null,
907			];
908			$rows[] = $row;
909		}
910
911		return $rows;
912	}
913
914}
915