Passed
Push — master ( 5f75c5...4540a7 )
by hugh
23:20 queued 16:16
created

ClearTableCommand::getOts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * Created by PhpStorm.
5
 * User: hugh.li
6
 * Date: 2021/2/22
7
 * Time: 11:18
8
 */
9
10
namespace HughCube\Laravel\OTS\Commands;
11
12
use Aliyun\OTS\Consts\DirectionConst;
13
use Aliyun\OTS\Consts\OperationTypeConst;
14
use Aliyun\OTS\Consts\PrimaryKeyTypeConst;
15
use Aliyun\OTS\Consts\RowExistenceExpectationConst;
16
use Aliyun\OTS\OTSClientException;
17
use Aliyun\OTS\OTSServerException;
18
use Carbon\Carbon;
19
use HughCube\Laravel\OTS\Connection;
20
use Illuminate\Console\Command;
21
use Illuminate\Console\Scheduling\Schedule;
22
use Illuminate\Support\Arr;
23
use Illuminate\Support\Facades\DB;
24
25
class ClearTableCommand extends Command
26
{
27
    /**
28
     * @inheritdoc
29
     */
30
    protected $signature = 'ots:clear-table
31
                            {--ots=ots : ots connection. }
32
                            {--name= : ots table name. }';
33
34
    /**
35
     * @inheritdoc
36
     */
37
    protected $description = 'Clear the ots table data.';
38
39
    /**
40
     * @param  Schedule  $schedule
41
     * @return void
42
     * @throws OTSClientException
43
     * @throws OTSServerException
44
     */
45
    public function handle(Schedule $schedule)
0 ignored issues
show
Unused Code introduced by
The parameter $schedule is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

45
    public function handle(/** @scrutinizer ignore-unused */ Schedule $schedule)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
46
    {
47
        $tableName = $this->getTable();
48
49
        try {
50
            $table = $this->getOts()->describeTable(['table_name' => $tableName]);
0 ignored issues
show
Bug introduced by
The method describeTable() does not exist on HughCube\Laravel\OTS\Connection. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
            $table = $this->getOts()->/** @scrutinizer ignore-call */ describeTable(['table_name' => $tableName]);
Loading history...
51
        } catch (OTSServerException $exception) {
52
            $this->error(sprintf("RequestId: %s", $exception->getRequestId()));
53
            $this->error(sprintf("%s: %s", $exception->getOTSErrorCode(), $exception->getOTSErrorMessage()));
54
            return;
55
        }
56
57
        if (!$this->confirm(sprintf('Are you sure you want to clear the %s table?', $tableName))) {
58
            return;
59
        }
60
61
        /** @var array $pks 表主键 */
62
        $pks = Arr::get($table, 'table_meta.primary_key_schema');
63
64
        /** 起始主键 */
65
        list($startPk, $endPk) = $this->parseRangePk($pks);
66
67
        $rowCount = 0;
68
        while (!empty ($startPk)) {
69
            $request = [
70
                'table_name' => $tableName, 'max_versions' => 1,
71
                'direction' => DirectionConst::CONST_FORWARD,
72
                'inclusive_start_primary_key' => $startPk,
73
                'exclusive_end_primary_key' => $endPk,
74
                'limit' => 200,
75
            ];
76
            $response = $this->getOts()->getRange($request);
0 ignored issues
show
Bug introduced by
The method getRange() does not exist on HughCube\Laravel\OTS\Connection. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

76
            $response = $this->getOts()->/** @scrutinizer ignore-call */ getRange($request);
Loading history...
77
78
            /** 删除查询出来的数据 */
79
            if (!empty($rows = $this->parseDeleteRows($response))) {
80
                $this->getOts()->batchWriteRow([
0 ignored issues
show
Bug introduced by
The method batchWriteRow() does not exist on HughCube\Laravel\OTS\Connection. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

80
                $this->getOts()->/** @scrutinizer ignore-call */ batchWriteRow([
Loading history...
81
                    'tables' => [['table_name' => $tableName, 'rows' => $rows]]
82
                ]);
83
            }
84
85
            /** 下一次轮询的key */
86
            $startPk = $response['next_start_primary_key'];
87
88
            $rowCount += count($rows);
89
            $this->comment(sprintf('%s Delete %s rows from the %s table',
90
                Carbon::now()->format('Y-m-d H:i:s.u'), count($rows), $tableName
91
            ));
92
        }
93
94
        $this->info(sprintf('%s The %s table has been cleared and %s data items have been deleted',
95
            Carbon::now()->format('Y-m-d H:i:s.u'), $tableName, $rowCount
96
        ));
97
    }
98
99
    protected function parseRangePk($pks): array
100
    {
101
        /** 起始主键 */
102
        $endPk = $startPk = [];
103
        foreach ($pks as $pk) {
104
            $startPk[] = [$pk[0], null, PrimaryKeyTypeConst::CONST_INF_MIN];
105
            $endPk[] = [$pk[0], null, PrimaryKeyTypeConst::CONST_INF_MAX];
106
        }
107
108
        return [$startPk, $endPk];
109
    }
110
111
    protected function parseDeleteRows($response): array
112
    {
113
        $rows = [];
114
        foreach ($response['rows'] as $row) {
115
            $rows[] = [
116
                'operation_type' => OperationTypeConst::CONST_DELETE,
117
                'condition' => RowExistenceExpectationConst::CONST_IGNORE,
118
                'primary_key' => $row['primary_key'],
119
            ];
120
        }
121
        return $rows;
122
    }
123
124
    /**
125
     * @return Connection
126
     */
127
    public function getOts(): Connection
128
    {
129
        return DB::connection($this->option('ots'));
0 ignored issues
show
Bug Best Practice introduced by
The expression return Illuminate\Suppor...n($this->option('ots')) returns the type Illuminate\Database\ConnectionInterface which includes types incompatible with the type-hinted return HughCube\Laravel\OTS\Connection.
Loading history...
130
    }
131
132
    /**
133
     * @return string
134
     * @throws OTSClientException
135
     * @throws OTSServerException
136
     */
137
    protected function getTable(): string
138
    {
139
        $name = $this->option('name');
140
        if (!empty($name)) {
141
            return $name;
142
        }
143
144
        $tables = $this->getOts()->listTable([]);
0 ignored issues
show
Bug introduced by
The method listTable() does not exist on HughCube\Laravel\OTS\Connection. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

144
        $tables = $this->getOts()->/** @scrutinizer ignore-call */ listTable([]);
Loading history...
145
        return $this->choice('You want to erase the data from that table?', $tables);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->choice('Yo... that table?', $tables) could return the type array which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
146
    }
147
}
148