LaravelFreelancerNL /
laravel-arangodb
| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace LaravelFreelancerNL\Aranguent\Schema\Concerns; |
||||
| 4 | |||||
| 5 | use ArangoClient\Exceptions\ArangoException; |
||||
| 6 | use Illuminate\Support\Fluent; |
||||
| 7 | |||||
| 8 | trait IndexCommands |
||||
| 9 | { |
||||
| 10 | use HandlesIndexNaming; |
||||
| 11 | |||||
| 12 | /** |
||||
| 13 | * Add a new index command to the blueprint. |
||||
| 14 | * |
||||
| 15 | * @param string|array<string>|null $columns |
||||
| 16 | */ |
||||
| 17 | 79 | protected function indexCommand( |
|||
| 18 | string $type, |
||||
| 19 | array|null|string $columns = null, |
||||
| 20 | string $name = null, |
||||
| 21 | array $indexOptions = [], |
||||
| 22 | ): Fluent { |
||||
| 23 | 79 | if ($columns === null) { |
|||
| 24 | 61 | $columns = end($this->columns); |
|||
| 25 | } |
||||
| 26 | |||||
| 27 | 79 | if (is_string($columns)) { |
|||
| 28 | 66 | $columns = [$columns]; |
|||
| 29 | } |
||||
| 30 | |||||
| 31 | 79 | $columns = $this->renameIdField($columns); |
|||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 32 | |||||
| 33 | 79 | $indexOptions['name'] = $name ?: $this->createIndexName($type, $columns, $indexOptions); |
|||
| 34 | |||||
| 35 | 79 | return $this->addCommand('index', compact('type', 'columns', 'indexOptions')); |
|||
|
0 ignored issues
–
show
It seems like
addCommand() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 36 | } |
||||
| 37 | |||||
| 38 | /** |
||||
| 39 | * Specify an index for the table. |
||||
| 40 | * |
||||
| 41 | * @param array|null|string $columns |
||||
| 42 | * @param null|string $name |
||||
| 43 | * @param null|string $algorithm |
||||
| 44 | * @param array<mixed> $indexOptions |
||||
| 45 | * @return Fluent |
||||
| 46 | */ |
||||
| 47 | 67 | public function index($columns = null, $name = null, $algorithm = null, $indexOptions = []) |
|||
| 48 | { |
||||
| 49 | 67 | $type = $this->mapIndexAlgorithm($algorithm); |
|||
| 50 | |||||
| 51 | 67 | return $this->indexCommand($type, $columns, $name, $indexOptions); |
|||
| 52 | } |
||||
| 53 | |||||
| 54 | /** |
||||
| 55 | * Specify a spatial index for the table. |
||||
| 56 | * |
||||
| 57 | * @param string|array $columns |
||||
| 58 | * @param null|string $name |
||||
| 59 | * @param array<mixed> $indexOptions |
||||
| 60 | * @return Fluent |
||||
| 61 | */ |
||||
| 62 | 2 | public function spatialIndex($columns, $name = null, $indexOptions = []) |
|||
| 63 | { |
||||
| 64 | 2 | return $this->indexCommand('geo', $columns, $name, $indexOptions); |
|||
| 65 | } |
||||
| 66 | |||||
| 67 | /** |
||||
| 68 | * Specify a spatial index for the table. |
||||
| 69 | * |
||||
| 70 | * @param array<mixed>|null|string $columns |
||||
| 71 | * @param null|string $name |
||||
| 72 | * @param array<mixed> $indexOptions |
||||
| 73 | * @return Fluent |
||||
| 74 | */ |
||||
| 75 | 1 | public function geoIndex($columns, $name = null, $indexOptions = []) |
|||
| 76 | { |
||||
| 77 | 1 | return $this->spatialIndex($columns, $name, $indexOptions); |
|||
| 78 | } |
||||
| 79 | |||||
| 80 | /** |
||||
| 81 | * Specify a inverted index for the table. |
||||
| 82 | * |
||||
| 83 | * @param array<mixed>|null|string $columns |
||||
| 84 | * @param null|string $name |
||||
| 85 | * @param array<mixed> $indexOptions |
||||
| 86 | * @return Fluent |
||||
| 87 | */ |
||||
| 88 | 61 | public function invertedIndex($columns = null, $name = null, $indexOptions = []) |
|||
| 89 | { |
||||
| 90 | 61 | return $this->indexCommand('inverted', $columns, $name, $indexOptions); |
|||
| 91 | } |
||||
| 92 | |||||
| 93 | |||||
| 94 | 2 | public function multiDimensionalIndex(array $columns = null, string $name = null, array $indexOptions = [], string $type = 'mdi'): Fluent |
|||
| 95 | { |
||||
| 96 | 2 | return $this->indexCommand( |
|||
| 97 | 2 | $type, |
|||
| 98 | 2 | $columns, |
|||
| 99 | 2 | $name, |
|||
| 100 | 2 | $indexOptions, |
|||
| 101 | 2 | ); |
|||
| 102 | } |
||||
| 103 | |||||
| 104 | 1 | public function persistentIndex(array $columns = null, string $name = null, array $indexOptions = []): Fluent |
|||
| 105 | { |
||||
| 106 | 1 | return $this->indexCommand('persistent', $columns, $name, $indexOptions); |
|||
| 107 | } |
||||
| 108 | |||||
| 109 | /** |
||||
| 110 | * @param array<string>|null|string $columns |
||||
| 111 | * @param string|null $name |
||||
| 112 | * @param array<mixed> $indexOptions |
||||
| 113 | * @return Fluent |
||||
| 114 | */ |
||||
| 115 | 61 | public function primary($columns = null, $name = null, $indexOptions = []): Fluent |
|||
| 116 | { |
||||
| 117 | 61 | $indexOptions['unique'] = true; |
|||
| 118 | |||||
| 119 | 61 | return $this->indexCommand('persistent', $columns, $name, $indexOptions); |
|||
| 120 | } |
||||
| 121 | |||||
| 122 | /** |
||||
| 123 | * Create a TTL index for the table. |
||||
| 124 | * |
||||
| 125 | * @param string $columns |
||||
| 126 | * @param int $expireAfter |
||||
| 127 | * @param null $name |
||||
|
0 ignored issues
–
show
|
|||||
| 128 | * @param array $indexOptions |
||||
| 129 | * @return Fluent |
||||
| 130 | */ |
||||
| 131 | 2 | public function ttlIndex($columns, $expireAfter, $name = null, $indexOptions = []): Fluent |
|||
| 132 | { |
||||
| 133 | 2 | $indexOptions['expireAfter'] = $expireAfter; |
|||
| 134 | 2 | return $this->indexCommand('ttl', $columns, $name, $indexOptions); |
|||
| 135 | } |
||||
| 136 | |||||
| 137 | /** |
||||
| 138 | * Specify a unique index for the table. |
||||
| 139 | * |
||||
| 140 | * @param string|array $columns |
||||
| 141 | * @param string $name |
||||
| 142 | * @param string|null $algorithm |
||||
| 143 | */ |
||||
| 144 | 60 | public function unique($columns = null, $name = null, $algorithm = null): Fluent |
|||
| 145 | { |
||||
| 146 | 60 | $type = $this->mapIndexAlgorithm($algorithm); |
|||
| 147 | |||||
| 148 | 60 | $indexOptions = []; |
|||
| 149 | 60 | $indexOptions['unique'] = true; |
|||
| 150 | |||||
| 151 | 60 | return $this->indexCommand($type, $columns, $name, $indexOptions); |
|||
| 152 | } |
||||
| 153 | |||||
| 154 | /** |
||||
| 155 | * @throws ArangoException |
||||
| 156 | */ |
||||
| 157 | 79 | public function executeIndexCommand(Fluent $command) |
|||
| 158 | { |
||||
| 159 | 79 | if ($this->connection->pretending()) { |
|||
| 160 | $this->connection->logQuery('/* ' . $command->explanation . " */\n", []); |
||||
| 161 | |||||
| 162 | return; |
||||
| 163 | } |
||||
| 164 | |||||
| 165 | // Skip persistent indexes set solely on id - ArangoDB already sets a unique index on _key. |
||||
| 166 | if ( |
||||
| 167 | 79 | $command->type === 'persistent' |
|||
|
0 ignored issues
–
show
|
|||||
| 168 | 79 | && count($command->columns) === 1 |
|||
| 169 | 79 | && $command->columns[0] === '_key' |
|||
| 170 | ) { |
||||
| 171 | 60 | return; |
|||
| 172 | } |
||||
| 173 | |||||
| 174 | 78 | $options = [ |
|||
| 175 | 78 | 'type' => $command->type, |
|||
| 176 | 78 | 'fields' => $command->columns, |
|||
| 177 | 78 | 'unique' => $command->unique, |
|||
| 178 | 78 | 'options' => $command->indexOptions, |
|||
| 179 | 78 | ]; |
|||
| 180 | |||||
| 181 | 78 | if (isset($command->indexOptions) && is_array($command->indexOptions)) { |
|||
|
0 ignored issues
–
show
|
|||||
| 182 | 78 | $options = array_merge($options, $command->indexOptions); |
|||
| 183 | } |
||||
| 184 | |||||
| 185 | 78 | $this->schemaManager->createIndex($this->table, $options); |
|||
| 186 | } |
||||
| 187 | |||||
| 188 | /** |
||||
| 189 | * Indicate that the given index should be dropped. |
||||
| 190 | */ |
||||
| 191 | 12 | public function dropIndex(string $name): Fluent |
|||
| 192 | { |
||||
| 193 | 12 | $parameters = []; |
|||
| 194 | 12 | $parameters['name'] = 'dropIndex'; |
|||
| 195 | 12 | $parameters['index'] = $name; |
|||
| 196 | 12 | $parameters['explanation'] = "Drop the '" . $name . "' index on the {$this->table} table."; |
|||
| 197 | 12 | $parameters['handler'] = 'collection'; |
|||
| 198 | |||||
| 199 | 12 | return $this->addCommand('dropIndex', $parameters); |
|||
| 200 | } |
||||
| 201 | |||||
| 202 | /** |
||||
| 203 | * Indicate that the given index should be dropped. |
||||
| 204 | */ |
||||
| 205 | public function dropPersistentIndex(string $name): Fluent |
||||
| 206 | { |
||||
| 207 | return $this->dropIndex($name); |
||||
| 208 | } |
||||
| 209 | |||||
| 210 | /** |
||||
| 211 | * Indicate that the given index should be dropped. |
||||
| 212 | */ |
||||
| 213 | 1 | public function dropPrimary(string $name): Fluent |
|||
| 214 | { |
||||
| 215 | 1 | return $this->dropIndex($name); |
|||
| 216 | } |
||||
| 217 | |||||
| 218 | /** |
||||
| 219 | * Indicate that the given index should be dropped. |
||||
| 220 | */ |
||||
| 221 | 1 | public function dropUnique(string $name): Fluent |
|||
| 222 | { |
||||
| 223 | 1 | return $this->dropIndex($name); |
|||
| 224 | } |
||||
| 225 | |||||
| 226 | /** |
||||
| 227 | * Indicate that the given index should be dropped. |
||||
| 228 | */ |
||||
| 229 | 2 | public function dropSpatialIndex(string $name): Fluent |
|||
| 230 | { |
||||
| 231 | 2 | return $this->dropIndex($name); |
|||
| 232 | } |
||||
| 233 | |||||
| 234 | /** |
||||
| 235 | * Indicate that the given index should be dropped. |
||||
| 236 | */ |
||||
| 237 | 2 | public function dropInvertedIndex(string $name): Fluent |
|||
| 238 | { |
||||
| 239 | 2 | return $this->dropIndex($name); |
|||
| 240 | } |
||||
| 241 | |||||
| 242 | /** |
||||
| 243 | * Indicate that the given index should be dropped. |
||||
| 244 | */ |
||||
| 245 | 2 | public function dropMultiDimensionalIndex(string $name): Fluent |
|||
| 246 | { |
||||
| 247 | 2 | return $this->dropIndex($name); |
|||
| 248 | } |
||||
| 249 | |||||
| 250 | /** |
||||
| 251 | * Drop the index by first getting all the indexes on the table; then selecting the matching one |
||||
| 252 | * by name. |
||||
| 253 | */ |
||||
| 254 | 12 | public function executeDropIndexCommand(Fluent $command) |
|||
| 255 | { |
||||
| 256 | 12 | if ($this->connection->pretending()) { |
|||
| 257 | $this->connection->logQuery('/* ' . $command->explanation . " */\n", []); // @phpstan-ignore-line |
||||
| 258 | |||||
| 259 | return; |
||||
| 260 | } |
||||
| 261 | 12 | $indexes = $this->schemaManager->getIndexes($this->table); |
|||
| 262 | 12 | $arrayIndex = array_search($command->index, array_column($indexes, 'name'), true); |
|||
| 263 | 12 | $indexId = $indexes[$arrayIndex]->id; |
|||
| 264 | |||||
| 265 | 12 | $this->schemaManager->deleteIndex($indexId); |
|||
| 266 | } |
||||
| 267 | |||||
| 268 | /** |
||||
| 269 | * @param string|null $algorithm |
||||
| 270 | * @return mixed|string |
||||
| 271 | */ |
||||
| 272 | 68 | protected function mapIndexAlgorithm($algorithm): mixed |
|||
| 273 | { |
||||
| 274 | 68 | $algorithm = strtoupper($algorithm); |
|||
|
0 ignored issues
–
show
It seems like
$algorithm can also be of type null; however, parameter $string of strtoupper() does only seem to accept string, 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...
|
|||||
| 275 | |||||
| 276 | 68 | $algorithmConversion = [ |
|||
| 277 | 68 | 'HASH' => 'hash', |
|||
| 278 | 68 | 'BTREE' => 'persistent', |
|||
| 279 | 68 | 'RTREE' => 'geo', |
|||
| 280 | 68 | 'TTL' => 'ttl', |
|||
| 281 | 68 | ]; |
|||
| 282 | |||||
| 283 | 68 | return (isset($algorithmConversion[$algorithm])) ? $algorithmConversion[$algorithm] : 'persistent'; |
|||
| 284 | } |
||||
| 285 | |||||
| 286 | } |
||||
| 287 |