Count items in database as much as possible (#344)
* Count items in database as much as possible * Fix the tests * Remove two useless queries * Run pragma directive before each sqlite connection * Pragma for tests too * Remove debug messages
This commit is contained in:
@@ -83,6 +83,15 @@ impl Blog {
|
||||
.expect("Blog::list_authors: author loading error")
|
||||
}
|
||||
|
||||
pub fn count_authors(&self, conn: &Connection) -> i64 {
|
||||
use schema::blog_authors;
|
||||
blog_authors::table
|
||||
.filter(blog_authors::blog_id.eq(self.id))
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Blog::count_authors: count loading error")
|
||||
}
|
||||
|
||||
pub fn find_for_author(conn: &Connection, author: &User) -> Vec<Blog> {
|
||||
use schema::blog_authors;
|
||||
let author_ids = blog_authors::table
|
||||
|
||||
@@ -56,16 +56,16 @@ impl Comment {
|
||||
Post::get(conn, self.post_id).expect("Comment::get_post: post error")
|
||||
}
|
||||
|
||||
pub fn count_local(conn: &Connection) -> usize {
|
||||
pub fn count_local(conn: &Connection) -> i64 {
|
||||
use schema::users;
|
||||
let local_authors = users::table
|
||||
.filter(users::instance_id.eq(Instance::local_id(conn)))
|
||||
.select(users::id);
|
||||
comments::table
|
||||
.filter(comments::author_id.eq_any(local_authors))
|
||||
.load::<Comment>(conn)
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Comment::count_local: loading error")
|
||||
.len() // TODO count in database?
|
||||
}
|
||||
|
||||
pub fn get_responses(&self, conn: &Connection) -> Vec<Comment> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use diesel::r2d2::{ConnectionManager, Pool, PooledConnection};
|
||||
use diesel::{dsl::sql_query, r2d2::{ConnectionManager, CustomizeConnection, Error as ConnError, Pool, PooledConnection}, ConnectionError, RunQueryDsl};
|
||||
use rocket::{
|
||||
http::Status,
|
||||
request::{self, FromRequest},
|
||||
@@ -38,3 +38,15 @@ impl Deref for DbConn {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
// Execute a pragma for every new sqlite connection
|
||||
#[derive(Debug)]
|
||||
pub struct PragmaForeignKey;
|
||||
impl CustomizeConnection<Connection, ConnError> for PragmaForeignKey {
|
||||
#[cfg(feature = "sqlite")] // will default to an empty function for postgres
|
||||
fn on_acquire(&self, conn: &mut Connection) -> Result<(), ConnError> {
|
||||
sql_query("PRAGMA foreign_keys = on;").execute(conn)
|
||||
.map(|_| ())
|
||||
.map_err(|_| ConnError::ConnectionError(ConnectionError::BadConnection(String::from("PRAGMA foreign_keys = on failed"))))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ pub fn ap_url(url: &str) -> String {
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
mod tests {
|
||||
use diesel::Connection;
|
||||
use diesel::{dsl::sql_query, Connection, RunQueryDsl};
|
||||
use Connection as Conn;
|
||||
use DATABASE_URL;
|
||||
|
||||
@@ -238,6 +238,8 @@ mod tests {
|
||||
let conn =
|
||||
Conn::establish(&*DATABASE_URL.as_str()).expect("Couldn't connect to the database");
|
||||
embedded_migrations::run(&conn).expect("Couldn't run migrations");
|
||||
#[cfg(feature = "sqlite")]
|
||||
sql_query("PRAGMA foreign_keys = on;").execute(&conn).expect("PRAGMA foreign_keys fail");
|
||||
conn
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,14 @@ impl Notification {
|
||||
.expect("Notification::find_for_user: notification loading error")
|
||||
}
|
||||
|
||||
pub fn count_for_user(conn: &Connection, user: &User) -> i64 {
|
||||
notifications::table
|
||||
.filter(notifications::user_id.eq(user.id))
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Notification::count_for_user: count loading error")
|
||||
}
|
||||
|
||||
pub fn page_for_user(
|
||||
conn: &Connection,
|
||||
user: &User,
|
||||
|
||||
@@ -12,7 +12,6 @@ use serde_json;
|
||||
|
||||
use blogs::Blog;
|
||||
use instance::Instance;
|
||||
use likes::Like;
|
||||
use medias::Media;
|
||||
use mentions::Mention;
|
||||
use plume_api::posts::PostEndpoint;
|
||||
@@ -24,7 +23,6 @@ use plume_common::{
|
||||
utils::md_to_html,
|
||||
};
|
||||
use post_authors::*;
|
||||
use reshares::Reshare;
|
||||
use safe_string::SafeString;
|
||||
use search::Searcher;
|
||||
use schema::posts;
|
||||
@@ -206,7 +204,7 @@ impl Post {
|
||||
.expect("Post::count_for_tag: no result error")
|
||||
}
|
||||
|
||||
pub fn count_local(conn: &Connection) -> usize {
|
||||
pub fn count_local(conn: &Connection) -> i64 {
|
||||
use schema::post_authors;
|
||||
use schema::users;
|
||||
let local_authors = users::table
|
||||
@@ -218,9 +216,9 @@ impl Post {
|
||||
posts::table
|
||||
.filter(posts::id.eq_any(local_posts_id))
|
||||
.filter(posts::published.eq(true))
|
||||
.load::<Post>(conn)
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Post::count_local: loading error")
|
||||
.len() // TODO count in database?
|
||||
}
|
||||
|
||||
pub fn count(conn: &Connection) -> i64 {
|
||||
@@ -271,6 +269,15 @@ impl Post {
|
||||
.expect("Post::get_for_blog:: loading error")
|
||||
}
|
||||
|
||||
pub fn count_for_blog(conn: &Connection, blog: &Blog) -> i64 {
|
||||
posts::table
|
||||
.filter(posts::blog_id.eq(blog.id))
|
||||
.filter(posts::published.eq(true))
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Post::count_for_blog:: count error")
|
||||
}
|
||||
|
||||
pub fn blog_page(conn: &Connection, blog: &Blog, (min, max): (i32, i32)) -> Vec<Post> {
|
||||
posts::table
|
||||
.filter(posts::blog_id.eq(blog.id))
|
||||
@@ -379,19 +386,21 @@ impl Post {
|
||||
.expect("Post::get_blog: no result error")
|
||||
}
|
||||
|
||||
pub fn get_likes(&self, conn: &Connection) -> Vec<Like> {
|
||||
pub fn count_likes(&self, conn: &Connection) -> i64 {
|
||||
use schema::likes;
|
||||
likes::table
|
||||
.filter(likes::post_id.eq(self.id))
|
||||
.load::<Like>(conn)
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Post::get_likes: loading error")
|
||||
}
|
||||
|
||||
pub fn get_reshares(&self, conn: &Connection) -> Vec<Reshare> {
|
||||
pub fn count_reshares(&self, conn: &Connection) -> i64 {
|
||||
use schema::reshares;
|
||||
reshares::table
|
||||
.filter(reshares::post_id.eq(self.id))
|
||||
.load::<Reshare>(conn)
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("Post::get_reshares: loading error")
|
||||
}
|
||||
|
||||
|
||||
+35
-28
@@ -30,16 +30,13 @@ use std::cmp::PartialEq;
|
||||
use url::Url;
|
||||
use webfinger::*;
|
||||
|
||||
use blog_authors::BlogAuthor;
|
||||
use blogs::Blog;
|
||||
use db_conn::DbConn;
|
||||
use follows::Follow;
|
||||
use instance::*;
|
||||
use likes::Like;
|
||||
use medias::Media;
|
||||
use post_authors::PostAuthor;
|
||||
use posts::Post;
|
||||
use reshares::Reshare;
|
||||
use safe_string::SafeString;
|
||||
use schema::users;
|
||||
use search::Searcher;
|
||||
@@ -111,7 +108,7 @@ impl User {
|
||||
|
||||
Blog::find_for_author(conn, self)
|
||||
.iter()
|
||||
.filter(|b| b.list_authors(conn).len() <= 1)
|
||||
.filter(|b| b.count_authors(conn) <= 1)
|
||||
.for_each(|b| b.delete(conn, searcher));
|
||||
// delete the posts if they is the only author
|
||||
let all_their_posts_ids: Vec<i32> = post_authors::table
|
||||
@@ -170,12 +167,12 @@ impl User {
|
||||
User::get(conn, self.id).expect("User::update: get error")
|
||||
}
|
||||
|
||||
pub fn count_local(conn: &Connection) -> usize {
|
||||
pub fn count_local(conn: &Connection) -> i64 {
|
||||
users::table
|
||||
.filter(users::instance_id.eq(Instance::local_id(conn)))
|
||||
.load::<User>(conn)
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("User::count_local: loading error")
|
||||
.len() // TODO count in database?
|
||||
}
|
||||
|
||||
pub fn find_local(conn: &Connection, username: &str) -> Option<User> {
|
||||
@@ -641,6 +638,16 @@ impl User {
|
||||
.expect("User::get_followers: loading error")
|
||||
}
|
||||
|
||||
pub fn count_followers(&self, conn: &Connection) -> i64 {
|
||||
use schema::follows;
|
||||
let follows = Follow::belonging_to(self).select(follows::follower_id);
|
||||
users::table
|
||||
.filter(users::id.eq_any(follows))
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.expect("User::count_followers: counting error")
|
||||
}
|
||||
|
||||
pub fn get_followers_page(&self, conn: &Connection, (min, max): (i32, i32)) -> Vec<User> {
|
||||
use schema::follows;
|
||||
let follows = Follow::belonging_to(self).select(follows::follower_id);
|
||||
@@ -663,52 +670,52 @@ impl User {
|
||||
|
||||
pub fn is_followed_by(&self, conn: &Connection, other_id: i32) -> bool {
|
||||
use schema::follows;
|
||||
!follows::table
|
||||
follows::table
|
||||
.filter(follows::follower_id.eq(other_id))
|
||||
.filter(follows::following_id.eq(self.id))
|
||||
.load::<Follow>(conn)
|
||||
.expect("User::is_followed_by: loading error")
|
||||
.is_empty() // TODO count in database?
|
||||
.count()
|
||||
.get_result::<i64>(conn)
|
||||
.expect("User::is_followed_by: loading error") > 0
|
||||
}
|
||||
|
||||
pub fn is_following(&self, conn: &Connection, other_id: i32) -> bool {
|
||||
use schema::follows;
|
||||
!follows::table
|
||||
follows::table
|
||||
.filter(follows::follower_id.eq(self.id))
|
||||
.filter(follows::following_id.eq(other_id))
|
||||
.load::<Follow>(conn)
|
||||
.expect("User::is_following: loading error")
|
||||
.is_empty() // TODO count in database?
|
||||
.count()
|
||||
.get_result::<i64>(conn)
|
||||
.expect("User::is_following: loading error") > 0
|
||||
}
|
||||
|
||||
pub fn has_liked(&self, conn: &Connection, post: &Post) -> bool {
|
||||
use schema::likes;
|
||||
!likes::table
|
||||
likes::table
|
||||
.filter(likes::post_id.eq(post.id))
|
||||
.filter(likes::user_id.eq(self.id))
|
||||
.load::<Like>(conn)
|
||||
.expect("User::has_liked: loading error")
|
||||
.is_empty() // TODO count in database?
|
||||
.count()
|
||||
.get_result::<i64>(conn)
|
||||
.expect("User::has_liked: loading error") > 0
|
||||
}
|
||||
|
||||
pub fn has_reshared(&self, conn: &Connection, post: &Post) -> bool {
|
||||
use schema::reshares;
|
||||
!reshares::table
|
||||
reshares::table
|
||||
.filter(reshares::post_id.eq(post.id))
|
||||
.filter(reshares::user_id.eq(self.id))
|
||||
.load::<Reshare>(conn)
|
||||
.expect("User::has_reshared: loading error")
|
||||
.is_empty() // TODO count in database?
|
||||
.count()
|
||||
.get_result::<i64>(conn)
|
||||
.expect("User::has_reshared: loading error") > 0
|
||||
}
|
||||
|
||||
pub fn is_author_in(&self, conn: &Connection, blog: &Blog) -> bool {
|
||||
use schema::blog_authors;
|
||||
!blog_authors::table
|
||||
blog_authors::table
|
||||
.filter(blog_authors::author_id.eq(self.id))
|
||||
.filter(blog_authors::blog_id.eq(blog.id))
|
||||
.load::<BlogAuthor>(conn)
|
||||
.expect("User::is_author_in: loading error")
|
||||
.is_empty() // TODO count in database?
|
||||
.count()
|
||||
.get_result::<i64>(conn)
|
||||
.expect("User::is_author_in: loading error") > 0
|
||||
}
|
||||
|
||||
pub fn get_keypair(&self) -> PKey<Private> {
|
||||
@@ -1173,7 +1180,7 @@ pub(crate) mod tests {
|
||||
last_username = page[0].username.clone();
|
||||
}
|
||||
assert_eq!(
|
||||
User::get_local_page(conn, (0, User::count_local(conn) as i32 + 10)).len(),
|
||||
User::get_local_page(conn, (0, User::count_local(conn) as i32 + 10)).len() as i64,
|
||||
User::count_local(conn)
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user