Skip to content

Commit dcacd17

Browse files
authored
Merge pull request #70 from teamones-open/fix_schema
fixed: 底层阻止外键表数据超过 2000 抛出异常
2 parents d92420c + f0fb588 commit dcacd17

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

src/think/exception/ErrorCode.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,7 @@ class ErrorCode
8484

8585
// 密码强度规则不匹配
8686
const PASSWORD_STRENGTH_NOT_MATCH = -4001020;
87-
}
87+
88+
// 当前参数查询关联表数据超过 2000
89+
const RELATED_TABLE_DATA_EXCEEDS_2000 = -4001021;
90+
}

src/think/model/RelationModel.php

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ private function handleEntityRelationReturnComplexData(&$newReturnData, $type =
950950
$this->unfoldEntityRelationConfig($relationUnfold, $maxDepthRelationConfig);
951951

952952
// 查询关联数据
953-
$middleEntityData = $this->getModelObj('entity')->field('id,entity_id')->where(['id' => ['IN', join(',', $this->queryModulePrimaryKeyIds)]])->select();
953+
$middleEntityData = $this->getFilterMiddleData('entity', ['id' => ['IN', join(',', $this->queryModulePrimaryKeyIds)]], 'id,entity_id');
954954

955955
$middleRelationIds = array_column($middleEntityData, 'entity_id');
956956

@@ -979,10 +979,10 @@ private function handleEntityRelationReturnComplexData(&$newReturnData, $type =
979979

980980
$this->handleQueryModuleCustomFields($fields, $relationUnfold[$i]['belong_module']);
981981

982-
$entityData = $this->getModelObj('entity')->field(join(',', $fields))->where([
982+
$entityData = $this->getFilterMiddleData('entity', [
983983
'id' => ['IN', join(',', $middleRelationIds)],
984984
'module_id' => $relationUnfold[$i]['src_module_id'],
985-
])->select();
985+
], join(',', $fields));
986986

987987

988988
if (!empty($entityData)) {
@@ -1661,15 +1661,6 @@ public function parserFilterModuleCustomFields($queryModuleList)
16611661
}
16621662
unset($queryModuleIds);
16631663

1664-
// 优化,使用全局静态缓存
1665-
// $customFieldData = $this->getModelObj('field')->field('id,table,module_id,config')
1666-
// ->where([
1667-
// 'type' => 'custom',
1668-
// 'is_horizontal' => 0,
1669-
// 'module_id' => ['IN', join(',', $queryModuleIds)]
1670-
// ])
1671-
// ->select();
1672-
16731664
if (!empty($customFieldData)) {
16741665
foreach ($customFieldData as $customFieldItem) {
16751666
$customFieldItemConfig = json_decode($customFieldItem['config'], true);
@@ -1688,7 +1679,6 @@ public function parserFilterModuleCustomFields($queryModuleList)
16881679
private function getRelationModuleCustomFields($modules)
16891680
{
16901681
$relationModule = [];
1691-
//$entityModuleList = $this->getModelObj('module')->field('code')->where(['type' => 'entity'])->select();
16921682

16931683
foreach ($modules as $moduleKey => $config) {
16941684
if ($config['type'] !== 'horizontal') {
@@ -1889,7 +1879,7 @@ private function parserFilterItemComplexValue($masterModuleCode, $itemModule, $s
18891879
*/
18901880
private function parserFilterItemEntityTaskRelated(&$filterData, $masterModuleCode, $itemModule, $filter)
18911881
{
1892-
$selectData = $this->getModelObj('entity')->where($this->formatFilterCondition($filter))->select();
1882+
$selectData = $this->getFilterMiddleData('entity', $this->formatFilterCondition($filter), 'id');
18931883
if (!empty($selectData)) {
18941884
$ids = array_column($selectData, 'id');
18951885
$idsString = join(',', $ids);
@@ -2065,7 +2055,7 @@ private function parserFilterItemValue($masterModuleCode, $itemModule, $filter)
20652055
}
20662056
break;
20672057
case 'direct':
2068-
$selectData = $this->getModelObj(get_module_table_name(Module::$moduleDictData['module_index_by_code'][$itemModule['module_code']]))->where($this->formatFilterCondition($filter))->select();
2058+
$selectData = $this->getFilterMiddleData(get_module_table_name(Module::$moduleDictData['module_index_by_code'][$itemModule['module_code']]), $this->formatFilterCondition($filter));
20692059
if (!empty($selectData)) {
20702060
$ids = array_column($selectData, 'id');
20712061
$idsString = join(',', $ids);
@@ -2097,7 +2087,7 @@ private function parserFilterItemValue($masterModuleCode, $itemModule, $filter)
20972087
"code" => $itemModule['module_code']
20982088
]);
20992089

2100-
$selectData = $this->getModelObj($tableName)->where($this->formatFilterCondition($filter))->select();
2090+
$selectData = $this->getFilterMiddleData($tableName, $this->formatFilterCondition($filter));
21012091
if (!empty($selectData)) {
21022092
$ids = array_column($selectData, 'id');
21032093
$idsString = join(',', $ids);
@@ -2931,6 +2921,23 @@ public function selectData($options = [], $needFormat = true)
29312921
}
29322922
}
29332923

2924+
/**
2925+
* 获取查询中间数据,单次关联id数量不能超过2000
2926+
* @param $modelName
2927+
* @param $filter
2928+
* @param $fields
2929+
* @return array|false|mixed|string
2930+
* @throws \Exception
2931+
*/
2932+
private function getFilterMiddleData($modelName, $filter, $fields = 'id')
2933+
{
2934+
$count = $this->getModelObj($modelName)->where($filter)->cache(60)->count();
2935+
if ($count > 2000) {
2936+
// 2000 条大约占用内存 2mb
2937+
throw_strack_exception('The associated table data exceeds 2000.', ErrorCode::RELATED_TABLE_DATA_EXCEEDS_2000);
2938+
}
2939+
return $this->getModelObj($modelName)->field($fields)->where($filter)->select();
2940+
}
29342941

29352942
/**
29362943
* 获取字段数据源映射

0 commit comments

Comments
 (0)