feat: initial release
Multi-database management tool built with Tauri + Vue 3. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server.
This commit is contained in:
commit
b2e6dfad7e
156 files changed
+21979
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import type { AiConfig } from "@/stores/settingsStore";
|
||||
|
||||
export async function generateSql(
|
||||
config: AiConfig,
|
||||
prompt: string,
|
||||
tableContext: string,
|
||||
): Promise<string> {
|
||||
const systemPrompt = `You are a SQL expert assistant. Given the database schema below, generate a SQL query based on the user's request. Return ONLY the SQL query, no explanations.\n\nSchema:\n${tableContext}`;
|
||||
|
||||
if (config.provider === "claude") {
|
||||
const res = await fetch(config.endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": config.apiKey,
|
||||
"anthropic-version": "2023-06-01",
|
||||
"anthropic-dangerous-direct-browser-access": "true",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: config.model,
|
||||
max_tokens: 2048,
|
||||
system: systemPrompt,
|
||||
messages: [{ role: "user", content: prompt }],
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error(`Claude API error: ${res.status}`);
|
||||
const data = await res.json();
|
||||
return data.content?.[0]?.text || "";
|
||||
}
|
||||
|
||||
// OpenAI-compatible (works for OpenAI, custom endpoints)
|
||||
const res = await fetch(config.endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${config.apiKey}`,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: config.model,
|
||||
messages: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: prompt },
|
||||
],
|
||||
max_tokens: 2048,
|
||||
}),
|
||||
});
|
||||
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
||||
const data = await res.json();
|
||||
return data.choices?.[0]?.message?.content || "";
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import type {
|
||||
ConnectionConfig,
|
||||
DatabaseInfo,
|
||||
TableInfo,
|
||||
ColumnInfo,
|
||||
IndexInfo,
|
||||
ForeignKeyInfo,
|
||||
TriggerInfo,
|
||||
QueryResult,
|
||||
} from "@/types/database";
|
||||
|
||||
export async function testConnection(config: ConnectionConfig): Promise<string> {
|
||||
return invoke("test_connection", { config });
|
||||
}
|
||||
|
||||
export async function connectDb(config: ConnectionConfig): Promise<string> {
|
||||
return invoke("connect_db", { config });
|
||||
}
|
||||
|
||||
export async function disconnectDb(connectionId: string): Promise<void> {
|
||||
return invoke("disconnect_db", { connectionId });
|
||||
}
|
||||
|
||||
export async function listDatabases(connectionId: string): Promise<DatabaseInfo[]> {
|
||||
return invoke("list_databases", { connectionId });
|
||||
}
|
||||
|
||||
export async function listTables(connectionId: string, database: string, schema: string): Promise<TableInfo[]> {
|
||||
return invoke("list_tables", { connectionId, database, schema });
|
||||
}
|
||||
|
||||
export async function listSchemas(connectionId: string, database: string): Promise<string[]> {
|
||||
return invoke("list_schemas", { connectionId, database });
|
||||
}
|
||||
|
||||
export async function getColumns(
|
||||
connectionId: string,
|
||||
database: string,
|
||||
schema: string,
|
||||
table: string,
|
||||
): Promise<ColumnInfo[]> {
|
||||
return invoke("get_columns", { connectionId, database, schema, table });
|
||||
}
|
||||
|
||||
export async function executeQuery(connectionId: string, database: string, sql: string): Promise<QueryResult> {
|
||||
return invoke("execute_query", { connectionId, database, sql });
|
||||
}
|
||||
|
||||
export async function listIndexes(connectionId: string, database: string, schema: string, table: string): Promise<IndexInfo[]> {
|
||||
return invoke("list_indexes", { connectionId, database, schema, table });
|
||||
}
|
||||
|
||||
export async function listForeignKeys(connectionId: string, database: string, schema: string, table: string): Promise<ForeignKeyInfo[]> {
|
||||
return invoke("list_foreign_keys", { connectionId, database, schema, table });
|
||||
}
|
||||
|
||||
export async function listTriggers(connectionId: string, database: string, schema: string, table: string): Promise<TriggerInfo[]> {
|
||||
return invoke("list_triggers", { connectionId, database, schema, table });
|
||||
}
|
||||
|
||||
export async function saveConnections(configs: ConnectionConfig[]): Promise<void> {
|
||||
return invoke("save_connections", { configs });
|
||||
}
|
||||
|
||||
export async function loadConnections(): Promise<ConnectionConfig[]> {
|
||||
return invoke("load_connections");
|
||||
}
|
||||
|
||||
// --- Redis ---
|
||||
export interface RedisKeyInfo {
|
||||
key: string;
|
||||
key_type: string;
|
||||
ttl: number;
|
||||
}
|
||||
|
||||
export interface RedisValue {
|
||||
key: string;
|
||||
key_type: string;
|
||||
ttl: number;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export async function redisListDatabases(connectionId: string): Promise<number[]> {
|
||||
return invoke("redis_list_databases", { connectionId });
|
||||
}
|
||||
|
||||
export async function redisScanKeys(connectionId: string, db: number, pattern: string, count: number): Promise<RedisKeyInfo[]> {
|
||||
return invoke("redis_scan_keys", { connectionId, db, pattern, count });
|
||||
}
|
||||
|
||||
export async function redisGetValue(connectionId: string, key: string): Promise<RedisValue> {
|
||||
return invoke("redis_get_value", { connectionId, key });
|
||||
}
|
||||
|
||||
export async function redisSetString(connectionId: string, key: string, value: string, ttl?: number): Promise<void> {
|
||||
return invoke("redis_set_string", { connectionId, key, value, ttl });
|
||||
}
|
||||
|
||||
export async function redisDeleteKey(connectionId: string, key: string): Promise<void> {
|
||||
return invoke("redis_delete_key", { connectionId, key });
|
||||
}
|
||||
|
||||
export async function redisHashSet(connectionId: string, key: string, field: string, value: string): Promise<void> {
|
||||
return invoke("redis_hash_set", { connectionId, key, field, value });
|
||||
}
|
||||
|
||||
export async function redisHashDel(connectionId: string, key: string, field: string): Promise<void> {
|
||||
return invoke("redis_hash_del", { connectionId, key, field });
|
||||
}
|
||||
|
||||
export async function redisListPush(connectionId: string, key: string, value: string): Promise<void> {
|
||||
return invoke("redis_list_push", { connectionId, key, value });
|
||||
}
|
||||
|
||||
export async function redisListRemove(connectionId: string, key: string, index: number): Promise<void> {
|
||||
return invoke("redis_list_remove", { connectionId, key, index });
|
||||
}
|
||||
|
||||
export async function redisSetAdd(connectionId: string, key: string, member: string): Promise<void> {
|
||||
return invoke("redis_set_add", { connectionId, key, member });
|
||||
}
|
||||
|
||||
export async function redisSetRemove(connectionId: string, key: string, member: string): Promise<void> {
|
||||
return invoke("redis_set_remove", { connectionId, key, member });
|
||||
}
|
||||
|
||||
// --- MongoDB ---
|
||||
export interface MongoDocumentResult {
|
||||
documents: any[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export async function mongoListDatabases(connectionId: string): Promise<string[]> {
|
||||
return invoke("mongo_list_databases", { connectionId });
|
||||
}
|
||||
|
||||
export async function mongoListCollections(connectionId: string, database: string): Promise<string[]> {
|
||||
return invoke("mongo_list_collections", { connectionId, database });
|
||||
}
|
||||
|
||||
export async function mongoFindDocuments(connectionId: string, database: string, collection: string, skip: number, limit: number): Promise<MongoDocumentResult> {
|
||||
return invoke("mongo_find_documents", { connectionId, database, collection, skip, limit });
|
||||
}
|
||||
|
||||
export async function mongoInsertDocument(connectionId: string, database: string, collection: string, docJson: string): Promise<string> {
|
||||
return invoke("mongo_insert_document", { connectionId, database, collection, docJson });
|
||||
}
|
||||
|
||||
export async function mongoUpdateDocument(connectionId: string, database: string, collection: string, id: string, docJson: string): Promise<number> {
|
||||
return invoke("mongo_update_document", { connectionId, database, collection, id, docJson });
|
||||
}
|
||||
|
||||
export async function mongoDeleteDocument(connectionId: string, database: string, collection: string, id: string): Promise<number> {
|
||||
return invoke("mongo_delete_document", { connectionId, database, collection, id });
|
||||
}
|
||||
|
||||
// --- History ---
|
||||
export interface HistoryEntry {
|
||||
id: string;
|
||||
connection_name: string;
|
||||
database: string;
|
||||
sql: string;
|
||||
executed_at: string;
|
||||
execution_time_ms: number;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export async function saveHistory(entry: HistoryEntry): Promise<void> {
|
||||
return invoke("save_history", { entry });
|
||||
}
|
||||
|
||||
export async function loadHistory(limit: number, offset: number): Promise<HistoryEntry[]> {
|
||||
return invoke("load_history", { limit, offset });
|
||||
}
|
||||
|
||||
export async function clearHistory(): Promise<void> {
|
||||
return invoke("clear_history");
|
||||
}
|
||||
|
||||
export async function deleteHistoryEntry(id: string): Promise<void> {
|
||||
return invoke("delete_history_entry", { id });
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { ClassValue } from "clsx"
|
||||
import { clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
Reference in new issue
Block a user