[Core] [Query] Add limit to query data (close #487) (#527)

This commit is contained in:
Devlive Community 2023-12-02 14:56:16 +08:00 committed by GitHub
commit a583a3814b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 74 additions and 4 deletions

View File

@ -81,3 +81,8 @@ datacap.pipeline.maxRunning=100
datacap.pipeline.maxQueue=200 datacap.pipeline.maxQueue=200
# When the service is restarted, the status of the pipeline with status RUNNING is reset. # When the service is restarted, the status of the pipeline with status RUNNING is reset.
datacap.pipeline.reset=STOPPED datacap.pipeline.reset=STOPPED
################################# Experimental features #################################
# This configuration is used to dynamically increase the total number of rows of returned data in SQL during query, and currently only takes effect for user-directed queries
# If the total number of rows returned is included in the SQL, it will not be automatically incremented
datacap.experimental.autoLimit=true

View File

@ -0,0 +1,33 @@
package io.edurt.datacap.common.utils;
public class SqlCheckerUtils
{
private SqlCheckerUtils()
{
}
/**
* Check whether the input SQL statement contains paging configurations
* <p>
* SQL input @param sql
*
* @return true indicates that paging configuration is included, and false indicates that paging configuration is not included
*/
public static boolean isPagedSql(String sql)
{
// Check whether the SQL statement contains the limit keyword or the rownum pseudo column
if (sql.toLowerCase().contains("limit") || sql.toLowerCase().contains("rownum")) {
// If a pagination configuration is included, you need to further determine whether it is in the comments
String[] lines = sql.split("\\n");
for (String line : lines) {
// Remove the space before the comment symbol "--".
line = line.replaceAll("\\s*--.*", "");
if (line.toLowerCase().contains("limit") || line.toLowerCase().contains("rownum")) {
// If the paging configuration is still included, the description is not in the comments
return true;
}
}
}
return false;
}
}

View File

@ -14,4 +14,5 @@ public class ExecuteEntity
private String content; private String content;
private Map<String, Object> env; private Map<String, Object> env;
private FormatType format = FormatType.NONE; private FormatType format = FormatType.NONE;
private int limit;
} }

View File

@ -46,6 +46,10 @@ public class InitializerConfigure
@Value(value = "${datacap.pipeline.maxQueue}") @Value(value = "${datacap.pipeline.maxQueue}")
private Integer maxQueue; private Integer maxQueue;
@Getter
@Value(value = "${datacap.experimental.autoLimit}")
private Boolean autoLimit;
@Getter @Getter
private LoadingCache<Long, ResultEntity> cache; private LoadingCache<Long, ResultEntity> cache;
@ -95,6 +99,11 @@ public class InitializerConfigure
} }
log.info("Datacap pipeline max queue: {}", this.maxQueue); log.info("Datacap pipeline max queue: {}", this.maxQueue);
if (ObjectUtils.isEmpty(autoLimit)) {
autoLimit = Boolean.TRUE;
}
log.info("Datacap experimental auto limit: [ {} ]", this.autoLimit);
this.taskQueue = new LinkedBlockingQueue<>(this.maxQueue); this.taskQueue = new LinkedBlockingQueue<>(this.maxQueue);
this.taskExecutors = Maps.newConcurrentMap(); this.taskExecutors = Maps.newConcurrentMap();
} }

View File

@ -6,11 +6,13 @@ import io.edurt.datacap.common.response.CommonResponse;
import io.edurt.datacap.common.sql.SqlBuilder; import io.edurt.datacap.common.sql.SqlBuilder;
import io.edurt.datacap.common.sql.configure.SqlBody; import io.edurt.datacap.common.sql.configure.SqlBody;
import io.edurt.datacap.common.sql.configure.SqlType; import io.edurt.datacap.common.sql.configure.SqlType;
import io.edurt.datacap.common.utils.SqlCheckerUtils;
import io.edurt.datacap.service.audit.AuditPlugin; import io.edurt.datacap.service.audit.AuditPlugin;
import io.edurt.datacap.service.body.ExecuteDslBody; import io.edurt.datacap.service.body.ExecuteDslBody;
import io.edurt.datacap.service.common.PluginUtils; import io.edurt.datacap.service.common.PluginUtils;
import io.edurt.datacap.service.entity.ExecuteEntity; import io.edurt.datacap.service.entity.ExecuteEntity;
import io.edurt.datacap.service.entity.SourceEntity; import io.edurt.datacap.service.entity.SourceEntity;
import io.edurt.datacap.service.initializer.InitializerConfigure;
import io.edurt.datacap.service.repository.SourceRepository; import io.edurt.datacap.service.repository.SourceRepository;
import io.edurt.datacap.service.service.ExecuteService; import io.edurt.datacap.service.service.ExecuteService;
import io.edurt.datacap.spi.Plugin; import io.edurt.datacap.spi.Plugin;
@ -29,12 +31,14 @@ public class ExecuteServiceImpl
private final Injector injector; private final Injector injector;
private final SourceRepository sourceRepository; private final SourceRepository sourceRepository;
private final Environment environment; private final Environment environment;
private final InitializerConfigure initializerConfigure;
public ExecuteServiceImpl(Injector injector, SourceRepository sourceRepository, Environment environment) public ExecuteServiceImpl(Injector injector, SourceRepository sourceRepository, Environment environment, InitializerConfigure initializerConfigure)
{ {
this.injector = injector; this.injector = injector;
this.sourceRepository = sourceRepository; this.sourceRepository = sourceRepository;
this.environment = environment; this.environment = environment;
this.initializerConfigure = initializerConfigure;
} }
@AuditPlugin @AuditPlugin
@ -74,6 +78,13 @@ public class ExecuteServiceImpl
_configure.setId(String.valueOf(entity.getId())); _configure.setId(String.valueOf(entity.getId()));
} }
plugin.connect(_configure); plugin.connect(_configure);
if (initializerConfigure.getAutoLimit()) {
if (!SqlCheckerUtils.isPagedSql(configure.getContent())) {
configure.setContent(String.format("%s%nLIMIT %s", configure.getContent(), configure.getLimit()));
}
}
io.edurt.datacap.spi.model.Response response = plugin.execute(configure.getContent()); io.edurt.datacap.spi.model.Response response = plugin.execute(configure.getContent());
response.setContent(configure.getContent()); response.setContent(configure.getContent());
plugin.destroy(); plugin.destroy();

View File

@ -10,4 +10,5 @@ export default {
filter: 'Filter', filter: 'Filter',
addFilter: 'Add Filter', addFilter: 'Add Filter',
addRows: 'Add Rows', addRows: 'Add Rows',
copyRows: 'Copy Rows',
} }

View File

@ -10,4 +10,5 @@ export default {
filter: '筛选器', filter: '筛选器',
addFilter: '添加筛选器', addFilter: '添加筛选器',
addRows: '添加行', addRows: '添加行',
copyRows: '复制行',
} }

View File

@ -4,4 +4,5 @@ export interface ExecuteModel
content: string; content: string;
env?: object; env?: object;
format?: string; format?: string;
limit?: number;
} }

View File

@ -85,7 +85,7 @@
<FontAwesomeIcon icon="plus"/> <FontAwesomeIcon icon="plus"/>
</Button> </Button>
</Tooltip> </Tooltip>
<Tooltip :content="$t('source.manager.addRows')" <Tooltip :content="$t('source.manager.copyRows')"
transfer> transfer>
<Button size="small" <Button size="small"
shape="circle" shape="circle"

View File

@ -90,6 +90,11 @@
@click="handlerVisibleHelp(true)"> @click="handlerVisibleHelp(true)">
</Button> </Button>
</Badge> </Badge>
<InputNumber v-model="queryLimit"
size="small"
:step="10"
:min="1">
</InputNumber>
</Space> </Space>
</template> </template>
<div ref="editorContainer"> <div ref="editorContainer">
@ -221,7 +226,8 @@ export default defineComponent({
aiSupportType: ['ANALYSIS', 'OPTIMIZE'], aiSupportType: ['ANALYSIS', 'OPTIMIZE'],
error: null, error: null,
buttonRunText: null, buttonRunText: null,
isSelection: false isSelection: false,
queryLimit: 100
} }
}, },
created() created()
@ -359,7 +365,8 @@ export default defineComponent({
const configure: ExecuteModel = { const configure: ExecuteModel = {
name: this.applySource, name: this.applySource,
content: this.isSelection ? editorInstance.instance.getSelectedText() : editorInstance.instance.getValue(), content: this.isSelection ? editorInstance.instance.getSelectedText() : editorInstance.instance.getValue(),
format: "JSON" format: "JSON",
limit: this.queryLimit
}; };
new ExecuteService() new ExecuteService()
.execute(configure, this.cancelToken.token) .execute(configure, this.cancelToken.token)
@ -374,6 +381,7 @@ export default defineComponent({
showSeriesNumber: false showSeriesNumber: false
}; };
this.tableConfigure = tConfigure; this.tableConfigure = tConfigure;
editorInstance.instance.setValue(response.data.content);
} }
else { else {
this.$Message.error({ this.$Message.error({