Skip to content

Commit 565158c

Browse files
Merge #1213
1213: Minor cleanup on dependency insertion and loading r=jtgeibel I'm going through some random code as I'm looking to point to this repo more in Diesel's guides for some actual examples. My goal was actually to do the following: - `#[derive(Insertable)]` on `upload::CrateDependency` and use that directly - `#[derive(Queryable)]` on `git::Dependency` and construct it from a returning clause However, doing the first piece would require skipping the `crate_name` field or pulling it out of that struct, and the second piece requires some way to tell Diesel that a subselect returns a single row (which is not hard to do, but is not code that should live in this repo) Either way, while I was experimenting I did a bit of cleanup here which I think is worthwhile on its own. - Removed an `Insertable` struct in favor of tuple inserts, since `Insertable` is really only mean to be used when your input comes from another source (like `Deserialize`). - Made some defaults explicit in the tests. It felt sketchy having the default impl that was only used in tests. I thought about pushing these defaults into the database, but that felt sketchy for the same reason - Removed a potential panic - Removed a few unneccessary iterations/allocations over the features vec.
2 parents 6802c05 + dc84155 commit 565158c

File tree

3 files changed

+73
-57
lines changed

3 files changed

+73
-57
lines changed

src/dependency.rs

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,6 @@ pub enum Kind {
6060
// if you add a kind here, be sure to update `from_row` below.
6161
}
6262

63-
#[derive(Default, Insertable, Debug)]
64-
#[table_name = "dependencies"]
65-
pub struct NewDependency<'a> {
66-
pub version_id: i32,
67-
pub crate_id: i32,
68-
pub req: String,
69-
pub optional: bool,
70-
pub default_features: bool,
71-
pub features: Vec<&'a str>,
72-
pub target: Option<&'a str>,
73-
pub kind: i32,
74-
}
75-
7663
impl Dependency {
7764
// `downloads` need only be specified when generating a reverse dependency
7865
pub fn encodable(self, crate_name: &str, downloads: Option<i32>) -> EncodableDependency {
@@ -101,9 +88,10 @@ impl ReverseDependency {
10188
pub fn add_dependencies(
10289
conn: &PgConnection,
10390
deps: &[::upload::CrateDependency],
104-
version_id: i32,
91+
target_version_id: i32,
10592
) -> CargoResult<Vec<git::Dependency>> {
10693
use diesel::insert_into;
94+
use self::dependencies::dsl::*;
10795

10896
let git_and_new_dependencies = deps.iter()
10997
.map(|dep| {
@@ -118,42 +106,62 @@ pub fn add_dependencies(
118106
information",
119107
));
120108
}
121-
let features: Vec<_> = dep.features.iter().map(|s| &**s).collect();
122109

123110
Ok((
124111
git::Dependency {
125112
name: dep.name.to_string(),
126113
req: dep.version_req.to_string(),
127-
features: features.iter().map(|s| s.to_string()).collect(),
114+
features: dep.features.iter().map(|s| s.to_string()).collect(),
128115
optional: dep.optional,
129116
default_features: dep.default_features,
130117
target: dep.target.clone(),
131118
kind: dep.kind.or(Some(Kind::Normal)),
132119
},
133-
NewDependency {
134-
version_id: version_id,
135-
crate_id: krate.id,
136-
req: dep.version_req.to_string(),
137-
kind: dep.kind.unwrap_or(Kind::Normal) as i32,
138-
optional: dep.optional,
139-
default_features: dep.default_features,
140-
features: features,
141-
target: dep.target.as_ref().map(|s| &**s),
142-
},
120+
(
121+
version_id.eq(target_version_id),
122+
crate_id.eq(krate.id),
123+
req.eq(dep.version_req.to_string()),
124+
dep.kind.map(|k| kind.eq(k as i32)),
125+
optional.eq(dep.optional),
126+
default_features.eq(dep.default_features),
127+
features.eq(&dep.features),
128+
target.eq(dep.target.as_ref().map(|s| &**s)),
129+
),
143130
))
144131
})
145132
.collect::<Result<Vec<_>, _>>()?;
146133

147134
let (git_deps, new_dependencies): (Vec<_>, Vec<_>) =
148135
git_and_new_dependencies.into_iter().unzip();
149136

150-
insert_into(dependencies::table)
137+
insert_into(dependencies)
151138
.values(&new_dependencies)
152139
.execute(conn)?;
153140

154141
Ok(git_deps)
155142
}
156143

144+
use diesel::types::{FromSql, FromSqlRow, Integer};
145+
use diesel::row::Row;
146+
147+
// FIXME: Replace with `#[derive(FromSqlRow)]` in Diesel 1.1
148+
impl FromSqlRow<Integer, Pg> for Kind {
149+
fn build_from_row<R: Row<Pg>>(row: &mut R) -> Result<Self, Box<Error + Send + Sync>> {
150+
Self::from_sql(row.take())
151+
}
152+
}
153+
154+
impl FromSql<Integer, Pg> for Kind {
155+
fn from_sql(bytes: Option<&[u8]>) -> Result<Self, Box<Error + Send + Sync>> {
156+
match <i32 as FromSql<Integer, Pg>>::from_sql(bytes)? {
157+
0 => Ok(Kind::Normal),
158+
1 => Ok(Kind::Build),
159+
2 => Ok(Kind::Dev),
160+
n => Err(format!("unknown kind: {}", n).into()),
161+
}
162+
}
163+
}
164+
157165
impl Queryable<dependencies::SqlType, Pg> for Dependency {
158166
type Row = (
159167
i32,
@@ -164,7 +172,7 @@ impl Queryable<dependencies::SqlType, Pg> for Dependency {
164172
bool,
165173
Vec<String>,
166174
Option<String>,
167-
i32,
175+
Kind,
168176
);
169177

170178
fn build(row: Self::Row) -> Self {
@@ -177,12 +185,7 @@ impl Queryable<dependencies::SqlType, Pg> for Dependency {
177185
default_features: row.5,
178186
features: row.6,
179187
target: row.7,
180-
kind: match row.8 {
181-
0 => Kind::Normal,
182-
1 => Kind::Build,
183-
2 => Kind::Dev,
184-
n => panic!("unknown kind: {}", n),
185-
},
188+
kind: row.8,
186189
}
187190
}
188191
}
@@ -202,12 +205,7 @@ impl QueryableByName<Pg> for Dependency {
202205
default_features: row.get::<SqlTypeOf<default_features>, _>("default_features")?,
203206
features: row.get::<SqlTypeOf<features>, _>("features")?,
204207
target: row.get::<SqlTypeOf<target>, _>("target")?,
205-
kind: match row.get::<SqlTypeOf<kind>, _>("kind")? {
206-
0 => Kind::Normal,
207-
1 => Kind::Build,
208-
2 => Kind::Dev,
209-
n => return Err(format!("unknown kind: {}", n).into()),
210-
},
208+
kind: row.get::<SqlTypeOf<kind>, _>("kind")?,
211209
})
212210
}
213211
}

src/tests/all.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
3030

3131
use cargo_registry::app::App;
3232
use cargo_registry::category::NewCategory;
33-
use cargo_registry::dependency::NewDependency;
3433
use cargo_registry::keyword::Keyword;
3534
use cargo_registry::krate::{CrateDownload, EncodableCrate, NewCrate};
3635
use cargo_registry::schema::*;
@@ -312,12 +311,16 @@ impl<'a> VersionBuilder<'a> {
312311

313312
let new_deps = self.dependencies
314313
.into_iter()
315-
.map(|(crate_id, target)| NewDependency {
316-
version_id: vers.id,
317-
req: ">= 0".into(),
318-
crate_id,
319-
target,
320-
..Default::default()
314+
.map(|(crate_id, target)| {
315+
(
316+
dependencies::version_id.eq(vers.id),
317+
dependencies::req.eq(">= 0"),
318+
dependencies::crate_id.eq(crate_id),
319+
dependencies::target.eq(target),
320+
dependencies::optional.eq(false),
321+
dependencies::default_features.eq(false),
322+
dependencies::features.eq(Vec::<String>::new()),
323+
)
321324
})
322325
.collect::<Vec<_>>();
323326
insert_into(dependencies::table)
@@ -503,16 +506,17 @@ fn sign_in(req: &mut Request, app: &App) -> User {
503506

504507
fn new_dependency(conn: &PgConnection, version: &Version, krate: &Crate) -> Dependency {
505508
use diesel::insert_into;
506-
use cargo_registry::schema::dependencies;
507-
508-
insert_into(dependencies::table)
509-
.values(&NewDependency {
510-
version_id: version.id,
511-
crate_id: krate.id,
512-
req: ">= 0".into(),
513-
optional: false,
514-
..Default::default()
515-
})
509+
use cargo_registry::schema::dependencies::dsl::*;
510+
511+
insert_into(dependencies)
512+
.values((
513+
version_id.eq(version.id),
514+
crate_id.eq(krate.id),
515+
req.eq(">= 0"),
516+
optional.eq(false),
517+
default_features.eq(false),
518+
features.eq(Vec::<String>::new()),
519+
))
516520
.get_result(conn)
517521
.unwrap()
518522
}

src/upload.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,17 @@ impl Deref for CategoryList {
250250
&self.0
251251
}
252252
}
253+
254+
use diesel::pg::Pg;
255+
use diesel::types::{IsNull, Text, ToSql, ToSqlOutput};
256+
use std::error::Error;
257+
use std::io::Write;
258+
259+
impl ToSql<Text, Pg> for Feature {
260+
fn to_sql<W: Write>(
261+
&self,
262+
out: &mut ToSqlOutput<W, Pg>,
263+
) -> Result<IsNull, Box<Error + Send + Sync>> {
264+
ToSql::<Text, Pg>::to_sql(&**self, out)
265+
}
266+
}

0 commit comments

Comments
 (0)