lucajackal85 /
Copycat
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace Jackal\Copycat\Writer; |
||||
| 4 | |||||
| 5 | use SplFileInfo; |
||||
| 6 | use Symfony\Component\OptionsResolver\OptionsResolver; |
||||
| 7 | |||||
| 8 | /** |
||||
| 9 | * Class SQLLoadDataLocalWriter |
||||
| 10 | * @package Jackal\Copycat\Writer |
||||
| 11 | */ |
||||
| 12 | class SQLLoadDataLocalWriter extends CSVFileWriter |
||||
| 13 | { |
||||
| 14 | /** |
||||
| 15 | * @var string |
||||
| 16 | */ |
||||
| 17 | protected $sqlOutputFilePathname; |
||||
| 18 | |||||
| 19 | /** |
||||
| 20 | * @var string |
||||
| 21 | */ |
||||
| 22 | protected $tableName; |
||||
| 23 | |||||
| 24 | /** |
||||
| 25 | * @var array |
||||
| 26 | */ |
||||
| 27 | protected $headers = []; |
||||
| 28 | |||||
| 29 | /** |
||||
| 30 | * SQLLoadDataLocalWriter constructor. |
||||
| 31 | * @param $tableName |
||||
| 32 | * @param $outputFilePathname |
||||
| 33 | * @param array $options |
||||
| 34 | */ |
||||
| 35 | public function __construct($tableName, $outputFilePathname, $options = []) |
||||
| 36 | { |
||||
| 37 | if (!is_dir(dirname($outputFilePathname))) { |
||||
| 38 | mkdir(dirname($outputFilePathname), 0775, true); |
||||
| 39 | } |
||||
| 40 | |||||
| 41 | touch($outputFilePathname); |
||||
| 42 | |||||
| 43 | $outputFile = new SplFileInfo($outputFilePathname); |
||||
| 44 | |||||
| 45 | $localPath = realpath($outputFile->getPathname()); |
||||
| 46 | $csvOutputFilePathname = str_replace('.' . $outputFile->getExtension(), '.csv', $localPath); |
||||
| 47 | |||||
| 48 | $opts = [ |
||||
| 49 | 'header' => true, |
||||
| 50 | 'delimiter' => "\t", |
||||
| 51 | ]; |
||||
| 52 | foreach (['columns','delimiter','enclosure','header','replace_file'] as $option) { |
||||
| 53 | if (array_key_exists($option, $options)) { |
||||
| 54 | $opts[$option] = $options[$option]; |
||||
| 55 | } |
||||
| 56 | } |
||||
| 57 | |||||
| 58 | parent::__construct($csvOutputFilePathname, $opts); |
||||
| 59 | |||||
| 60 | $resolver = new OptionsResolver(); |
||||
| 61 | $resolver->setDefaults([ |
||||
| 62 | 'replace_file' => false, |
||||
| 63 | 'delimiter' => $opts['delimiter'], |
||||
| 64 | 'enclosure' => '"', |
||||
| 65 | 'header' => $opts['header'], |
||||
| 66 | 'autoincrement_field' => false, |
||||
| 67 | 'drop_data' => false, |
||||
| 68 | 'create_table' => false, |
||||
| 69 | 'columns' => [], |
||||
| 70 | ]); |
||||
| 71 | |||||
| 72 | $this->options = $resolver->resolve(array_merge($options, $opts)); |
||||
| 73 | |||||
| 74 | $this->sqlOutputFilePathname = $localPath; |
||||
| 75 | $this->tableName = $tableName; |
||||
| 76 | } |
||||
| 77 | |||||
| 78 | /** |
||||
| 79 | * @param array $item |
||||
| 80 | */ |
||||
| 81 | public function writeItem(array $item) |
||||
| 82 | { |
||||
| 83 | if ($this->index == 0) { |
||||
| 84 | $this->headers = array_keys($item); |
||||
| 85 | } |
||||
| 86 | parent::writeItem($item); |
||||
| 87 | } |
||||
| 88 | |||||
| 89 | /** |
||||
| 90 | * |
||||
| 91 | */ |
||||
| 92 | public function finish() |
||||
| 93 | { |
||||
| 94 | parent::finish(); |
||||
| 95 | |||||
| 96 | $dropRecordsString = $this->options['drop_data'] ? sprintf("\n" . 'DELETE FROM %s;', $this->tableName) : null; |
||||
| 97 | $autoIncrementString = $this->options['autoincrement_field'] ? sprintf('SET %s = NULL', $this->options['autoincrement_field']) : null; |
||||
| 98 | $rowsToIgnore = $this->options['header'] ? 1 : 0; |
||||
| 99 | $headers = '(' . implode(', ', $this->headers) . ')'; |
||||
| 100 | |||||
| 101 | $delimiter = str_replace(["\t","\n","\r"], ['\\t','\\n','\\r'], $this->options['delimiter']); |
||||
| 102 | $enclosure = $this->options['enclosure']; |
||||
| 103 | |||||
| 104 | $createTableSql = null; |
||||
| 105 | if ($this->options['create_table']) { |
||||
| 106 | $h = fopen($this->outputFilePathname, 'r'); |
||||
| 107 | $columnNames = fgetcsv($h, 0, $this->options['delimiter'], $this->options['enclosure']); |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 108 | |||||
| 109 | $autoIncrementField = $this->options['autoincrement_field'] ? $this->options['autoincrement_field'] . ' int auto_increment not null, ' : ''; |
||||
| 110 | $primaryKeyField = $this->options['autoincrement_field'] ? ', primary key (' . $this->options['autoincrement_field'] . ')' : ''; |
||||
| 111 | $createTableSql = sprintf('DROP TABLE IF EXISTS %s;CREATE TABLE %s (%s%s%s);', $this->tableName, $this->tableName, $autoIncrementField, implode(', ', array_map(function ($value) { |
||||
| 112 | return $value . ' text'; |
||||
| 113 | }, $columnNames)), $primaryKeyField); |
||||
|
0 ignored issues
–
show
It seems like
$columnNames can also be of type false and null; however, parameter $arr1 of array_map() 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
Loading history...
|
|||||
| 114 | } |
||||
| 115 | |||||
| 116 | $contents = <<<SQL |
||||
| 117 | {$createTableSql}{$dropRecordsString} |
||||
| 118 | LOAD DATA LOCAL INFILE '{$this->outputFilePathname}' |
||||
| 119 | INTO TABLE {$this->tableName} |
||||
| 120 | CHARACTER SET utf8 |
||||
| 121 | FIELDS |
||||
| 122 | TERMINATED BY '{$delimiter}' |
||||
| 123 | ENCLOSED BY '{$enclosure}' |
||||
| 124 | ESCAPED BY '' |
||||
| 125 | LINES |
||||
| 126 | TERMINATED BY '\\n' |
||||
| 127 | IGNORE $rowsToIgnore LINES |
||||
| 128 | $headers |
||||
| 129 | $autoIncrementString |
||||
| 130 | ; |
||||
| 131 | SQL; |
||||
| 132 | file_put_contents($this->sqlOutputFilePathname, $contents); |
||||
| 133 | } |
||||
| 134 | } |
||||
| 135 |