Test Setup Failed
Push — master ( 1fae15...0a0a56 )
by Bas
01:35
created

Blueprint::fulltextIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Schema;
4
5
use ArangoDBClient\CollectionHandler;
6
use Closure;
7
use Illuminate\Database\Connection;
8
use Illuminate\Support\Fluent;
9
use Illuminate\Support\Traits\Macroable;
10
use LaravelFreelancerNL\Aranguent\Schema\Concerns\Columns;
11
use LaravelFreelancerNL\Aranguent\Schema\Concerns\Tables;
12
use LaravelFreelancerNL\Aranguent\Schema\Concerns\Indexes;
13
use LaravelFreelancerNL\Aranguent\Schema\Concerns\Views;
14
15
/**
16
 * Class Blueprint.
17
 *
18
 * The Schema blueprint works differently from the standard Illuminate version:
19
 * 1) ArangoDB is schemaless: we don't need to (and can't) create columns
20
 * 2) ArangoDB doesn't allow DB schema actions within AQL nor within a transaction.
21
 *
22
 * This means that:
23
 * 1) We catch column related methods silently for backwards compatibility and ease of migrating from one DB type to another
24
 * 2) We don't need to compile AQL for transactions within the accompanying schema grammar. (for now)
25
 * 3) We can just execute each command on order. We will gather them first for possible future optimisations.
26
 */
27
class Blueprint
28
{
29
    use Macroable,
30
        Tables,
31
        Columns,
32
        Indexes;
33
34
    /**
35
     * The connection that is used by the blueprint.
36
     *
37
     * @var Connection
38
     */
39
    protected $connection;
40
41
    /**
42
     * The grammar that is used by the blueprint.
43
     *
44
     * @var Grammar
45
     */
46
    protected $grammar;
47
48
    /**
49
     * The table the blueprint describes.
50
     *
51
     * @var string
52
     */
53
    protected $table;
54
55
    /**
56
     * The handler for table manipulation.
57
     */
58
    protected $collectionHandler;
59
60
    /**
61
     * The prefix of the table.
62
     *
63
     * @var string
64
     */
65
    protected $prefix;
66
67
    /**
68
     * The commands that should be run for the table.
69
     *
70
     * @var Fluent[]
71
     */
72
    protected $commands = [];
73
74
    /**
75
     * Catching columns to be able to add fluent indexes.
76
     *
77
     * @var array
78
     */
79
    protected $columns = [];
80
81
    /**
82
     * Whether to make the table temporary.
83
     *
84
     * @var bool
85
     */
86
    public $temporary = false;
87
88
    /**
89
     * Detect if _key (and thus proxy _id) should autoincrement.
90
     *
91
     * @var bool
92
     */
93
    protected $autoIncrement = false;
94
95
    /**
96
     * Create a new schema blueprint.
97
     *
98
     * Blueprint constructor.
99
     * @param string $collection
100
     * @param CollectionHandler $collectionHandler
101
     * @param Closure|null $callback
102
     * @param string $prefix
103
     */
104
    public function __construct($collection, $collectionHandler, Closure $callback = null, $prefix = '')
105
    {
106
        $this->table = $collection;
107
108
        $this->collectionHandler = $collectionHandler;
109
110
        $this->prefix = $prefix;
111
112
        if (! is_null($callback)) {
113
            $callback($this);
114
        }
115
    }
116
117
    /**
118
     * Execute the blueprint against the database.
119
     *
120
     * @param Connection $connection
121
     * @param Grammar $grammar
122
     * @return void
123
     */
124
    public function build(Connection $connection, Grammar $grammar)
125
    {
126
        $this->connection = $connection;
127
128
        if (! isset($grammar)) {
129
            $this->grammar = $connection->getSchemaGrammar();
130
        }
131
132
        foreach ($this->commands as $command) {
133
            if ($command->handler == 'aql') {
134
                $command = $this->compileAqlCommand($command);
135
            }
136
137
            $this->executeCommand($command);
138
        }
139
    }
140
141
    /**
142
     * Generate the compilation method name and call it if method exists in the Grammar object.
143
     *
144
     * @param $command
145
     * @return mixed
146
     */
147
    public function compileAqlCommand($command)
148
    {
149
        $compileMethod = 'compile'.ucfirst($command->name);
150
        if (method_exists($this->grammar, $compileMethod)) {
151
            return $this->grammar->$compileMethod($this->table, $command);
152
        }
153
    }
154
155
    /**
156
     * Generate the execution method name and call it if the method exists.
157
     *
158
     * @param $command
159
     */
160
    public function executeCommand($command)
161
    {
162
        $executeNamedMethod = 'execute'.ucfirst($command->name).'Command';
163
        $executeHandlerMethod = 'execute'.ucfirst($command->handler).'Command';
164
        if (method_exists($this, $executeNamedMethod)) {
165
            $this->$executeNamedMethod($command);
166
        } elseif (method_exists($this, $executeHandlerMethod)) {
167
            $this->$executeHandlerMethod($command);
168
        }
169
    }
170
171
    /**
172
     * Execute an AQL statement.
173
     *
174
     * @param $command
175
     */
176
    public function executeAqlCommand($command)
177
    {
178
        $this->connection->statement($command->aqb->query, $command->aqb->binds);
179
    }
180
181
    public function executeCollectionCommand($command)
182
    {
183
        if ($this->connection->pretending()) {
184
            $this->connection->logQuery('/* '.$command->explanation." */\n", []);
185
186
            return;
187
        }
188
189
        if (method_exists($this->collectionHandler, $command->method)) {
190
            $this->collectionHandler->{$command->method}($command->parameters);
191
        }
192
    }
193
194
    /**
195
     * Solely provides feedback to the developer in pretend mode.
196
     *
197
     * @param $command
198
     * @return null
199
     */
200
    public function executeIgnoreCommand($command)
201
    {
202
        if ($this->connection->pretending()) {
203
            $this->connection->logQuery('/* '.$command->explanation." */\n", []);
204
205
            return;
206
        }
207
    }
208
209
    /**
210
     * Add a new command to the blueprint.
211
     *
212
     * @param  string  $name
213
     * @param  array  $parameters
214
     * @return Fluent
215
     */
216
    protected function addCommand($name, array $parameters = [])
217
    {
218
        $this->commands[] = $command = $this->createCommand($name, $parameters);
219
220
        return $command;
221
    }
222
223
    /**
224
     * Create a new Fluent command.
225
     *
226
     * @param  string  $name
227
     * @param  array  $parameters
228
     * @return Fluent
229
     */
230
    protected function createCommand($name, array $parameters = [])
231
    {
232
        return new Fluent(array_merge(compact('name'), $parameters));
233
    }
234
235
236
    /**
237
     * Get the commands on the blueprint.
238
     *
239
     * @return Fluent[]
240
     */
241
    public function getCommands()
242
    {
243
        return $this->commands;
244
    }
245
246
    /**
247
     * Silently catch unsupported schema methods. Store columns for backwards compatible fluent index creation.
248
     *
249
     * @param $method
250
     * @param $args
251
     * @return Blueprint
252
     */
253
    public function __call($method, $args)
254
    {
255
        $columnMethods = [
256
            'bigIncrements', 'bigInteger', 'binary', 'boolean', 'char', 'date', 'dateTime', 'dateTimeTz', 'decimal',
257
            'double', 'enum', 'engine', 'float', 'geometry', 'geometryCollection', 'increments', 'integer', 'ipAddress', 'json',
258
            'jsonb', 'lineString', 'longText', 'macAddress', 'mediumIncrements', 'mediumInteger', 'mediumText',
259
            'morphs', 'uuidMorphs', 'multiLineString', 'multiPoint', 'multiPolygon',
260
            'nullableMorphs', 'nullableUuidMorphs', 'nullableTimestamps', 'point', 'polygon', 'rememberToken',
261
            'set', 'smallIncrements', 'smallInteger', 'softDeletes', 'softDeletesTz', 'string',
262
            'text', 'time', 'timeTz', 'timestamp', 'timestampTz', 'timestamps', 'tinyIncrements', 'tinyInteger',
263
            'unsignedBigInteger', 'unsignedDecimal', 'unsignedInteger', 'unsignedMediumInteger', 'unsignedSmallInteger',
264
            'unsignedTinyInteger', 'uuid', 'year',
265
        ];
266
267
        if (in_array($method, $columnMethods)) {
268
            if (isset($args)) {
269
                $this->columns[] = $args;
270
            }
271
        }
272
273
        $autoIncrementMethods = ['increments', 'autoIncrement'];
274
        if (in_array($method, $autoIncrementMethods)) {
275
            $this->autoIncrement = true;
276
        }
277
278
        $info['method'] = $method;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$info was never initialized. Although not strictly required by PHP, it is generally a good practice to add $info = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
279
        $info['explanation'] = "'$method' is ignored; Aranguent Schema Blueprint doesn't support it.";
280
        $this->addCommand('ignore', $info);
281
282
        return $this;
283
    }
284
285
}
286