1 | <?php |
||
30 | class ProvisionCommand extends Command |
||
31 | { |
||
32 | const HELP_MESSAGE = <<<'EOF' |
||
33 | The <info>%command.name% [path-to-folder]</info> command will scan the content of [path-to-folder] directory. |
||
34 | |||
35 | The script will look for <info>.env</info> file containing connection information in format: |
||
36 | <comment> |
||
37 | DATABASE_USER=[user] |
||
38 | DATABASE_PASSWORD=[password] |
||
39 | DATABASE_HOST=[host] |
||
40 | DATABASE_PORT=[port] |
||
41 | DATABASE_NAME=[database] |
||
42 | PROVISIONING_TABLE=changelog_database_deployments |
||
43 | PROVISIONING_TABLE_CANDIDATE_NUMBER_COLUMN=deploy_script_number |
||
44 | </comment> |
||
45 | |||
46 | If you want to create initial .env use <info>--init</info> |
||
47 | |||
48 | <info>%command.name% --init [path-to-folder]</info> |
||
49 | |||
50 | The next step is searching for sql files and trying to queue them in numerical order. |
||
51 | First n-th digits of a filename will be treated as candidate number. |
||
52 | This will be used then to check in database if a certain file was already deployed (PROVISIONING_TABLE_CANDIDATE_NUMBER_COLUMN). |
||
53 | Before the insert, it will print the formatted output of a file and result of internal syntax check. |
||
54 | Then you can either skip or execute each. |
||
55 | |||
56 | If you would like to skip already provisioned candidates use <info>--skip-provisioned</info> |
||
57 | EOF; |
||
58 | const TABLE_HEADERS = ['FILENAME', 'STATUS']; |
||
59 | private $candidateIndexValue = 1; |
||
60 | |||
61 | /** @var Candidate[] */ |
||
62 | private $workingDirectoryCandidates; |
||
63 | |||
64 | /** @var Sql */ |
||
65 | private $sqlFormatter; |
||
66 | |||
67 | /** @var Filesystem */ |
||
68 | private $filesystem; |
||
69 | |||
70 | /** @var string */ |
||
71 | private $workingDirectory; |
||
72 | |||
73 | /** @var CandidatesFinder */ |
||
74 | private $finder; |
||
75 | |||
76 | /** @var SymfonyStyle */ |
||
77 | private $io; |
||
78 | |||
79 | /** @var Connection */ |
||
80 | private $connection; |
||
81 | |||
82 | /** @var CandidateProcessor */ |
||
83 | private $processor; |
||
84 | |||
85 | /** @var Executor */ |
||
86 | private $executor; |
||
87 | |||
88 | /** @var boolean */ |
||
89 | private $skipProvisionedCandidates; |
||
90 | |||
91 | /** @var CandidateBuilder */ |
||
92 | private $builder; |
||
93 | |||
94 | /** @var bool */ |
||
95 | private $hasQueuedCandidates; |
||
96 | |||
97 | /** @var integer */ |
||
98 | private $queuedCandidatesCount; |
||
99 | |||
100 | /** @var array */ |
||
101 | private $errorMessages; |
||
102 | |||
103 | |||
104 | |||
105 | /** |
||
106 | * @param string $name |
||
107 | * @param WorkingDirectory $workingDirectory |
||
108 | * @param Connection $connection |
||
109 | * @param Sql $sqlFormatter |
||
110 | * @param CandidateProcessor $processor |
||
111 | * @param CandidateBuilder $builder |
||
112 | * @param Executor $executor |
||
113 | */ |
||
114 | public function __construct( |
||
115 | $name, |
||
116 | WorkingDirectory $workingDirectory, |
||
117 | Connection $connection, |
||
118 | Sql $sqlFormatter, |
||
119 | CandidateProcessor $processor, |
||
120 | CandidateBuilder $builder, |
||
121 | Executor $executor |
||
122 | ) { |
||
123 | $this->workingDirectory = $workingDirectory; |
||
|
|||
124 | $this->connection = $connection; |
||
125 | $this->sqlFormatter = $sqlFormatter; |
||
126 | $this->filesystem = new Filesystem(); |
||
127 | $this->processor = $processor; |
||
128 | $this->builder = $builder; |
||
129 | $this->executor = $executor; |
||
130 | |||
131 | $this->workingDirectoryCandidates = []; |
||
132 | $this->skipProvisionedCandidates = false; |
||
133 | $this->hasQueuedCandidates = false; |
||
134 | $this->queuedCandidatesCount = 0; |
||
135 | $this->errorMessages = []; |
||
136 | |||
137 | parent::__construct($name); |
||
138 | } |
||
139 | |||
140 | |||
141 | |||
142 | protected function configure() |
||
143 | { |
||
144 | $this |
||
145 | ->setDescription('Execute the content of *.sql files from given') |
||
146 | ->setHelp(self::HELP_MESSAGE); |
||
147 | $this->addOption('init', null, InputOption::VALUE_NONE, 'Initialize .env in given directory'); |
||
148 | $this->addOption( |
||
149 | 'skip-provisioned', |
||
150 | null, |
||
151 | InputOption::VALUE_NONE, |
||
152 | 'Skip provisioned candidates from printing' |
||
153 | ); |
||
154 | $this->addArgument('path', InputArgument::REQUIRED, 'Path to dbdeploys folder'); |
||
155 | } |
||
156 | |||
157 | |||
158 | |||
159 | /** |
||
160 | * @param InputInterface $input |
||
161 | * @param OutputInterface $output |
||
162 | * @return int |
||
163 | */ |
||
164 | protected function execute(InputInterface $input, OutputInterface $output) |
||
165 | { |
||
166 | $this->start($input, $output); |
||
167 | $this->io->section('Working directory processing'); |
||
168 | |||
169 | if ($input->getOption('skip-provisioned')) { |
||
170 | $this->skipProvisionedCandidates = true; |
||
171 | $this->io->warning('Hiding of provisioned candidates ENABLED'); |
||
172 | } |
||
173 | |||
174 | $this->processWorkingDirectory($input); |
||
175 | $this->processCandidates(); |
||
176 | $this->finish(); |
||
177 | |||
178 | return 0; |
||
179 | } |
||
180 | |||
181 | |||
182 | |||
183 | /** |
||
184 | * @param InputInterface $input |
||
185 | * @param OutputInterface $output |
||
186 | */ |
||
187 | protected function start(InputInterface $input, OutputInterface $output) |
||
193 | |||
194 | |||
195 | |||
196 | protected function fetchCandidates() |
||
209 | |||
210 | |||
211 | |||
212 | /** |
||
213 | * @param SplFileInfo $candidateFile |
||
214 | */ |
||
215 | protected function processCandidateFile($candidateFile) |
||
234 | |||
235 | |||
236 | |||
237 | protected function iterateOverWorkingDirectory() |
||
249 | |||
250 | |||
251 | |||
252 | protected function showSyntaxErrors() |
||
259 | |||
260 | |||
261 | |||
262 | /** |
||
263 | * @param InputInterface $input |
||
264 | */ |
||
265 | protected function processWorkingDirectory(InputInterface $input) |
||
271 | |||
272 | |||
273 | |||
274 | /** |
||
275 | * @param InputInterface $input |
||
276 | */ |
||
277 | private function loadDotEnv(InputInterface $input) |
||
287 | |||
288 | |||
289 | |||
290 | private function setConnectionParameters() |
||
301 | |||
302 | |||
303 | |||
304 | private function processCandidates() |
||
314 | |||
315 | |||
316 | |||
317 | /** |
||
318 | * @param Candidate $candidate |
||
319 | */ |
||
320 | private function executeCandidateScript(Candidate $candidate) |
||
342 | |||
343 | |||
344 | |||
345 | private function printAllCandidates() |
||
377 | |||
378 | |||
379 | |||
380 | private function processQueuedCandidates() |
||
391 | |||
392 | |||
393 | |||
394 | /** |
||
395 | * @param Candidate $candidate |
||
396 | */ |
||
397 | private function deployCandidate(Candidate $candidate) |
||
413 | |||
414 | |||
415 | |||
416 | private function finish() |
||
421 | |||
422 | |||
423 | |||
424 | private function terminate() |
||
429 | } |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..