Dumper::parseTables()   B
last analyzed

Complexity

Conditions 10
Paths 14

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 17
nc 14
nop 2
dl 0
loc 35
rs 7.6666
c 1
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Class Dumper
4
 *
5
 * @filesource   Dumper.php
6
 * @created      07.01.2018
7
 * @package      chillerlan\Database
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2018 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\Database;
14
15
use chillerlan\Settings\SettingsContainerInterface;
16
use Psr\Log\LoggerInterface;
17
use Psr\SimpleCache\CacheInterface;
18
19
/**
20
 * @todo WIP
21
 */
22
class Dumper extends DatabaseAbstract{
23
24
	const PAGESIZE = 100;
25
26
	/**
27
	 * @var \chillerlan\Database\Dialects\Dialect
28
	 */
29
	protected $dialect;
30
31
	public function __construct(SettingsContainerInterface $options, CacheInterface $cache = null, LoggerInterface $logger = null){
32
		parent::__construct($options, $cache, $logger);
33
34
		$this->dialect = $this->driver->getDialect();
35
		$this->driver->connect();
36
	}
37
38
	public function dump(array $selection = null, array $not = null){
39
		$tables = $this->parseTables($selection, $not);
40
41
		$fh = fopen($this->options->storage_path.'/dump.sql', 'w');
42
43
		foreach($tables as $table){
44
			$this->logger->info('dumping table: '.$table);
45
			fwrite($fh, PHP_EOL.'--'.PHP_EOL.'-- '.$table.PHP_EOL.'--'.PHP_EOL.PHP_EOL.$this->query->show->create->table($table)->query()[0]->{'Create Table'}.';'.PHP_EOL.PHP_EOL);
0 ignored issues
show
Bug introduced by
The method query() does not exist on chillerlan\Database\Query\ShowItem. Since it exists in all sub-types, consider adding an abstract or default implementation to chillerlan\Database\Query\ShowItem. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

45
			fwrite($fh, PHP_EOL.'--'.PHP_EOL.'-- '.$table.PHP_EOL.'--'.PHP_EOL.PHP_EOL.$this->query->show->create->table($table)->/** @scrutinizer ignore-call */ query()[0]->{'Create Table'}.';'.PHP_EOL.PHP_EOL);
Loading history...
46
47
			$q = $this->query->select->from([$table]);
48
			$pages = (int)floor($q->count() / $this::PAGESIZE);
49
50
			foreach(range(0, $pages) as $i){
51
52
				$data = (clone $q)
53
					->limit($this::PAGESIZE)
0 ignored issues
show
Bug introduced by
The method limit() does not exist on chillerlan\Database\Query\Select. Since it exists in all sub-types, consider adding an abstract or default implementation to chillerlan\Database\Query\Select. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

53
					->/** @scrutinizer ignore-call */ limit($this::PAGESIZE)
Loading history...
54
					->offset($i * $this::PAGESIZE)
55
					->query();
56
57
58
				if($data instanceof Result && $data->length > 0){
59
					$sql = ['INSERT INTO'];
60
					$sql[] = $this->dialect->quote($table);
61
					$sql[] = '('.implode(', ', array_map([$this->dialect, 'quote'], $data[0]->__fields())).')';
0 ignored issues
show
Bug introduced by
The method __fields() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
					$sql[] = '('.implode(', ', array_map([$this->dialect, 'quote'], $data[0]->/** @scrutinizer ignore-call */ __fields())).')';

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
62
					$sql[] = 'VALUES'.PHP_EOL;
63
64
					/** @var \chillerlan\Database\ResultRow $row */
65
					$values = [];
66
					foreach($data as $row){
67
						$values[] = '('.implode(', ', array_map([$this->driver, 'escape'], $row->__values())).')';
0 ignored issues
show
Bug introduced by
The method __values() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

67
						$values[] = '('.implode(', ', array_map([$this->driver, 'escape'], $row->/** @scrutinizer ignore-call */ __values())).')';

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
68
					}
69
70
					$sql[] = implode(','.PHP_EOL, $values).';'.PHP_EOL.PHP_EOL;
71
72
					fwrite($fh, implode(' ', $sql));
73
				}
74
75
76
				if($i > 0){
77
					$this->logger->info('dumping data: '.round((100 / $pages) * $i, 2).'%');
78
				}
79
80
			}
81
82
		}
83
84
85
	}
86
87
88
	protected function parseTables(array $tables = null, array $not = null):array{
89
		$q  = $this->query->show->tables()->query()->__toArray();
90
		$r  = [];
91
		$st = [];
92
93
		foreach($q as $t){
94
			[$table] = array_values($t);
95
			$st[] = $table;
96
		}
97
98
		if(empty($tables) && empty($not)){
99
			return $st;
100
		}
101
102
		foreach($tables as $expression){
103
			$x = explode('*', $expression, 2);
104
105
			foreach($st as $table){
106
107
				if(count($x) === 2){
108
109
					if(strpos($table, $x[0]) === 0 && !in_array($table, $not, true)){
0 ignored issues
show
Bug introduced by
It seems like $not can also be of type null; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
					if(strpos($table, $x[0]) === 0 && !in_array($table, /** @scrutinizer ignore-type */ $not, true)){
Loading history...
110
						$r[] = $table;
111
					}
112
113
				}
114
				elseif($expression === $table){
115
					$r[] = $table;
116
				}
117
118
			}
119
120
		}
121
122
		return $r;
123
	}
124
}
125