switched to sqlite
This commit is contained in:
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -605,6 +605,8 @@ dependencies = [
|
|||||||
"diesel",
|
"diesel",
|
||||||
"diesel-enum",
|
"diesel-enum",
|
||||||
"json",
|
"json",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
"regex",
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@ -1324,6 +1326,17 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
|
checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-derive"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
|||||||
@ -11,6 +11,8 @@ clap = "4.6.1"
|
|||||||
diesel = { version = "2.3.9", features = ["sqlite", "r2d2", "chrono"] }
|
diesel = { version = "2.3.9", features = ["sqlite", "r2d2", "chrono"] }
|
||||||
diesel-enum = "0.2.1"
|
diesel-enum = "0.2.1"
|
||||||
json = "0.12.4"
|
json = "0.12.4"
|
||||||
|
num-derive = "0.4.2"
|
||||||
|
num-traits = "0.2.19"
|
||||||
regex = "1.12.3"
|
regex = "1.12.3"
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
thiserror = "2.0.18"
|
thiserror = "2.0.18"
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
-- This file was automatically created by Diesel to setup helper functions
|
|
||||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
|
||||||
-- changes will be added to existing projects as new migrations.
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
|
|
||||||
DROP FUNCTION IF EXISTS diesel_set_updated_at();
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
-- This file was automatically created by Diesel to setup helper functions
|
|
||||||
-- and other internal bookkeeping. This file is safe to edit, any future
|
|
||||||
-- changes will be added to existing projects as new migrations.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Sets up a trigger for the given table to automatically set a column called
|
|
||||||
-- `updated_at` whenever the row is modified (unless `updated_at` was included
|
|
||||||
-- in the modified columns)
|
|
||||||
--
|
|
||||||
-- # Example
|
|
||||||
--
|
|
||||||
-- ```sql
|
|
||||||
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
|
|
||||||
--
|
|
||||||
-- SELECT diesel_manage_updated_at('users');
|
|
||||||
-- ```
|
|
||||||
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
|
|
||||||
BEGIN
|
|
||||||
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
|
|
||||||
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
|
|
||||||
END;
|
|
||||||
$$ LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
|
|
||||||
BEGIN
|
|
||||||
IF (
|
|
||||||
NEW IS DISTINCT FROM OLD AND
|
|
||||||
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
|
|
||||||
) THEN
|
|
||||||
NEW.updated_at := current_timestamp;
|
|
||||||
END IF;
|
|
||||||
RETURN NEW;
|
|
||||||
END;
|
|
||||||
$$ LANGUAGE plpgsql;
|
|
||||||
@ -1,11 +1,10 @@
|
|||||||
CREATE TABLE "servers" (
|
CREATE TABLE "servers" (
|
||||||
"id" BIGSERIAL PRIMARY KEY,
|
"name" varchar(255) UNIQUE NOT NULL PRIMARY KEY,
|
||||||
"name" varchar(255) UNIQUE NOT NULL,
|
|
||||||
"last_login" timestamp,
|
"last_login" timestamp,
|
||||||
"container_id" varchar(30),
|
"container_id" varchar(30),
|
||||||
"status" int2 NOT NULL DEFAULT 0,
|
"status" INT2 NOT NULL DEFAULT 0,
|
||||||
"is_default" bool NOT NULL DEFAULT false,
|
"is_default" bool NOT NULL DEFAULT false,
|
||||||
"redirect_ip" varchar(50)
|
"redirect_ip" varchar(50)
|
||||||
);
|
);
|
||||||
|
|
||||||
insert into servers (name, last_login, container_id, status, is_default, redirect_ip) values ('potato', now(), null, 1, false, 'play.hypixel.net:25565');
|
insert into servers (name, last_login, container_id, status, is_default, redirect_ip) values ('potato', datetime(), null, 1, false, 'play.hypixel.net:25565');
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use crate::cli::env_settings;
|
|||||||
use crate::status::ServerStatus;
|
use crate::status::ServerStatus;
|
||||||
use crate::utils::{ validate_name, extract_archive, move_all_elements};
|
use crate::utils::{ validate_name, extract_archive, move_all_elements};
|
||||||
|
|
||||||
use diesel::{insert_into, prelude::*};
|
use diesel::prelude::*;
|
||||||
use crate::{DbPool, models};
|
use crate::{DbPool, models};
|
||||||
use crate::schema;
|
use crate::schema;
|
||||||
|
|
||||||
@ -27,21 +27,22 @@ pub fn create_subcommand() -> Command {
|
|||||||
|
|
||||||
|
|
||||||
pub async fn subcommand(arg: &ArgMatches, pool: DbPool) -> Result<(), String>{
|
pub async fn subcommand(arg: &ArgMatches, pool: DbPool) -> Result<(), String>{
|
||||||
|
// use schema::servers::dsl::*;
|
||||||
let config = crate::Config::load();
|
let config = crate::Config::load();
|
||||||
let name = arg.get_one::<String>("NAME").unwrap();
|
let server_name = arg.get_one::<String>("NAME").unwrap();
|
||||||
|
|
||||||
|
|
||||||
if !validate_name(name) {
|
if !validate_name(server_name) {
|
||||||
return Err("Invalid name provided".to_string());
|
return Err("Invalid name provided".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let conn = &mut pool.get().unwrap();
|
let conn = &mut pool.get().unwrap();
|
||||||
|
|
||||||
if let Ok(_) = schema::servers::table.filter(schema::servers::name.eq(name)).select(models::Servers::as_select()).first(conn) {
|
if let Ok(_) = schema::servers::table.filter(schema::servers::name.eq(server_name)).select(models::Servers::as_select()).first(conn) {
|
||||||
return Err("Server with this name already exists".to_string())
|
return Err("Server with this name already exists".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = config.config_path + "/" + name + "/";
|
let path = config.config_path + "/" + server_name + "/";
|
||||||
|
|
||||||
create_dir(&path).await.map_err(|e| format!("failed to create the config folder, reason : {}", e))?;
|
create_dir(&path).await.map_err(|e| format!("failed to create the config folder, reason : {}", e))?;
|
||||||
|
|
||||||
@ -56,14 +57,14 @@ pub async fn subcommand(arg: &ArgMatches, pool: DbPool) -> Result<(), String>{
|
|||||||
std::fs::remove_dir_all(path.to_string() + "tmp").map_err(|e| format!("failed to remove the tmp dir, reason : {}", e))?;
|
std::fs::remove_dir_all(path.to_string() + "tmp").map_err(|e| format!("failed to remove the tmp dir, reason : {}", e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_server = models::CreateServer {
|
let _new_server = models::CreateServer {
|
||||||
name: name,
|
name: server_name,
|
||||||
last_login: Some(SystemTime::now()),
|
last_login: Some(SystemTime::now()),
|
||||||
container_id: None,
|
container_id: None,
|
||||||
status: ServerStatus::Stopped,
|
status: ServerStatus::Stopped,
|
||||||
redirect_ip: None
|
redirect_ip: None
|
||||||
};
|
};
|
||||||
|
|
||||||
insert_into(schema::servers::dsl::servers).values(&new_server).execute(conn).map_err(|e| format!("Failed to insert in db, error : {:?}", e))?;
|
// insert_into(schema::servers::dsl::servers).values(&new_server).execute(conn).map_err(|e| format!("Failed to insert in db, error : {:?}", e))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
|
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2026/05/29 21:22:17 by tomoron #+# #+# */
|
/* Created: 2026/05/29 21:22:17 by tomoron #+# #+# */
|
||||||
/* Updated: 2026/06/06 18:18:03 by tomoron ### ########.fr */
|
/* Updated: 2026/06/06 19:39:47 by tomoron ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -15,8 +15,6 @@ use minecraft::mc_socket_listen;
|
|||||||
|
|
||||||
use diesel::{prelude::*, r2d2::{ConnectionManager, Pool}};
|
use diesel::{prelude::*, r2d2::{ConnectionManager, Pool}};
|
||||||
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
|
|
||||||
@ -33,7 +31,7 @@ pub use config::Config;
|
|||||||
pub type DbPool = Pool<ConnectionManager<SqliteConnection>>;
|
pub type DbPool = Pool<ConnectionManager<SqliteConnection>>;
|
||||||
|
|
||||||
fn get_connection_pool() -> DbPool {
|
fn get_connection_pool() -> DbPool {
|
||||||
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
let database_url = "sqlite:///".to_string() + &Config::load().config_path + "/db.sqlite";
|
||||||
|
|
||||||
let manager = ConnectionManager::<SqliteConnection>::new(&database_url);
|
let manager = ConnectionManager::<SqliteConnection>::new(&database_url);
|
||||||
Pool::builder()
|
Pool::builder()
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, TimeZone, Utc};
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -14,7 +14,6 @@ use crate::schema;
|
|||||||
#[diesel(table_name = schema::servers)]
|
#[diesel(table_name = schema::servers)]
|
||||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||||
pub struct Servers {
|
pub struct Servers {
|
||||||
pub id: i64,
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub last_login: Option<NaiveDateTime>,
|
pub last_login: Option<NaiveDateTime>,
|
||||||
pub container_id: Option<String>,
|
pub container_id: Option<String>,
|
||||||
@ -38,7 +37,7 @@ impl fmt::Display for Servers {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let login = match self.last_login {
|
let login = match self.last_login {
|
||||||
Some(date) => {
|
Some(date) => {
|
||||||
let datetime: DateTime<Utc> = date.into();
|
let datetime: DateTime<Utc> = Utc.from_utc_datetime(&date);
|
||||||
|
|
||||||
format!("{}", datetime.format("%d-%m-%Y at %H:%M").to_string())
|
format!("{}", datetime.format("%d-%m-%Y at %H:%M").to_string())
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,16 +1,12 @@
|
|||||||
// @generated automatically by Diesel CLI.
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
servers (id) {
|
servers (name) {
|
||||||
id -> Int8,
|
name -> Text,
|
||||||
#[max_length = 255]
|
|
||||||
name -> Varchar,
|
|
||||||
last_login -> Nullable<Timestamp>,
|
last_login -> Nullable<Timestamp>,
|
||||||
#[max_length = 30]
|
container_id -> Nullable<Text>,
|
||||||
container_id -> Nullable<Varchar>,
|
status -> SmallInt,
|
||||||
status -> Int2,
|
|
||||||
is_default -> Bool,
|
is_default -> Bool,
|
||||||
#[max_length = 50]
|
redirect_ip -> Nullable<Text>,
|
||||||
redirect_ip -> Nullable<Varchar>,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
use diesel::deserialize::{self, FromSql, FromSqlRow};
|
|
||||||
use diesel::sqlite::Sqlite;
|
|
||||||
use diesel::serialize::{self, ToSql, Output};
|
|
||||||
use diesel::sql_types::SmallInt;
|
|
||||||
use diesel::expression::AsExpression;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsExpression, FromSqlRow, serde::Serialize, serde::Deserialize)]
|
use diesel::{deserialize::{FromSql, FromSqlRow}, expression::AsExpression, serialize::{Output, ToSql}, sql_types::SmallInt, sqlite::{Sqlite, SqliteValue}};
|
||||||
|
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
|
use num_derive::FromPrimitive;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(FromSqlRow, Debug, AsExpression, FromPrimitive, Serialize, Deserialize, PartialEq, Clone)]
|
||||||
#[diesel(sql_type = SmallInt)]
|
#[diesel(sql_type = SmallInt)]
|
||||||
|
#[repr(i16)]
|
||||||
pub enum ServerStatus {
|
pub enum ServerStatus {
|
||||||
Archived = 0,
|
Archived = 0,
|
||||||
Stopped = 1,
|
Stopped = 1,
|
||||||
@ -16,27 +19,25 @@ pub enum ServerStatus {
|
|||||||
Unknown = 5,
|
Unknown = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql<SmallInt, Sqlite> for ServerStatus {
|
impl FromSql<SmallInt, Sqlite> for ServerStatus{
|
||||||
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
|
fn from_sql(bytes: SqliteValue) -> diesel::deserialize::Result<Self> {
|
||||||
let val = *self as i16;
|
let t = <i16 as FromSql<SmallInt, Sqlite>>::from_sql(bytes)?;
|
||||||
<i16 as ToSql<SmallInt, Sqlite>>::to_sql(&val, out)
|
if let Some(status) = ServerStatus::from_i16(t) {
|
||||||
|
return Ok(status)
|
||||||
|
}
|
||||||
|
Ok(ServerStatus::Unknown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql<SmallInt, Sqlite> for ServerStatus {
|
impl ToSql<SmallInt, Sqlite> for ServerStatus {
|
||||||
fn from_sql(value: diesel::sqlite::SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
|
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> diesel::serialize::Result {
|
||||||
let val = value.as_i64() as i16;
|
let value: i16 = self.clone() as i16;
|
||||||
match val {
|
out.set_value(value.to_le_bytes().to_vec());
|
||||||
0 => Ok(ServerStatus::Archived),
|
Ok(diesel::serialize::IsNull::No)
|
||||||
1 => Ok(ServerStatus::Stopped),
|
|
||||||
2 => Ok(ServerStatus::Stopping),
|
|
||||||
3 => Ok(ServerStatus::Starting),
|
|
||||||
4 => Ok(ServerStatus::Running),
|
|
||||||
_ => Ok(ServerStatus::Unknown),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl fmt::Display for ServerStatus {
|
impl fmt::Display for ServerStatus {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let str_status = match self {
|
let str_status = match self {
|
||||||
|
|||||||
Reference in New Issue
Block a user