This commit is contained in:
邓皓元 2018-11-28 19:09:47 +08:00
parent b0bcad53d6
commit 9e519369b0
9 changed files with 80 additions and 17 deletions

View File

@ -62,7 +62,7 @@ class ActivateSync extends Command
foreach (array_chunk($list, 3000) as $data) {
echo '.';
Card::updateBatch($data, 'sim');
Card::upsert($data, 'sim');
}
$this->line('更新数据成功');

View File

@ -35,7 +35,7 @@ class BlocSync extends Command
unset($item['del']);
}
Bloc::replace($blocs);
Bloc::upsert($blocs, 'id');
app(BlocRepository::class)->forgetCached();
}

View File

@ -34,7 +34,7 @@ class CompanySync extends Command
unset($item['del']);
}
Company::replace($data);
Company::upsert($data, 'id');
app(CompanyRepository::class)->forgetCached();
}

View File

@ -44,7 +44,7 @@ class OrderBaseSync extends Command
$this->line('插入订单数据,条数:'.count($dataOrders));
foreach (array_chunk($dataOrders, $this->chunks) as $data) {
echo '.';
Order::replace($data);
Order::upsert($data, 'id');
}
app(OrderRepository::class)->forgetCached();
unset($dataOrders);
@ -53,7 +53,7 @@ class OrderBaseSync extends Command
$this->line('插入卡数据,条数:'.count($dataCards));
foreach (array_chunk($dataCards, $this->chunks) as $data) {
echo '.';
Card::replace($data);
Card::upsert($data, 'sim');
}
app(CardRepository::class)->forgetCached();
unset($dataCards);
@ -62,7 +62,7 @@ class OrderBaseSync extends Command
$this->line('插入订单关联数据,条数:'.count($dataOrderCards));
foreach (array_chunk($dataOrderCards, $this->chunks) as $data) {
echo '.';
DB::table('real_order_base_cards')->replace($data);
DB::table('real_order_base_cards')->upsert($data, 'sim');
}
unset($dataOrderCards);
$this->line('插入订单关联数据成功');

View File

@ -65,7 +65,7 @@ class OrderCustomSync extends Command
$this->line('插入订单数据,条数:'.count($dataOrders));
foreach (array_chunk($dataOrders, $this->chunks) as $data) {
echo '.';
Order::replace($data);
Order::upsert($data, 'id');
}
app(OrderRepository::class)->forgetCached();
@ -83,7 +83,7 @@ class OrderCustomSync extends Command
foreach ($dataOrderCards as $type => $orderCards) {
foreach (array_chunk($orderCards, $this->chunks) as $data) {
echo '.';
DB::table($tables[$type])->replace($data);
DB::table($tables[$type])->upsert($data, 'sim');
}
}
unset($dataOrderCards);
@ -101,7 +101,7 @@ class OrderCustomSync extends Command
foreach ($dataPackageCards as $type => $packageCards) {
foreach (array_chunk($packageCards, $this->chunks) as $data) {
echo '.';
DB::table($tables[$type])->replace($data);
DB::table($tables[$type])->upsert($data, 'sim');
}
}
unset($dataPackageCards);

View File

@ -50,7 +50,7 @@ class PackageSync extends Command
$packages = array_merge($basePackages, $renewalPackages, $flowPackages, $optionalPackages, $additionalPackages);
Package::replace($packages);
Package::upsert($packages, 'id');
app(PackageRepository::class)->forgetCached();
}

View File

@ -4,8 +4,11 @@ namespace Dipper\Foundation\Database;
use Closure;
use Illuminate\Support\Arr;
use Illuminate\Database\Connection;
use Illuminate\Support\ServiceProvider;
use Dipper\Foundation\Database\PostgresGrammar;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Dipper\Foundation\Database\MySqlGrammar;
class DatabaseServiceProvider extends ServiceProvider
{
@ -16,11 +19,12 @@ class DatabaseServiceProvider extends ServiceProvider
*/
public function register()
{
QueryBuilder::macro('upsert', $this->macroUpsert());
QueryBuilder::macro('replace', $this->macroReplace());
QueryBuilder::macro('insertUpdate', $this->macroInsertUpdate());
QueryBuilder::macro('createOrIgnore', $this->macroCreateOrIgnore());
QueryBuilder::macro('createNotExist', $this->macroCreateNotExist());
QueryBuilder::macro('updateBatch', $this->macroUpdateBatch());
QueryBuilder::macro('updateBatch', $this->macroUpsert());
}
/**
@ -158,7 +162,7 @@ class DatabaseServiceProvider extends ServiceProvider
*
* @return void
*/
public function macroUpdateBatch()
public function macroUpsert()
{
return function (array $values, $filed = 'id') {
if (empty($values)) {
@ -172,13 +176,27 @@ class DatabaseServiceProvider extends ServiceProvider
$values[$key] = $value;
}
}
$grammar = new MySqlGrammar();
$grammar = DatabaseServiceProvider::getGrammar($this->connection);
return $this->connection->affectingStatement(
$grammar->compileUpdateBatch($this, $values, $filed),
$grammar->compileUpsert($this, $values, $filed),
$this->cleanBindings(Arr::flatten($values, 1))
);
};
}
public static function getGrammar(Connection $connection)
{
$driver = $connection->getDriverName();
switch ($driver) {
case 'mysql':
return new MySqlGrammar();
case 'pgsql':
return new PostgresGrammar();
}
throw new \InvalidArgumentException("Unsupported driver [{$driver}]");
}
}

View File

@ -161,7 +161,7 @@ class MySqlGrammar extends Grammar
* @param string $filed
* @return string
*/
public function compileUpdateBatch(QueryBuilder $query, array $values, $filed = 'id')
public function compileUpsert(QueryBuilder $query, array $values, $filed = 'id')
{
// Essentially we will force every insert to be treated as a batch insert which
// simply makes creating the SQL easier for us since we can utilize the same

View File

@ -0,0 +1,45 @@
<?php
namespace Dipper\Foundation\Database;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Query\Grammars\PostgresGrammar as Grammar;
class PostgresGrammar extends Grammar
{
/**
* Compile an upsert statement into SQL.
*
* @param Builder $query
* @param array $values
* @param string $unique
* @return string
*/
public function compileUpsert(QueryBuilder $query, array $values, $filed = 'id')
{
$insert = $this->compileInsert($query, $values);
if (! is_array(reset($values))) {
$values = [$values];
}
$row = current($values);
$keys = array_keys(reset($values));
// 指定更新字段默认id字段,不存在时选用第一个字段。
$reference = isset($row[$filed]) ? $filed : current($keys);
// excluded fields are all fields except $unique one that will be updated
// also created_at should be excluded since record already exists
$excluded = array_filter($keys, function ($e) use ($reference) {
return $e != $reference && $e != 'created_at';
});
$update = join(', ', array_map(function ($e) {
return "\"$e\" = \"excluded\".\"$e\"";
}, $excluded));
return "$insert on conflict ($reference) do update set $update";
}
}