Completed
Pull Request — 4.0 (#153)
by Maxime
03:32
created

Oci8Connection::withSchemaPrefix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Yajra\Oci8;
4
5
use Doctrine\DBAL\Connection as DoctrineConnection;
6
use Doctrine\DBAL\Driver\OCI8\Driver as DoctrineDriver;
7
use Illuminate\Database\Connection;
8
use Illuminate\Database\Grammar;
9
use PDO;
10
use Yajra\Oci8\Query\Grammars\OracleGrammar as QueryGrammar;
11
use Yajra\Oci8\Query\OracleBuilder as QueryBuilder;
12
use Yajra\Oci8\Query\Processors\OracleProcessor as Processor;
13
use Yajra\Oci8\Schema\Grammars\OracleGrammar as SchemaGrammar;
14
use Yajra\Oci8\Schema\OracleBuilder as SchemaBuilder;
15
use Yajra\Oci8\Schema\Sequence;
16
use Yajra\Oci8\Schema\Trigger;
17
18
class Oci8Connection extends Connection
19
{
20
    /**
21
     * @var string
22
     */
23
    protected $schema;
24
25
    /**
26
     * @var \Yajra\Oci8\Schema\Sequence
27
     */
28
    protected $sequence;
29
30
    /**
31
     * @var \Yajra\Oci8\Schema\Trigger
32
     */
33
    protected $trigger;
34
35
    /**
36
     * @param PDO|\Closure $pdo
37
     * @param string $database
38
     * @param string $tablePrefix
39
     * @param array $config
40
     */
41
    public function __construct($pdo, $database = '', $tablePrefix = '', array $config = [])
42
    {
43
        parent::__construct($pdo, $database, $tablePrefix, $config);
44
        $this->sequence = new Sequence($this);
45
        $this->trigger  = new Trigger($this);
46
    }
47
48
    /**
49
     * Get current schema.
50
     *
51
     * @return string
52
     */
53
    public function getSchema()
54
    {
55
        return $this->schema;
56
    }
57
58
    /**
59
     * Set current schema.
60
     *
61
     * @param string $schema
62
     * @return $this
63
     */
64
    public function setSchema($schema)
65
    {
66
        $this->schema = $schema;
67
        $sessionVars  = [
68
            'CURRENT_SCHEMA' => $schema,
69
        ];
70
71
        return $this->setSessionVars($sessionVars);
72
    }
73
74
    /**
75
     * Update oracle session variables.
76
     *
77
     * @param array $sessionVars
78
     * @return $this
79
     */
80
    public function setSessionVars(array $sessionVars)
81
    {
82
        $vars = [];
83
        foreach ($sessionVars as $option => $value) {
84
            if (strtoupper($option) == 'CURRENT_SCHEMA') {
85
                $vars[] = "$option  = $value";
86
            } else {
87
                $vars[] = "$option  = '$value'";
88
            }
89
        }
90
        $sql = "ALTER SESSION SET " . implode(" ", $vars);
91
        $this->statement($sql);
92
93
        return $this;
94
    }
95
96
    /**
97
     * Get sequence class.
98
     *
99
     * @return \Yajra\Oci8\Schema\Sequence
100
     */
101
    public function getSequence()
102
    {
103
        return $this->sequence;
104
    }
105
106
    /**
107
     * Set sequence class.
108
     *
109
     * @param \Yajra\Oci8\Schema\Sequence $sequence
110
     * @return \Yajra\Oci8\Schema\Sequence
111
     */
112
    public function setSequence(Sequence $sequence)
113
    {
114
        return $this->sequence = $sequence;
115
    }
116
117
    /**
118
     * Get oracle trigger class.
119
     *
120
     * @return \Yajra\Oci8\Schema\Trigger
121
     */
122
    public function getTrigger()
123
    {
124
        return $this->trigger;
125
    }
126
127
    /**
128
     * Set oracle trigger class.
129
     *
130
     * @param \Yajra\Oci8\Schema\Trigger $trigger
131
     * @return \Yajra\Oci8\Schema\Trigger
132
     */
133
    public function setTrigger(Trigger $trigger)
134
    {
135
        return $this->trigger = $trigger;
136
    }
137
138
    /**
139
     * Get a schema builder instance for the connection.
140
     *
141
     * @return \Yajra\Oci8\Schema\OracleBuilder
142
     */
143
    public function getSchemaBuilder()
144
    {
145
        if (is_null($this->schemaGrammar)) {
146
            $this->useDefaultSchemaGrammar();
147
        }
148
149
        return new SchemaBuilder($this);
150
    }
151
152
    /**
153
     * Begin a fluent query against a database table.
154
     *
155
     * @param  string $table
156
     * @return \Yajra\Oci8\Query\OracleBuilder
157
     */
158
    public function table($table)
159
    {
160
        $processor = $this->getPostProcessor();
161
162
        $query = new QueryBuilder($this, $this->getQueryGrammar(), $processor);
0 ignored issues
show
Compatibility introduced by
$this->getQueryGrammar() of type object<Illuminate\Databa...Query\Grammars\Grammar> is not a sub-type of object<Yajra\Oci8\Query\Grammars\OracleGrammar>. It seems like you assume a child class of the class Illuminate\Database\Query\Grammars\Grammar to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Compatibility introduced by
$processor of type object<Illuminate\Databa...y\Processors\Processor> is not a sub-type of object<Yajra\Oci8\Query\...essors\OracleProcessor>. It seems like you assume a child class of the class Illuminate\Database\Query\Processors\Processor to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
163
164
        return $query->from($table);
165
    }
166
167
    /**
168
     * Set oracle session date format.
169
     *
170
     * @param string $format
171
     * @return $this
172
     */
173
    public function setDateFormat($format = 'YYYY-MM-DD HH24:MI:SS')
174
    {
175
        $sessionVars = [
176
            'NLS_DATE_FORMAT'      => $format,
177
            'NLS_TIMESTAMP_FORMAT' => $format,
178
        ];
179
180
        return $this->setSessionVars($sessionVars);
181
    }
182
183
    /**
184
     * Get doctrine connection.
185
     *
186
     * @return \Doctrine\DBAL\Connection
187
     */
188
    public function getDoctrineConnection()
189
    {
190
        $driver = $this->getDoctrineDriver();
191
192
        $data = ['pdo' => $this->getPdo(), 'user' => $this->getConfig('database')];
193
194
        return new DoctrineConnection($data, $driver);
195
    }
196
197
    /**
198
     * Get doctrine driver.
199
     *
200
     * @return \Doctrine\DBAL\Driver\OCI8\Driver
201
     */
202
    protected function getDoctrineDriver()
203
    {
204
        return new DoctrineDriver;
205
    }
206
207
    /**
208
     * Get the default query grammar instance.
209
     *
210
     * @return \Yajra\Oci8\Query\Grammars\OracleGrammar
211
     */
212
    protected function getDefaultQueryGrammar()
213
    {
214
        return $this->withTablePrefix(new QueryGrammar);
215
    }
216
217
    /**
218
     * Set the table prefix and return the grammar.
219
     *
220
     * @param \Illuminate\Database\Grammar $grammar
221
     * @return \Illuminate\Database\Grammar
222
     */
223
    public function withTablePrefix(Grammar $grammar)
224
    {
225
226
        return $this->withSchemaPrefix(parent::withTablePrefix($grammar));
227
    }
228
229
    /**
230
     * Get the default schema grammar instance.
231
     *
232
     * @return \Yajra\Oci8\Schema\Grammars\OracleGrammar
233
     */
234
    protected function getDefaultSchemaGrammar()
235
    {
236
        return $this->withTablePrefix(new SchemaGrammar);
237
    }
238
239
    /**
240
     * Get the default post processor instance.
241
     *
242
     * @return \Yajra\Oci8\Query\Processors\OracleProcessor
243
     */
244
    protected function getDefaultPostProcessor()
245
    {
246
        return new Processor;
247
    }
248
249
250
    /**
251
     * Set the table prefix and return the grammar.
252
     *
253
     * @param \Illuminate\Database\Grammar $grammar
254
     * @return \Illuminate\Database\Grammar
255
     */
256
    public function withSchemaPrefix(Grammar $grammar)
257
    {
258
        $grammar->setSchemaPrefix($this->config['prefix_schema']);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Illuminate\Database\Grammar as the method setSchemaPrefix() does only exist in the following sub-classes of Illuminate\Database\Grammar: Yajra\Oci8\Query\Grammars\OracleGrammar. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
259
260
        return $grammar;
261
    }
262
}
263