Skip to content

Commit 0ef2ab2

Browse files
authored
feat(base/db/platform): 数据库底层基座功能完善、跨平台路径优化和其他底层能力 (#12)
1 parent aba8edc commit 0ef2ab2

28 files changed

Lines changed: 2463 additions & 147 deletions

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ name = "OmegaCode"
33
version = "0.1.0-alpha"
44
edition = "2024"
55

6+
[lib]
7+
path = "src/lib.rs"
8+
9+
[[bin]]
10+
name = "OmegaCode"
11+
path = "src/main.rs"
12+
613
[dependencies]
714
clap = "4.6.1"
815
anyhow = "1.0.102"
@@ -12,10 +19,10 @@ indicatif = "0.18.4"
1219
reqwest = "0.13.3"
1320
tokio-stream = "0.1.18"
1421
futures-util = "0.3.32"
15-
serde = "1.0.228"
22+
serde = { version = "1.0.228", features = ["derive"] }
1623
serde_json = "1.0.149"
1724
rmcp = "1.7.0"
18-
rusqlite = "0.39.0"
25+
rusqlite = { version = "0.39.0", features = ["bundled"] }
1926
ratatui = "0.30.0"
2027
crossterm = "0.29.0"
2128
log = "0.4.29"

locales/en.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ _version: 1
22
test_message: "Hello, %{name}"
33
logger_is_initialized: "Logger is initialized."
44
current_locale: "Current locale: %{locale_name}"
5+
database_path: "Connecting to database at: %{database_path}"
6+
database_initialized: "Database initialized."
7+
database_table_create: "Database table %{table_name} is created."

locales/zh-CN.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ _version: 1
22
test_message: "你好,%{name}"
33
logger_is_initialized: "日志已经初始化了喵~"
44
current_locale: "当前语言: %{locale_name}"
5+
database_path: "数据库位置: %{database_path}"
6+
database_initialized: "数据库初始化成功"
7+
database_table_create: "数据表 %{table_name} 已创建"

src/core/db/db_init.rs

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
use rusqlite::Connection;
2+
use anyhow::{Context, Result};
3+
use log::{info};
4+
use rust_i18n::t;
5+
use crate::core::db::Model;
6+
use crate::db::models::{
7+
ai_provider::AiProvider,
8+
llm_model::LLMModel,
9+
prompt_info::PromptInfo,
10+
agent_info::AgentInfo,
11+
prompt_placeholder::PromptPlaceholder,
12+
agent_arena::AgentArena,
13+
chat_session::ChatSession,
14+
chat_message::ChatMessage,
15+
memory_info::MemoryInfo,
16+
mcp_provider::McpProvider,
17+
mcp_tool::McpTool,
18+
agent_mcp_rel::AgentMcpRel,
19+
project_info::ProjectInfo,
20+
system_api_log::SystemApiLog,
21+
system_config::SystemConfig
22+
};
23+
24+
pub fn init_all_tables(conn: &Connection) -> Result<()> {
25+
info!("Initializing database tables...");
26+
27+
create_table_ai_provider(conn)
28+
.context("Failed to create ai_provider table")?;
29+
create_table_llm_model(conn)
30+
.context("Failed to create llm_model table")?;
31+
create_table_prompt_info(conn)
32+
.context("Failed to create prompt_info table")?;
33+
create_table_agent_info(conn)
34+
.context("Failed to create agent_info table")?;
35+
create_table_prompt_placeholder(conn)
36+
.context("Failed to create prompt_placeholder table")?;
37+
create_table_agent_arena(conn)
38+
.context("Failed to create agent_arena table")?;
39+
create_table_chat_session(conn)
40+
.context("Failed to create chat_session table")?;
41+
create_table_chat_message(conn)
42+
.context("Failed to create chat_message table")?;
43+
create_table_memory_info(conn)
44+
.context("Failed to create memory_info table")?;
45+
create_table_mcp_provider(conn)
46+
.context("Failed to create mcp_provider table")?;
47+
create_table_mcp_tool(conn)
48+
.context("Failed to create mcp_tool table")?;
49+
create_table_agent_mcp_rel(conn)
50+
.context("Failed to create agent_mcp_rel table")?;
51+
create_table_project_info(conn)
52+
.context("Failed to create project_info table")?;
53+
create_table_system_api_log(conn)
54+
.context("Failed to create system_api_log table")?;
55+
create_table_system_config(conn)
56+
.context("Failed to create system_config table")?;
57+
create_indexes(conn)
58+
.context("Failed to create indexes")?;
59+
60+
info!("Database tables initialized successfully");
61+
Ok(())
62+
}
63+
64+
// ============================================================
65+
// Create table
66+
// ============================================================
67+
fn create_table_ai_provider(conn: &Connection) -> Result<()> {
68+
let exists: bool = conn.query_row(
69+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='ai_provider'",
70+
[],
71+
|row| row.get(0),
72+
)?;
73+
if !exists {
74+
conn.execute_batch(AiProvider::create_table_sql())?;
75+
info!("{}", t!("database_table_create", table_name = "ai_provider"));
76+
}
77+
Ok(())
78+
}
79+
80+
fn create_table_llm_model(conn: &Connection) -> Result<()> {
81+
let exists: bool = conn.query_row(
82+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='llm_model'",
83+
[],
84+
|row| row.get(0),
85+
)?;
86+
if !exists {
87+
conn.execute_batch(LLMModel::create_table_sql())?;
88+
info!("{}", t!("database_table_create", table_name = "llm_model"));
89+
}
90+
Ok(())
91+
}
92+
93+
fn create_table_prompt_info(conn: &Connection) -> Result<()> {
94+
let exists: bool = conn.query_row(
95+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='prompt_info'",
96+
[],
97+
|row| row.get(0),
98+
)?;
99+
if !exists {
100+
conn.execute_batch(PromptInfo::create_table_sql())?;
101+
info!("{}", t!("database_table_create", table_name = "prompt_info"));
102+
}
103+
Ok(())
104+
}
105+
106+
fn create_table_agent_info(conn: &Connection) -> Result<()> {
107+
let exists: bool = conn.query_row(
108+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='agent_info'",
109+
[],
110+
|row| row.get(0),
111+
)?;
112+
if !exists {
113+
conn.execute_batch(AgentInfo::create_table_sql())?;
114+
info!("{}", t!("database_table_create", table_name = "agent_info"));
115+
}
116+
Ok(())
117+
}
118+
119+
fn create_table_prompt_placeholder(conn: &Connection) -> Result<()> {
120+
let exists: bool = conn.query_row(
121+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='prompt_placeholder'",
122+
[],
123+
|row| row.get(0),
124+
)?;
125+
if !exists {
126+
conn.execute_batch(PromptPlaceholder::create_table_sql())?;
127+
info!("{}", t!("database_table_create", table_name = "prompt_placeholder"));
128+
}
129+
Ok(())
130+
}
131+
132+
fn create_table_agent_arena(conn: &Connection) -> Result<()> {
133+
let exists: bool = conn.query_row(
134+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='agent_arena'",
135+
[],
136+
|row| row.get(0),
137+
)?;
138+
if !exists {
139+
conn.execute_batch(AgentArena::create_table_sql())?;
140+
info!("{}", t!("database_table_create", table_name = "agent_arena"));
141+
}
142+
Ok(())
143+
}
144+
145+
fn create_table_chat_session(conn: &Connection) -> Result<()> {
146+
let exists: bool = conn.query_row(
147+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='chat_session'",
148+
[],
149+
|row| row.get(0),
150+
)?;
151+
if !exists {
152+
conn.execute_batch(ChatSession::create_table_sql())?;
153+
info!("{}", t!("database_table_create", table_name = "chat_session"));
154+
}
155+
Ok(())
156+
}
157+
158+
fn create_table_chat_message(conn: &Connection) -> Result<()> {
159+
let exists: bool = conn.query_row(
160+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='chat_message'",
161+
[],
162+
|row| row.get(0),
163+
)?;
164+
if !exists {
165+
conn.execute_batch(ChatMessage::create_table_sql())?;
166+
info!("{}", t!("database_table_create", table_name = "chat_message"));
167+
}
168+
Ok(())
169+
}
170+
171+
fn create_table_memory_info(conn: &Connection) -> Result<()> {
172+
let exists: bool = conn.query_row(
173+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='memory_info'",
174+
[],
175+
|row| row.get(0),
176+
)?;
177+
if !exists {
178+
conn.execute_batch(MemoryInfo::create_table_sql())?;
179+
info!("{}", t!("database_table_create", table_name = "memory_info"));
180+
}
181+
Ok(())
182+
}
183+
184+
fn create_table_mcp_provider(conn: &Connection) -> Result<()> {
185+
let exists: bool = conn.query_row(
186+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='mcp_provider'",
187+
[],
188+
|row| row.get(0),
189+
)?;
190+
if !exists {
191+
conn.execute_batch(McpProvider::create_table_sql())?;
192+
info!("{}", t!("database_table_create", table_name = "mcp_provider"));
193+
}
194+
Ok(())
195+
}
196+
197+
fn create_table_mcp_tool(conn: &Connection) -> Result<()> {
198+
let exists: bool = conn.query_row(
199+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='mcp_tool'",
200+
[],
201+
|row| row.get(0),
202+
)?;
203+
if !exists {
204+
conn.execute_batch(McpTool::create_table_sql())?;
205+
info!("{}", t!("database_table_create", table_name = "mcp_tool"));
206+
}
207+
Ok(())
208+
}
209+
210+
fn create_table_agent_mcp_rel(conn: &Connection) -> Result<()> {
211+
let exists: bool = conn.query_row(
212+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='agent_mcp_rel'",
213+
[],
214+
|row| row.get(0),
215+
)?;
216+
if !exists {
217+
conn.execute_batch(AgentMcpRel::create_table_sql())?;
218+
info!("{}", t!("database_table_create", table_name = "agent_mcp_rel"));
219+
}
220+
Ok(())
221+
}
222+
223+
fn create_table_project_info(conn: &Connection) -> Result<()> {
224+
let exists: bool = conn.query_row(
225+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='project_info'",
226+
[],
227+
|row| row.get(0),
228+
)?;
229+
if !exists {
230+
conn.execute_batch(ProjectInfo::create_table_sql())?;
231+
info!("{}", t!("database_table_create", table_name = "project_info"));
232+
}
233+
Ok(())
234+
}
235+
236+
fn create_table_system_api_log(conn: &Connection) -> Result<()> {
237+
let exists: bool = conn.query_row(
238+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='system_api_log'",
239+
[],
240+
|row| row.get(0),
241+
)?;
242+
if !exists {
243+
conn.execute_batch(SystemApiLog::create_table_sql())?;
244+
info!("{}", t!("database_table_create", table_name = "system_api_log"));
245+
}
246+
Ok(())
247+
}
248+
249+
fn create_table_system_config(conn: &Connection) -> Result<()> {
250+
let exists: bool = conn.query_row(
251+
"SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='system_config'",
252+
[],
253+
|row| row.get(0),
254+
)?;
255+
if !exists {
256+
conn.execute_batch(SystemConfig::create_table_sql())?;
257+
info!("{}", t!("database_table_create", table_name = "system_config"));
258+
}
259+
Ok(())
260+
}
261+
262+
// ============================================================
263+
// Index
264+
// ============================================================
265+
266+
fn create_indexes(conn: &Connection) -> Result<()> {
267+
conn.execute_batch(
268+
"
269+
CREATE INDEX IF NOT EXISTS idx_chat_session_chat_uuid ON chat_session(chat_uuid);
270+
CREATE INDEX IF NOT EXISTS idx_chat_message_session_id ON chat_message(session_id);
271+
CREATE INDEX IF NOT EXISTS idx_agent_arena_agent_id ON agent_arena(agent_id);
272+
CREATE INDEX IF NOT EXISTS idx_agent_arena_arena_id ON agent_arena(arena_id);
273+
CREATE INDEX IF NOT EXISTS idx_memory_info_session_id ON memory_info(session_id);
274+
CREATE INDEX IF NOT EXISTS idx_agent_mcp_rel_agent_id ON agent_mcp_rel(agent_id);
275+
CREATE INDEX IF NOT EXISTS idx_agent_mcp_rel_mcp_id ON agent_mcp_rel(mcp_id);
276+
CREATE INDEX IF NOT EXISTS idx_prompt_placeholder_prompt_id ON prompt_placeholder(prompt_id);
277+
CREATE INDEX IF NOT EXISTS idx_llm_model_provider_id ON llm_model(provider_id);
278+
CREATE INDEX IF NOT EXISTS idx_mcp_tool_provider_id ON mcp_tool(provider_id);
279+
CREATE INDEX IF NOT EXISTS idx_agent_info_model_id ON agent_info(model_id);
280+
CREATE INDEX IF NOT EXISTS idx_agent_info_prompt_id ON agent_info(prompt_id);
281+
",
282+
)?;
283+
info!("{}", t!("database_table_create", table_name = "table_indexes"));
284+
Ok(())
285+
}

0 commit comments

Comments
 (0)