diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 4def945..1a0152a 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -925,6 +925,10 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' } } + if (func_num_args() == 1 && is_string($column)) { + throw new \ArgumentCountError(sprintf('Too few arguments to function %s("%s"), 1 passed and at least 2 expected when the 1st is a string.', __METHOD__, $column)); + } + return parent::where(...$params); } @@ -1378,4 +1382,28 @@ public function havingBetween($column, iterable $values, $boolean = 'and', $not { throw new \BadMethodCallException('This method is not supported by MongoDB'); } + + /** @internal This method is not supported by MongoDB. */ + public function whereIntegerInRaw($column, $values, $boolean = 'and', $not = false) + { + throw new \BadMethodCallException('This method is not supported by MongoDB'); + } + + /** @internal This method is not supported by MongoDB. */ + public function orWhereIntegerInRaw($column, $values) + { + throw new \BadMethodCallException('This method is not supported by MongoDB'); + } + + /** @internal This method is not supported by MongoDB. */ + public function whereIntegerNotInRaw($column, $values, $boolean = 'and') + { + throw new \BadMethodCallException('This method is not supported by MongoDB'); + } + + /** @internal This method is not supported by MongoDB. */ + public function orWhereIntegerNotInRaw($column, $values, $boolean = 'and') + { + throw new \BadMethodCallException('This method is not supported by MongoDB'); + } } diff --git a/tests/Query/BuilderTest.php b/tests/Query/BuilderTest.php index fb5bc20..8f7d8f8 100644 --- a/tests/Query/BuilderTest.php +++ b/tests/Query/BuilderTest.php @@ -45,7 +45,36 @@ public static function provideQueryBuilderToMql(): iterable */ $date = new DateTimeImmutable('2016-07-12 15:30:00'); - yield 'find' => [ + yield 'select replaces previous select' => [ + ['find' => [[], ['projection' => ['bar' => 1]]]], + fn (Builder $builder) => $builder->select('foo')->select('bar'), + ]; + + yield 'select array' => [ + ['find' => [[], ['projection' => ['foo' => 1, 'bar' => 1]]]], + fn (Builder $builder) => $builder->select(['foo', 'bar']), + ]; + + /** @see DatabaseQueryBuilderTest::testAddingSelects */ + yield 'addSelect' => [ + ['find' => [[], ['projection' => ['foo' => 1, 'bar' => 1, 'baz' => 1, 'boom' => 1]]]], + fn (Builder $builder) => $builder->select('foo') + ->addSelect('bar') + ->addSelect(['baz', 'boom']) + ->addSelect('bar'), + ]; + + yield 'select all' => [ + ['find' => [[], []]], + fn (Builder $builder) => $builder->select('*'), + ]; + + yield 'find all with select' => [ + ['find' => [[], ['projection' => ['foo' => 1, 'bar' => 1]]]], + fn (Builder $builder) => $builder->select('foo', 'bar'), + ]; + + yield 'find equals' => [ ['find' => [['foo' => 'bar'], []]], fn (Builder $builder) => $builder->where('foo', 'bar'), ]; @@ -66,11 +95,55 @@ public static function provideQueryBuilderToMql(): iterable fn (Builder $builder) => $builder->where('foo', '>', $date), ]; - yield 'find in array' => [ + /** @see DatabaseQueryBuilderTest::testBasicWhereIns */ + yield 'whereIn' => [ ['find' => [['foo' => ['$in' => ['bar', 'baz']]], []]], fn (Builder $builder) => $builder->whereIn('foo', ['bar', 'baz']), ]; + // Nested array are not flattened like in the Eloquent builder. MongoDB can compare objects. + $array = [['issue' => 45582], ['id' => 2], [3]]; + yield 'whereIn nested array' => [ + ['find' => [['id' => ['$in' => $array]], []]], + fn (Builder $builder) => $builder->whereIn('id', $array), + ]; + + yield 'orWhereIn' => [ + ['find' => [ + ['$or' => [ + ['id' => 1], + ['id' => ['$in' => [1, 2, 3]]], + ]], + [], // options + ]], + fn (Builder $builder) => $builder->where('id', '=', 1) + ->orWhereIn('id', [1, 2, 3]), + ]; + + /** @see DatabaseQueryBuilderTest::testBasicWhereNotIns */ + yield 'whereNotIn' => [ + ['find' => [['id' => ['$nin' => [1, 2, 3]]], []]], + fn (Builder $builder) => $builder->whereNotIn('id', [1, 2, 3]), + ]; + + yield 'orWhereNotIn' => [ + ['find' => [ + ['$or' => [ + ['id' => 1], + ['id' => ['$nin' => [1, 2, 3]]], + ]], + [], // options + ]], + fn (Builder $builder) => $builder->where('id', '=', 1) + ->orWhereNotIn('id', [1, 2, 3]), + ]; + + /** @see DatabaseQueryBuilderTest::testEmptyWhereIns */ + yield 'whereIn empty array' => [ + ['find' => [['id' => ['$in' => []]], []]], + fn (Builder $builder) => $builder->whereIn('id', []), + ]; + yield 'find limit offset select' => [ ['find' => [[], ['limit' => 10, 'skip' => 5, 'projection' => ['foo' => 1, 'bar' => 1]]]], fn (Builder $builder) => $builder->limit(10)->offset(5)->select('foo', 'bar'), @@ -266,6 +339,43 @@ public static function provideQueryBuilderToMql(): iterable fn (Builder $builder) => $builder->forPage(3, 20), ]; + /** @see DatabaseQueryBuilderTest::testLimitsAndOffsets() */ + yield 'offset limit' => [ + ['find' => [[], ['skip' => 5, 'limit' => 10]]], + fn (Builder $builder) => $builder->offset(5)->limit(10), + ]; + + yield 'offset limit zero (unset)' => [ + ['find' => [[], []]], + fn (Builder $builder) => $builder + ->offset(0)->limit(0), + ]; + + yield 'offset limit zero (reset)' => [ + ['find' => [[], []]], + fn (Builder $builder) => $builder + ->offset(5)->limit(10) + ->offset(0)->limit(0), + ]; + + yield 'offset limit negative (unset)' => [ + ['find' => [[], []]], + fn (Builder $builder) => $builder + ->offset(-5)->limit(-10), + ]; + + yield 'offset limit null (reset)' => [ + ['find' => [[], []]], + fn (Builder $builder) => $builder + ->offset(5)->limit(10) + ->offset(null)->limit(null), + ]; + + yield 'skip take (aliases)' => [ + ['find' => [[], ['skip' => 5, 'limit' => 10]]], + fn (Builder $builder) => $builder->skip(5)->limit(10), + ]; + /** @see DatabaseQueryBuilderTest::testOrderBys() */ yield 'orderBy multiple columns' => [ ['find' => [[], ['sort' => ['email' => 1, 'age' => -1]]]], @@ -452,11 +562,57 @@ function (Builder $builder) { ->orWhereNotBetween('id', collect([3, 4])), ]; + /** @see DatabaseQueryBuilderTest::testBasicSelectDistinct */ yield 'distinct' => [ ['distinct' => ['foo', [], []]], fn (Builder $builder) => $builder->distinct('foo'), ]; + yield 'select distinct' => [ + ['distinct' => ['foo', [], []]], + fn (Builder $builder) => $builder->select('foo', 'bar') + ->distinct(), + ]; + + /** @see DatabaseQueryBuilderTest::testBasicSelectDistinctOnColumns */ + yield 'select distinct on' => [ + ['distinct' => ['foo', [], []]], + fn (Builder $builder) => $builder->distinct('foo') + ->select('foo', 'bar'), + ]; + + /** @see DatabaseQueryBuilderTest::testLatest() */ + yield 'latest' => [ + ['find' => [[], ['sort' => ['created_at' => -1]]]], + fn (Builder $builder) => $builder->latest(), + ]; + + yield 'latest limit' => [ + ['find' => [[], ['sort' => ['created_at' => -1], 'limit' => 1]]], + fn (Builder $builder) => $builder->latest()->limit(1), + ]; + + yield 'latest custom field' => [ + ['find' => [[], ['sort' => ['updated_at' => -1]]]], + fn (Builder $builder) => $builder->latest('updated_at'), + ]; + + /** @see DatabaseQueryBuilderTest::testOldest() */ + yield 'oldest' => [ + ['find' => [[], ['sort' => ['created_at' => 1]]]], + fn (Builder $builder) => $builder->oldest(), + ]; + + yield 'oldest limit' => [ + ['find' => [[], ['sort' => ['created_at' => 1], 'limit' => 1]]], + fn (Builder $builder) => $builder->oldest()->limit(1), + ]; + + yield 'oldest custom field' => [ + ['find' => [[], ['sort' => ['updated_at' => 1]]]], + fn (Builder $builder) => $builder->oldest('updated_at'), + ]; + yield 'groupBy' => [ ['aggregate' => [ [['$group' => ['_id' => ['foo' => '$foo'], 'foo' => ['$last' => '$foo']]]], @@ -516,6 +672,12 @@ public static function provideExceptions(): iterable 'Between $values must be a list with exactly two elements: [min, max]', fn (Builder $builder) => $builder->whereBetween('id', ['min' => 1, 'max' => 2]), ]; + + yield 'find with single string argument' => [ + \ArgumentCountError::class, + 'Too few arguments to function Jenssegers\Mongodb\Query\Builder::where("foo"), 1 passed and at least 2 expected when the 1st is a string', + fn (Builder $builder) => $builder->where('foo'), + ]; } /** @dataProvider getEloquentMethodsNotSupported */ @@ -562,6 +724,18 @@ public static function getEloquentMethodsNotSupported() yield 'having' => [fn (Builder $builder) => $builder->having('baz', '=', 1)]; yield 'havingBetween' => [fn (Builder $builder) => $builder->havingBetween('last_login_date', ['2018-11-16', '2018-12-16'])]; yield 'orHavingRaw' => [fn (Builder $builder) => $builder->orHavingRaw('user_foo < user_bar')]; + + /** @see DatabaseQueryBuilderTest::testWhereIntegerInRaw */ + yield 'whereIntegerInRaw' => [fn (Builder $builder) => $builder->whereIntegerInRaw('id', ['1a', 2])]; + + /** @see DatabaseQueryBuilderTest::testOrWhereIntegerInRaw */ + yield 'orWhereIntegerInRaw' => [fn (Builder $builder) => $builder->orWhereIntegerInRaw('id', ['1a', 2])]; + + /** @see DatabaseQueryBuilderTest::testWhereIntegerNotInRaw */ + yield 'whereIntegerNotInRaw' => [fn (Builder $builder) => $builder->whereIntegerNotInRaw('id', ['1a', 2])]; + + /** @see DatabaseQueryBuilderTest::testOrWhereIntegerNotInRaw */ + yield 'orWhereIntegerNotInRaw' => [fn (Builder $builder) => $builder->orWhereIntegerNotInRaw('id', ['1a', 2])]; } private static function getBuilder(): Builder diff --git a/tests/TransactionTest.php b/tests/TransactionTest.php index 46fbf2e..06f1c21 100644 --- a/tests/TransactionTest.php +++ b/tests/TransactionTest.php @@ -332,7 +332,7 @@ public function testTransaction(): void $count = User::count(); $this->assertEquals(2, $count); - $this->assertTrue(User::where('alcaeus')->exists()); + $this->assertTrue(User::where('name', 'alcaeus')->exists()); $this->assertTrue(User::where(['name' => 'klinson'])->where('age', 21)->exists()); }