Issues (49)

src/Importer.php (3 issues)

1
<?php
2
3
/**
4
 * This file is part of dimtrovich/db-dumper".
5
 *
6
 * (c) 2024 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Dimtrovich\DbDumper;
13
14
use Dimtrovich\DbDumper\Compressor\Factory as CompressorFactory;
15
use Dimtrovich\DbDumper\Exceptions\Exception;
16
use PDOException;
17
18
/**
19
 * @method void onTableCreate(callable(string $tableName) $callback)
20
 * @method void onTableInsert(callable(string $tableName, int $rowCount) $callback)
21
 */
22
class Importer
23
{
24
    use Dumper;
0 ignored issues
show
The trait Dimtrovich\DbDumper\Dumper requires some properties which are not provided by Dimtrovich\DbDumper\Importer: $init_commands, $compress
Loading history...
25
26
    /**
27
     * Primary function, triggers restoration.
28
     *
29
     * @param string $filename Name of file to read sql dump to
30
     */
31
    public function process(string $filename): void
32
    {
33
        $extension = pathinfo($filename, PATHINFO_EXTENSION);
34
35
        switch ($extension) {
36
            case 'gz':
37
            case 'gzip':
38
                $this->compressor = CompressorFactory::create(Option::COMPRESSION_GZIP);
39
                break;
40
41
            case 'bz2':
42
            case 'bzip2':
43
                $this->compressor = CompressorFactory::create(Option::COMPRESSION_BZIP2);
44
                break;
45
46
            case 'sql':
47
                $this->compressor = CompressorFactory::create(Option::COMPRESSION_NONE);
48
                break;
49
50
            default:
51
                throw Exception::unavailableDriverForcompression($extension);
0 ignored issues
show
It seems like $extension can also be of type array; however, parameter $extension of Dimtrovich\DbDumper\Exce...eDriverForcompression() does only seem to accept string, 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

51
                throw Exception::unavailableDriverForcompression(/** @scrutinizer ignore-type */ $extension);
Loading history...
52
        }
53
54
        if (null === $filename = $this->getFile($filename)) {
55
            throw Exception::failledToRead(func_get_arg(0));
56
        }
57
58
        if ($this->option->disable_foreign_keys_check && '' !== $disableForeignKeysCheck = $this->adapter->startDisableForeignKeysCheck()) {
59
            $this->pdo->exec($disableForeignKeysCheck);
60
        }
61
62
        /**
63
         * Read backup file line by line
64
         */
65
        $handle = fopen($filename, 'rb');
66
67
        if (! $handle) {
0 ignored issues
show
$handle is of type resource, thus it always evaluated to false.
Loading history...
68
            throw Exception::failledToRead($filename);
69
        }
70
71
        $buffer = '';
72
73
        try {
74
            while (! feof($handle)) {
75
                $line = fgets($handle);
76
77
                if (substr($line, 0, 2) === '--' || ! $line) {
78
                    continue; // skip comments
79
                }
80
81
                $buffer .= $line;
82
83
                // if it has a semicolon at the end, it's the end of the query
84
                if (';' === substr(rtrim($line), -1, 1)) {
85
                    if (false !== $affectedRows = $this->pdo->exec($buffer)) {
86
                        if (preg_match('/^CREATE TABLE `([^`]+)`/i', $buffer, $tableName)) {
87
                            $this->event->emit('table.create', $tableName[1]);
88
                        }
89
                        if (preg_match('/^INSERT INTO `([^`]+)`/i', $buffer, $tableName)) {
90
                            $this->event->emit('table.insert', $tableName[1], $affectedRows);
91
                        }
92
                    }
93
94
                    $buffer = '';
95
                }
96
            }
97
        } catch (PDOException $e) {
98
            throw Exception::pdoException($e->getMessage(), $buffer);
99
        } finally {
100
            fclose($handle);
101
            unlink($filename);
102
        }
103
104
        if ($this->option->disable_foreign_keys_check && '' !== $enableForeignKeysCheck = $this->adapter->endDisableForeignKeysCheck()) {
105
            $this->pdo->exec($enableForeignKeysCheck);
106
        }
107
    }
108
109
    /**
110
     * Return unzipped file
111
     */
112
    private function getFile(string $source): ?string
113
    {
114
        $pathinfo = pathinfo($source);
115
116
        $dest = $pathinfo['dirname'] . '/' . date('Ymd_His', time()) . '_' . $pathinfo['filename'];
117
118
        // Remove $dest file if exists
119
        if (file_exists($dest) && ! unlink($dest)) {
120
            return null;
121
        }
122
123
        // Open gzipped and destination files in binary mode
124
        $this->compressor->open($source, 'rb');
125
        if (! $dstFile = fopen($dest, 'wb')) {
126
            return null;
127
        }
128
129
        if (! fwrite($dstFile, $this->compressor->read())) {
130
            return null;
131
        }
132
133
        fclose($dstFile);
134
        $this->compressor->close();
135
136
        return $dest;
137
    }
138
}
139