Skip to content

Commit 42585da

Browse files
committed
Merge branch 'master' of github.com:thecodingmachine/tdbm into setter_resource_null
2 parents 919e555 + 1b9acd0 commit 42585da

15 files changed

+485
-174
lines changed

.travis.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ matrix:
1212
env: PREFER_LOWEST="" DB=mysql COVERALLS=true
1313
- php: 7.1
1414
env: PREFER_LOWEST="--prefer-lowest" DB=mysql
15+
- php: 7.1
16+
env: PREFER_LOWEST="" DB=mysql8
17+
sudo: required
18+
services:
19+
- docker
1520
- php: 7.1
1621
env: PREFER_LOWEST="" DB=mariadb
1722
addons:
@@ -63,7 +68,15 @@ before_script:
6368
- if [ -z "$NO_WEAKREF" ] ; then pecl install weakref-beta; fi
6469
script:
6570
# Let's run the Oracle script only when the password is available (it is not available in forks unfortunately)
66-
- if [ "$DB" != "oracle" ] ; then ./vendor/bin/phpunit $PHPUNITFILE; else docker run -v $(pwd):/app -v $(pwd)/tests/Fixtures/oracle-startup.sql:/docker-entrypoint-initdb.d/oracle-startup.sql moufmouf/oracle-xe-php vendor/bin/phpunit $PHPUNITFILE; fi
71+
- |
72+
if [ "$DB" == "oracle" ] ; then
73+
docker run -v $(pwd):/app -v $(pwd)/tests/Fixtures/oracle-startup.sql:/docker-entrypoint-initdb.d/oracle-startup.sql moufmouf/oracle-xe-php vendor/bin/phpunit $PHPUNITFILE;
74+
elif [ "$DB" == "mysql8" ] ; then
75+
sudo /etc/init.d/mysql stop;
76+
tests/phpunit-mysql8.sh
77+
else
78+
./vendor/bin/phpunit $PHPUNITFILE;
79+
fi
6780
- composer phpstan
6881
- composer require-checker
6982
after_script:

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
],
2020
"require" : {
2121
"php" : ">=7.1",
22-
"mouf/magic-query" : "^1.2.8",
22+
"mouf/magic-query" : "^1.3.0",
2323
"mouf/schema-analyzer": "^1.1.4",
2424
"doctrine/dbal": "^2.9.2",
2525
"psr/log": "~1.0",

phpunit.mariadb.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,4 @@
3434
</exclude>
3535
</whitelist>
3636
</filter>
37-
<logging>
38-
<log type="coverage-html" target="build/coverage" charset="UTF-8" yui="true" highlight="true"/>
39-
<log type="coverage-clover" target="build/logs/clover.xml"/>
40-
</logging>
4137
</phpunit>

phpunit.mysql8.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit backupGlobals="false"
4+
backupStaticAttributes="false"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false"
11+
bootstrap="vendor/autoload.php"
12+
>
13+
<testsuites>
14+
<testsuite name="TDBM Test Suite">
15+
<directory>./tests/</directory>
16+
</testsuite>
17+
</testsuites>
18+
19+
<php>
20+
<!-- "Real" test database -->
21+
<var name="db_host" value="127.0.0.1" />
22+
<var name="db_username" value="root" />
23+
<var name="db_password" value="" />
24+
<var name="db_name" value="tdbm_testcase" />
25+
<var name="db_port" value="3306"/>
26+
<var name="db_driver" value="pdo_mysql"/>
27+
</php>
28+
29+
<filter>
30+
<whitelist processUncoveredFilesFromWhitelist="true">
31+
<directory suffix=".php">src/</directory>
32+
<exclude>
33+
<directory suffix=".php">src/Test</directory>
34+
</exclude>
35+
</whitelist>
36+
</filter>
37+
</phpunit>

src/InnerResultIterator.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\DBAL\Statement;
88
use Mouf\Database\MagicQuery;
99
use Psr\Log\LoggerInterface;
10+
use TheCodingMachine\TDBM\Utils\DbalUtils;
1011

1112
/*
1213
Copyright (C) 2006-2017 David Négrier - THE CODING MACHINE
@@ -85,7 +86,7 @@ public function __construct(string $magicSql, array $parameters, ?int $limit, ?i
8586

8687
private function getQuery(): string
8788
{
88-
$sql = $this->magicQuery->build($this->magicSql, $this->parameters);
89+
$sql = $this->magicQuery->buildPreparedStatement($this->magicSql, $this->parameters);
8990
$sql = $this->tdbmService->getConnection()->getDatabasePlatform()->modifyLimitQuery($sql, $this->limit, $this->offset);
9091
return $sql;
9192
}
@@ -96,7 +97,7 @@ protected function executeQuery(): void
9697

9798
$this->logger->debug('Running SQL request: '.$sql);
9899

99-
$this->statement = $this->tdbmService->getConnection()->executeQuery($sql, $this->parameters);
100+
$this->statement = $this->tdbmService->getConnection()->executeQuery($sql, $this->parameters, DbalUtils::generateArrayTypes($this->parameters));
100101

101102
$this->fetchStarted = true;
102103
}

src/QueryFactory/FindObjectsQueryFactory.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace TheCodingMachine\TDBM\QueryFactory;
55

6+
use Doctrine\Common\Cache\Cache;
67
use Doctrine\DBAL\Platforms\MySqlPlatform;
78
use Doctrine\DBAL\Schema\Schema;
89
use TheCodingMachine\TDBM\OrderByAnalyzer;
@@ -16,17 +17,32 @@ class FindObjectsQueryFactory extends AbstractQueryFactory
1617
private $mainTable;
1718
private $additionalTablesFetch;
1819
private $filterString;
20+
/**
21+
* @var Cache
22+
*/
23+
private $cache;
1924

20-
public function __construct(string $mainTable, array $additionalTablesFetch, $filterString, $orderBy, TDBMService $tdbmService, Schema $schema, OrderByAnalyzer $orderByAnalyzer)
25+
public function __construct(string $mainTable, array $additionalTablesFetch, $filterString, $orderBy, TDBMService $tdbmService, Schema $schema, OrderByAnalyzer $orderByAnalyzer, Cache $cache)
2126
{
2227
parent::__construct($tdbmService, $schema, $orderByAnalyzer, $orderBy);
2328
$this->mainTable = $mainTable;
2429
$this->additionalTablesFetch = $additionalTablesFetch;
2530
$this->filterString = $filterString;
31+
$this->cache = $cache;
2632
}
2733

2834
protected function compute(): void
2935
{
36+
$key = 'FindObjectsQueryFactory_'.$this->mainTable.'__'.implode('_/_',$this->additionalTablesFetch).'__'.$this->filterString.'__'.$this->orderBy;
37+
if ($this->cache->contains($key)) {
38+
[
39+
$this->magicSql,
40+
$this->magicSqlCount,
41+
$this->columnDescList
42+
] = $this->cache->fetch($key);
43+
return;
44+
}
45+
3046
list($columnDescList, $columnsList, $orderString) = $this->getColumnsList($this->mainTable, $this->additionalTablesFetch, $this->orderBy, true);
3147

3248
$sql = 'SELECT DISTINCT '.implode(', ', $columnsList).' FROM MAGICJOIN('.$this->mainTable.')';
@@ -54,5 +70,11 @@ protected function compute(): void
5470
$this->magicSql = $sql;
5571
$this->magicSqlCount = $countSql;
5672
$this->columnDescList = $columnDescList;
73+
74+
$this->cache->save($key, [
75+
$this->magicSql,
76+
$this->magicSqlCount,
77+
$this->columnDescList,
78+
]);
5779
}
5880
}

src/ResultIterator.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33

44
namespace TheCodingMachine\TDBM;
55

6+
use function array_map;
7+
use Doctrine\DBAL\Connection;
68
use Doctrine\DBAL\Statement;
9+
use function is_array;
10+
use function is_int;
711
use Mouf\Database\MagicQuery;
812
use TheCodingMachine\TDBM\QueryFactory\QueryFactory;
913
use Porpaginas\Result;
1014
use Psr\Log\LoggerInterface;
15+
use TheCodingMachine\TDBM\Utils\DbalUtils;
1116
use Traversable;
1217

1318
/*
@@ -82,9 +87,9 @@ public function __construct(QueryFactory $queryFactory, array $parameters, Objec
8287

8388
protected function executeCountQuery(): void
8489
{
85-
$sql = $this->magicQuery->build($this->queryFactory->getMagicSqlCount(), $this->parameters);
90+
$sql = $this->magicQuery->buildPreparedStatement($this->queryFactory->getMagicSqlCount(), $this->parameters);
8691
$this->logger->debug('Running count query: '.$sql);
87-
$this->totalCount = (int) $this->tdbmService->getConnection()->fetchColumn($sql, $this->parameters);
92+
$this->totalCount = (int) $this->tdbmService->getConnection()->fetchColumn($sql, $this->parameters, 0, DbalUtils::generateArrayTypes($this->parameters));
8893
}
8994

9095
/**

src/TDBMService.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ public function completeSave(): void
387387
*/
388388
public function buildFilterFromFilterBag($filter_bag, AbstractPlatform $platform, int $counter = 1): array
389389
{
390-
if ($filter_bag === null) {
390+
if ($filter_bag === null || $filter_bag === []) {
391391
return ['', [], $counter];
392392
} elseif (is_string($filter_bag)) {
393393
return [$filter_bag, [], $counter];
@@ -403,7 +403,7 @@ public function buildFilterFromFilterBag($filter_bag, AbstractPlatform $platform
403403
} else {
404404
$paramName = 'tdbmparam'.$counter;
405405
if (is_array($value)) {
406-
$sqlParts[] = $platform->quoteIdentifier($column).' IN :'.$paramName;
406+
$sqlParts[] = $platform->quoteIdentifier($column).' IN (:'.$paramName.')';
407407
} else {
408408
$sqlParts[] = $platform->quoteIdentifier($column).' = :'.$paramName;
409409
}
@@ -412,7 +412,7 @@ public function buildFilterFromFilterBag($filter_bag, AbstractPlatform $platform
412412
}
413413
}
414414

415-
return [implode(' AND ', $sqlParts), $parameters, $counter];
415+
return ['(' . implode(') AND (', $sqlParts) . ')', $parameters, $counter];
416416
} elseif ($filter_bag instanceof AbstractTDBMObject) {
417417
$sqlParts = [];
418418
$parameters = [];
@@ -1134,7 +1134,7 @@ public function findObjects(string $mainTable, $filter = null, array $parameters
11341134

11351135
$parameters = array_merge($parameters, $additionalParameters);
11361136

1137-
$queryFactory = new FindObjectsQueryFactory($mainTable, $additionalTablesFetch, $filterString, $orderString, $this, $this->tdbmSchemaAnalyzer->getSchema(), $this->orderByAnalyzer);
1137+
$queryFactory = new FindObjectsQueryFactory($mainTable, $additionalTablesFetch, $filterString, $orderString, $this, $this->tdbmSchemaAnalyzer->getSchema(), $this->orderByAnalyzer, $this->cache);
11381138

11391139
return new ResultIterator($queryFactory, $parameters, $this->objectStorage, $className, $this, $this->magicQuery, $mode, $this->logger);
11401140
}

src/UncheckedOrderBy.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,12 @@ public function getOrderBy() : string
3535
{
3636
return $this->orderBy;
3737
}
38+
39+
/**
40+
* @return string
41+
*/
42+
public function __toString()
43+
{
44+
return 'UncheckedOrderBy_'.$this->orderBy;
45+
}
3846
}

src/Utils/DbalUtils.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
4+
namespace TheCodingMachine\TDBM\Utils;
5+
6+
use Doctrine\DBAL\Connection;
7+
use function is_array;
8+
use function is_int;
9+
10+
/**
11+
* Utility class to ease the use of DBAL types.
12+
*/
13+
class DbalUtils
14+
{
15+
/**
16+
* If a parameter is an array (used in a "IN" statement), we need to tell Doctrine about it.
17+
* @see https://www.doctrine-project.org/projects/doctrine-dbal/en/2.9/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion
18+
* @param array<string, mixed> $parameters
19+
* @return array<string, int>
20+
*/
21+
public static function generateArrayTypes(array $parameters): array
22+
{
23+
$types = [];
24+
foreach ($parameters as $key => $value) {
25+
if (is_array($value)) {
26+
foreach ($value as $val) {
27+
if (!is_int($val)) {
28+
$types[$key] = Connection::PARAM_STR_ARRAY;
29+
continue 2;
30+
}
31+
}
32+
$types[$key] = Connection::PARAM_INT_ARRAY;
33+
}
34+
}
35+
36+
return $types;
37+
}
38+
}

0 commit comments

Comments
 (0)