getTableLocator()->get('Articles'); $driver = $articles->getConnection()->getDriver(); if ( $driver instanceof Sqlite || $driver instanceof Sqlserver ) { $this->expectException(RuntimeException::class); $this->expectExceptionMessage( 'Tuple comparison transform only supports the `IN` and `=` operators, `NOT IN` given.' ); } else { $this->markTestSkipped('Tuple comparisons are only being transformed for Sqlite and Sqlserver.'); } $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], $articles ->subquery() ->select(['ArticlesAlias.id', 'ArticlesAlias.author_id']) ->from(['ArticlesAlias' => $articles->getTable()]) ->where(['ArticlesAlias.author_id' => 1]), [], 'NOT IN' ), ]) ->orderAsc('Articles.id') ->disableHydration() ->toArray(); } public function testInWithMultiResultSubquery(): void { $articles = $this->getTableLocator()->get('Articles'); $query = $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], $articles ->subquery() ->select(['ArticlesAlias.id', 'ArticlesAlias.author_id']) ->from(['ArticlesAlias' => $articles->getTable()]) ->where(['ArticlesAlias.author_id' => 1]), [], 'IN' ), ]) ->orderAsc('Articles.id') ->disableHydration(); $expected = [ [ 'id' => 1, 'author_id' => 1, ], [ 'id' => 3, 'author_id' => 1, ], ]; $this->assertSame($expected, $query->toArray()); } public function testInWithSingleResultSubquery(): void { $articles = $this->getTableLocator()->get('Articles'); $query = $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], $articles ->subquery() ->select(['ArticlesAlias.id', 'ArticlesAlias.author_id']) ->from(['ArticlesAlias' => $articles->getTable()]) ->where(['ArticlesAlias.id' => 1]), [], 'IN' ), ]) ->disableHydration(); $expected = [ [ 'id' => 1, 'author_id' => 1, ], ]; $this->assertSame($expected, $query->toArray()); } public function testInWithMultiArrayValues(): void { $articles = $this->getTableLocator()->get('Articles'); $query = $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], [[1, 1], [3, 1]], ['integer', 'integer'], 'IN' ), ]) ->orderAsc('Articles.id') ->disableHydration(); $expected = [ [ 'id' => 1, 'author_id' => 1, ], [ 'id' => 3, 'author_id' => 1, ], ]; $this->assertSame($expected, $query->toArray()); } public function testEqualWithMultiResultSubquery(): void { $articles = $this->getTableLocator()->get('Articles'); $driver = $articles->getConnection()->getDriver(); if ( $driver instanceof Mysql || $driver instanceof Postgres ) { $this->expectException(PDOException::class); $this->expectExceptionMessageMatches('/cardinality violation/i'); } else { // Due to the way tuple comparisons are being translated, the DBMS will // not run into a cardinality violation scenario. $this->markTestSkipped( 'Sqlite and Sqlserver currently do not fail with subqueries returning incompatible results.' ); } $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], $articles ->subquery() ->select(['ArticlesAlias.id', 'ArticlesAlias.author_id']) ->from(['ArticlesAlias' => $articles->getTable()]) ->where(['ArticlesAlias.author_id' => 1]), [], '=' ), ]) ->orderAsc('Articles.id') ->disableHydration() ->toArray(); } public function testEqualWithSingleResultSubquery(): void { $articles = $this->getTableLocator()->get('Articles'); $query = $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], $articles ->subquery() ->select(['ArticlesAlias.id', 'ArticlesAlias.author_id']) ->from(['ArticlesAlias' => $articles->getTable()]) ->where(['ArticlesAlias.id' => 1]), [], '=' ), ]) ->disableHydration(); $expected = [ [ 'id' => 1, 'author_id' => 1, ], ]; $this->assertSame($expected, $query->toArray()); } public function testEqualWithSingleArrayValue(): void { $articles = $this->getTableLocator()->get('Articles'); $query = $articles ->find() ->select(['Articles.id', 'Articles.author_id']) ->where([ new TupleComparison( ['Articles.id', 'Articles.author_id'], [1, 1], ['integer', 'integer'], '=' ), ]) ->orderAsc('Articles.id') ->disableHydration(); $expected = [ [ 'id' => 1, 'author_id' => 1, ], ]; $this->assertSame($expected, $query->toArray()); } }