Merge branch 'develop' into 'master'

merging CI and nailed-down drivers

See merge request byjoby/destructr!2
This commit is contained in:
Joby Elliott 2018-09-19 21:20:20 +00:00
commit 1ea866da71
15 changed files with 73 additions and 140 deletions

1
.gitignore vendored
View file

@ -3,4 +3,5 @@ composer.lock
.phpunit.result.cache .phpunit.result.cache
test.php test.php
test.sqlite test.sqlite
*.test.sqlite
.DS_Store .DS_Store

28
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,28 @@
image: php:7.1-alpine
services:
- mysql:latest
variables:
MYSQL_DATABASE: destructr_test
MYSQL_ROOT_PASSWORD: badpassword
before_script:
- apk update
- apk add git
- docker-php-ext-install pdo
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install
test:local:
script:
- php composer.phar test-local
test:mysql:
script:
- docker-php-ext-install pdo_mysql
- php composer.phar test-mysql
test:sqlite:
script:
- php composer.phar test-sqlite

View file

@ -21,11 +21,11 @@
"test-local": [ "test-local": [
"phpunit --testsuite Local" "phpunit --testsuite Local"
], ],
"test-db": [ "test-mysql": [
"phpunit --testsuite DB" "phpunit --testsuite MySQL"
], ],
"test-legacydb": [ "test-sqlite": [
"phpunit --testsuite LegacyDB" "phpunit --testsuite SQLite"
] ]
}, },
"autoload": { "autoload": {

View file

@ -5,11 +5,11 @@
<exclude>tests/Drivers</exclude> <exclude>tests/Drivers</exclude>
<exclude>tests/LegacyDrivers</exclude> <exclude>tests/LegacyDrivers</exclude>
</testsuite> </testsuite>
<testsuite name="DB"> <testsuite name="MySQL">
<directory>tests/Drivers</directory> <directory>tests/Drivers/MySQL</directory>
</testsuite> </testsuite>
<testsuite name="LegacyDB"> <testsuite name="SQLite">
<directory>tests/LegacyDrivers</directory> <directory>tests/LegacyDrivers/SQLite</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>
</phpunit> </phpunit>

View file

@ -83,7 +83,7 @@ abstract class AbstractDriver implements DSODriverInterface
if (!$s->execute($params)) { if (!$s->execute($params)) {
return []; return [];
} }
return $s->fetchAll(\PDO::FETCH_ASSOC); return @$s->fetchAll(\PDO::FETCH_ASSOC);
} }
public function insert(string $table, DSOInterface $dso) : bool public function insert(string $table, DSOInterface $dso) : bool

View file

@ -1,35 +0,0 @@
<?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr\LegacyDrivers;
/**
* What this driver supports: MySQL 5.6, as long as you have permissions to
* create user-defined functions
*
* Also, this driver does flatten its JSON data, so complex unstructured data
* will not be straight compatible with modern drivers. You'll need to run a
* migration tool to unflatten and resave everything.
*
* Complex queries on JSON fields will almost certainly fail in edge cases.
* This should work for most basic uses though.
*/
class MySQL56Driver extends AbstractLegacyDriver
{
public function createTable(string $table, array $virtualColumns) : bool
{
$this->createLegacyUDF();
return parent::createTable($table, $virtualColumns);
}
public function createLegacyUDF()
{
$drop = $this->pdo->exec('DROP FUNCTION IF EXISTS `destructr_json_extract`;');
$create = $this->pdo->exec(file_get_contents(__DIR__.'/destructr_json_extract.sql'));
}
protected function expandPath(string $path) : string
{
$path = str_replace('.', '|', $path);
return "destructr_json_extract(`json_data`,'$.{$path}')";
}
}

View file

@ -41,19 +41,5 @@ using SQLite if you don't have access to a fully supported database version.
### MySQL 5.6 ### MySQL 5.6
**\Destructr\LegacyDrivers\MySQL56Driver** ** No longer supported. You should really use SQLite if you don't have access to
something better. Will most likely never be supported. **
**Overall support level: Decent performance, highly suspect accuracy**
LegacyDrivers\MySQL56Driver provides bare-minimum support for MySQL < 5.7.
This driver now passes the basic tests and basic integration tests, but hasn't
been verified in the slightest beyond that.
It flattens unstructured JSON and uses a highly dodgy user-defined function to
extract values from it. There are absolutely edge cases that will extract the
wrong data. That said, outside of those edge cases it should actually work
fairly well. All the sorting and filtering is happening in SQL, and things
should mostly be fairly predictable.
This driver should be your last resort. I cannot emphasize enough that this
thing is extremely kludgey and should not be trusted.

View file

@ -1,29 +0,0 @@
CREATE FUNCTION `destructr_json_extract`(
details TEXT,
required_field VARCHAR (255)
) RETURNS TEXT CHARSET utf8
BEGIN
DECLARE search_term TEXT;
SET details = SUBSTRING_INDEX(details, "{", -1);
SET details = SUBSTRING_INDEX(details, "}", 1);
SET search_term = CONCAT('"', SUBSTRING_INDEX(required_field,'$.', - 1), '"');
IF INSTR(details, search_term) > 0 THEN
RETURN TRIM(
BOTH '"' FROM SUBSTRING_INDEX(
SUBSTRING_INDEX(
SUBSTRING_INDEX(
details,
search_term,
- 1
),
',"',
1
),
':',
-1
)
);
ELSE
RETURN NULL;
END IF;
END;

View file

@ -1,7 +1,7 @@
<?php <?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */ /* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1); declare(strict_types=1);
namespace Destructr\Drivers\IntegrationTests; namespace Destructr\Drivers;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use PHPUnit\DbUnit\TestCaseTrait; use PHPUnit\DbUnit\TestCaseTrait;

View file

@ -1,16 +0,0 @@
<?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Destructr\Drivers\IntegrationTests;
use PHPUnit\Framework\TestCase;
class MySQLDriverTest extends AbstractDriverIntegrationTest
{
const DRIVER_CLASS = \Destructr\Drivers\MySQLDriver::class;
const DRIVER_DSN = 'mysql:host=127.0.0.1;dbname=phpunit';
const DRIVER_USERNAME = 'travis';
const DRIVER_PASSWORD = null;
const DRIVER_OPTIONS = null;
const TEST_TABLE = 'mysqlintegrationtest';
}

View file

@ -0,0 +1,18 @@
<?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Destructr\Drivers\MySQL;
use PHPUnit\Framework\TestCase;
use Destructr\Drivers\AbstractDriverIntegrationTest;
use Destructr\Drivers\MySQLDriver;
class MySQLDriverIntegrationTest extends AbstractDriverIntegrationTest
{
const DRIVER_CLASS = \Destructr\Drivers\MySQLDriver::class;
const DRIVER_DSN = 'mysql:host=mysql;dbname=destructr_test';
const DRIVER_USERNAME = 'root';
const DRIVER_PASSWORD = 'badpassword';
const DRIVER_OPTIONS = null;
const TEST_TABLE = 'integrationtest';
}

View file

@ -1,15 +1,17 @@
<?php <?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */ /* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1); declare(strict_types=1);
namespace Destructr\Drivers; namespace Destructr\Drivers\MySQL;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Destructr\Drivers\AbstractDriverTest;
use Destructr\Drivers\MySQLDriver;
class MySQLDriverTest extends AbstractDriverTest class MySQLDriverTest extends AbstractDriverTest
{ {
const DRIVER_CLASS = MySQLDriver::class; const DRIVER_CLASS = MySQLDriver::class;
const DRIVER_DSN = 'mysql:host=127.0.0.1;dbname=phpunit'; const DRIVER_DSN = 'mysql:host=mysql;dbname=destructr_test';
const DRIVER_USERNAME = 'travis'; const DRIVER_USERNAME = 'root';
const DRIVER_PASSWORD = null; const DRIVER_PASSWORD = 'badpassword';
const DRIVER_OPTIONS = null; const DRIVER_OPTIONS = null;
} }

View file

@ -1,23 +0,0 @@
<?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Destructr\LegacyDrivers;
use PHPUnit\Framework\TestCase;
use Destructr\Drivers\AbstractDriverTest;
class MySQL56DriverTest extends AbstractDriverTest
{
const DRIVER_CLASS = \Destructr\LegacyDrivers\MySQL56Driver::class;
const DRIVER_DSN = 'mysql:host=127.0.0.1;dbname=phpunit';
const DRIVER_USERNAME = 'travis';
const DRIVER_PASSWORD = null;
const DRIVER_OPTIONS = null;
public function createDriver()
{
$class = parent::createDriver();
$class->createLegacyUDF();
return $class;
}
}

View file

@ -1,16 +1,16 @@
<?php <?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */ /* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1); declare(strict_types=1);
namespace Destructr\LegacyDrivers\IntegrationTests; namespace Destructr\LegacyDrivers\SQLite;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Destructr\Drivers\IntegrationTests\AbstractDriverIntegrationTest; use Destructr\Drivers\AbstractDriverIntegrationTest;
use Destructr\LegacyDrivers\SQLiteDriver; use Destructr\LegacyDrivers\SQLiteDriver;
class MySQLDriverTest extends AbstractDriverIntegrationTest class MySQLDriverTest extends AbstractDriverIntegrationTest
{ {
const DRIVER_CLASS = SQLiteDriver::class; const DRIVER_CLASS = SQLiteDriver::class;
const DRIVER_DSN = 'sqlite:'.__DIR__.'/test.sqlite'; const DRIVER_DSN = 'sqlite:'.__DIR__.'/integration.test.sqlite';
const DRIVER_USERNAME = null; const DRIVER_USERNAME = null;
const DRIVER_PASSWORD = null; const DRIVER_PASSWORD = null;
const DRIVER_OPTIONS = null; const DRIVER_OPTIONS = null;
@ -18,6 +18,6 @@ class MySQLDriverTest extends AbstractDriverIntegrationTest
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
@unlink(__DIR__.'/test.sqlite'); @unlink(__DIR__.'/integration.test.sqlite');
} }
} }

View file

@ -1,21 +1,22 @@
<?php <?php
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */ /* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1); declare(strict_types=1);
namespace Destructr\LegacyDrivers; namespace Destructr\LegacyDrivers\SQLite;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Destructr\Drivers\AbstractDriverTest; use Destructr\Drivers\AbstractDriverTest;
use Destructr\LegacyDrivers\SQLiteDriver;
class SQLiteDriverTest extends AbstractDriverTest class SQLiteDriverTest extends AbstractDriverTest
{ {
const DRIVER_CLASS = SQLiteDriver::class; const DRIVER_CLASS = SQLiteDriver::class;
const DRIVER_DSN = 'sqlite:'.__DIR__.'/test.sqlite'; const DRIVER_DSN = 'sqlite:'.__DIR__.'/driver.test.sqlite';
const DRIVER_USERNAME = null; const DRIVER_USERNAME = null;
const DRIVER_PASSWORD = null; const DRIVER_PASSWORD = null;
const DRIVER_OPTIONS = null; const DRIVER_OPTIONS = null;
public static function setUpBeforeClass() public static function setUpBeforeClass()
{ {
@unlink(__DIR__.'/test.sqlite'); @unlink(__DIR__.'/driver.test.sqlite');
} }
} }