Skip to content

Commit

Permalink
make faster mebbe... (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
lifeofguenter authored Jan 16, 2018
1 parent c726abf commit c755b0c
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 80 deletions.
37 changes: 21 additions & 16 deletions app/Transformer/Transform.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
namespace App\Transformer;

use Exception;
use PhpMyAdmin\SqlParser\Parser;
use PhpMyAdmin\SqlParser\Statements\InsertStatement;
use MyFormer\Parser\Insert as InsertParser;

class Transform
{
protected $mappings = [];

protected $transformers = [];

public function __construct(array $mappings)
{
$this->mappings = $mappings;
Expand All @@ -28,31 +29,35 @@ public function transform($row)
}

try {
$parser = new Parser($row);
$insert = new InsertParser($row);
} catch(Exception $e) {
return $row;
}

$insert = $parser->statements[0];
$mappings = $this->mappings[$table];

$new_values = $this->map($insert, $mappings);

$insert->values[0] = new \PhpMyAdmin\SqlParser\Components\ArrayObj(array_values($new_values));
$new_values = $this->map(array_combine($insert->columns, $insert->values), $mappings);

return $insert->build();
return sprintf(
'INSERT INTO `%s` (`%s`) VALUES (%s);',
$table,
implode('`, `', array_keys($new_values)),
implode(', ', array_values($new_values))
);
}

protected function map(InsertStatement $insert, array $mappings)
protected function map(array $values, array $mappings)
{
$values = array_combine($insert->into->columns, $insert->values[0]->raw);

foreach ($mappings as $column => $rule) {
$class_name = 'App\\Transformer\\Transformers\\' . key($rule);
$transformer = new $class_name;
$transformer->setParam(current($rule));
$values[$column] = $transformer->transform($values, $column);
unset($transformer);
$rule_name = key($rule);

if (!isset($this->transformers[$rule_name])) {
$class_name = 'App\\Transformer\\Transformers\\' . $rule_name;
$this->transformers[$rule_name] = new $class_name;
$this->transformers[$rule_name]->setParam(current($rule));
}

$values[$column] = $this->transformers[$rule_name]->transform($values, $column);
}

return $values;
Expand Down
8 changes: 5 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
],
"require": {
"php": ">=7.1.0",
"symfony/console": "^4.0",
"phpmyadmin/sql-parser": "^4.2"
"symfony/console": "^4.0"
},
"autoload": {
"psr-4": {"App\\": "app/"}
"psr-4": {
"App\\": "app/",
"MyFormer\\": "src/"
}
}
}
62 changes: 1 addition & 61 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 84 additions & 0 deletions src/Parser/Insert.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace MyFormer\Parser;

class Insert
{
public $table;

public $columns = [];

public $values = [];

public function __construct($raw)
{
$this->parse($raw);
}

public function parse($raw)
{
if (preg_match('~^INSERT INTO `([^`]+)` \((.*)\) VALUES \((.*)\);$~i', $raw, $matches)) {
$this->table = $matches[1];
$this->splitColumns($matches[2]);
$this->splitValues($matches[3]);
}
}

protected function splitColumns($raw)
{
// https://stackoverflow.com/a/6243797/567193
$raw_columns = preg_split('~\\\\.(*SKIP)(*FAIL)|,\s*~s', $raw);
foreach ($raw_columns as $raw_column) {
$this->columns[] = trim($raw_column, '`');
}
}

protected function splitValues($raw)
{
$str_len = strlen($raw);
$cur = 0;
$tok_end = '';

for ($i = 0; $i < $str_len; ++$i) {

// token-end reached
if ($raw[$i] === $tok_end) {
// skip next char if token-end is not the delimiter
if ($tok_end === "'") {
$this->values[$cur] .= $raw[$i];
++$i;
}
++$cur;
$tok_end = '';
continue;
}

// token-end not yet defined
if ($tok_end === '') {
// skip whitespaces
if ($raw[$i] === ' ') {
continue;
}

// define token-end
if ($raw[$i] === "'") {
$tok_end = "'";
} else {
$tok_end = ',';
}
}

// don't tokenise escaped
if ($raw[$i] === '\\') {
$this->values[$cur] .= $raw[$i] . $raw[++$i];
continue;
}

if (!isset($this->values[$cur])) {
$this->values[$cur] = '';
}

$this->values[$cur] .= $raw[$i];
}
}
}

0 comments on commit c755b0c

Please sign in to comment.