132 lines
4 KiB
TypeScript
132 lines
4 KiB
TypeScript
import { create } from 'zustand';
|
|
import { invoke } from '../lib/tauri';
|
|
|
|
function logError(context: string, error: unknown): void {
|
|
if (import.meta.env.PROD) {
|
|
console.error(`[Database] ${context}: ${error instanceof Error ? error.name : 'Unknown'}`);
|
|
} else {
|
|
console.error(`[Database] ${context}:`, error);
|
|
}
|
|
}
|
|
|
|
export type DatabaseType = 'kv' | 'document' | 'vector' | 'timeseries' | 'graph' | 'sql';
|
|
|
|
export interface DatabaseInstanceInfo {
|
|
id: string;
|
|
name: string;
|
|
dbType: DatabaseType;
|
|
region: string;
|
|
status: string;
|
|
storageUsed: number;
|
|
readOps: number;
|
|
writeOps: number;
|
|
monthlyCost: string;
|
|
connectionString: string;
|
|
}
|
|
|
|
interface DatabaseState {
|
|
instances: DatabaseInstanceInfo[];
|
|
isLoading: boolean;
|
|
isCreating: boolean;
|
|
error: string | null;
|
|
|
|
clearError: () => void;
|
|
fetchInstances: () => Promise<void>;
|
|
createDatabase: (name: string, dbType: DatabaseType, region: string) => Promise<DatabaseInstanceInfo>;
|
|
getDatabase: (dbId: string) => Promise<DatabaseInstanceInfo>;
|
|
deleteDatabase: (dbId: string) => Promise<void>;
|
|
executeQuery: (dbId: string, query: string) => Promise<unknown>;
|
|
}
|
|
|
|
export const useDatabaseStore = create<DatabaseState>()((set) => ({
|
|
instances: [],
|
|
isLoading: false,
|
|
isCreating: false,
|
|
error: null,
|
|
|
|
clearError: () => set({ error: null }),
|
|
|
|
fetchInstances: async () => {
|
|
set({ isLoading: true });
|
|
try {
|
|
const instances = await invoke<DatabaseInstanceInfo[]>('database_list');
|
|
set({ instances, isLoading: false });
|
|
} catch (error) {
|
|
logError('fetchInstances', error);
|
|
set({ isLoading: false });
|
|
}
|
|
},
|
|
|
|
createDatabase: async (name, dbType, region) => {
|
|
set({ isCreating: true });
|
|
try {
|
|
const instance = await invoke<DatabaseInstanceInfo>('database_create', {
|
|
name,
|
|
dbType,
|
|
region,
|
|
});
|
|
set((state) => ({
|
|
instances: [instance, ...state.instances],
|
|
isCreating: false,
|
|
}));
|
|
return instance;
|
|
} catch (error) {
|
|
logError('createDatabase', error);
|
|
set({ isCreating: false, error: 'Failed to create database' });
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
getDatabase: async (dbId) => {
|
|
try {
|
|
const instance = await invoke<DatabaseInstanceInfo>('database_get_info', { dbId });
|
|
set((state) => ({
|
|
instances: state.instances.map((i) => (i.id === dbId ? instance : i)),
|
|
}));
|
|
return instance;
|
|
} catch (error) {
|
|
logError('getDatabase', error);
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
deleteDatabase: async (dbId) => {
|
|
try {
|
|
await invoke('database_delete', { dbId });
|
|
set((state) => ({
|
|
instances: state.instances.filter((i) => i.id !== dbId),
|
|
}));
|
|
} catch (error) {
|
|
logError('deleteDatabase', error);
|
|
set({ error: 'Failed to delete database' });
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
executeQuery: async (dbId, query) => {
|
|
try {
|
|
const result = await invoke('database_query', { dbId, query });
|
|
return result;
|
|
} catch (error) {
|
|
logError('executeQuery', error);
|
|
set({ error: 'Query execution failed' });
|
|
throw error;
|
|
}
|
|
},
|
|
}));
|
|
|
|
export const DATABASE_TYPES: { value: DatabaseType; label: string; description: string }[] = [
|
|
{ value: 'kv', label: 'Key-Value', description: 'Redis-compatible fast key-value store' },
|
|
{ value: 'document', label: 'Document', description: 'MongoDB-compatible document database' },
|
|
{ value: 'vector', label: 'Vector', description: 'AI/ML vector search database' },
|
|
{ value: 'timeseries', label: 'Time-Series', description: 'Metrics and analytics database' },
|
|
{ value: 'graph', label: 'Graph', description: 'Node/edge relationship database' },
|
|
{ value: 'sql', label: 'SQL', description: 'PostgreSQL-compatible relational database' },
|
|
];
|
|
|
|
export const REGIONS = [
|
|
{ value: 'us-east', label: 'US East (Virginia)' },
|
|
{ value: 'us-west', label: 'US West (Oregon)' },
|
|
{ value: 'eu-west', label: 'EU West (Ireland)' },
|
|
{ value: 'ap-southeast', label: 'Asia Pacific (Singapore)' },
|
|
];
|