Skip to content

Commit 9318605

Browse files
committed
Add descriptions to categories
Have to switch from a nice batch insert to running a query for each category so that we can use apostrophes in the descriptions and have the string escaped for SQL.
1 parent f7d2780 commit 9318605

File tree

7 files changed

+70
-28
lines changed

7 files changed

+70
-28
lines changed

app/models/category.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import DS from 'ember-data';
33
export default DS.Model.extend({
44
category: DS.attr('string'),
55
slug: DS.attr('string'),
6+
description: DS.attr('string'),
67
created_at: DS.attr('date'),
78
crates_cnt: DS.attr('number'),
89

app/templates/categories.hbs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,19 @@
4242
<div class='white-rows'>
4343
{{#each model as |category|}}
4444
<div class='row'>
45-
<div class='info'>
46-
{{link-to category.category "category" category.slug}}
47-
<span class='vers small'>
48-
{{ format-num category.crates_cnt }}
49-
crates
50-
</span>
45+
<div class='desc'>
46+
<div class='info'>
47+
{{link-to category.category "category" category.slug}}
48+
<span class='small'>
49+
{{ format-num category.crates_cnt }}
50+
crates
51+
</span>
52+
</div>
53+
<div class='summary'>
54+
<span class='small'>
55+
{{ truncate-text category.description }}
56+
</span>
57+
</div>
5158
</div>
5259
</div>
5360
{{/each}}

app/templates/category/index.hbs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@
1111
<div class='white-rows'>
1212
{{#each category.subcategories as |subcategory| }}
1313
<div class='row'>
14-
<div class='info'>
15-
{{link-to subcategory.category "category" subcategory.slug}}
16-
<span class='vers small'>
17-
{{ format-num subcategory.crates_cnt }}
18-
crates
19-
</span>
14+
<div class='desc'>
15+
<div class='info'>
16+
{{link-to subcategory.category "category" subcategory.slug}}
17+
<span class='small'>
18+
{{ format-num subcategory.crates_cnt }}
19+
crates
20+
</span>
21+
</div>
22+
<div class='summary'>
23+
<span class='small'>
24+
{{ truncate-text subcategory.description }}
25+
</span>
26+
</div>
2027
</div>
2128
</div>
2229
{{/each}}

src/bin/migrate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ fn migrations() -> Vec<Migration> {
768768
id SERIAL PRIMARY KEY, \
769769
category VARCHAR NOT NULL UNIQUE, \
770770
slug VARCHAR NOT NULL UNIQUE, \
771+
description VARCHAR NOT NULL DEFAULT '', \
771772
crates_cnt INTEGER NOT NULL DEFAULT 0, \
772773
created_at TIMESTAMP NOT NULL DEFAULT current_timestamp"),
773774
Migration::add_table(20161115111828, "crates_categories", " \

src/categories.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ use util::errors::{CargoResult, ChainError, internal};
99
struct Category {
1010
name: String,
1111
slug: String,
12+
description: String,
1213
}
1314

1415
impl Category {
1516
fn concat(&self, child: &Category) -> Category {
1617
Category {
1718
name: format!("{}::{}", self.name, child.name),
1819
slug: format!("{}::{}", self.slug, child.slug),
20+
description: child.description.clone(),
1921
}
2022
}
2123
}
@@ -35,6 +37,14 @@ fn required_string_from_toml(toml: &toml::Table, key: &str)
3537
})
3638
}
3739

40+
fn optional_string_from_toml(toml: &toml::Table, key: &str)
41+
-> String {
42+
toml.get(key)
43+
.and_then(toml::Value::as_str)
44+
.unwrap_or("")
45+
.to_string()
46+
}
47+
3848
fn category_from_toml(toml: &toml::Value, parent: Option<&Category>)
3949
-> CargoResult<Vec<Category>> {
4050
let toml = toml.as_table().chain_error(|| {
@@ -44,6 +54,7 @@ fn category_from_toml(toml: &toml::Value, parent: Option<&Category>)
4454
let category = Category {
4555
slug: required_string_from_toml(&toml, "slug")?,
4656
name: required_string_from_toml(&toml, "name")?,
57+
description: optional_string_from_toml(&toml, "description"),
4758
};
4859

4960
let category = concat_parent_and_child(parent, category);
@@ -85,25 +96,27 @@ pub fn sync() -> CargoResult<()> {
8596
.expect("Categories from toml failed")
8697
}).collect();
8798

88-
let insert = categories.iter().map(|ref category| {
89-
format!("(LOWER('{}'), '{}')", category.slug, category.name)
90-
}).collect::<Vec<_>>().join(",");
99+
for category in categories.iter() {
100+
tx.execute("\
101+
INSERT INTO categories (slug, category, description) \
102+
VALUES (LOWER($1), $2, $3) \
103+
ON CONFLICT (slug) DO UPDATE \
104+
SET category = EXCLUDED.category, \
105+
description = EXCLUDED.description;",
106+
&[&category.slug, &category.name, &category.description]
107+
)?;
108+
}
91109

92110
let in_clause = categories.iter().map(|ref category| {
93111
format!("LOWER('{}')", category.slug)
94112
}).collect::<Vec<_>>().join(",");
95113

96-
try!(tx.batch_execute(
97-
&format!(" \
98-
INSERT INTO categories (slug, category) \
99-
VALUES {} \
100-
ON CONFLICT (slug) DO UPDATE SET category = EXCLUDED.category; \
101-
DELETE FROM categories \
102-
WHERE slug NOT IN ({});",
103-
insert,
104-
in_clause
105-
)[..]
106-
));
114+
tx.execute(&format!("\
115+
DELETE FROM categories \
116+
WHERE slug NOT IN ({});",
117+
in_clause),
118+
&[]
119+
)?;
107120
tx.set_commit();
108121
tx.finish().unwrap();
109122
Ok(())

src/categories.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
[[categories]]
22
slug = "development-tools"
33
name = "Development Tools"
4+
description = "Ways to make developing in Rust better"
45

56
[[categories.categories]]
67
slug = "testing"
78
name = "Testing"
9+
description = "Additions to automated testing features"
810

911
[[categories.categories.categories]]
1012
slug = "mocking"
@@ -17,11 +19,14 @@ name = "Libraries"
1719
[[categories.categories]]
1820
slug = "async"
1921
name = "Async"
22+
description = "Code that can take time to run but won't block"
2023

2124
[[categories.categories]]
2225
slug = "date-and-time"
2326
name = "Date and Time"
27+
description = "Date and time math"
2428

2529
[[categories]]
2630
slug = "games"
2731
name = "Games"
32+
description = "Share fun things"

src/category.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub struct Category {
1616
pub id: i32,
1717
pub category: String,
1818
pub slug: String,
19+
pub description: String,
1920
pub created_at: Timespec,
2021
pub crates_cnt: i32,
2122
}
@@ -25,6 +26,7 @@ pub struct EncodableCategory {
2526
pub id: String,
2627
pub category: String,
2728
pub slug: String,
29+
pub description: String,
2830
pub created_at: String,
2931
pub crates_cnt: i32,
3032
}
@@ -34,6 +36,7 @@ pub struct EncodableCategoryWithSubcategories {
3436
pub id: String,
3537
pub category: String,
3638
pub slug: String,
39+
pub description: String,
3740
pub created_at: String,
3841
pub crates_cnt: i32,
3942
pub subcategories: Vec<EncodableCategory>,
@@ -61,10 +64,13 @@ impl Category {
6164
}
6265

6366
pub fn encodable(self) -> EncodableCategory {
64-
let Category { id: _, crates_cnt, category, slug, created_at } = self;
67+
let Category {
68+
id: _, crates_cnt, category, slug, description, created_at
69+
} = self;
6570
EncodableCategory {
6671
id: slug.clone(),
6772
slug: slug.clone(),
73+
description: description.clone(),
6874
created_at: ::encode_time(created_at),
6975
crates_cnt: crates_cnt,
7076
category: category,
@@ -155,6 +161,7 @@ impl Model for Category {
155161
crates_cnt: row.get("crates_cnt"),
156162
category: row.get("category"),
157163
slug: row.get("slug"),
164+
description: row.get("description"),
158165
}
159166
}
160167
fn table_name(_: Option<Category>) -> &'static str { "categories" }
@@ -174,7 +181,7 @@ pub fn index(req: &mut Request) -> CargoResult<Response> {
174181
// Collect all the top-level categories and sum up the crates_cnt of
175182
// the crates in all subcategories
176183
let stmt = try!(conn.prepare(&format!(
177-
"SELECT c.id, c.category, c.slug, c.created_at, \
184+
"SELECT c.id, c.category, c.slug, c.description, c.created_at, \
178185
counts.sum::int as crates_cnt \
179186
FROM categories as c \
180187
LEFT JOIN ( \
@@ -224,6 +231,7 @@ pub fn show(req: &mut Request) -> CargoResult<Response> {
224231
id: cat.id,
225232
category: cat.category,
226233
slug: cat.slug,
234+
description: cat.description,
227235
created_at: cat.created_at,
228236
crates_cnt: cat.crates_cnt,
229237
subcategories: subcats,

0 commit comments

Comments
 (0)