Skip to content

Split keyword and category functionality into MVC units #1247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 1, 2018
Merged
6 changes: 3 additions & 3 deletions src/badge.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use krate::Crate;
use schema::badges;

use diesel::pg::Pg;
use diesel::prelude::*;
use serde_json;
use std::collections::HashMap;

use models::Crate;
use schema::badges;

#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case", tag = "badge_type", content = "attributes")]
pub enum Badge {
Expand Down
2 changes: 1 addition & 1 deletion src/bin/delete-crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::env;
use std::io;
use std::io::prelude::*;

use cargo_registry::Crate;
use cargo_registry::models::Crate;
use cargo_registry::schema::crates;

#[allow(dead_code)]
Expand Down
2 changes: 1 addition & 1 deletion src/bin/delete-version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::env;
use std::io;
use std::io::prelude::*;

use cargo_registry::{Crate, Version};
use cargo_registry::models::{Crate, Version};
use cargo_registry::schema::versions;

#[allow(dead_code)]
Expand Down
6 changes: 4 additions & 2 deletions src/bin/render-readmes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ use std::thread;
use tar::Archive;
use url::Url;

use cargo_registry::{Config, Version};
use cargo_registry::schema::*;
use cargo_registry::Config;
use cargo_registry::render::readme_to_html;

use cargo_registry::models::Version;
use cargo_registry::schema::*;

const DEFAULT_PAGE_SIZE: usize = 25;
const USAGE: &str = "
Usage: render-readmes [options]
Expand Down
3 changes: 1 addition & 2 deletions src/bin/transfer-crates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ use std::env;
use std::io;
use std::io::prelude::*;

use cargo_registry::{Crate, User};
use cargo_registry::owner::OwnerKind;
use cargo_registry::models::{Crate, OwnerKind, User};
use cargo_registry::schema::*;

fn main() {
Expand Down
6 changes: 2 additions & 4 deletions src/bin/update-downloads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use diesel::prelude::*;
use std::env;
use std::time::Duration;

use cargo_registry::VersionDownload;
use cargo_registry::models::VersionDownload;
use cargo_registry::schema::*;

static LIMIT: i64 = 1000;
Expand Down Expand Up @@ -118,9 +118,7 @@ mod test {
use diesel::insert_into;
use super::*;
use cargo_registry::env;
use cargo_registry::krate::{Crate, NewCrate};
use cargo_registry::user::{NewUser, User};
use cargo_registry::version::{NewVersion, Version};
use cargo_registry::models::{Crate, NewCrate, NewUser, NewVersion, User, Version};

fn conn() -> PgConnection {
let conn = PgConnection::establish(&env("TEST_DATABASE_URL")).unwrap();
Expand Down
89 changes: 89 additions & 0 deletions src/controllers/category.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use super::prelude::*;

use models::Category;
use schema::categories;
use views::{EncodableCategory, EncodableCategoryWithSubcategories};

/// Handles the `GET /categories` route.
pub fn index(req: &mut Request) -> CargoResult<Response> {
let conn = req.db_conn()?;
let (offset, limit) = req.pagination(10, 100)?;
let query = req.query();
let sort = query.get("sort").map_or("alpha", String::as_str);

let categories = Category::toplevel(&conn, sort, limit, offset)?;
let categories = categories.into_iter().map(Category::encodable).collect();

// Query for the total count of categories
let total = Category::count_toplevel(&conn)?;

#[derive(Serialize)]
struct R {
categories: Vec<EncodableCategory>,
meta: Meta,
}
#[derive(Serialize)]
struct Meta {
total: i64,
}

Ok(req.json(&R {
categories: categories,
meta: Meta { total: total },
}))
}

/// Handles the `GET /categories/:category_id` route.
pub fn show(req: &mut Request) -> CargoResult<Response> {
let slug = &req.params()["category_id"];
let conn = req.db_conn()?;
let cat = categories::table
.filter(categories::slug.eq(::lower(slug)))
.first::<Category>(&*conn)?;
let subcats = cat.subcategories(&conn)?
.into_iter()
.map(Category::encodable)
.collect();

let cat = cat.encodable();
let cat_with_subcats = EncodableCategoryWithSubcategories {
id: cat.id,
category: cat.category,
slug: cat.slug,
description: cat.description,
created_at: cat.created_at,
crates_cnt: cat.crates_cnt,
subcategories: subcats,
};

#[derive(Serialize)]
struct R {
category: EncodableCategoryWithSubcategories,
}
Ok(req.json(&R {
category: cat_with_subcats,
}))
}

/// Handles the `GET /category_slugs` route.
pub fn slugs(req: &mut Request) -> CargoResult<Response> {
let conn = req.db_conn()?;
let slugs = categories::table
.select((categories::slug, categories::slug))
.order(categories::slug)
.load(&*conn)?;

#[derive(Serialize, Queryable)]
struct Slug {
id: String,
slug: String,
}

#[derive(Serialize)]
struct R {
category_slugs: Vec<Slug>,
}
Ok(req.json(&R {
category_slugs: slugs,
}))
}
3 changes: 3 additions & 0 deletions src/controllers/helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod pagination;

pub use self::pagination::Paginate;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use diesel::query_builder::*;
use diesel::sql_types::BigInt;
use diesel::pg::Pg;

#[derive(Debug)]
pub struct Paginated<T> {
query: T,
limit: i64,
Expand Down
62 changes: 62 additions & 0 deletions src/controllers/keyword.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use super::prelude::*;

use controllers::helpers::Paginate;
use models::Keyword;
use views::EncodableKeyword;

/// Handles the `GET /keywords` route.
pub fn index(req: &mut Request) -> CargoResult<Response> {
use schema::keywords;

let conn = req.db_conn()?;
let (offset, limit) = req.pagination(10, 100)?;
let query = req.query();
let sort = query.get("sort").map(|s| &s[..]).unwrap_or("alpha");

let mut query = keywords::table.into_boxed();

if sort == "crates" {
query = query.order(keywords::crates_cnt.desc());
} else {
query = query.order(keywords::keyword.asc());
}

let data = query
.paginate(limit, offset)
.load::<(Keyword, i64)>(&*conn)?;
let total = data.get(0).map(|&(_, t)| t).unwrap_or(0);
let kws = data.into_iter()
.map(|(k, _)| k.encodable())
.collect::<Vec<_>>();

#[derive(Serialize)]
struct R {
keywords: Vec<EncodableKeyword>,
meta: Meta,
}
#[derive(Serialize)]
struct Meta {
total: i64,
}

Ok(req.json(&R {
keywords: kws,
meta: Meta { total: total },
}))
}

/// Handles the `GET /keywords/:keyword_id` route.
pub fn show(req: &mut Request) -> CargoResult<Response> {
let name = &req.params()["keyword_id"];
let conn = req.db_conn()?;

let kw = Keyword::find_by_keyword(&conn, name)?;

#[derive(Serialize)]
struct R {
keyword: EncodableKeyword,
}
Ok(req.json(&R {
keyword: kw.encodable(),
}))
}
15 changes: 15 additions & 0 deletions src/controllers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// TODO: Finish moving api endpoints to submodules here

mod prelude {
pub use diesel::prelude::*;

pub use conduit::{Request, Response};
pub use conduit_router::RequestParams;
pub use db::RequestTransaction;
pub use util::{CargoResult, RequestUtils};
}

pub mod helpers;

pub mod category;
pub mod keyword;
5 changes: 3 additions & 2 deletions src/crate_owner_invitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use diesel::prelude::*;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, crate_owners, crates, users};
use user::RequestUser;
use util::errors::{human, CargoResult};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

use models::{CrateOwner, OwnerKind};
use schema::{crate_owner_invitations, crate_owners, crates, users};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
Expand Down
8 changes: 4 additions & 4 deletions src/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use diesel::row::NamedRow;
use semver;

use git;
use krate::Crate;
use schema::*;
use util::{human, CargoResult};
use version::Version;

use models::{Crate, Version};
use schema::*;

#[derive(Identifiable, Associations, Debug)]
#[belongs_to(Version)]
Expand Down Expand Up @@ -86,7 +86,7 @@ impl ReverseDependency {

pub fn add_dependencies(
conn: &PgConnection,
deps: &[::upload::CrateDependency],
deps: &[::views::EncodableCrateDependency],
target_version_id: i32,
) -> CargoResult<Vec<git::Dependency>> {
use diesel::insert_into;
Expand Down
2 changes: 1 addition & 1 deletion src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use chrono::NaiveDate;
use diesel;
use diesel::prelude::*;

use models::Version;
use schema::version_downloads;
use version::Version;

#[derive(Queryable, Identifiable, Associations, Debug, Clone, Copy)]
#[belongs_to(Version)]
Expand Down
3 changes: 2 additions & 1 deletion src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use git2;
use serde_json;

use app::App;
use dependency::Kind;
use util::{internal, CargoResult};

use models::Kind;

#[derive(Serialize, Deserialize, Debug)]
pub struct Crate {
pub name: String,
Expand Down
9 changes: 5 additions & 4 deletions src/krate/downloads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ use conduit_router::RequestParams;
use diesel::prelude::*;

use db::RequestTransaction;
use download::{EncodableVersionDownload, VersionDownload};
use schema::*;
use util::{CargoResult, RequestUtils};
use Version;

use super::{to_char, Crate};
use views::EncodableVersionDownload;
use models::{Crate, Version, VersionDownload};
use schema::*;

use super::to_char;

/// Handles the `GET /crates/:crate_id/downloads` route.
pub fn downloads(req: &mut Request) -> CargoResult<Response> {
Expand Down
4 changes: 2 additions & 2 deletions src/krate/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use diesel::prelude::*;
use diesel;

use db::RequestTransaction;
use schema::*;
use user::RequestUser;
use util::{CargoResult, RequestUtils};

use super::{Crate, Follow};
use models::{Crate, Follow};
use schema::*;

fn follow_target(req: &mut Request) -> CargoResult<Follow> {
let user = req.user()?;
Expand Down
13 changes: 6 additions & 7 deletions src/krate/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ use conduit_router::RequestParams;
use diesel::prelude::*;

use app::RequestApp;
use category::{CrateCategory, EncodableCategory};
use db::RequestTransaction;
use dependency::EncodableDependency;
use keyword::{CrateKeyword, EncodableKeyword};
use schema::*;
use util::{human, CargoResult, RequestUtils};
use version::EncodableVersion;
use {Category, Keyword, Version};

use super::{Crate, CrateDownload, EncodableCrate, ALL_COLUMNS};
use views::{EncodableCategory, EncodableCrate, EncodableDependency, EncodableKeyword,
EncodableVersion};
use models::{Category, Crate, CrateCategory, CrateDownload, CrateKeyword, Keyword, Version};
use schema::*;

use super::ALL_COLUMNS;

/// Handles the `GET /summary` route.
pub fn summary(req: &mut Request) -> CargoResult<Response> {
Expand Down
Loading