1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Create RC database layer

This commit is contained in:
NGnius (Graham)
2025-05-07 20:23:22 -04:00
parent 69c6c54650
commit 77ddeb7891
55 changed files with 2689 additions and 395 deletions

20
rc_database/Cargo.toml Normal file
View File

@@ -0,0 +1,20 @@
[package]
name = "rc_database"
version.workspace = true
edition.workspace = true
repository.workspace = true
license.workspace = true
authors.workspace = true
readme.workspace = true
[features]
all_databases = ["mysql", "postgres", "sqlite"]
mysql = [ "sea-orm/sqlx-mysql" ]
postgres = [ "sea-orm/sqlx-postgres" ]
sqlite = [ "sea-orm/sqlx-sqlite" ]
default = [ "all_databases" ]
[dependencies]
sea-orm = { version = "1.1.10", features = [ "runtime-tokio-rustls", "macros" ] }
sea-orm-migration = "1.1.10"
itertools = "0.14"

9
rc_database/src/lib.rs Normal file
View File

@@ -0,0 +1,9 @@
mod migration;
pub use migration::Migrator;
pub mod schema;
mod wrapper;
pub use wrapper::Database;
pub use sea_orm;

View File

@@ -0,0 +1,43 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20250424_000001_create_user_table"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the Users table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(crate::schema::user::Entity)
.col(
ColumnDef::new(crate::schema::user::Column::Id)
.unsigned()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(crate::schema::user::Column::CreationTime).big_integer().not_null())
.col(ColumnDef::new(crate::schema::user::Column::PublicId).string().not_null())
.col(ColumnDef::new(crate::schema::user::Column::DisplayName).string().not_null())
.col(ColumnDef::new(crate::schema::user::Column::Password).string().not_null())
.col(ColumnDef::new(crate::schema::user::Column::Email).string().not_null())
.col(ColumnDef::new(crate::schema::user::Column::SteamId).string())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the Users table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(crate::schema::user::Entity).to_owned())
.await
}
}

View File

@@ -0,0 +1,50 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20250424_000002_create_user_permissions_table"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the Permissions table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(crate::schema::permissions::Entity)
.col(
ColumnDef::new(crate::schema::permissions::Column::Id)
.unsigned()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(crate::schema::permissions::Column::UserId).unsigned().not_null())
.foreign_key(
ForeignKey::create()
.name("fk-permissions-user_id")
.from(crate::schema::permissions::Entity, crate::schema::permissions::Column::UserId)
.to(crate::schema::user::Entity, crate::schema::user::Column::Id),
)
.col(ColumnDef::new(crate::schema::permissions::Column::Moderator).boolean().not_null())
//.col(crate::schema::permissions::Column::Moderator.def()) // I wish this worked...
.col(ColumnDef::new(crate::schema::permissions::Column::Administrator).boolean().not_null())
.col(ColumnDef::new(crate::schema::permissions::Column::Developer).boolean().not_null())
.col(ColumnDef::new(crate::schema::permissions::Column::Royalty).boolean().not_null())
.col(ColumnDef::new(crate::schema::permissions::Column::Banned).boolean().not_null())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the Permissions table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(crate::schema::permissions::Entity).to_owned())
.await
}
}

View File

@@ -0,0 +1,68 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20250424_000003_create_garage_table"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the Garages table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(crate::schema::garage::Entity)
.col(
ColumnDef::new(crate::schema::garage::Column::Id)
.unsigned()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(crate::schema::garage::Column::UserId).unsigned().not_null())
.foreign_key(
ForeignKey::create()
.name("fk-garage-user_id")
.from(crate::schema::garage::Entity, crate::schema::garage::Column::UserId)
.to(crate::schema::user::Entity, crate::schema::user::Column::Id),
)
.col(ColumnDef::new(crate::schema::garage::Column::CreationTime).big_integer().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::Slot).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::Name).string().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::CrfId).unsigned())
.col(ColumnDef::new(crate::schema::garage::Column::WasRated).boolean().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::MovementCategories).string().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::Uuid).big_integer().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::ThumbnailVersion).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::TotalRobotCpu).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::TotalCosmeticCpu).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::TotalRobotRanking).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::BayCpu).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::TutorialRobot).boolean().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::StarterRobotIndex).unsigned())
.col(ColumnDef::new(crate::schema::garage::Column::ControlType).tiny_unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::VerticalStrafing).boolean().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::SidewaysDriving).boolean().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::TracksTurnOnSpot).boolean().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::MasteryLevel).unsigned().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::BaySkinId).string().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::WeaponOrder).string().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::RobotData).blob().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::ColourData).blob().not_null())
.col(ColumnDef::new(crate::schema::garage::Column::Selected).boolean().not_null())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the Garages table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(crate::schema::garage::Entity).to_owned())
.await
}
}

View File

@@ -0,0 +1,47 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20250424_000004_create_user_aux_table"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the User auxiliary table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(crate::schema::user_aux::Entity)
.col(
ColumnDef::new(crate::schema::user_aux::Column::Id)
.unsigned()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(crate::schema::user_aux::Column::UserId).unsigned().not_null())
.foreign_key(
ForeignKey::create()
.name("fk-users_aux-user_id")
.from(crate::schema::user_aux::Entity, crate::schema::user_aux::Column::UserId)
.to(crate::schema::user::Entity, crate::schema::user::Column::Id),
)
.col(ColumnDef::new(crate::schema::user_aux::Column::CreationTime).big_integer().not_null())
.col(ColumnDef::new(crate::schema::user_aux::Column::Descriptor).string().not_null())
.col(ColumnDef::new(crate::schema::user_aux::Column::Data).string().not_null())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the User auxiliary table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(crate::schema::user_aux::Entity).to_owned())
.await
}
}

View File

@@ -0,0 +1,74 @@
use sea_orm_migration::prelude::*;
pub struct Migration;
impl MigrationName for Migration {
fn name(&self) -> &str {
"m20250424_000005_create_campaign_tables"
}
}
#[async_trait::async_trait]
impl MigrationTrait for Migration {
// Define how to apply this migration: Create the Campaigns table.
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(crate::schema::campaign::Entity)
.col(
ColumnDef::new(crate::schema::campaign::Column::Id)
.unsigned()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(crate::schema::campaign::Column::UserId).unsigned().not_null())
.foreign_key(
ForeignKey::create()
.name("fk-campaign-user_id")
.from(crate::schema::campaign::Entity, crate::schema::campaign::Column::UserId)
.to(crate::schema::user::Entity, crate::schema::user::Column::Id),
)
.col(ColumnDef::new(crate::schema::campaign::Column::CreationTime).big_integer().not_null())
.col(ColumnDef::new(crate::schema::campaign::Column::CampaignId).string().not_null())
.to_owned(),
)
.await?;
manager
.create_table(
Table::create()
.table(crate::schema::campaign_difficulty_completion::Entity)
.col(
ColumnDef::new(crate::schema::campaign_difficulty_completion::Column::Id)
.unsigned()
.not_null()
.auto_increment()
.primary_key(),
)
.col(ColumnDef::new(crate::schema::campaign_difficulty_completion::Column::CampaignId).unsigned().not_null())
.foreign_key(
ForeignKey::create()
.name("fk-campaigns_completion-campaign_id")
.from(crate::schema::campaign_difficulty_completion::Entity, crate::schema::campaign_difficulty_completion::Column::CampaignId)
.to(crate::schema::campaign::Entity, crate::schema::campaign::Column::Id),
)
.col(ColumnDef::new(crate::schema::campaign_difficulty_completion::Column::CreationTime).big_integer().not_null())
.col(ColumnDef::new(crate::schema::campaign_difficulty_completion::Column::Level).unsigned().not_null())
.col(ColumnDef::new(crate::schema::campaign_difficulty_completion::Column::Wave).unsigned().not_null())
.col(ColumnDef::new(crate::schema::campaign_difficulty_completion::Column::Complete).boolean().not_null())
.to_owned(),
)
.await
}
// Define how to rollback this migration: Drop the Campaigns table.
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(crate::schema::campaign::Entity).to_owned())
.await?;
manager
.drop_table(Table::drop().table(crate::schema::campaign_difficulty_completion::Entity).to_owned())
.await
}
}

View File

@@ -0,0 +1,22 @@
use sea_orm_migration::{MigratorTrait, MigrationTrait, prelude::async_trait};
mod m20250424_000001_create_user_table;
mod m20250424_000002_create_user_permissions_table;
mod m20250424_000003_create_garage_table;
mod m20250424_000004_create_user_aux_table;
mod m20250424_000005_create_campaign_tables;
pub struct Migrator;
#[async_trait::async_trait]
impl MigratorTrait for Migrator {
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![
Box::new(m20250424_000001_create_user_table::Migration),
Box::new(m20250424_000002_create_user_permissions_table::Migration),
Box::new(m20250424_000003_create_garage_table::Migration),
Box::new(m20250424_000004_create_user_aux_table::Migration),
Box::new(m20250424_000005_create_campaign_tables::Migration),
]
}
}

View File

@@ -0,0 +1,37 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "campaigns")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub user_id: u32,
pub creation_time: i64, // seconds since unix epoch
pub campaign_id: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id"
)]
User,
#[sea_orm(has_many = "super::campaign_difficulty_completion::Entity")]
CampaignCompletion,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl Related<super::campaign_difficulty_completion::Entity> for Entity {
fn to() -> RelationDef {
Relation::CampaignCompletion.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@@ -0,0 +1,31 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "campaigns_completion")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub campaign_id: u32,
pub creation_time: i64, // seconds since unix epoch
pub level: u32,
pub wave: u32,
pub complete: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::campaign::Entity",
from = "Column::CampaignId",
to = "super::campaign::Column::Id"
)]
Campaign,
}
impl Related<super::campaign::Entity> for Entity {
fn to() -> RelationDef {
Relation::Campaign.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@@ -0,0 +1,6 @@
use sea_orm::FromQueryResult;
#[derive(FromQueryResult)]
pub struct Id {
pub id: u32,
}

View File

@@ -0,0 +1,70 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "garages")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub user_id: u32,
pub creation_time: i64, // seconds since unix epoch
pub slot: u32,
pub name: String,
pub crf_id: Option<u32>,
pub was_rated: bool,
pub movement_categories: String, // csv?
pub uuid: i64,
pub thumbnail_version: u32,
pub total_robot_cpu: u32,
pub total_cosmetic_cpu: u32,
pub total_robot_ranking: u32,
pub bay_cpu: u32,
pub tutorial_robot: bool,
pub starter_robot_index: Option<u32>,
pub control_type: ControlType,
pub vertical_strafing: bool,
pub sideways_driving: bool,
pub tracks_turn_on_spot: bool,
pub mastery_level: u32,
pub bay_skin_id: String,
pub weapon_order: String, // csv?
pub robot_data: Vec<u8>,
pub colour_data: Vec<u8>,
pub selected: bool,
}
impl Model {
pub fn cube_count(&self) -> u32 {
if self.robot_data.len() >= 4 {
u32::from_le_bytes([self.robot_data[0], self.robot_data[1], self.robot_data[2], self.robot_data[3]])
} else {
0
}
}
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
#[repr(u8)]
#[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "u8", db_type = "TinyInteger")]
pub enum ControlType {
Camera = 0,
Keyboard = 1,
Count = 2,
}

View File

@@ -0,0 +1,17 @@
pub mod user;
pub mod user_aux;
pub mod permissions;
pub mod garage;
pub mod campaign;
pub mod campaign_difficulty_completion;
pub mod common_query;
pub fn parse_int_csv(s: &str) -> Vec<u32> {
s.split(',').filter_map(|i_as_s| {
i_as_s.parse().ok()
}).collect()
}
pub fn dump_csv<T: std::string::ToString>(slice: &[T]) -> String {
itertools::Itertools::intersperse(slice.iter().map(|x| x.to_string()), ",".to_owned()).collect()
}

View File

@@ -0,0 +1,32 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "permissions")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub user_id: u32,
pub moderator: bool,
pub administrator: bool,
pub developer: bool,
pub royalty: bool,
pub banned: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@@ -0,0 +1,52 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "users")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub creation_time: i64, // seconds since unix epoch
pub public_id: String,
pub display_name: String,
pub password: String,
pub email: String,
pub steam_id: Option<String>, // u64
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(has_one = "super::permissions::Entity")]
Permission,
#[sea_orm(has_many = "super::garage::Entity")]
Garages,
#[sea_orm(has_many = "super::user_aux::Entity")]
Aux,
#[sea_orm(has_many = "super::campaign::Entity")]
Campaigns,
}
impl Related<super::permissions::Entity> for Entity {
fn to() -> RelationDef {
Relation::Permission.def()
}
}
impl Related<super::garage::Entity> for Entity {
fn to() -> RelationDef {
Relation::Garages.def()
}
}
impl Related<super::user_aux::Entity> for Entity {
fn to() -> RelationDef {
Relation::Aux.def()
}
}
impl Related<super::campaign::Entity> for Entity {
fn to() -> RelationDef {
Relation::Campaigns.def()
}
}
impl ActiveModelBehavior for ActiveModel {}

View File

@@ -0,0 +1,42 @@
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "users_aux")]
pub struct Model {
#[sea_orm(primary_key)]
pub id: u32,
pub user_id: u32,
pub creation_time: i64, // seconds since unix epoch
pub descriptor: Descriptor,
pub data: String, // usually JSON
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::user::Entity",
from = "Column::UserId",
to = "super::user::Column::Id"
)]
User,
}
impl Related<super::user::Entity> for Entity {
fn to() -> RelationDef {
Relation::User.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
#[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::None)", rename_all = "PascalCase")]
pub enum Descriptor {
UserXP, // u32
PremiumExpiry, // u64, seconds since Unix epoch
UnlockedParts, // rc_core::persist::user::UnlockedParts
TechPoints, // u32
UserRank, // u32
UserFreeCurrency, // u64
UserPaidCurrency, // u64
}

115
rc_database/src/wrapper.rs Normal file
View File

@@ -0,0 +1,115 @@
use sea_orm_migration::MigratorTrait;
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect};
pub struct Database {
orm: sea_orm::DatabaseConnection,
}
impl Database {
pub async fn init(uri: &str) -> Result<Self, sea_orm::DbErr>{
let db = sea_orm::Database::connect(uri).await?;
//let schema_manager = SchemaManager::new(&db);
super::Migrator::up(&db, None).await?;
Ok(Self {
orm: db,
})
}
pub async fn user_by_public_id(&self, public_id: String) -> Result<Option<crate::schema::user::Model>, sea_orm::DbErr> {
crate::schema::user::Entity::find()
.filter(crate::schema::user::Column::PublicId.eq(public_id))
.one(&self.orm)
.await
}
pub async fn insert_user(&self, entity: crate::schema::user::ActiveModel) -> Result<crate::schema::user::Model, sea_orm::DbErr> {
entity.insert(&self.orm).await
}
pub async fn user_aux_by_user_id(&self, user_id: u32) -> Result<Vec<crate::schema::user_aux::Model>, sea_orm::DbErr> {
crate::schema::user_aux::Entity::find()
.filter(crate::schema::user_aux::Column::UserId.eq(user_id))
.all(&self.orm)
.await
}
pub async fn user_aux_by_user_id_and_descriptor(&self, user_id: u32, descriptor: crate::schema::user_aux::Descriptor) -> Result<Option<crate::schema::user_aux::Model>, sea_orm::DbErr> {
crate::schema::user_aux::Entity::find()
.filter(crate::schema::user_aux::Column::UserId.eq(user_id))
.filter(crate::schema::user_aux::Column::Descriptor.eq(descriptor))
.one(&self.orm)
.await
}
pub async fn insert_user_aux(&self, entities: Vec<crate::schema::user_aux::ActiveModel>) -> Result<(), sea_orm::DbErr> {
crate::schema::user_aux::Entity::insert_many(entities.into_iter()).exec(&self.orm).await?;
Ok(())
}
pub async fn perms_by_user_id(&self, user_id: u32) -> Result<Option<crate::schema::permissions::Model>, sea_orm::DbErr> {
crate::schema::permissions::Entity::find()
.filter(crate::schema::permissions::Column::UserId.eq(user_id))
.one(&self.orm)
.await
}
pub async fn insert_perms(&self, entity: crate::schema::permissions::ActiveModel) -> Result<crate::schema::permissions::Model, sea_orm::DbErr> {
entity.insert(&self.orm).await
}
pub async fn garage_selected(&self, user_id: u32) -> Result<Option<crate::schema::garage::Model>, sea_orm::DbErr> {
crate::schema::garage::Entity::find()
.filter(crate::schema::garage::Column::UserId.eq(user_id))
.filter(crate::schema::garage::Column::Selected.eq(true))
.one(&self.orm)
.await
}
pub async fn garage_by_user_id_and_slot(&self, user_id: u32, garage_slot: u32) -> Result<Option<crate::schema::garage::Model>, sea_orm::DbErr> {
crate::schema::garage::Entity::find()
.filter(crate::schema::garage::Column::UserId.eq(user_id))
.filter(crate::schema::garage::Column::Slot.eq(garage_slot))
.one(&self.orm)
.await
}
pub async fn garages_by_user_id(&self, user_id: u32) -> Result<Vec<crate::schema::garage::Model>, sea_orm::DbErr> {
crate::schema::garage::Entity::find()
.filter(crate::schema::garage::Column::UserId.eq(user_id))
.order_by_asc(crate::schema::garage::Column::Slot)
.all(&self.orm)
.await
}
pub async fn insert_garages(&self, entities: Vec<crate::schema::garage::ActiveModel>) -> Result<(), sea_orm::DbErr> {
crate::schema::garage::Entity::insert_many(entities.into_iter()).exec(&self.orm).await?;
Ok(())
}
pub async fn update_garage(&self, entity: crate::schema::garage::ActiveModel, id: u32) -> Result<crate::schema::garage::Model, sea_orm::DbErr> {
crate::schema::garage::Entity::update(entity)
.filter(crate::schema::garage::Column::Id.eq(id))
.exec(&self.orm)
.await
}
pub async fn update_garage_by_user_id_and_slot(&self, mut entity: crate::schema::garage::ActiveModel, user_id: u32, slot: u32) -> Result<Option<crate::schema::garage::Model>, sea_orm::DbErr> {
let id_opt = crate::schema::garage::Entity::find()
.select_only()
.column(crate::schema::garage::Column::Id)
.filter(crate::schema::garage::Column::UserId.eq(user_id))
.filter(crate::schema::garage::Column::Slot.eq(slot))
.into_model::<crate::schema::common_query::Id>()
.one(&self.orm)
.await?;
if let Some(id) = id_opt {
entity.id = sea_orm::ActiveValue::Set(id.id);
Ok(Some(crate::schema::garage::Entity::update(entity)
.exec(&self.orm)
.await?))
} else {
Ok(None)
}
}
}