Skip to content

Commit

Permalink
feat(sidepanel): database debug in system view
Browse files Browse the repository at this point in the history
  • Loading branch information
lastsunday committed Dec 22, 2024
1 parent f6820a4 commit 8e16be3
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 7 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
1. (Sidepanel)添加文件管理页面。
2. 添加任务的最大执行次数限制。
3. 自动清理历史文件。(当前只保留共10MB历史文件)
4. (Sidepanel)添加系统页面。
4. (Sidepanel)添加系统页面(数据库信息展示,数据库调试,历史文件信息)

## 2.3.0(2024-12-21)

Expand Down
15 changes: 15 additions & 0 deletions common/api/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ export async function dbSchemaVersion() {
return result.data;
}

export async function dbGetAllTableName() {
let result = await invoke("dbGetAllTableName", {});
return result.data;
}

/**
*
* @param {{sql:string}} param
* @returns Promise<{result:any}>
*/
export async function dbExec(param) {
let result = await invoke("dbExec", param);
return result.data;
}

/**
* 提交网络请求
* @param {string} param url
Expand Down
149 changes: 144 additions & 5 deletions entrypoints/admin/src/pages/SystemView.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
import { FileApi } from "@/common/api";
import { dbSchemaVersion, dbSize } from "@/common/api/common";
import { dbExec, dbGetAllTableName, dbSchemaVersion, dbSize } from "@/common/api/common";
import { FileStatisticDTO } from "@/common/data/dto/fileStatisticDTO";
import { errorLog } from "@/common/log";
import { convertToAbbreviation } from "@/common/utils";
import { Icon } from "@iconify/react";
import {
Alert,
Button,
Card,
Flex,
Popover,
Row,
Select,
Switch,
Table,
Typography, message
} from "antd";
import TextArea from "antd/lib/input/TextArea";
import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import StatisticCard from "../components/StatisticCard";
import styles from "./SystemView.module.css";
const { Text } = Typography;
dayjs.extend(duration)


const SystemView: React.FC = () => {

const [messageApi, contextHolder] = message.useMessage();
const [databaseSize, setDatabaseSize] = useState();
const [schemaVersion, setSchemaVersion] = useState();
const [fileStatistic, setFileStatistic] = useState<FileStatisticDTO>({});


const [isDebugDatabaseMenuOpen, setIsDebugDatabaseMenuOpen] = useState(false);
const [columns, setColumns] = useState([]);
const [dataSource, setDataSource] = useState([]);
const [sql, setSql] = useState<string>();
const [execSqlLoading, setExecSqlLoading] = useState(false);
const [sqlExecError, setSqlExecError] = useState<string>();
const [tables, setTables] = useState<{ name: string }[]>([]);
const [sqlCostTime, setSqlCostTime] = useState<number>();
useEffect(
() => {
const query = async () => {
Expand All @@ -34,6 +47,8 @@ const SystemView: React.FC = () => {
setSchemaVersion(schemaVersion);
let fileStatistic = await FileApi.fileStatistic();
setFileStatistic(fileStatistic);
const allTables = (await dbGetAllTableName()).result;
setTables(allTables);
}

query();
Expand Down Expand Up @@ -71,10 +86,84 @@ const SystemView: React.FC = () => {
}
}

const getSwitchStyle = () => {
if (isDebugDatabaseMenuOpen) {
return { backgroundColor: "red" };
} else {
return null
}
}

const execSql = async (sql) => {
if (!sql) {
setSqlExecError("");
setColumns(null);
setDataSource(null);
return;
}
setExecSqlLoading(true);
setSqlExecError(null);
try {
const beginExecSqlTime = dayjs();
const result = (await dbExec({ sql })).result;
const afterExecSqlTime = dayjs();
setSqlCostTime(afterExecSqlTime.diff(beginExecSqlTime));
if (result && result.length > 0) {
let headers = [];
let keys = Object.keys(result[0]);
headers.push({
title: "#",
dataIndex: "$index",
key: "$index",
ellipsis: false,
width: 60,
});
for (let n = 0; n < keys.length; n++) {
let key = keys[n];
headers.push({
title: key,
dataIndex: key,
key: key,
width: 200,
sorter: true,
render: (value, record, index) => {
return (
<Popover key={index} content={<Text copyable>{value}</Text>} trigger="click">
<Text key={index} title={value} ellipsis>{value}</Text>
</Popover>
)
}
});
}
setColumns(headers);
result.forEach((item, index) => {
item.$index = index + 1;
})
setDataSource(result);
setSqlExecError("");
} else {
setColumns(null);
setDataSource(null);
}
} catch (e) {
errorLog(e);
setSqlExecError(e.message);
} finally {
setExecSqlLoading(false);
}
}

return <>
{contextHolder}
<Flex vertical gap={5}>
<Card title="数据库信息" bordered={false} size="small">
<Card title={
<Flex align="center" gap={5}>
<Text>数据库</Text>
<Switch style={getSwitchStyle()} checkedChildren="数据库调试开启" unCheckedChildren="数据库调试关闭" size="small" checked={isDebugDatabaseMenuOpen} onChange={(checked) => {
setIsDebugDatabaseMenuOpen(checked);
}}></Switch>
</Flex>
} bordered={false} size="small">
<Row gutter={2}>
<StatisticCard
name={<Flex className={styles.title}><Icon icon="material-symbols:database" /><Text>数据库大小</Text></Flex>}
Expand All @@ -86,6 +175,11 @@ const SystemView: React.FC = () => {
count={schemaVersion != null ? `V${schemaVersion}` : "N/A"}
unit={""}
></StatisticCard>
<StatisticCard
name={<Flex className={styles.title}><Icon icon="material-symbols:table" /><Text>数据库表数量</Text></Flex>}
count={tables != null ? `${tables.length}` : "N/A"}
unit={"张"}
></StatisticCard>
</Row>
</Card>
<Card title="历史文件信息" bordered={false} size="small">
Expand All @@ -106,6 +200,51 @@ const SystemView: React.FC = () => {
></StatisticCard>
</Row>
</Card>
{isDebugDatabaseMenuOpen ?
<Card title="数据库调试" bordered={false} size="small">
<Flex vertical gap={5}>
<Flex justify="end" gap={5}>
<Flex style={{ width: 200 }}>
<Select disabled={execSqlLoading} style={{ width: '100%' }} allowClear onSelect={(value) => {
if (value) {
const sql = `SELECT * FROM ${value}`;
setSql(sql);
execSql(sql);
}
}} placeholder="选择表名快速查询" options={tables} fieldNames={{ label: "name", value: "name" }}
labelRender={({ label }) => (
<Flex align="center" gap={5}><Icon icon="material-symbols:table" /><Text>{label}</Text></Flex>
)}
optionRender={(option) => (
<Flex align="center" gap={5}><Icon icon="material-symbols:table" /><Text>{option.data.name}</Text></Flex>
)} />
</Flex>
<Button type="primary" loading={execSqlLoading} onClick={() => {
execSql(sql);
}}><Icon icon="mdi:play" />执行</Button>
</Flex>
<Flex>
<TextArea placeholder="请输入SQL" rows={5} disabled={execSqlLoading} value={sql} onChange={((e) => {
setSql(e.target.value)
})}></TextArea>
</Flex>
{
sqlExecError != null ? (
sqlExecError == "" ? <Alert message={`执行成功,耗时${sqlCostTime}ms`} type="success" showIcon closable /> : <Alert
message="执行异常"
description={sqlExecError}
type="error"
showIcon
/>
) : null
}
<Flex>
<Table loading={execSqlLoading} pagination={{ showTotal: (total, range) => `${range[0]}-${range[1]}${total} 条记录` }} scroll={{ x: '100%' }} sticky={{ offsetHeader: 64 }} size="small" dataSource={dataSource} columns={columns} />
</Flex>
</Flex>
</Card>
: null
}
</Flex>
</>
}
Expand Down
36 changes: 35 additions & 1 deletion entrypoints/offscreen/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,42 @@ export const Database = {
"[worker] dbSchemaVersion error : " + e.message
);
}
},
dbExec: async function (message, param) {
try {
let sql = param.sql;
let queryRows = [];
(await getDb()).exec({
sql: sql,
rowMode: "object",
resultRows: queryRows,
});
postSuccessMessage(message, { result: queryRows });
} catch (e) {
postErrorMessage(
message,
"[worker] dbExec error : " + e.message
);
}
},
dbGetAllTableName: async function (message, param) {
try {
let sql = `SELECT name FROM sqlite_master where type ='table'`;
let queryRows = [];
(await getDb()).exec({
sql: sql,
rowMode: "object",
resultRows: queryRows,
});
postSuccessMessage(message, { result: queryRows });
} catch (e) {
postErrorMessage(
message,
"[worker] dbGetAllTableName error : " + e.message
);
}
}

};

/**
Expand Down

0 comments on commit 8e16be3

Please sign in to comment.