From 745c0867f3144241f529f20aa159c5ced856e26e Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Thu, 4 Mar 2021 07:29:54 -0500 Subject: [PATCH 1/4] Replace mongo and dynamodb with postgres deps --- Cargo.toml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e2218e6..0906138 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,6 @@ edition = "2018" serde = { version = "1.0.105", features = ["derive"] } serde_json = "1.0.49" rand = "0.7.3" -rusoto_core = "0.43.0" -rusoto_dynamodb = "0.43.0" uuid = { version = "0.8.1", features = ["v4", "serde"] } futures = { version = "0.3.4", features = ["compat"] } regex = "1.3.6" @@ -24,7 +22,7 @@ dotenv = "0.15" reqwest = { version = "0.10.6", features = ["json"] } tokio = "0.2.21" -mongodb = {version = "1.0", optional = true} +tokio-postgres = {version = "0.7", features = ["with-uuid-0_8"]} [[bin]] name = "yank_config" @@ -35,4 +33,4 @@ name = "hcor" [features] actix = ["actix-web"] -mongo = ["mongodb"] + From 2955a090975bb0a964d876a5edd97c1a1c456673 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Thu, 4 Mar 2021 07:51:15 -0500 Subject: [PATCH 2/4] Scaffold Hacksteader postgres methods --- src/lib.rs | 1 - src/models.rs | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 53dbb9a..43d6cd9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ #![warn(missing_docs)] use humantime::{format_rfc3339, parse_rfc3339}; -use rusoto_dynamodb::{AttributeValue, DynamoDb, DynamoDbClient}; use std::collections::HashMap; use std::fmt; use std::time::SystemTime; diff --git a/src/models.rs b/src/models.rs index 594b77e..6509cfd 100644 --- a/src/models.rs +++ b/src/models.rs @@ -2,6 +2,9 @@ use crate::config::{ArchetypeHandle, PlantArchetype}; use crate::*; use serde::Serialize; use std::time::SystemTime; +use tokio_postgres::Client as PgClient; +use tokio_postgres::error::Error as SqlError; + #[derive(Clone, Debug, Serialize)] pub struct Hacksteader { @@ -48,6 +51,17 @@ pub struct Craft { pub makes: ArchetypeHandle, } +impl Hacksteader { + pub async fn insert_to_sql(&self, client: &PgClient) -> Result<(), SqlError> { + + Ok(()) + } + + pub async fn update_in_sql(&self, client: &PgClient) -> Result<(), SqlError> { + Ok(()) + } +} + impl std::ops::Deref for Plant { type Target = PlantArchetype; From 720cab4aad11e4cae9e354390840b07368a993c3 Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Thu, 4 Mar 2021 09:50:51 -0500 Subject: [PATCH 3/4] Derive appropriate macros on models --- .gitignore | 1 + Cargo.toml | 3 ++- src/config.rs | 2 +- src/lib.rs | 1 + src/models.rs | 39 ++++++++++++++------------------------- src/possess/seed.rs | 5 +++-- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index eed9fe5..725edc6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ Cargo.lock .env /config/content.json +*.swp diff --git a/Cargo.toml b/Cargo.toml index eb30baf..2b20d74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,9 @@ derive_more = "0.99" dotenv = "0.15" reqwest = { version = "0.11.1", features = ["json"] } tokio = "1.0" +time = {version="0.2", features=["serde", "std"]} -tokio-postgres = {version = "0.7", features = ["with-uuid-0_8"]} +sqlx = {version = "0.5.1", features=["postgres", "macros", "uuid", "time", "runtime-tokio-rustls"]} [[bin]] name = "yank_config" diff --git a/src/config.rs b/src/config.rs index ccc13e3..bcc2d1f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -164,7 +164,7 @@ impl Config { } // I should _really_ use a different version of this for PlantArchetypes and PossessionArchetypes ... -pub type ArchetypeHandle = usize; +pub type ArchetypeHandle = u32; lazy_static::lazy_static! { pub static ref CONFIG: Config = { diff --git a/src/lib.rs b/src/lib.rs index 43d6cd9..a183235 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![recursion_limit = "256"] #![feature(try_trait)] +#![feature(trivial_bounds)] #![warn(missing_docs)] use humantime::{format_rfc3339, parse_rfc3339}; diff --git a/src/models.rs b/src/models.rs index 6509cfd..e79299e 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,12 +1,12 @@ use crate::config::{ArchetypeHandle, PlantArchetype}; use crate::*; use serde::Serialize; -use std::time::SystemTime; -use tokio_postgres::Client as PgClient; -use tokio_postgres::error::Error as SqlError; +use time::PrimitiveDateTime; +use sqlx::types::Type; +use sqlx::FromRow; -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Serialize, FromRow)] pub struct Hacksteader { pub user_id: String, pub profile: Profile, @@ -15,35 +15,35 @@ pub struct Hacksteader { pub gotchis: Vec>, } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Type)] pub struct Tile { - pub acquired: SystemTime, + pub acquired: PrimitiveDateTime, pub plant: Option, pub id: uuid::Uuid, pub steader: String, } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Serialize, Type)] pub struct Profile { /// Indicates when this Hacksteader first joined the elite community. - pub joined: SystemTime, - pub last_active: SystemTime, - pub last_farm: SystemTime, + pub joined: PrimitiveDateTime, + pub last_active: PrimitiveDateTime, + pub last_farm: PrimitiveDateTime, /// This is not an uuid::Uuid because it's actually the steader id of the person who owns this Profile pub id: String, - pub xp: u64, + pub xp: u32, } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Type)] pub struct Plant { - pub xp: u64, + pub xp: u32, pub until_yield: f32, pub craft: Option, pub pedigree: Vec, pub archetype_handle: ArchetypeHandle, } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Type)] pub struct Craft { pub until_finish: f32, pub total_cycles: f32, @@ -51,17 +51,6 @@ pub struct Craft { pub makes: ArchetypeHandle, } -impl Hacksteader { - pub async fn insert_to_sql(&self, client: &PgClient) -> Result<(), SqlError> { - - Ok(()) - } - - pub async fn update_in_sql(&self, client: &PgClient) -> Result<(), SqlError> { - Ok(()) - } -} - impl std::ops::Deref for Plant { type Target = PlantArchetype; diff --git a/src/possess/seed.rs b/src/possess/seed.rs index 3b2fcdd..a498df5 100644 --- a/src/possess/seed.rs +++ b/src/possess/seed.rs @@ -3,6 +3,7 @@ use crate::{config, AttributeParseError, Item, CONFIG}; use config::{ArchetypeHandle, ArchetypeKind}; use rusoto_dynamodb::AttributeValue; use serde::{Deserialize, Serialize}; +use sqlx::types::Type as PgType; #[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] pub struct Seed { @@ -17,10 +18,10 @@ impl Possessable for Seed { PossessionKind::Seed(self) } } -#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, PgType)] pub struct SeedGrower { pub id: String, - pub generations: u64, + pub generations: u32, } impl SeedGrower { pub fn new(id: String, generations: u64) -> Self { From 33fc89810f814fea1db8c50d99e23ae85cdf3f3d Mon Sep 17 00:00:00 2001 From: Owen Salter Date: Fri, 5 Mar 2021 15:50:19 -0500 Subject: [PATCH 4/4] Start writing migrations --- Cargo.toml | 3 +- migrations/20210305203340_hacksteaders.sql | 53 ++++++++++++++++++++++ src/lib.rs | 5 +- src/models.rs | 8 ++-- src/possess/seed.rs | 30 +----------- 5 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 migrations/20210305203340_hacksteaders.sql diff --git a/Cargo.toml b/Cargo.toml index 2b20d74..831c35e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,8 @@ reqwest = { version = "0.11.1", features = ["json"] } tokio = "1.0" time = {version="0.2", features=["serde", "std"]} -sqlx = {version = "0.5.1", features=["postgres", "macros", "uuid", "time", "runtime-tokio-rustls"]} +sqlx = {version = "0.5", features=["postgres", "macros", "uuid", "time", "runtime-tokio-rustls", "migrate"]} +barrel = "0.6" [[bin]] name = "yank_config" diff --git a/migrations/20210305203340_hacksteaders.sql b/migrations/20210305203340_hacksteaders.sql new file mode 100644 index 0000000..6f6a5f3 --- /dev/null +++ b/migrations/20210305203340_hacksteaders.sql @@ -0,0 +1,53 @@ +-- Add migration script here +CREATE TABLE IF NOT EXISTS crafts ( + id uuid PRIMARY KEY, + until_finish float, + total_cycles float, + destroys_plant boolean, + makes text + ); + +CREATE TYPE seed_grower AS ( + id text, + generations numeric +); + +CREATE TABLE IF NOT EXISTS plants ( + id uuid PRIMARY KEY, + xp numeric, + until_yield float, + craft references crafts(id), + pedigree []seed_grower, + archetype_handle text, + on_market boolean + ); + +CREATE TABLE IF NOT EXISTS tiles ( + id uuid PRIMARY KEY, + acquired timestamp, + plant references plants(id), + steader text + ); + +CREATE TABLE IF NOT EXISTS profiles ( + joined timestamp, + last_active timestamp, + last_farm timestamp, + id text, + xp numeric + ); + + +CREATE TABLE IF NOT EXISTS hacksteaders ( + user_id text, + profile references profiles(id) + ); + +CREATE TABLE IF NOT EXISTS tiles_steaders ( + steader_id text references hacksteaders(user_id), + tile_id uuid references tiles(id) + ); + +CREATE TABLE IF NOT EXISTS possess_steaders ( + steader_id text references hacksteaders(user_id), + diff --git a/src/lib.rs b/src/lib.rs index a183235..7682a2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,8 @@ pub use category::{Category, CategoryError}; pub use config::CONFIG; pub use possess::{Possessed, Possession}; +use sqlx::postgres::PgConnection; + pub const TABLE_NAME: &'static str = "hackagotchi"; pub type Item = HashMap; @@ -130,7 +132,8 @@ impl Profile { .increase_xp(&mut self.xp, amt) } - pub async fn fetch_all(db: &DynamoDbClient) -> Result, String> { + pub async fn fetch_all(conn: &PgConnection) -> Result, String> { + let result = sqlx::query!("SELECT * FROM hacksteaders").fetch_all(&mut conn).await?; let query = db .query(rusoto_dynamodb::QueryInput { table_name: TABLE_NAME.to_string(), diff --git a/src/models.rs b/src/models.rs index e79299e..8870db5 100644 --- a/src/models.rs +++ b/src/models.rs @@ -15,7 +15,7 @@ pub struct Hacksteader { pub gotchis: Vec>, } -#[derive(Debug, Clone, Serialize, Type)] +#[derive(Debug, Clone, Serialize, FromRow)] pub struct Tile { pub acquired: PrimitiveDateTime, pub plant: Option, @@ -23,7 +23,7 @@ pub struct Tile { pub steader: String, } -#[derive(Clone, Debug, Serialize, Type)] +#[derive(Clone, Debug, Serialize, FromRow)] pub struct Profile { /// Indicates when this Hacksteader first joined the elite community. pub joined: PrimitiveDateTime, @@ -34,7 +34,7 @@ pub struct Profile { pub xp: u32, } -#[derive(Debug, Clone, Serialize, Type)] +#[derive(Debug, Clone, Serialize, FromRow)] pub struct Plant { pub xp: u32, pub until_yield: f32, @@ -43,7 +43,7 @@ pub struct Plant { pub archetype_handle: ArchetypeHandle, } -#[derive(Debug, Clone, Serialize, Type)] +#[derive(Debug, Clone, Serialize, FromRow)] pub struct Craft { pub until_finish: f32, pub total_cycles: f32, diff --git a/src/possess/seed.rs b/src/possess/seed.rs index a498df5..5184bf3 100644 --- a/src/possess/seed.rs +++ b/src/possess/seed.rs @@ -24,7 +24,7 @@ pub struct SeedGrower { pub generations: u32, } impl SeedGrower { - pub fn new(id: String, generations: u64) -> Self { + pub fn new(id: String, generations: u32) -> Self { SeedGrower { id, generations } } @@ -50,34 +50,6 @@ impl SeedGrower { }) } } -impl Into for SeedGrower { - fn into(self) -> AttributeValue { - AttributeValue { - m: Some( - [ - ( - "id".to_string(), - AttributeValue { - s: Some(self.id.clone()), - ..Default::default() - }, - ), - ( - "generations".to_string(), - AttributeValue { - n: Some(self.generations.to_string()), - ..Default::default() - }, - ), - ] - .iter() - .cloned() - .collect(), - ), - ..Default::default() - } - } -} impl std::ops::Deref for Seed { type Target = config::SeedArchetype;