feat: Model are created
This commit is contained in:
parent
37c5c7235e
commit
49419cbc4c
@ -1,6 +1,6 @@
|
||||
use config::parse_local_config;
|
||||
use poise::serenity_prelude as serenity;
|
||||
use tracing::{error, info};
|
||||
use tracing::{error, info, instrument};
|
||||
|
||||
pub mod config;
|
||||
pub mod dotenv;
|
||||
@ -11,6 +11,7 @@ type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||
type Context<'a> = poise::Context<'a, Data, Error>;
|
||||
|
||||
/// Displays your or another user's account creation date
|
||||
#[instrument(skip(ctx), level = "info", fields(channel_id = ctx.channel_id().get() , guild_id = ?ctx.guild_id(), user_id = ?ctx.author().id.get(), user_name = ctx.author().name))]
|
||||
#[poise::command(slash_command, prefix_command)]
|
||||
async fn age(
|
||||
ctx: Context<'_>,
|
||||
|
@ -1,6 +1,9 @@
|
||||
use std::{error::Error, sync::Arc};
|
||||
|
||||
pub mod trivial;
|
||||
pub mod trivial_point;
|
||||
pub mod trivial_question;
|
||||
pub mod trivial_round;
|
||||
|
||||
use clickhouse_pool::{
|
||||
config::{ClickhouseConfig, DatalakeConfig, RetryConfig},
|
||||
@ -9,6 +12,9 @@ use clickhouse_pool::{
|
||||
};
|
||||
use tracing::{error, info, instrument};
|
||||
use trivial::Trivial;
|
||||
use trivial_point::TrivialPoint;
|
||||
use trivial_question::TrivialQuestion;
|
||||
use trivial_round::TrivialRound;
|
||||
|
||||
use crate::config::PersistenceConfig;
|
||||
|
||||
@ -37,20 +43,51 @@ pub fn create_pool_manager(db_config: PersistenceConfig) -> Result<Arc<DatalakeC
|
||||
pub async fn create_manager_and_init(
|
||||
datalake_config: Arc<DatalakeConfig>,
|
||||
) -> Result<Arc<PoolManager>, Box<dyn Error>> {
|
||||
let manager = PoolManager::new(datalake_config, None).await;
|
||||
let mut manager = PoolManager::new(datalake_config, None).await;
|
||||
|
||||
let _ = match manager
|
||||
.execute_with_retry(Trivial::create_table_sql())
|
||||
.await
|
||||
{
|
||||
Ok(_) => {
|
||||
info!("Table {} created successfully", Trivial::table_name());
|
||||
}
|
||||
manager = match create_table::<Trivial>(manager).await {
|
||||
Ok(manager) => manager,
|
||||
Err(e) => {
|
||||
error!("Failed to create table {} : {}", Trivial::table_name(), e);
|
||||
return Err(Box::new(e));
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
manager = match create_table::<TrivialQuestion>(manager).await {
|
||||
Ok(manager) => manager,
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
manager = match create_table::<TrivialRound>(manager).await {
|
||||
Ok(manager) => manager,
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
manager = match create_table::<TrivialPoint>(manager).await {
|
||||
Ok(manager) => manager,
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
|
||||
info!("All tables created successfully");
|
||||
|
||||
Ok(Arc::new(manager))
|
||||
}
|
||||
|
||||
#[instrument(skip(manager))]
|
||||
pub async fn create_table<T: Model>(manager: PoolManager) -> Result<PoolManager, Box<dyn Error>> {
|
||||
let _ = match manager.execute_with_retry(T::create_table_sql()).await {
|
||||
Ok(_) => {
|
||||
info!("Table {} created successfully", T::table_name());
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to create table {} : {}", T::table_name(), e);
|
||||
return Err(Box::new(e));
|
||||
}
|
||||
};
|
||||
Ok(manager)
|
||||
}
|
||||
|
121
apps/bot/src/model/trivial_point.rs
Normal file
121
apps/bot/src/model/trivial_point.rs
Normal file
@ -0,0 +1,121 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use clickhouse::Row;
|
||||
use clickhouse_pool::traits::Model;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Row, Serialize, Deserialize)]
|
||||
pub struct TrivialPoint {
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub id: Uuid,
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub trivial_id: Uuid,
|
||||
|
||||
pub user_id: u64,
|
||||
|
||||
pub points: i64,
|
||||
|
||||
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
pub updater_id: u64,
|
||||
}
|
||||
|
||||
impl Model for TrivialPoint {
|
||||
type T = TrivialPoint;
|
||||
|
||||
fn table_name() -> &'static str {
|
||||
"trivial_point"
|
||||
}
|
||||
|
||||
fn create_table_sql() -> &'static str {
|
||||
r#"
|
||||
CREATE TABLE IF NOT EXISTS trivial_point (
|
||||
id UUID PRIMARY KEY,
|
||||
trivial_id UUID,
|
||||
user_id UInt64,
|
||||
points Int64,
|
||||
created_at DateTime64(3),
|
||||
updated_at DateTime64(3),
|
||||
updater_id UInt64
|
||||
) ENGINE = MergeTree()
|
||||
ORDER BY (id, trivial_id)
|
||||
"#
|
||||
.trim()
|
||||
}
|
||||
|
||||
fn column_names() -> Vec<&'static str> {
|
||||
vec![
|
||||
"id",
|
||||
"trivial_id",
|
||||
"user_id",
|
||||
"points",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"updater_id",
|
||||
]
|
||||
}
|
||||
|
||||
fn to_row(&self) -> (Vec<&'static str>, Vec<String>) {
|
||||
(
|
||||
Self::column_names(),
|
||||
vec![
|
||||
self.id.to_string(),
|
||||
self.trivial_id.to_string(),
|
||||
self.user_id.to_string(),
|
||||
self.points.to_string(),
|
||||
self.created_at.to_rfc3339(),
|
||||
self.updated_at.to_rfc3339(),
|
||||
self.updater_id.to_string(),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
fn insert_query(&self) -> String {
|
||||
let (columns, values) = self.to_row();
|
||||
let columns = columns.join(", ");
|
||||
let values = values.join(", ");
|
||||
format!(
|
||||
"INSERT INTO {} ({}) VALUES ({})",
|
||||
Self::table_name(),
|
||||
columns,
|
||||
values
|
||||
)
|
||||
}
|
||||
|
||||
fn batch_insert_query(items: &[Self::T]) -> String {
|
||||
let mut queries = Vec::new();
|
||||
for item in items {
|
||||
let (columns, values) = item.to_row();
|
||||
let columns = columns.join(", ");
|
||||
let values = values.join(", ");
|
||||
queries.push(format!(
|
||||
"INSERT INTO {} ({}) VALUES ({})",
|
||||
Self::table_name(),
|
||||
columns,
|
||||
values
|
||||
));
|
||||
}
|
||||
queries.join("; ")
|
||||
}
|
||||
|
||||
fn build_select_query(
|
||||
where_clause: Option<&str>,
|
||||
limit: Option<u64>,
|
||||
offset: Option<u64>,
|
||||
) -> String {
|
||||
let mut query = format!("SELECT * FROM {}", Self::table_name());
|
||||
if let Some(where_clause) = where_clause {
|
||||
query.push_str(&format!(" WHERE {}", where_clause));
|
||||
}
|
||||
if let Some(limit) = limit {
|
||||
query.push_str(&format!(" LIMIT {}", limit));
|
||||
}
|
||||
if let Some(offset) = offset {
|
||||
query.push_str(&format!(" OFFSET {}", offset));
|
||||
}
|
||||
query
|
||||
}
|
||||
}
|
119
apps/bot/src/model/trivial_question.rs
Normal file
119
apps/bot/src/model/trivial_question.rs
Normal file
@ -0,0 +1,119 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use clickhouse::Row;
|
||||
use clickhouse_pool::traits::Model;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Row, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct TrivialQuestion {
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub id: Uuid,
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub trivial_id: Uuid,
|
||||
|
||||
pub question: String,
|
||||
pub answer: String,
|
||||
|
||||
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
pub creator_id: u64,
|
||||
pub updater_id: u64,
|
||||
}
|
||||
|
||||
impl Model for TrivialQuestion {
|
||||
type T = TrivialQuestion;
|
||||
|
||||
fn table_name() -> &'static str {
|
||||
"trivial_question"
|
||||
}
|
||||
|
||||
fn create_table_sql() -> &'static str {
|
||||
r#"
|
||||
CREATE TABLE IF NOT EXISTS trivial_question (
|
||||
id UUID PRIMARY KEY,
|
||||
trivial_id UUID,
|
||||
question String,
|
||||
answer String,
|
||||
created_at DateTime64(3),
|
||||
updated_at DateTime64(3),
|
||||
creator_id UInt64,
|
||||
updater_id UInt64
|
||||
) ENGINE = MergeTree()
|
||||
ORDER BY (id, trivial_id)
|
||||
"#
|
||||
.trim()
|
||||
}
|
||||
|
||||
fn column_names() -> Vec<&'static str> {
|
||||
vec![
|
||||
"id",
|
||||
"trivial_id",
|
||||
"question",
|
||||
"answer",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"creator_id",
|
||||
"updater_id",
|
||||
]
|
||||
}
|
||||
|
||||
fn to_row(&self) -> (Vec<&'static str>, Vec<String>) {
|
||||
(
|
||||
Self::column_names(),
|
||||
vec![
|
||||
self.id.to_string(),
|
||||
self.trivial_id.to_string(),
|
||||
self.question.clone(),
|
||||
self.answer.clone(),
|
||||
self.created_at.to_string(),
|
||||
self.updated_at.to_string(),
|
||||
self.creator_id.to_string(),
|
||||
self.updater_id.to_string(),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
fn insert_query(&self) -> String {
|
||||
let (columns, values) = self.to_row();
|
||||
let columns = columns.join(", ");
|
||||
let values = values.join(", ");
|
||||
format!(
|
||||
"INSERT INTO {} ({}) VALUES ({})",
|
||||
Self::table_name(),
|
||||
columns,
|
||||
values
|
||||
)
|
||||
}
|
||||
|
||||
fn batch_insert_query(items: &[Self::T]) -> String {
|
||||
let mut queries = Vec::new();
|
||||
for item in items {
|
||||
let (columns, values) = item.to_row();
|
||||
let columns = columns.join(", ");
|
||||
let values = values.join(", ");
|
||||
queries.push(format!("({}, {})", columns, values));
|
||||
}
|
||||
queries.join(", ")
|
||||
}
|
||||
|
||||
fn build_select_query(
|
||||
where_clause: Option<&str>,
|
||||
limit: Option<u64>,
|
||||
offset: Option<u64>,
|
||||
) -> String {
|
||||
let mut query = format!("SELECT * FROM {}", Self::table_name());
|
||||
if let Some(where_clause) = where_clause {
|
||||
query.push_str(&format!(" WHERE {}", where_clause));
|
||||
}
|
||||
if let Some(limit) = limit {
|
||||
query.push_str(&format!(" LIMIT {}", limit));
|
||||
}
|
||||
if let Some(offset) = offset {
|
||||
query.push_str(&format!(" OFFSET {}", offset));
|
||||
}
|
||||
query
|
||||
}
|
||||
}
|
116
apps/bot/src/model/trivial_round.rs
Normal file
116
apps/bot/src/model/trivial_round.rs
Normal file
@ -0,0 +1,116 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use clickhouse::Row;
|
||||
use clickhouse_pool::traits::Model;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Row, Serialize, Deserialize)]
|
||||
pub struct TrivialRound {
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub id: Uuid,
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub trivial_id: Uuid,
|
||||
#[serde(with = "clickhouse::serde::uuid")]
|
||||
pub question_id: Uuid,
|
||||
pub answer: Vec<(u64, String, DateTime<Utc>)>,
|
||||
|
||||
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
#[serde(with = "clickhouse::serde::chrono::datetime64::millis")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl Model for TrivialRound {
|
||||
type T = TrivialRound;
|
||||
|
||||
fn table_name() -> &'static str {
|
||||
"trivial_round"
|
||||
}
|
||||
|
||||
fn create_table_sql() -> &'static str {
|
||||
r#"
|
||||
CREATE TABLE IF NOT EXISTS trivial_round (
|
||||
id UUID PRIMARY KEY,
|
||||
trivial_id UUID,
|
||||
question_id UUID,
|
||||
answer Array(Tuple(UInt64, String, DateTime64(3))),
|
||||
created_at DateTime64(3),
|
||||
updated_at DateTime64(3)
|
||||
) ENGINE = MergeTree()
|
||||
ORDER BY (id, trivial_id)
|
||||
"#
|
||||
.trim()
|
||||
}
|
||||
|
||||
fn column_names() -> Vec<&'static str> {
|
||||
vec![
|
||||
"id",
|
||||
"trivial_id",
|
||||
"question_id",
|
||||
"answer",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
]
|
||||
}
|
||||
|
||||
fn to_row(&self) -> (Vec<&'static str>, Vec<String>) {
|
||||
(
|
||||
Self::column_names(),
|
||||
vec![
|
||||
self.id.to_string(),
|
||||
self.trivial_id.to_string(),
|
||||
self.question_id.to_string(),
|
||||
format!("{:?}", self.answer),
|
||||
self.created_at.to_string(),
|
||||
self.updated_at.to_string(),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
fn insert_query(&self) -> String {
|
||||
let (columns, values) = self.to_row();
|
||||
let columns_str = columns.join(", ");
|
||||
let values_str = values.join(", ");
|
||||
|
||||
format!(
|
||||
"INSERT INTO {} ({}) VALUES ({})",
|
||||
Self::table_name(),
|
||||
columns_str,
|
||||
values_str
|
||||
)
|
||||
}
|
||||
|
||||
fn batch_insert_query(items: &[Self::T]) -> String {
|
||||
let mut queries = Vec::new();
|
||||
for item in items {
|
||||
let (columns, values) = item.to_row();
|
||||
let columns_str = columns.join(", ");
|
||||
let values_str = values.join(", ");
|
||||
queries.push(format!(
|
||||
"INSERT INTO {} ({}) VALUES ({})",
|
||||
Self::table_name(),
|
||||
columns_str,
|
||||
values_str
|
||||
));
|
||||
}
|
||||
queries.join("; ")
|
||||
}
|
||||
|
||||
fn build_select_query(
|
||||
where_clause: Option<&str>,
|
||||
limit: Option<u64>,
|
||||
offset: Option<u64>,
|
||||
) -> String {
|
||||
let mut query = format!("SELECT * FROM {}", Self::table_name());
|
||||
if let Some(where_clause) = where_clause {
|
||||
query.push_str(&format!(" WHERE {}", where_clause));
|
||||
}
|
||||
if let Some(limit) = limit {
|
||||
query.push_str(&format!(" LIMIT {}", limit));
|
||||
}
|
||||
if let Some(offset) = offset {
|
||||
query.push_str(&format!(" OFFSET {}", offset));
|
||||
}
|
||||
query
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ services:
|
||||
SERVER_click: database
|
||||
USER_click: default
|
||||
PASSWORD_click: password
|
||||
PORT_click: 9000
|
||||
PORT_click: 8123
|
||||
ENGINE_click: clickhouse@dbgate-plugin-clickhouse
|
||||
DATABASE_click: default
|
||||
depends_on:
|
||||
|
Loading…
Reference in New Issue
Block a user