diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 74f13c43c1aa..c994a546381a 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2647,6 +2647,33 @@ public function insert(array $values) ); } + /** + * Insert ignore a new record into the database. + * + * @param array $values + * @return int + */ + public function insertOrIgnore(array $values) + { + if (empty($values)) { + return 0; + } + + if (! is_array(reset($values))) { + $values = [$values]; + } else { + foreach ($values as $key => $value) { + ksort($value); + $values[$key] = $value; + } + } + + return $this->connection->affectingStatement( + $this->grammar->compileInsertOrIgnore($this, $values), + $this->cleanBindings(Arr::flatten($values, 1)) + ); + } + /** * Insert a new record and get the value of the primary key. * diff --git a/src/Illuminate/Database/Query/Grammars/Grammar.php b/src/Illuminate/Database/Query/Grammars/Grammar.php index cd1ed736c2cb..973a3c6aeab6 100755 --- a/src/Illuminate/Database/Query/Grammars/Grammar.php +++ b/src/Illuminate/Database/Query/Grammars/Grammar.php @@ -872,6 +872,18 @@ public function compileInsert(Builder $query, array $values) return "insert into $table ($columns) values $parameters"; } + /** + * Compile an insert ignore statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileInsertOrIgnore(Builder $query, array $values) + { + throw new RuntimeException('This database engine does not support insert or ignore.'); + } + /** * Compile an insert and get ID statement into SQL. * diff --git a/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php b/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php index 5a9cea6e5663..b369ea1831f4 100755 --- a/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php @@ -54,6 +54,18 @@ public function compileSelect(Builder $query) return $sql; } + /** + * Compile an insert ignore statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileInsertOrIgnore(Builder $query, array $values) + { + return substr_replace($this->compileInsert($query, $values), ' ignore', 6, 0); + } + /** * Compile a "JSON contains" statement into SQL. * diff --git a/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php index 64ac0f0f68e0..4f593a232820 100755 --- a/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/PostgresGrammar.php @@ -195,6 +195,18 @@ public function compileInsert(Builder $query, array $values) : parent::compileInsert($query, $values); } + /** + * Compile an insert ignore statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileInsertOrIgnore(Builder $query, array $values) + { + return $this->compileInsert($query, $values).' on conflict do nothing'; + } + /** * Compile an insert and get ID statement into SQL. * diff --git a/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php b/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php index 5d5df6d1cbff..6e7a95147a99 100755 --- a/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php @@ -178,6 +178,18 @@ public function compileInsert(Builder $query, array $values) : parent::compileInsert($query, $values); } + /** + * Compile an insert ignore statement into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @return string + */ + public function compileInsertOrIgnore(Builder $query, array $values) + { + return substr_replace($this->compileInsert($query, $values), ' or ignore', 6, 0); + } + /** * Compile an update statement into SQL. * diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index aecbbabfe645..826022b920c4 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1867,6 +1867,46 @@ function (Builder $query) { $this->assertTrue($result); } + public function testInsertOrIgnoreMethod() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('This database engine does not support insert or ignore.'); + $builder = $this->getBuilder(); + $builder->from('users')->insertOrIgnore(['email' => 'foo']); + } + + public function testMySqlInsertOrIgnoreMethod() + { + $builder = $this->getMySqlBuilder(); + $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert ignore into `users` (`email`) values (?)', ['foo'])->andReturn(1); + $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']); + $this->assertEquals(1, $result); + } + + public function testPostgresInsertOrIgnoreMethod() + { + $builder = $this->getPostgresBuilder(); + $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert into "users" ("email") values (?) on conflict do nothing', ['foo'])->andReturn(1); + $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']); + $this->assertEquals(1, $result); + } + + public function testSQLiteInsertOrIgnoreMethod() + { + $builder = $this->getSQLiteBuilder(); + $builder->getConnection()->shouldReceive('affectingStatement')->once()->with('insert or ignore into "users" ("email") values (?)', ['foo'])->andReturn(1); + $result = $builder->from('users')->insertOrIgnore(['email' => 'foo']); + $this->assertEquals(1, $result); + } + + public function testSqlServerInsertOrIgnoreMethod() + { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('This database engine does not support insert or ignore.'); + $builder = $this->getSqlServerBuilder(); + $builder->from('users')->insertOrIgnore(['email' => 'foo']); + } + public function testInsertGetIdMethod() { $builder = $this->getBuilder();