123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- //! Db executor actor
- use actix::prelude::*;
- use diesel;
- use diesel::prelude::*;
- use diesel::result::Error;
- use rand::{thread_rng, Rng, ThreadRng};
- use std::io;
- use models;
- pub struct DbExecutor {
- conn: PgConnection,
- rng: ThreadRng,
- }
- unsafe impl Send for DbExecutor {}
- impl Actor for DbExecutor {
- type Context = SyncContext<Self>;
- }
- impl DbExecutor {
- pub fn new(db_url: &str) -> DbExecutor {
- DbExecutor {
- conn: PgConnection::establish(db_url)
- .expect(&format!("Error connecting to {}", db_url)),
- rng: thread_rng(),
- }
- }
- }
- pub struct RandomWorld;
- impl Message for RandomWorld {
- type Result = io::Result<models::World>;
- }
- impl Handler<RandomWorld> for DbExecutor {
- type Result = io::Result<models::World>;
- fn handle(&mut self, _: RandomWorld, _: &mut Self::Context) -> Self::Result {
- use schema::world::dsl::*;
- let random_id = self.rng.gen_range(1, 10_001);
- match world
- .filter(id.eq(random_id))
- .load::<models::World>(&self.conn)
- {
- Ok(mut items) => Ok(items.pop().unwrap()),
- Err(_) => Err(io::Error::new(io::ErrorKind::Other, "Database error")),
- }
- }
- }
- pub struct RandomWorlds(pub u16);
- impl Message for RandomWorlds {
- type Result = io::Result<Vec<models::World>>;
- }
- impl Handler<RandomWorlds> for DbExecutor {
- type Result = io::Result<Vec<models::World>>;
- fn handle(&mut self, msg: RandomWorlds, _: &mut Self::Context) -> Self::Result {
- use schema::world::dsl::*;
- let mut worlds = Vec::with_capacity(msg.0 as usize);
- for _ in 0..msg.0 {
- let w_id = self.rng.gen_range(1, 10_001);
- let w = match world.filter(id.eq(w_id)).load::<models::World>(&self.conn) {
- Ok(mut items) => items.pop().unwrap(),
- Err(_) => {
- return Err(io::Error::new(io::ErrorKind::Other, "Database error"))
- }
- };
- worlds.push(w)
- }
- Ok(worlds)
- }
- }
- pub struct UpdateWorld(pub usize);
- impl Message for UpdateWorld {
- type Result = io::Result<Vec<models::World>>;
- }
- impl Handler<UpdateWorld> for DbExecutor {
- type Result = io::Result<Vec<models::World>>;
- fn handle(&mut self, msg: UpdateWorld, _: &mut Self::Context) -> Self::Result {
- use schema::world::dsl::*;
- let mut worlds = Vec::with_capacity(msg.0);
- for _ in 0..msg.0 {
- let w_id = self.rng.gen_range::<i32>(1, 10_001);
- let mut w = match world.filter(id.eq(w_id)).load::<models::World>(&self.conn)
- {
- Ok(mut items) => items.pop().unwrap(),
- Err(_) => {
- return Err(io::Error::new(io::ErrorKind::Other, "Database error"))
- }
- };
- w.randomnumber = self.rng.gen_range(1, 10_001);
- worlds.push(w);
- }
- worlds.sort_by_key(|w| w.id);
- let _ = self.conn.transaction::<(), Error, _>(|| {
- for w in &worlds {
- let _ = diesel::update(world)
- .filter(id.eq(w.id))
- .set(randomnumber.eq(w.randomnumber))
- .execute(&self.conn);
- }
- Ok(())
- });
- Ok(worlds)
- }
- }
- pub struct TellFortune;
- impl Message for TellFortune {
- type Result = io::Result<Vec<models::Fortune>>;
- }
- impl Handler<TellFortune> for DbExecutor {
- type Result = io::Result<Vec<models::Fortune>>;
- fn handle(&mut self, _: TellFortune, _: &mut Self::Context) -> Self::Result {
- use schema::fortune::dsl::*;
- match fortune.load::<models::Fortune>(&self.conn) {
- Ok(mut items) => {
- items.push(models::Fortune {
- id: 0,
- message: "Additional fortune added at request time.".to_string(),
- });
- items.sort_by(|it, next| it.message.cmp(&next.message));
- Ok(items)
- }
- Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
- }
- }
- }
|