diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 6823998fd..1f7dad751 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -890,6 +890,45 @@ public function decrementEach(array $columns, array $extra = [], array $options return $this->incrementEach($decrement, $extra, $options); } + /** + * Multiply a column's value by a given amount. + * + * @param string $column + * @param float|int $amount + * @return int + */ + public function multiply($column, $amount = 1, array $extra = [], array $options = []) + { + $query = ['$mul' => [(string) $column => $amount]]; + + if (! empty($extra)) { + $query['$set'] = $extra; + } + + // Protect + $this->where(function ($query) use ($column) { + $query->where($column, 'exists', false); + + $query->orWhereNotNull($column); + }); + + $options = $this->inheritConnectionOptions($options); + + return $this->performUpdate($query, $options); + } + + /** + * Divide a column's value by a given amount. + * + * @param string $column + * @param float|int $amount + * @return int + */ + public function divide($column, $amount = 1, array $extra = [], array $options = []) + { + return $this->multiply($column, 1 / $amount, $extra, $options); + } + /** @inheritdoc */ public function pluck($column, $key = null) { diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index 1233cda75..48b17ce5e 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -1052,6 +1052,55 @@ public function testIncrement() $this->assertEquals(1, $user->age); } + public function testMultiplyAndDivide() + { + DB::table('users')->insert([ + ['name' => 'John Doe', 'salary' => 88000, 'note' => 'senior'], + ['name' => 'Jane Doe', 'salary' => 64000, 'note' => 'junior'], + ['name' => 'Robert Roe', 'salary' => null], + ['name' => 'Mark Moe'], + ]); + + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(88000, $user->salary); + + DB::table('users')->where('name', 'John Doe')->multiply('salary'); + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(88000, $user->salary); + + DB::table('users')->where('name', 'John Doe')->divide('salary'); + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(88000, $user->salary); + + DB::table('users')->where('name', 'John Doe')->multiply('salary', 2); + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(176000, $user->salary); + + DB::table('users')->where('name', 'John Doe')->divide('salary', 2); + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(88000, $user->salary); + + DB::table('users')->where('name', 'Jane Doe')->multiply('salary', 10, ['note' => 'senior']); + $user = DB::table('users')->where('name', 'Jane Doe')->first(); + $this->assertEquals(640000, $user->salary); + $this->assertEquals('senior', $user->note); + + DB::table('users')->where('name', 'John Doe')->divide('salary', 2, ['note' => 'junior']); + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(44000, $user->salary); + $this->assertEquals('junior', $user->note); + + DB::table('users')->multiply('salary'); + $user = DB::table('users')->where('name', 'John Doe')->first(); + $this->assertEquals(44000, $user->salary); + $user = DB::table('users')->where('name', 'Jane Doe')->first(); + $this->assertEquals(640000, $user->salary); + $user = DB::table('users')->where('name', 'Robert Roe')->first(); + $this->assertNull($user->salary); + $user = DB::table('users')->where('name', 'Mark Moe')->first(); + $this->assertEquals(0, $user->salary); + } + public function testProjections() { DB::table('items')->insert([