db.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //! Db executor actor
  2. use actix::prelude::*;
  3. use diesel;
  4. use diesel::prelude::*;
  5. use diesel::result::Error;
  6. use rand::{thread_rng, Rng, ThreadRng};
  7. use std::io;
  8. use models;
  9. pub struct DbExecutor {
  10. conn: PgConnection,
  11. rng: ThreadRng,
  12. }
  13. unsafe impl Send for DbExecutor {}
  14. impl Actor for DbExecutor {
  15. type Context = SyncContext<Self>;
  16. }
  17. impl DbExecutor {
  18. pub fn new(db_url: &str) -> DbExecutor {
  19. DbExecutor {
  20. conn: PgConnection::establish(db_url)
  21. .expect(&format!("Error connecting to {}", db_url)),
  22. rng: thread_rng(),
  23. }
  24. }
  25. }
  26. pub struct RandomWorld;
  27. impl Message for RandomWorld {
  28. type Result = io::Result<models::World>;
  29. }
  30. impl Handler<RandomWorld> for DbExecutor {
  31. type Result = io::Result<models::World>;
  32. fn handle(&mut self, _: RandomWorld, _: &mut Self::Context) -> Self::Result {
  33. use schema::world::dsl::*;
  34. let random_id = self.rng.gen_range(1, 10_001);
  35. match world
  36. .filter(id.eq(random_id))
  37. .load::<models::World>(&self.conn)
  38. {
  39. Ok(mut items) => Ok(items.pop().unwrap()),
  40. Err(_) => Err(io::Error::new(io::ErrorKind::Other, "Database error")),
  41. }
  42. }
  43. }
  44. pub struct RandomWorlds(pub u16);
  45. impl Message for RandomWorlds {
  46. type Result = io::Result<Vec<models::World>>;
  47. }
  48. impl Handler<RandomWorlds> for DbExecutor {
  49. type Result = io::Result<Vec<models::World>>;
  50. fn handle(&mut self, msg: RandomWorlds, _: &mut Self::Context) -> Self::Result {
  51. use schema::world::dsl::*;
  52. let mut worlds = Vec::with_capacity(msg.0 as usize);
  53. for _ in 0..msg.0 {
  54. let w_id = self.rng.gen_range(1, 10_001);
  55. let w = match world.filter(id.eq(w_id)).load::<models::World>(&self.conn) {
  56. Ok(mut items) => items.pop().unwrap(),
  57. Err(_) => {
  58. return Err(io::Error::new(io::ErrorKind::Other, "Database error"))
  59. }
  60. };
  61. worlds.push(w)
  62. }
  63. Ok(worlds)
  64. }
  65. }
  66. pub struct UpdateWorld(pub usize);
  67. impl Message for UpdateWorld {
  68. type Result = io::Result<Vec<models::World>>;
  69. }
  70. impl Handler<UpdateWorld> for DbExecutor {
  71. type Result = io::Result<Vec<models::World>>;
  72. fn handle(&mut self, msg: UpdateWorld, _: &mut Self::Context) -> Self::Result {
  73. use schema::world::dsl::*;
  74. let mut worlds = Vec::with_capacity(msg.0);
  75. for _ in 0..msg.0 {
  76. let w_id = self.rng.gen_range::<i32>(1, 10_001);
  77. let mut w = match world.filter(id.eq(w_id)).load::<models::World>(&self.conn)
  78. {
  79. Ok(mut items) => items.pop().unwrap(),
  80. Err(_) => {
  81. return Err(io::Error::new(io::ErrorKind::Other, "Database error"))
  82. }
  83. };
  84. w.randomnumber = self.rng.gen_range(1, 10_001);
  85. worlds.push(w);
  86. }
  87. worlds.sort_by_key(|w| w.id);
  88. let _ = self.conn.transaction::<(), Error, _>(|| {
  89. for w in &worlds {
  90. let _ = diesel::update(world)
  91. .filter(id.eq(w.id))
  92. .set(randomnumber.eq(w.randomnumber))
  93. .execute(&self.conn);
  94. }
  95. Ok(())
  96. });
  97. Ok(worlds)
  98. }
  99. }
  100. pub struct TellFortune;
  101. impl Message for TellFortune {
  102. type Result = io::Result<Vec<models::Fortune>>;
  103. }
  104. impl Handler<TellFortune> for DbExecutor {
  105. type Result = io::Result<Vec<models::Fortune>>;
  106. fn handle(&mut self, _: TellFortune, _: &mut Self::Context) -> Self::Result {
  107. use schema::fortune::dsl::*;
  108. match fortune.load::<models::Fortune>(&self.conn) {
  109. Ok(mut items) => {
  110. items.push(models::Fortune {
  111. id: 0,
  112. message: "Additional fortune added at request time.".to_string(),
  113. });
  114. items.sort_by(|it, next| it.message.cmp(&next.message));
  115. Ok(items)
  116. }
  117. Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
  118. }
  119. }
  120. }