Merge branch 'develop' into 'master'

housekeeping

See merge request byjoby/destructr!1
This commit is contained in:
Joby Elliott 2018-08-20 01:00:57 +00:00
commit 13371f25db
28 changed files with 100 additions and 343 deletions

View file

@ -21,13 +21,13 @@ In order to read/write objects from a database table, you'll need to configure a
// DriverFactory::factory() has the same arguments as PDO::__construct
// You can also construct a driver directly, from a class in Drivers,
// but for common databases DriverFactory::factory should pick the right class
$driver = \Digraph\DriverFactory::factory(
$driver = \Destructr\DriverFactory::factory(
'mysql:host=127.0.0.1',
'username',
'password'
);
// Driver is then used to construct a Factory
$factory = new \Digraph\Destructr\Factory(
$factory = new \Destructr\Factory(
$driver, //driver is used to manage connection and generate queries
'dso_objects' //all of a Factory's data is stored in a single table
);

View file

@ -1,23 +0,0 @@
Date: 2018-08-10T03:16:29+01:00
Machine: PAULZE
Ops per: 1000
Each result is the average number of milliseconds it took to complete each operation. Lower is better.
Digraph\Destructr\Drivers\MySQLDriver
insert: 30.19ms
update: 31.07ms
search vcol: 147.44ms
search json: 154.34ms
Digraph\Destructr\LegacyDrivers\MySQL56Driver
insert: 32.89ms
update: 25.11ms
search vcol: 174.05ms
search json: 192.56ms
Digraph\Destructr\LegacyDrivers\SQLiteDriver
insert: 140.28ms
update: 145.12ms
search vcol: 157.92ms
search json: 165.01ms

View file

@ -1,143 +0,0 @@
<?php
/**
* This benchmarking script uses the same connection settings as the unit tests,
* so if you've got that working it should work too.
*/
include_once __DIR__.'/../vendor/autoload.php';
use Digraph\Destructr\Factory;
use Digraph\Destructr\Drivers\MySQLDriver;
use Digraph\Destructr\LegacyDrivers\SQLiteDriver;
use Digraph\Destructr\LegacyDrivers\MySQL56Driver;
const OPS_PER = 1000;
$dsos = [];
$out = [];
$out[] = 'Date: '.date('c');
$out[] = 'Machine: '.gethostname();
$out[] = 'Ops per: '.OPS_PER;
$out[] = 'Each result is the average number of milliseconds it took to complete each operation. Lower is better.';
$out[] = '';
foreach (drivers_list() as $class => $config) {
$driver = new $class(@$config['dsn'], @$config['username'], @$config['password'], @$config['options']);
$factory = new Factory($driver, $config['table']);
$factory->createTable();
benchmark_empty($factory);
$out[] = $class;
$out[] = benchmark_insert($factory);
$out[] = benchmark_update($factory);
$out[] = benchmark_search_vcol($factory);
$out[] = benchmark_search_json($factory);
$out[]= '';
}
$out[] = '';
file_put_contents(__DIR__.'/results.txt', implode(PHP_EOL, $out));
/**
* The classes and connection settings for benchmarking
*/
function drivers_list()
{
@unlink(__DIR__.'/test.sqlite');
$out = [];
$out[MySQLDriver::class] = [
'table' => 'benchmark57',
'dsn' => 'mysql:host=127.0.0.1;dbname=phpunit',
'username' => 'travis'
];
$out[MySQL56Driver::class] = [
'table' => 'benchmark56',
'dsn' => 'mysql:host=127.0.0.1;dbname=phpunit',
'username' => 'travis'
];
$out[SQLiteDriver::class] = [
'table' => 'benchmark',
'dsn' => 'sqlite:'.__DIR__.'/test.sqlite'
];
return $out;
}
/**
* Empties a table before beginning
*/
function benchmark_empty(&$factory)
{
global $dsos;
$dsos = [];
foreach ($factory->search()->execute([], null) as $o) {
$o->delete(true);
}
}
/**
* Benchmark insert operations
*/
function benchmark_insert(&$factory)
{
global $dsos;
$start = microtime(true);
for ($i=0; $i < OPS_PER; $i++) {
$dsos[$i] = $factory->create(
[
'dso.id'=>'benchmark-'.$i,
'dso.type'=>'benchmark-'.($i%2?'odd':'even'),
'benchmark.mod'=>($i%2?'odd':'even')
]
);
$dsos[$i]->insert();
}
$end = microtime(true);
$per = round(($end-$start)*100000/OPS_PER)/100;
return 'insert: '.$per.'ms';
}
/**
* Benchmark update operations
*/
function benchmark_update(&$factory)
{
global $dsos;
$start = microtime(true);
for ($i=0; $i < OPS_PER; $i++) {
$dsos[$i]['benchmark.int'] = $i;
$dsos[$i]['benchmark.string'] = 'benchmark-'.$i;
$dsos[$i]->update();
}
$end = microtime(true);
$per = round(($end-$start)*100000/OPS_PER)/100;
return 'update: '.$per.'ms';
}
/**
* Benchmark searching on a vcol
*/
function benchmark_search_vcol(&$factory)
{
$start = microtime(true);
for ($i=0; $i < OPS_PER; $i++) {
$search = $factory->search();
$search->where('${dso.type} = :type');
$search->execute([':type'=>'benchmark-odd']);
}
$end = microtime(true);
$per = round(($end-$start)*100000/OPS_PER)/100;
return 'search vcol: '.$per.'ms';
}
/**
* Benchmark searching on a JSON value
*/
function benchmark_search_json(&$factory)
{
$start = microtime(true);
for ($i=0; $i < OPS_PER; $i++) {
$search = $factory->search();
$search->where('${benchmark.mod} = :type');
$search->execute([':type'=>'even']);
}
$end = microtime(true);
$per = round(($end-$start)*100000/OPS_PER)/100;
return 'search json: '.$per.'ms';
}

View file

@ -7,8 +7,8 @@
"prefer-stable": true,
"require": {
"php": ">=7.1",
"digraphcms/utilities": "^0.6",
"mofodojodino/profanity-filter": "^1.3"
"mofodojodino/profanity-filter": "^1.3",
"byjoby/flatrr": "dev-master"
},
"require-dev": {
"phpunit/phpunit": "^7",
@ -30,12 +30,12 @@
},
"autoload": {
"psr-4": {
"Digraph\\Destructr\\": "src/"
"Destructr\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Digraph\\Destructr\\": "tests/"
"Destructr\\": "tests/"
}
}
}

View file

@ -1,8 +1,8 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
use \Digraph\FlatArray\FlatArray;
use \Flatrr\FlatArray;
/**
* Interface for DeStructure Objects (DSOs). These are the class that is

View file

@ -1,9 +1,6 @@
<?php
/* Digraph CMS: Destructr
https://github.com/digraphcms/destructr
MIT License
Copyright (c) 2018 Joby Elliott <joby@byjoby.com> */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
interface DSOFactoryInterface
{

View file

@ -1,8 +1,8 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
use Digraph\FlatArray\FlatArrayInterface;
use Flatrr\FlatArrayInterface;
/**
* Interface for DeStructure Objects (DSOs). These are the class that is

View file

@ -1,6 +1,6 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
class DriverFactory
{

View file

@ -1,9 +1,9 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\Drivers;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr\Drivers;
use Digraph\Destructr\DSOInterface;
use Digraph\Destructr\Search;
use Destructr\DSOInterface;
use Destructr\Search;
//TODO: Caching? It should happen somewhere in this class I think.
abstract class AbstractDriver implements DSODriverInterface

View file

@ -1,9 +1,9 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\Drivers;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr\Drivers;
use Digraph\Destructr\DSOInterface;
use Digraph\Destructr\Search;
use Destructr\DSOInterface;
use Destructr\Search;
interface DSODriverInterface
{

View file

@ -1,6 +1,6 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\Drivers;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr\Drivers;
/**
* What this driver supports: MySQL and MariaDB databases new enough to support

View file

@ -1,87 +0,0 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\Drivers;
/**
* What this driver supports: PostgreSQL >=9.3
*
* Eventually, anyway. At the moment it's untested and probably doesn't work.
*/
class PostgreSQLDriver extends AbstractDriver
{
/**
* Within the search we expand strings like ${dso.id} into JSON queries.
* Note that the Search will have already had these strings expanded into
* column names if there are virtual columns configured for them. That
* happens in the Factory before it gets here.
*/
protected function sql_select($args)
{
//extract query parts from Search and expand paths
$where = $this->expandPaths($args['search']->where());
$order = $this->expandPaths($args['search']->order());
$limit = $args['search']->limit();
$offset = $args['search']->offset();
//select from
$out = ["SELECT * FROM `{$args['table']}`"];
//where statement
if ($where !== null) {
$out[] = "WHERE ".$where;
}
//order statement
if ($order !== null) {
$out[] = "ORDER BY ".$order;
}
//limit
if ($limit !== null) {
$out[] = "LIMIT ".$limit;
}
//offset
if ($offset !== null) {
$out[] = "OFFSET ".$offset;
}
//return
return implode(PHP_EOL, $out).';';
}
protected function sql_ddl($args=array())
{
$out = [];
$out[] = "CREATE TABLE `{$args['table']}` (";
$lines = [];
$lines[] = "`json_data` JSON DEFAULT NULL";
foreach ($args['virtualColumns'] as $path => $col) {
$lines[] = "`{$col['name']}` {$col['type']} GENERATED ALWAYS AS (".$this->expandPath($path).") VIRTUAL";
}
foreach ($args['virtualColumns'] as $path => $col) {
if (@$col['unique'] && $as = @$col['index']) {
$lines[] = "UNIQUE KEY `{$args['table']}_{$col['name']}_idx` (`{$col['name']}`) USING $as";
} elseif ($as = @$col['index']) {
$lines[] = "KEY `{$args['table']}_{$col['name']}_idx` (`{$col['name']}`) USING $as";
}
}
$out[] = implode(','.PHP_EOL, $lines);
$out[] = ") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
return implode(PHP_EOL, $out);
}
protected function expandPath(string $path) : string
{
return "JSON_UNQUOTE(JSON_EXTRACT(`json_data`,'$.{$path}'))";
}
protected function sql_setJSON($args)
{
return 'UPDATE `'.$args['table'].'` SET `json_data` = :data WHERE `dso_id` = :dso_id;';
}
protected function sql_insert($args)
{
return "INSERT INTO `{$args['table']}` (`json_data`) VALUES (:data);";
}
protected function sql_delete($args)
{
return 'DELETE FROM `'.$args['table'].'` WHERE `dso_id` = :dso_id;';
}
}

View file

@ -1,6 +1,6 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
use mofodojodino\ProfanityFilter\Check;

View file

@ -1,12 +1,12 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\LegacyDrivers;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr\LegacyDrivers;
use Digraph\Destructr\Drivers\AbstractDriver;
use Digraph\Destructr\DSOInterface;
use Digraph\Destructr\Factory;
use Digraph\Destructr\Search;
use Digraph\FlatArray\FlatArray;
use Destructr\Drivers\AbstractDriver;
use Destructr\DSOInterface;
use Destructr\Factory;
use Destructr\Search;
use Flatrr\FlatArray;
/**
* This driver is for supporting older SQL servers that don't have their own

View file

@ -1,6 +1,6 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\LegacyDrivers;
/* 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

View file

@ -20,7 +20,7 @@ The things many of this sort of driver will *not* ever support:
### SQLite 3
**\Digraph\Destructr\LegacyDrivers\SQLiteDriver**
**\Destructr\LegacyDrivers\SQLiteDriver**
**Overall support level: Highly functional, a touch slow**
@ -41,7 +41,7 @@ using SQLite if you don't have access to a fully supported database version.
### MySQL 5.6
**\Digraph\Destructr\LegacyDrivers\MySQL56Driver**
**\Destructr\LegacyDrivers\MySQL56Driver**
**Overall support level: Decent performance, highly suspect accuracy**

View file

@ -1,10 +1,9 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr\LegacyDrivers;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr\LegacyDrivers;
use Digraph\Destructr\DSOInterface;
use Digraph\FlatArray\FlatArray;
use Digraph\Destructr\Factory;
use Destructr\DSOInterface;
use Destructr\Factory;
/**
* What this driver supports: Version of SQLite3 in PHP environments that allow
@ -27,7 +26,7 @@ class SQLiteDriver extends AbstractLegacyDriver
*/
$this->pdo->sqliteCreateFunction(
'DESTRUCTR_JSON_EXTRACT',
'\\Digraph\\Destructr\\LegacyDrivers\\SQLiteDriver::JSON_EXTRACT',
'\\Destructr\\LegacyDrivers\\SQLiteDriver::JSON_EXTRACT',
2
);
}

View file

@ -1,15 +1,17 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
use Digraph\Destructr\DSOFactoryInterface;
use Digraph\Destructr\Drivers\DSODriverInterface;
use Destructr\DSOFactoryInterface;
use Destructr\Drivers\DSODriverInterface;
class Search implements \Serializable
{
use \Digraph\Utilities\ValueFunctionTrait;
protected $factory;
protected $where;
protected $order;
protected $limit;
protected $offset;
public function __construct(DSOFactoryInterface &$factory=null)
{
@ -23,22 +25,34 @@ class Search implements \Serializable
public function where(string $set = null) : ?string
{
return $this->valueFunction('where', $set);
if ($set !== null) {
$this->where = $set;
}
return $this->where;
}
public function order(string $set = null) : ?string
{
return $this->valueFunction('order', $set);
if ($set !== null) {
$this->order = $set;
}
return $this->order;
}
public function limit(int $set = null) : ?int
{
return $this->valueFunction('limit', $set);
if ($set !== null) {
$this->limit = $set;
}
return $this->limit;
}
public function offset(int $set = null) : ?int
{
return $this->valueFunction('offset', $set);
if ($set !== null) {
$this->offset = $set;
}
return $this->offset;
}
public function serialize()

View file

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

View file

@ -1,12 +1,12 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Digraph\Destructr\Drivers;
namespace Destructr\Drivers;
use PHPUnit\Framework\TestCase;
use PHPUnit\DbUnit\TestCaseTrait;
use Digraph\Destructr\DSO;
use Digraph\Destructr\Search;
use Destructr\DSO;
use Destructr\Search;
/**
* This class tests a factory in isolation. In the name of simplicity it's a bit

View file

@ -1,13 +1,13 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Digraph\Destructr\Drivers\IntegrationTests;
namespace Destructr\Drivers\IntegrationTests;
use PHPUnit\Framework\TestCase;
use PHPUnit\DbUnit\TestCaseTrait;
use Digraph\Destructr\DSO;
use Digraph\Destructr\Search;
use Digraph\Destructr\Factory;
use Destructr\DSO;
use Destructr\Search;
use Destructr\Factory;
abstract class AbstractDriverIntegrationTest extends TestCase
{

View file

@ -1,13 +1,13 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Digraph\Destructr\Drivers\IntegrationTests;
namespace Destructr\Drivers\IntegrationTests;
use PHPUnit\Framework\TestCase;
class MySQLDriverTest extends AbstractDriverIntegrationTest
{
const DRIVER_CLASS = \Digraph\Destructr\Drivers\MySQLDriver::class;
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;

View file

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

View file

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

View file

@ -1,6 +1,6 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
namespace Digraph\Destructr;
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
namespace Destructr;
class HarnessDriver implements Drivers\DSODriverInterface
{

View file

@ -1,11 +1,11 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Digraph\Destructr\LegacyDrivers\IntegrationTests;
namespace Destructr\LegacyDrivers\IntegrationTests;
use PHPUnit\Framework\TestCase;
use Digraph\Destructr\Drivers\IntegrationTests\AbstractDriverIntegrationTest;
use Digraph\Destructr\LegacyDrivers\SQLiteDriver;
use Destructr\Drivers\IntegrationTests\AbstractDriverIntegrationTest;
use Destructr\LegacyDrivers\SQLiteDriver;
class MySQLDriverTest extends AbstractDriverIntegrationTest
{

View file

@ -1,14 +1,14 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Digraph\Destructr\LegacyDrivers;
namespace Destructr\LegacyDrivers;
use PHPUnit\Framework\TestCase;
use Digraph\Destructr\Drivers\AbstractDriverTest;
use Destructr\Drivers\AbstractDriverTest;
class MySQL56DriverTest extends AbstractDriverTest
{
const DRIVER_CLASS = \Digraph\Destructr\LegacyDrivers\MySQL56Driver::class;
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;

View file

@ -1,10 +1,10 @@
<?php
/* Digraph CMS: Destructr | https://github.com/digraphcms/destructr | MIT License */
/* Destructr | https://gitlab.com/byjoby/destructr | MIT License */
declare(strict_types=1);
namespace Digraph\Destructr\LegacyDrivers;
namespace Destructr\LegacyDrivers;
use PHPUnit\Framework\TestCase;
use Digraph\Destructr\Drivers\AbstractDriverTest;
use Destructr\Drivers\AbstractDriverTest;
class SQLiteDriverTest extends AbstractDriverTest
{