Added database
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
target/
|
target/
|
||||||
plugins/
|
plugins/
|
||||||
config.json
|
config.json
|
||||||
/Cargo.lock
|
/Cargo.lock
|
||||||
|
*.db
|
||||||
@@ -8,6 +8,7 @@ anyhow = "1.0.99"
|
|||||||
chrono = "0.4.42"
|
chrono = "0.4.42"
|
||||||
libloading = { version = "0.8.8", optional = true }
|
libloading = { version = "0.8.8", optional = true }
|
||||||
once_cell = "1.21.3"
|
once_cell = "1.21.3"
|
||||||
|
rusqlite = "0.37.0"
|
||||||
serde = { version = "1.0.219", features = ["serde_derive"] }
|
serde = { version = "1.0.219", features = ["serde_derive"] }
|
||||||
serde_json = "1.0.143"
|
serde_json = "1.0.143"
|
||||||
tungstenite = "0.27.0"
|
tungstenite = "0.27.0"
|
||||||
|
|||||||
Generated
+85
@@ -23,6 +23,12 @@ version = "1.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
@@ -121,6 +127,18 @@ dependencies = [
|
|||||||
"crypto-common",
|
"crypto-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@@ -133,6 +151,12 @@ version = "1.0.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.7"
|
||||||
@@ -155,6 +179,24 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.15.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashlink"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
@@ -228,6 +270,16 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libsqlite3-sys"
|
||||||
|
version = "0.35.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f"
|
||||||
|
dependencies = [
|
||||||
|
"pkg-config",
|
||||||
|
"vcpkg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.27"
|
version = "0.4.27"
|
||||||
@@ -255,6 +307,12 @@ version = "1.21.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@@ -317,6 +375,20 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusqlite"
|
||||||
|
version = "0.37.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"fallible-iterator",
|
||||||
|
"fallible-streaming-iterator",
|
||||||
|
"hashlink",
|
||||||
|
"libsqlite3-sys",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
@@ -378,6 +450,12 @@ version = "1.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.15.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.106"
|
version = "2.0.106"
|
||||||
@@ -444,6 +522,12 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vcpkg"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
@@ -458,6 +542,7 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"libloading",
|
"libloading",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
use crate::ServerConfig;
|
||||||
|
use rusqlite::{Connection, Result, params};
|
||||||
|
|
||||||
|
pub struct Database {
|
||||||
|
pub messages_db: MessagesDb,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Database {
|
||||||
|
pub fn new(config: &ServerConfig) -> Option<Self> {
|
||||||
|
let conn = Connection::open("main.db").ok()?;
|
||||||
|
let messages_db = MessagesDb(conn);
|
||||||
|
messages_db.init(config)?;
|
||||||
|
Some(Self { messages_db })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Database {}
|
||||||
|
unsafe impl Sync for Database {}
|
||||||
|
|
||||||
|
pub struct MessagesDb(pub Connection);
|
||||||
|
|
||||||
|
impl MessagesDb {
|
||||||
|
pub fn init(&self, _config: &ServerConfig) -> Option<usize> {
|
||||||
|
self.0
|
||||||
|
.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS chat (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
channel_id TEXT NOT NULL,
|
||||||
|
user_id TEXT NOT NULL,
|
||||||
|
contents TEXT NOT NULL,
|
||||||
|
timestamp INTEGER NOT NULL
|
||||||
|
)",
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Insert a message into the DB
|
||||||
|
pub fn insert(
|
||||||
|
&self,
|
||||||
|
channel_id: &str,
|
||||||
|
user_id: &str,
|
||||||
|
contents: &str,
|
||||||
|
timestamp: i64,
|
||||||
|
) -> Result<usize> {
|
||||||
|
self.0.execute(
|
||||||
|
"INSERT INTO chat (channel_id, user_id, contents, timestamp)
|
||||||
|
VALUES (?1, ?2, ?3, ?4)",
|
||||||
|
params![channel_id, user_id, contents, timestamp],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetch the latest N messages for a channel
|
||||||
|
pub fn fetch_recent(
|
||||||
|
&self,
|
||||||
|
channel_id: &str,
|
||||||
|
limit: usize,
|
||||||
|
) -> Result<Vec<(i64, String, String, String, i64)>> {
|
||||||
|
let mut stmt = self.0.prepare(
|
||||||
|
"SELECT id, channel_id, user_id, contents, timestamp
|
||||||
|
FROM chat
|
||||||
|
WHERE channel_id = ?1
|
||||||
|
ORDER BY timestamp DESC
|
||||||
|
LIMIT ?2",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let rows = stmt.query_map(params![channel_id, limit], |row| {
|
||||||
|
Ok((
|
||||||
|
row.get::<_, i64>(0)?, // id
|
||||||
|
row.get::<_, String>(1)?, // channel_id
|
||||||
|
row.get::<_, String>(2)?, // user_id
|
||||||
|
row.get::<_, String>(3)?, // contents
|
||||||
|
row.get::<_, i64>(4)?, // timestamp
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut results = Vec::new();
|
||||||
|
for row in rows {
|
||||||
|
results.push(row?);
|
||||||
|
}
|
||||||
|
Ok(results)
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-7
@@ -6,6 +6,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
pub mod database;
|
||||||
#[cfg(feature = "loader")]
|
#[cfg(feature = "loader")]
|
||||||
pub mod loader;
|
pub mod loader;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
@@ -27,6 +28,7 @@ pub use once_cell;
|
|||||||
#[derive(serde::Serialize, serde::Deserialize)]
|
#[derive(serde::Serialize, serde::Deserialize)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
port: u16,
|
port: u16,
|
||||||
|
channels: Vec<types::data::Channel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@@ -35,11 +37,15 @@ pub struct Server {
|
|||||||
config: ServerConfig,
|
config: ServerConfig,
|
||||||
plugins: Mutex<Vec<DynPlugin>>,
|
plugins: Mutex<Vec<DynPlugin>>,
|
||||||
clients: Mutex<HashSet<Client>>,
|
clients: Mutex<HashSet<Client>>,
|
||||||
|
pub db: database::Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { port: 7080 }
|
Self {
|
||||||
|
port: 7080,
|
||||||
|
channels: Vec::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,16 +59,12 @@ impl Server {
|
|||||||
logger!(LOGGER "Server");
|
logger!(LOGGER "Server");
|
||||||
|
|
||||||
pub fn new(root: &Path) -> Arc<Self> {
|
pub fn new(root: &Path) -> Arc<Self> {
|
||||||
Arc::new(Self {
|
Self::new_config(root, ServerConfig::default())
|
||||||
plugins: Mutex::new(Vec::new()),
|
|
||||||
root: root.to_path_buf(),
|
|
||||||
config: ServerConfig::default(),
|
|
||||||
clients: Mutex::new(HashSet::new()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_config(root: &Path, config: ServerConfig) -> Arc<Self> {
|
pub fn new_config(root: &Path, config: ServerConfig) -> Arc<Self> {
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
|
db: database::Database::new(&config).unwrap(),
|
||||||
plugins: Mutex::new(Vec::new()),
|
plugins: Mutex::new(Vec::new()),
|
||||||
root: root.to_path_buf(),
|
root: root.to_path_buf(),
|
||||||
config,
|
config,
|
||||||
@@ -128,6 +130,15 @@ impl Server {
|
|||||||
contents,
|
contents,
|
||||||
} => {
|
} => {
|
||||||
Self::LOGGER.info(format!("SendMessage to {channel_id}: {contents}"));
|
Self::LOGGER.info(format!("SendMessage to {channel_id}: {contents}"));
|
||||||
|
self.wrap_err(
|
||||||
|
&client,
|
||||||
|
self.db.messages_db.insert(
|
||||||
|
&channel_id,
|
||||||
|
"idk",
|
||||||
|
&contents,
|
||||||
|
chrono::Utc::now().timestamp(),
|
||||||
|
),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientMessage::EditMessage {
|
ClientMessage::EditMessage {
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ pub mod data {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub id: usize,
|
pub id: String,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub kind: ChannelKind,
|
pub kind: ChannelKind,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user