mirror of
https://github.com/ershisan99/db-studio.git
synced 2025-12-18 12:33:07 +00:00
initial commit
This commit is contained in:
64
frontend/src/services/db/db.hooks.ts
Normal file
64
frontend/src/services/db/db.hooks.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { keepPreviousData, useQuery } from "@tanstack/react-query";
|
||||
import { DB_QUERY_KEYS } from "./db.query-keys";
|
||||
import { dbService } from "./db.service";
|
||||
import type { GetTableDataArgs, GetTablesListArgs } from "./db.types";
|
||||
|
||||
export const useDatabasesListQuery = () => {
|
||||
return useQuery({
|
||||
queryKey: [DB_QUERY_KEYS.DATABASES.ALL],
|
||||
queryFn: () => dbService.getDatabasesList(),
|
||||
placeholderData: keepPreviousData,
|
||||
});
|
||||
};
|
||||
|
||||
export const useTablesListQuery = (args: GetTablesListArgs) => {
|
||||
return useQuery({
|
||||
queryKey: [DB_QUERY_KEYS.TABLES.ALL, args],
|
||||
queryFn: () => dbService.getTablesList(args),
|
||||
enabled: !!args.dbName,
|
||||
placeholderData: keepPreviousData,
|
||||
});
|
||||
};
|
||||
|
||||
export const useTableDataQuery = (args: GetTableDataArgs) => {
|
||||
return useQuery({
|
||||
queryKey: [DB_QUERY_KEYS.TABLES.DATA, args],
|
||||
queryFn: () => dbService.getTableData(args),
|
||||
placeholderData: (previousData, previousQuery) => {
|
||||
if (
|
||||
typeof previousQuery?.queryKey[1] !== "string" &&
|
||||
(previousQuery?.queryKey[1].dbName !== args.dbName ||
|
||||
previousQuery?.queryKey[1].tableName !== args.tableName)
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
return previousData;
|
||||
},
|
||||
enabled: !!args.tableName && !!args.dbName,
|
||||
});
|
||||
};
|
||||
|
||||
export const useTableColumnsQuery = (args: { name?: string }) => {
|
||||
return useQuery({
|
||||
queryKey: [DB_QUERY_KEYS.TABLES.COLUMNS, args],
|
||||
queryFn: () => dbService.getTableColumns(args.name ?? ""),
|
||||
placeholderData: keepPreviousData,
|
||||
enabled: !!args.name,
|
||||
});
|
||||
};
|
||||
|
||||
export const useTableIndexesQuery = (args: { name?: string }) => {
|
||||
return useQuery({
|
||||
queryKey: [DB_QUERY_KEYS.TABLES.INDEXES, args],
|
||||
queryFn: () => dbService.getTableIndexes(args.name ?? ""),
|
||||
enabled: !!args.name,
|
||||
});
|
||||
};
|
||||
|
||||
export const useTableForeignKeysQuery = (args: { name?: string }) => {
|
||||
return useQuery({
|
||||
queryKey: [DB_QUERY_KEYS.TABLES.FOREIGN_KEYS, args],
|
||||
queryFn: () => dbService.getTableForeignKeys(args.name ?? ""),
|
||||
enabled: !!args.name,
|
||||
});
|
||||
};
|
||||
5
frontend/src/services/db/db.instance.ts
Normal file
5
frontend/src/services/db/db.instance.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import ky from 'ky'
|
||||
|
||||
export const dbInstance = ky.create({
|
||||
prefixUrl: 'http://localhost:3000'
|
||||
})
|
||||
12
frontend/src/services/db/db.query-keys.ts
Normal file
12
frontend/src/services/db/db.query-keys.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export const DB_QUERY_KEYS = {
|
||||
DATABASES: {
|
||||
ALL: "databases.all",
|
||||
},
|
||||
TABLES: {
|
||||
ALL: "tables.all",
|
||||
DATA: "tables.data",
|
||||
COLUMNS: "tables.columns",
|
||||
INDEXES: "tables.indexes",
|
||||
FOREIGN_KEYS: "tables.foreign_keys",
|
||||
},
|
||||
} as const;
|
||||
50
frontend/src/services/db/db.service.ts
Normal file
50
frontend/src/services/db/db.service.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { getValuable } from "@/lib/utils";
|
||||
import { dbInstance } from "@/services/db/db.instance";
|
||||
import type {
|
||||
DatabasesResponse,
|
||||
GetTableDataArgs,
|
||||
GetTableDataResponse,
|
||||
GetTablesListArgs,
|
||||
GetTablesListResponse,
|
||||
TableColumns,
|
||||
TableForeignKeys,
|
||||
TableIndexes,
|
||||
} from "@/services/db/db.types";
|
||||
|
||||
class DbService {
|
||||
getDatabasesList() {
|
||||
return dbInstance.get("api/databases").json<DatabasesResponse>();
|
||||
}
|
||||
|
||||
getTablesList({ dbName, sortDesc, sortField }: GetTablesListArgs) {
|
||||
return dbInstance
|
||||
.get(`api/databases/${dbName}/tables`, {
|
||||
searchParams: getValuable({ sortField, sortDesc }),
|
||||
})
|
||||
.json<GetTablesListResponse>();
|
||||
}
|
||||
|
||||
getTableData({ dbName, tableName, page, perPage }: GetTableDataArgs) {
|
||||
return dbInstance
|
||||
.get(`api/databases/${dbName}/tables/${tableName}/data`, {
|
||||
searchParams: getValuable({ perPage, page }),
|
||||
})
|
||||
.json<GetTableDataResponse>();
|
||||
}
|
||||
|
||||
getTableColumns(name: string) {
|
||||
return dbInstance.get(`api/db/tables/${name}/columns`).json<TableColumns>();
|
||||
}
|
||||
|
||||
getTableIndexes(name: string) {
|
||||
return dbInstance.get(`api/db/tables/${name}/indexes`).json<TableIndexes>();
|
||||
}
|
||||
|
||||
getTableForeignKeys(name: string) {
|
||||
return dbInstance
|
||||
.get(`api/db/tables/${name}/foreign-keys`)
|
||||
.json<TableForeignKeys>();
|
||||
}
|
||||
}
|
||||
|
||||
export const dbService = new DbService();
|
||||
64
frontend/src/services/db/db.types.ts
Normal file
64
frontend/src/services/db/db.types.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
export type DatabasesResponse = Array<string>;
|
||||
|
||||
// Tables List
|
||||
export type GetTablesListArgs = {
|
||||
dbName: string;
|
||||
sortField?: string;
|
||||
sortDesc?: boolean;
|
||||
};
|
||||
export type TableInfo = {
|
||||
comments: string;
|
||||
index_size: number;
|
||||
indexes: string;
|
||||
owner: string;
|
||||
primary_key: string;
|
||||
row_count: number;
|
||||
schema_name: string;
|
||||
table_name: string;
|
||||
table_size: number;
|
||||
total_size: number;
|
||||
};
|
||||
export type GetTablesListResponse = TableInfo[];
|
||||
|
||||
// Table Data
|
||||
export type GetTableDataArgs = {
|
||||
tableName: string;
|
||||
dbName: string;
|
||||
perPage?: number;
|
||||
page?: number;
|
||||
};
|
||||
|
||||
export type GetTableDataResponse = {
|
||||
count: number;
|
||||
data: Array<Record<string, any>>;
|
||||
};
|
||||
|
||||
export type TableColumn = {
|
||||
column_name: string;
|
||||
data_type: string;
|
||||
udt_name: string;
|
||||
column_comment?: any;
|
||||
};
|
||||
export type TableColumns = TableColumn[];
|
||||
|
||||
export type TableIndexEntry = {
|
||||
key: string;
|
||||
type: string;
|
||||
columns: string[];
|
||||
descs: any[];
|
||||
lengths: any[];
|
||||
};
|
||||
export type TableIndexes = TableIndexEntry[];
|
||||
|
||||
export type TableForeignKey = {
|
||||
conname: string;
|
||||
deferrable: boolean;
|
||||
definition: string;
|
||||
source: string[];
|
||||
ns: string;
|
||||
table: string;
|
||||
target: string[];
|
||||
on_delete: string;
|
||||
on_update: string;
|
||||
};
|
||||
export type TableForeignKeys = TableForeignKey[];
|
||||
2
frontend/src/services/db/index.ts
Normal file
2
frontend/src/services/db/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './db.hooks'
|
||||
export * from './db.types'
|
||||
Reference in New Issue
Block a user