diff --git a/.travis.yml b/.travis.yml index 3661eb50b..04467f208 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ branches: php: - 5.3 - 5.4 + - 5.5 services: mongodb diff --git a/README.md b/README.md index 8c2c7913b..e5ac5f610 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,8 @@ $users = User::where('votes', '>', 100)->orWhere('name', 'John')->get(); $users = User::whereIn('age', array(16, 18, 20))->get(); ``` +When using `whereNotIn` objects will be returned if the field is non existant. Combine with `whereNotNull('age')` to leave out those documents. + **Using Where Between** ```php @@ -181,3 +183,30 @@ $user = Comment::where('body', 'like', '%spam%')->get(); **Inserts, updates and deletes** All basic insert, update, delete and select methods should be implemented. + +**Increments & decrements** + +Perform increments (default 1) on specified attributes. +Attention: without a where-clause, every object will be modified. + +```php +User::where('name', 'John Doe')->increment('age'); +User::where('name', 'Bart De Wever')->decrement('weight', 50); +``` + +The number of updated objects is returned. + +```php +$count = User->increment('age'); +echo $count; +``` + +will return the number of users where `age` is a valid field. + +These functions also allow for a third attribute: + +```php +User::where('age', '29')->increment('age', 1, array('group' => 'thirty something')); + +User::where('bmi', 30)->decrement('bmi', 1, array('category' => 'overweight')); +``` \ No newline at end of file diff --git a/src/Jenssegers/Mongodb/Builder.php b/src/Jenssegers/Mongodb/Builder.php index 1dcbf6bed..faec737b4 100644 --- a/src/Jenssegers/Mongodb/Builder.php +++ b/src/Jenssegers/Mongodb/Builder.php @@ -286,6 +286,49 @@ public function update(array $values) return 0; } + /** + * Increment a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @param array $extra + * @return int + */ + public function increment($column, $amount = 1, array $extra = array()) + { + // build update statement + $update = array( + '$inc' => array($column => $amount), + '$set' => $extra, + ); + + // protect + $this->whereNotNull($column); + + // perform + $result = $this->collection->update($this->compileWheres(), $update, array('multiple' => true)); + + if (1 == (int) $result['ok']) + { + return $result['n']; + } + + return 0; + } + + /** + * Decrement a column's value by a given amount. + * + * @param string $column + * @param int $amount + * @param array $extra + * @return int + */ + public function decrement($column, $amount = 1, array $extra = array()) + { + return $this->increment($column, -1 * $amount, $extra); + } + /** * Delete a record from the database. * @@ -429,6 +472,13 @@ private function compileWhereIn($where) return array($column => array('$in' => $values)); } + private function compileWhereNotIn($where) + { + extract($where); + + return array($column => array('$nin' => $values)); + } + private function compileWhereNull($where) { $where['operator'] = '='; diff --git a/tests/QueryTest.php b/tests/QueryTest.php index 7615b9b2c..5d1ff4498 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -112,6 +112,12 @@ public function testSelect() $this->assertEquals('John Doe', $user->name); $this->assertEquals(null, $user->age); + $user = User::select('name', 'title')->first(); + + $this->assertEquals('John Doe', $user->name); + $this->assertEquals('admin', $user->title); + $this->assertEquals(null, $user->age); + $user = User::get(array('name'))->first(); $this->assertEquals('John Doe', $user->name); @@ -143,12 +149,22 @@ public function testIn() $users = User::whereIn('age', array(33, 35, 13))->get(); $this->assertEquals(6, count($users)); + + $users = User::whereNotIn('age', array(33, 35))->get(); + $this->assertEquals(4, count($users)); + + $users = User::whereNotNull('age') + ->whereNotIn('age', array(33, 35))->get(); + $this->assertEquals(3, count($users)); } public function testWhereNull() { $users = User::whereNull('age')->get(); $this->assertEquals(1, count($users)); + + $users = User::whereNotNull('age')->get(); + $this->assertEquals(8, count($users)); } public function testOrder() @@ -173,6 +189,37 @@ public function testOffset() $this->assertEquals('Jane Doe', $users[0]->name); } + public function testIncrements() + { + User::where('name', 'John Doe')->increment('age'); + User::where('name', 'John Doe')->increment('age', 2, array('title' => 'user')); + + $user = User::where('name', 'John Doe')->first(); + $this->assertEquals(38, $user->age); + $this->assertEquals('user', $user->title); + + User::where('name', 'John Doe')->decrement('age'); + $num = User::where('name', 'John Doe')->decrement('age', 2, array('title' => 'admin')); + + $user = User::where('name', 'John Doe')->first(); + $this->assertEquals(35, $user->age); + $this->assertEquals('admin', $user->title); + $this->assertEquals(1, $num); + + User::increment('age'); + User::increment('age', 2); + + $user = User::where('name', 'Mark Moe')->first(); + $this->assertEquals(26, $user->age); + + User::decrement('age', 2); + $num = User::decrement('age'); + + $user = User::where('name', 'Mark Moe')->first(); + $this->assertEquals(23, $user->age); + $this->assertEquals(8, $num); + } + public function testAggregates() { $this->assertEquals(9, User::count()); @@ -183,6 +230,9 @@ public function testAggregates() $this->assertEquals(35, User::where('title', 'admin')->max('age')); $this->assertEquals(37, User::where('title', 'user')->max('age')); + + $this->assertEquals(33, User::where('title', 'admin')->min('age')); + $this->assertEquals(13, User::where('title', 'user')->min('age')); } public function testGroupBy()