diff --git a/src/Illuminate/Database/Schema/Blueprint.php b/src/Illuminate/Database/Schema/Blueprint.php index 980940dd57be..e500907156ba 100755 --- a/src/Illuminate/Database/Schema/Blueprint.php +++ b/src/Illuminate/Database/Schema/Blueprint.php @@ -684,11 +684,12 @@ public function fullText($columns, $name = null, $algorithm = null) * * @param string|array $columns * @param string|null $name + * @param string|null $operatorClass * @return \Illuminate\Database\Schema\IndexDefinition */ - public function spatialIndex($columns, $name = null) + public function spatialIndex($columns, $name = null, $operatorClass = null) { - return $this->indexCommand('spatialIndex', $columns, $name); + return $this->indexCommand('spatialIndex', $columns, $name, null, $operatorClass); } /** @@ -1641,15 +1642,16 @@ public function comment($comment) } /** - * Add a new index command to the blueprint. + * Create a new index command on the blueprint. * * @param string $type * @param string|array $columns * @param string $index * @param string|null $algorithm + * @param string|null $operatorClass * @return \Illuminate\Support\Fluent */ - protected function indexCommand($type, $columns, $index, $algorithm = null) + protected function indexCommand($type, $columns, $index, $algorithm = null, $operatorClass = null) { $columns = (array) $columns; @@ -1659,7 +1661,7 @@ protected function indexCommand($type, $columns, $index, $algorithm = null) $index = $index ?: $this->createIndexName($type, $columns); return $this->addCommand( - $type, compact('index', 'columns', 'algorithm') + $type, compact('index', 'columns', 'algorithm', 'operatorClass') ); } diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 7e1e6a1d2fa8..708e75058d1f 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -403,9 +403,46 @@ public function compileSpatialIndex(Blueprint $blueprint, Fluent $command) { $command->algorithm = 'gist'; + if (! is_null($command->operatorClass)) { + return $this->compileIndexWithOperatorClass($blueprint, $command); + } + return $this->compileIndex($blueprint, $command); } + /** + * Compile a spatial index with operator class key command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + protected function compileIndexWithOperatorClass(Blueprint $blueprint, Fluent $command) + { + $columns = $this->columnizeWithOperatorClass($command->columns, $command->operatorClass); + + return sprintf('create index %s on %s%s (%s)', + $this->wrap($command->index), + $this->wrapTable($blueprint), + $command->algorithm ? ' using '.$command->algorithm : '', + $columns + ); + } + + /** + * Convert an array of column names to a delimited string with operator class. + * + * @param array $columns + * @param string $operatorClass + * @return string + */ + protected function columnizeWithOperatorClass(array $columns, $operatorClass) + { + return implode(', ', array_map(function ($column) use ($operatorClass) { + return $this->wrap($column).' '.$operatorClass; + }, $columns)); + } + /** * Compile a foreign key command. * diff --git a/tests/Database/DatabasePostgresSchemaGrammarTest.php b/tests/Database/DatabasePostgresSchemaGrammarTest.php index f3402250245f..6a21cca7093d 100755 --- a/tests/Database/DatabasePostgresSchemaGrammarTest.php +++ b/tests/Database/DatabasePostgresSchemaGrammarTest.php @@ -386,6 +386,26 @@ public function testAddingFluentSpatialIndex() $this->assertSame('create index "geo_coordinates_spatialindex" on "geo" using gist ("coordinates")', $statements[1]); } + public function testAddingSpatialIndexWithOperatorClass() + { + $blueprint = new Blueprint($this->getConnection(), 'geo'); + $blueprint->spatialIndex('coordinates', 'my_index', 'point_ops'); + $statements = $blueprint->toSql(); + + $this->assertCount(1, $statements); + $this->assertSame('create index "my_index" on "geo" using gist ("coordinates" point_ops)', $statements[0]); + } + + public function testAddingSpatialIndexWithOperatorClassMultipleColumns() + { + $blueprint = new Blueprint($this->getConnection(), 'geo'); + $blueprint->spatialIndex(['coordinates', 'location'], 'my_index', 'point_ops'); + $statements = $blueprint->toSql(); + + $this->assertCount(1, $statements); + $this->assertSame('create index "my_index" on "geo" using gist ("coordinates" point_ops, "location" point_ops)', $statements[0]); + } + public function testAddingRawIndex() { $blueprint = new Blueprint($this->getConnection(), 'users');