-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7932748
Showing
5 changed files
with
459 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "ajcastro/insert-update-many", | ||
"description": "Laravel's batch insert or batch update for collection of eloquent models.", | ||
"type": "library", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Arjon Jason Castro", | ||
"email": "ajcastro29@gmail.com" | ||
} | ||
], | ||
"require": { | ||
"php": ">=5.4.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"AjCastro\\InsertUpdateMany\\": "src" | ||
} | ||
}, | ||
"extra": { | ||
"laravel": { | ||
"providers": [ | ||
"AjCastro\\InsertUpdateMany\\ServiceProvider" | ||
], | ||
"aliases": { | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# Laravel Eloquent's Insert/Update Many | ||
|
||
Laravel's batch insert or batch update for collection of eloquent models. | ||
Perform single query for batch insert or update operations. | ||
This updates the `created_at` and `updated_at` column of the models and the tables. | ||
The method names `insertMany` and `updateMany` is based from the eloquent method name `saveMany`. | ||
Both `insertMany` and `updateMany` can accept collection of models or just plain array data. | ||
|
||
## Installation | ||
|
||
``` | ||
composer require ajcastro/insert-update-many | ||
``` | ||
|
||
## Usage | ||
|
||
### Insert Many | ||
|
||
Directly pass array or collection of models unlike Laravel's built-in `insert()` which only accept arrays. | ||
This already sets the `created_at` and `updated_at` columns. | ||
|
||
```php | ||
$users = factory(User::class, 10)->make(); | ||
User::insertMany($users); | ||
``` | ||
|
||
#### How it works | ||
|
||
The passed collection of models is transformed to its array form, only including fillable attributes, and passed its array | ||
form to Laravel's native `insert()` method. | ||
|
||
### Update Many | ||
|
||
Update array or collection of models. This perform a single update query for all the passed models. | ||
Only the dirty or changed attributes will be included in the update. | ||
This updates the `updated_at` column of the models and the tables. | ||
|
||
```php | ||
User::updateMany($users); // update many models using id as the default key | ||
User::updateMany($users, 'id'); // same as above | ||
User::updateMany($users, 'username'); // use username as key instead of id | ||
|
||
``` | ||
|
||
#### Specifying which columns to be updated | ||
|
||
```php | ||
User::updateMany($users, 'id', ['email', 'first_name', 'last_name']); | ||
``` | ||
|
||
#### How it works | ||
|
||
This will produce a query like this: | ||
|
||
```sql | ||
UPDATE | ||
`users` | ||
SET | ||
`email` = | ||
CASE | ||
WHEN | ||
`id` = '426' | ||
THEN | ||
'favian.russel@example.com' | ||
WHEN | ||
`id` = '427' | ||
THEN | ||
'opurdy@example.org' | ||
WHEN | ||
`id` = '428' | ||
THEN | ||
'kaylah.hyatt@example.com' | ||
ELSE | ||
`email` | ||
END | ||
, `first_name` = | ||
CASE | ||
WHEN | ||
`id` = '426' | ||
THEN | ||
'Orie' | ||
WHEN | ||
`id` = '427' | ||
THEN | ||
'Hubert' | ||
WHEN | ||
`id` = '428' | ||
THEN | ||
'Mikayla' | ||
ELSE | ||
`first_name` | ||
END | ||
, `last_name` = | ||
CASE | ||
WHEN | ||
`id` = '426' | ||
THEN | ||
'Weissnat' | ||
WHEN | ||
`id` = '427' | ||
THEN | ||
'Wiza' | ||
WHEN | ||
`id` = '428' | ||
THEN | ||
'Keeling' | ||
ELSE | ||
`last_name` | ||
END | ||
WHERE | ||
`id` IN | ||
( | ||
426, 427, 428 | ||
); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
namespace AjCastro\InsertUpdateMany; | ||
|
||
use Illuminate\Database\Eloquent\Model; | ||
|
||
class InsertMany | ||
{ | ||
protected $query; | ||
public $timestamps = true; | ||
protected $createdAtColumn; | ||
protected $updatedAtColumn; | ||
|
||
public function __construct($query, $timestamps = true, $createdAtColumn = 'created_at', $updatedAtColumn = 'updated_at') | ||
{ | ||
$this->query = $query; | ||
$this->timestamps = $timestamps; | ||
$this->createdAtColumn = $createdAtColumn; | ||
$this->updatedAtColumn = $updatedAtColumn; | ||
} | ||
|
||
public function insert($rows) | ||
{ | ||
$ts = now(); | ||
|
||
$rows = collect($rows)->map(function ($row) use ($ts) { | ||
$timestamps = $this->timestamps; | ||
$createdAtColumn = $this->createdAtColumn; | ||
$updatedAtColumn = $this->updatedAtColumn; | ||
|
||
if ($row instanceof Model) { | ||
$timestamps = $row->usesTimestamps(); | ||
$createdAtColumn = $row->getCreatedAtColumn(); | ||
$updatedAtColumn = $row->getUpdatedAtColumn(); | ||
$row->{$createdAtColumn} = $ts; | ||
$row->{$updatedAtColumn} = $ts; | ||
$row = array_only($row->getAttributes(), $row->getFillable()); | ||
} | ||
|
||
if ($timestamps) { | ||
$row = $row + [$createdAtColumn => $ts, $updatedAtColumn => $ts]; | ||
} | ||
|
||
return $row; | ||
}) | ||
->all(); | ||
|
||
return $this->query->insert($rows); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
namespace AjCastro\InsertUpdateMany; | ||
|
||
use Illuminate\Database\Query\Builder; | ||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; | ||
use Illuminate\Support\ServiceProvider as BaseServiceProvider; | ||
|
||
class ServiceProvider extends BaseServiceProvider | ||
{ | ||
/** | ||
* Register any application services. | ||
* | ||
* @return void | ||
*/ | ||
public function register() | ||
{ | ||
Builder::macro('updateMany', function ($rows, $key = 'id', $columns = []) { | ||
return (new UpdateMany( | ||
$this->from, | ||
$key, | ||
$columns | ||
))->update($rows); | ||
}); | ||
|
||
EloquentBuilder::macro('updateMany', function ($rows, $key = 'id', $columns = []) { | ||
return (new UpdateMany( | ||
$this->getModel()->getTable(), | ||
$key, | ||
!empty($columns) ? $columns : $this->getModel()->getFillable() | ||
))->update($rows); | ||
}); | ||
|
||
Builder::macro('insertMany', function ($rows) { | ||
return (new InsertMany($this))->insert($rows); | ||
}); | ||
|
||
EloquentBuilder::macro('insertMany', function ($rows) { | ||
return $this->getQuery()->insertMany($rows); | ||
}); | ||
} | ||
} |
Oops, something went wrong.