Passed
Push — main ( e5a85d...619edc )
by Michiel
07:04
created

AbstractLiquibaseTask   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 32
eloc 85
dl 0
loc 290
ccs 0
cts 89
cp 0
rs 9.84
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A setJar() 0 3 1
A setOutputProperty() 0 3 1
A setDisplay() 0 3 1
A setUrl() 0 3 1
B checkParams() 0 27 7
A createParameter() 0 6 1
A setCheckreturn() 0 3 1
A setPassword() 0 3 1
A setUsername() 0 3 1
B execute() 0 47 8
A checkChangeLogFile() 0 17 5
A setclasspathref() 0 3 1
A setChangeLogFile() 0 3 1
A setPassthru() 0 3 1
A createProperty() 0 6 1
1
<?php
2
3
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Task\Ext\Liquibase;
22
23
use Phing\Exception\BuildException;
24
use Phing\Task;
25
use Phing\Util\StringHelper;
26
27
/**
28
 * Abstract Liquibase task. Base class for all Liquibase Phing tasks.
29
 *
30
 * @author  Stephan Hochdoerfer <[email protected]>
31
 * @since   2.4.10
32
 * @package phing.tasks.ext.liquibase
33
 */
34
abstract class AbstractLiquibaseTask extends Task
35
{
36
    /**
37
     * Used for liquibase -Dname=value properties.
38
     */
39
    private $properties = [];
40
41
    /**
42
     * Used to set liquibase --name=value parameters
43
     */
44
    private $parameters = [];
45
46
    protected $jar;
47
    protected $changeLogFile;
48
    protected $username;
49
    protected $password;
50
    protected $url;
51
    protected $classpathref;
52
53
    /**
54
     * Whether to display the output of the command.
55
     * True by default to preserve old behaviour
56
     *
57
     * @var boolean
58
     */
59
    protected $display = true;
60
61
    /**
62
     * Whether liquibase return code can cause a Phing failure.
63
     *
64
     * @var boolean
65
     */
66
    protected $checkreturn = false;
67
68
    /**
69
     * Set true if we should run liquibase with PHP passthru
70
     * instead of exec.
71
     */
72
    protected $passthru = true;
73
74
    /**
75
     * Property name to set with output value from exec call.
76
     *
77
     * @var string
78
     */
79
    protected $outputProperty;
80
81
    /**
82
     * Sets the absolute path to liquibase jar.
83
     *
84
     * @param string the absolute path to the liquibase jar.
0 ignored issues
show
Bug introduced by
The type Phing\Task\Ext\Liquibase\the was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
85
     */
86
    public function setJar($jar)
87
    {
88
        $this->jar = $jar;
89
    }
90
91
    /**
92
     * Sets the absolute path to the changelog file to use.
93
     *
94
     * @param string the absolute path to the changelog file
95
     */
96
    public function setChangeLogFile($changelogFile)
97
    {
98
        $this->changeLogFile = $changelogFile;
99
    }
100
101
    /**
102
     * Sets the username to connect to the database.
103
     *
104
     * @param string the username
105
     */
106
    public function setUsername($username)
107
    {
108
        $this->username = $username;
109
    }
110
111
    /**
112
     * Sets the password to connect to the database.
113
     *
114
     * @param string the password
115
     */
116
    public function setPassword($password)
117
    {
118
        $this->password = $password;
119
    }
120
121
    /**
122
     * Sets the url to connect to the database in jdbc style, e.g.
123
     * <code>
124
     * jdbc:postgresql://psqlhost/mydatabase
125
     * </code>
126
     *
127
     * @param string jdbc connection string
0 ignored issues
show
Bug introduced by
The type Phing\Task\Ext\Liquibase\jdbc was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
128
     */
129
    public function setUrl($url)
130
    {
131
        $this->url = $url;
132
    }
133
134
    /**
135
     * Sets the Java classpathref.
136
     *
137
     * @param string A reference to the classpath that contains the database
138
     *                    driver, liquibase.jar, and the changelog.xml file
139
     */
140
    public function setclasspathref($classpathref)
141
    {
142
        $this->classpathref = $classpathref;
143
    }
144
145
    /**
146
     * Sets whether to display the output of the command
147
     *
148
     * @param boolean $display
149
     */
150
    public function setDisplay($display)
151
    {
152
        $this->display = StringHelper::booleanValue($display);
153
    }
154
155
    /**
156
     * Whether to check the liquibase return code.
157
     *
158
     * @param boolean $checkreturn
159
     */
160
    public function setCheckreturn($checkreturn)
161
    {
162
        $this->checkreturn = StringHelper::booleanValue($checkreturn);
163
    }
164
165
    /**
166
     * Whether to check the liquibase return code.
167
     *
168
     * @param    $passthru
169
     * @internal param bool $checkreturn
170
     */
171
    public function setPassthru($passthru)
172
    {
173
        $this->passthru = StringHelper::booleanValue($passthru);
174
    }
175
176
    /**
177
     * the name of property to set to output value from exec() call.
178
     *
179
     * @param string $prop property name
180
     *
181
     * @return void
182
     */
183
    public function setOutputProperty($prop)
184
    {
185
        $this->outputProperty = $prop;
186
    }
187
188
    /**
189
     * Creates a nested <property> tag.
190
     *
191
     * @return LiquibaseProperty Argument object
192
     */
193
    public function createProperty()
194
    {
195
        $prop = new LiquibaseProperty();
196
        $this->properties[] = $prop;
197
198
        return $prop;
199
    }
200
201
    /**
202
     * Creates a nested <parameter> tag.
203
     *
204
     * @return LiquibaseParameter Argument object
205
     */
206
    public function createParameter()
207
    {
208
        $param = new LiquibaseParameter();
209
        $this->parameters[] = $param;
210
211
        return $param;
212
    }
213
214
    /**
215
     * Ensure that correct parameters were passed in.
216
     *
217
     * @throws BuildException
218
     * @return void
219
     */
220
    protected function checkParams()
221
    {
222
        if ((null === $this->jar) or !file_exists($this->jar)) {
223
            throw new BuildException(
224
                sprintf(
225
                    'Specify the name of the LiquiBase.jar. "%s" does not exist!',
226
                    $this->jar
227
                )
228
            );
229
        }
230
231
        $this->checkChangeLogFile();
232
233
        if (null === $this->classpathref) {
234
            throw new BuildException('Please provide a classpath!');
235
        }
236
237
        if (null === $this->username) {
238
            throw new BuildException('Please provide a username for database acccess!');
239
        }
240
241
        if (null === $this->password) {
242
            throw new BuildException('Please provide a password for database acccess!');
243
        }
244
245
        if (null === $this->url) {
246
            throw new BuildException('Please provide a url for database acccess!');
247
        }
248
    }
249
250
    /**
251
     * Executes the given command and returns the output.
252
     *
253
     * @param  $lbcommand
254
     * @param  string $lbparams the command to execute
255
     * @throws BuildException
256
     * @return string the output of the executed command
257
     */
258
    protected function execute($lbcommand, $lbparams = '')
259
    {
260
        $nestedparams = "";
261
        foreach ($this->parameters as $p) {
262
            $nestedparams .= $p->getCommandline($this->project) . ' ';
263
        }
264
        $nestedprops = "";
265
        foreach ($this->properties as $p) {
266
            $nestedprops .= $p->getCommandline($this->project) . ' ';
267
        }
268
269
        $command = sprintf(
270
            'java -jar %s --changeLogFile=%s --url=%s --username=%s --password=%s --classpath=%s %s %s %s %s 2>&1',
271
            escapeshellarg($this->jar),
272
            escapeshellarg($this->changeLogFile),
273
            escapeshellarg($this->url),
274
            escapeshellarg($this->username),
275
            escapeshellarg($this->password),
276
            escapeshellarg($this->classpathref),
277
            $nestedparams,
278
            escapeshellarg($lbcommand),
279
            $lbparams,
280
            $nestedprops
281
        );
282
283
        if ($this->passthru) {
284
            passthru($command);
285
        } else {
286
            $output = [];
287
            $return = null;
288
            exec($command, $output, $return);
289
            $output = implode(PHP_EOL, $output);
290
291
            if ($this->display) {
292
                print $output;
293
            }
294
295
            if (!empty($this->outputProperty)) {
296
                $this->project->setProperty($this->outputProperty, $output);
297
            }
298
299
            if ($this->checkreturn && $return != 0) {
300
                throw new BuildException("Liquibase exited with code $return");
301
            }
302
        }
303
304
        return;
305
    }
306
307
    protected function checkChangeLogFile()
308
    {
309
        if (null === $this->changeLogFile) {
310
            throw new BuildException('Specify the name of the changelog file.');
311
        }
312
313
        foreach (explode(":", $this->classpathref) as $path) {
314
            if (file_exists($path . DIRECTORY_SEPARATOR . $this->changeLogFile)) {
315
                return;
316
            }
317
        }
318
319
        if (!file_exists($this->changeLogFile)) {
320
            throw new BuildException(
321
                sprintf(
322
                    'The changelog file "%s" does not exist!',
323
                    $this->changeLogFile
324
                )
325
            );
326
        }
327
    }
328
}
329