Skip to content

Commit

Permalink
feat: sqlite数据库查看
Browse files Browse the repository at this point in the history
  • Loading branch information
XasYer committed Oct 10, 2024
1 parent 5d9be2f commit cf5a8fa
Show file tree
Hide file tree
Showing 4 changed files with 694 additions and 1 deletion.
94 changes: 94 additions & 0 deletions src/api/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,97 @@ export const deleteRedisKeys = (keys: string[]) => {
data: { keys }
});
};

export type getSqlitePathResult = {
success: boolean;
data: string[];
};

/** 获取sqlite的db文件路径 */
export const getSqlitePath = () => {
return http.request<getSqlitePathResult>("post", "/get-sqlite-path");
};

/** 获取指定路径的sqlite的所有表名 */
export const getSqliteTable = (path: string) => {
return http.request<getSqlitePathResult>("post", "/get-sqlite-table", {
data: { path }
});
};

export type getSqliteTableDataResult = {
success: boolean;
data: {
[key: string]: any;
}[];
total: number;
tableInfo: {
[key: string]: {
pk: 0 | 1;
name: string;
type: string;
notnull: 0 | 1;
dflt_value: string;
autoincrement: boolean;
};
};
};

/** 获取指定路径的sqlite的指定表的数据 */
export const getSqliteTableData = (
path: string,
table: string,
pageNum: number,
pageSize: number,
search: string
) => {
return http.request<getSqliteTableDataResult>(
"post",
"/get-sqlite-table-data",
{
data: { path, table, pageSize, pageNum, search }
}
);
};

export type setSqliteTableDataResult = {
success: boolean;
data: any;
message?: string;
};

/** 设置或添加表的数据 */
export const setSqliteTableData = (
path: string,
table: string,
data: { [key: string]: any }
) => {
return http.request<setSqliteTableDataResult>(
"post",
"/set-sqlite-table-data",
{
data: { path, table, data }
}
);
};

export type deleteSqliteTableDataResult = {
success: boolean;
data: any;
message?: string;
};

/** 删除指定路径的sqlite的指定表的数据 */
export const deleteSqliteTableData = (
path: string,
table: string,
data: { [key: string]: any }
) => {
return http.request<deleteSqliteTableDataResult>(
"post",
"/delete-sqlite-table-data",
{
data: { path, table, data }
}
);
};
10 changes: 9 additions & 1 deletion src/router/modules/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ export default {
component: () => import("@/views/database/redis/index.vue"),
meta: {
title: "redis",
showParent: true,
icon: "cib:redis"
}
},
{
path: "/database/sqlite",
name: "sqlite",
component: () => import("@/views/database/sqlite/index.vue"),
meta: {
title: "sqlite",
icon: "file-icons:sqlite"
}
}
]
} as RouteConfigsTable;
166 changes: 166 additions & 0 deletions src/views/database/sqlite/components/add.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<template>
<el-row justify="center">
<el-col :lg="20" :xs="24">
<PlusForm
ref="ruleFormRef"
v-model="data.value"
:rules="rules"
:columns="columns"
inline-message
labelWidth="120px"
label-position="right"
:has-footer="false"
/>
</el-col>
</el-row>
</template>

<script lang="ts" setup>
import { ElText } from "element-plus";
import {
type FieldValues,
FieldValueType,
PlusColumn,
PlusForm,
PlusFormGroupRow
} from "plus-pro-components";
import { h, ref } from "vue";
import { IconifyIconOnline as iconify } from "@/components/ReIcon";
export interface DataProps {
data: {
column: string[];
value: any;
tableInfo: {
[key: string]: {
pk: 0 | 1;
name: string;
type: string;
notnull: 0 | 1;
dflt_value: string;
autoincrement: boolean;
};
};
type: "add" | "edit";
};
}
const props = withDefaults(defineProps<DataProps>(), {
data: () => ({
column: [],
value: "",
tableInfo: {},
type: "add"
})
});
const data = ref<DataProps["data"]>(props.data);
const rules = ref({});
const columns = ref<PlusColumn[]>([]);
for (const key in data.value.tableInfo) {
if (["createdAt", "updatedAt"].includes(key)) {
continue;
}
const column: PlusColumn = {
label: key,
prop: key
};
column.fieldProps = {};
if (data.value.tableInfo[key].notnull) {
rules.value[key] = [{ required: true, message: `请填写${key}` }];
}
if (data.value.tableInfo[key].dflt_value && data.value.type === "add") {
data.value.value[key] = data.value.tableInfo[key].dflt_value?.replace?.(
/'/g,
""
);
}
column.fieldProps.placeholder = `类型: ${data.value.tableInfo[key].type}`;
if (data.value.tableInfo[key].autoincrement) {
continue;
}
switch (getSQLiteStorageType(data.value.tableInfo[key].type)) {
case "INTEGER":
column.valueType = "input-number";
break;
case "TEXT":
column.valueType = "textarea";
column.fieldProps.autosize = { minRows: 2, maxRows: 10 };
column.fieldProps.resize = "none";
break;
case "NUMERIC":
case "BLOB":
case "REAL":
default:
column.renderField = (value, onChange) =>
h(
ElText,
{ type: "warning" },
`暂未适配本类型: ${data.value.tableInfo[key].type}`
);
break;
}
if (data.value.tableInfo[key].pk) {
if (data.value.type === "edit") {
column.fieldProps.disabled = true;
} else if (!data.value.tableInfo[key].autoincrement) {
rules.value[key] = [{ required: true, message: `请填写${key}` }];
}
column.renderLabel = () =>
h("span", { class: "flex-c" }, [
h(iconify, {
icon: "mdi:primary-key",
width: 18,
height: 18
}),
h("span", {}, column.label as string)
]);
}
columns.value.push(column as any);
}
const ruleFormRef = ref();
function getRef() {
return ruleFormRef.value.formInstance;
}
function getData() {
return data.value.value;
}
defineExpose({ getRef, getData });
function getSQLiteStorageType(typeAlias: string) {
const type = typeAlias.toUpperCase();
if (type.includes("INT")) {
return "INTEGER";
} else if (
type.includes("CHAR") ||
type.includes("CLOB") ||
type.includes("TEXT")
) {
return "TEXT";
} else if (type.includes("BLOB")) {
return "BLOB";
} else if (
type.includes("REAL") ||
type.includes("FLOA") ||
type.includes("DOUB")
) {
return "REAL";
} else if (
type.includes("NUMERIC") ||
type.includes("DECIMAL") ||
type.includes("BOOLEAN") ||
type.includes("DATE")
) {
return "NUMERIC";
}
// 默认情况返回 BLOB,因为未识别的类型在 SQLite 中通常按 BLOB 处理
return "BLOB";
}
</script>
Loading

0 comments on commit cf5a8fa

Please sign in to comment.