diff options
Diffstat (limited to 'src/db')
| -rw-r--r-- | src/db/mod.rs | 25 | ||||
| -rw-r--r-- | src/db/models.rs | 108 | ||||
| -rw-r--r-- | src/db/schema.rs | 2 |
3 files changed, 127 insertions, 8 deletions
diff --git a/src/db/mod.rs b/src/db/mod.rs index 258d5a5..0862883 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,4 +1,5 @@ use std::env;
+use std::convert::AsRef;
use diesel::prelude::*;
use diesel::r2d2::{ConnectionManager, ManageConnection};
@@ -19,8 +20,10 @@ pub fn connection() -> Result<PgConnection> { CONN_MGR.connect().map_err(Error::from)
}
-pub fn find_text(conn: &PgConnection, search: String) -> Result<Meme> {
+pub fn find_meme<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme> {
use diesel::dsl::sql;
+
+ let search = search.as_ref();
let format_search = format!("%{}%", search);
memes::table
@@ -30,18 +33,32 @@ pub fn find_text(conn: &PgConnection, search: String) -> Result<Meme> { .map_err(Error::from)
}
-pub fn find_audio(conn: &PgConnection, search: String) -> Result<Meme> {
+pub fn find_text<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme> {
+ use diesel::dsl::sql;
+
+ let search = search.as_ref();
let format_search = format!("%{}%", search);
memes::table
+ .filter((memes::title.ilike(&format_search).or(sql(&format!("content ILIKE %{}%", search))))
+ .and(memes::content.is_not_null()))
+ .limit(1)
+ .first::<Meme>(conn)
+ .map_err(Error::from)
+}
+
+pub fn find_audio<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme> {
+ let format_search = format!("%{}%", search.as_ref());
+
+ memes::table
.filter(memes::title.ilike(format_search).and(memes::audio_id.is_not_null()))
.limit(1)
.first::<Meme>(conn)
.map_err(Error::from)
}
-pub fn find_image(conn: &PgConnection, search: String) -> Result<Meme> {
- let format_search = format!("%{}%", search);
+pub fn find_image<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme> {
+ let format_search = format!("%{}%", search.as_ref());
memes::table
.filter(memes::title.ilike(format_search).and(memes::image_id.is_not_null()))
diff --git a/src/db/models.rs b/src/db/models.rs index 7479fff..32ccc4b 100644 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -17,11 +17,11 @@ pub struct Meme { impl Meme {
pub fn image(&self, conn: &PgConnection) -> Option<Result<Image>> {
- self.image_id.map(|x: i32| images::table.find(x).first(conn).map_err(Error::from))
+ self.image_id.map(|x: i32| images::table.filter(images::id.eq(x)).first(conn).map_err(Error::from))
}
pub fn audio(&self, conn: &PgConnection) -> Option<Result<Audio>> {
- self.audio_id.map(|x: i32| audio::table.find(x).first(conn).map_err(Error::from))
+ self.audio_id.map(|x: i32| audio::table.filter(audio::id.eq(x)).first(conn).map_err(Error::from))
}
}
@@ -35,19 +35,65 @@ pub struct NewMeme { pub metadata_id: i32,
}
+impl NewMeme {
+ pub fn save(mut self, conn: &PgConnection, by_user: u64) -> Result<Meme> {
+ let metadata = Metadata::create(conn, by_user)?;
+
+ self.metadata_id = metadata.id;
+
+ ::diesel::insert_into(memes::table)
+ .values(&self)
+ .get_result::<Meme>(conn)
+ .map_err(Error::from)
+ }
+}
+
#[derive(Queryable, Identifiable, PartialEq, Debug)]
#[table_name="audio"]
pub struct Audio {
pub id: i32,
pub data: Vec<u8>,
+ pub data_hash: Vec<u8>,
pub metadata_id: i32,
}
+impl Audio {
+ pub fn create(conn: &PgConnection, data: Vec<u8>, by_user: u64) -> Result<i32> {
+ let mut data_hash = ::sha1::Sha1::new();
+ data_hash.update(&data);
+ let data_hash = data_hash.digest().bytes().to_vec();
+
+ let id = audio::table
+ .select(audio::id)
+ .filter(audio::data_hash.eq(&data_hash))
+ .get_results::<i32>(conn)?;
+
+ if let Some(id) = id.first() {
+ return Ok(*id);
+ }
+
+ let metadata = Metadata::create(conn, by_user)?;
+
+ let new_audio = NewAudio {
+ data,
+ data_hash,
+ metadata_id: metadata.id,
+ };
+
+ ::diesel::insert_into(audio::table)
+ .values(&new_audio)
+ .returning(audio::id)
+ .get_result(conn)
+ .map_err(Error::from)
+ }
+}
+
#[derive(Insertable, PartialEq, Debug)]
#[table_name="audio"]
pub struct NewAudio {
pub data: Vec<u8>,
+ pub data_hash: Vec<u8>,
pub metadata_id: i32,
}
@@ -57,13 +103,46 @@ pub struct NewAudio { pub struct Image {
pub id: i32,
pub data: Vec<u8>,
+ pub data_hash: Vec<u8>,
pub metadata_id: i32,
}
+impl Image {
+ pub fn create(conn: &PgConnection, data: Vec<u8>, by_user: u64) -> Result<i32> {
+ let mut data_hash = ::sha1::Sha1::new();
+ data_hash.update(&data);
+ let data_hash = data_hash.digest().bytes().to_vec();
+
+ let id = images::table
+ .select(images::id)
+ .filter(images::data_hash.eq(&data_hash))
+ .get_results::<i32>(conn)?;
+
+ if let Some(id) = id.first() {
+ return Ok(*id);
+ }
+
+ let metadata = Metadata::create(conn, by_user)?;
+
+ let new_image = NewImage {
+ data,
+ data_hash,
+ metadata_id: metadata.id,
+ };
+
+ ::diesel::insert_into(images::table)
+ .values(&new_image)
+ .returning(images::id)
+ .get_result(conn)
+ .map_err(Error::from)
+ }
+}
+
#[derive(Insertable, PartialEq, Debug)]
#[table_name="images"]
pub struct NewImage {
pub data: Vec<u8>,
+ pub data_hash: Vec<u8>,
pub metadata_id: i32,
}
@@ -76,10 +155,20 @@ pub struct Metadata { pub created_by: i64,
}
+impl Metadata {
+ pub fn create(conn: &PgConnection, by_user: u64) -> Result<Metadata> {
+ ::diesel::insert_into(metadata::table)
+ .values(&NewMetadata {
+ created_by: by_user as i64,
+ })
+ .get_result::<Metadata>(conn)
+ .map_err(Error::from)
+ }
+}
+
#[derive(Insertable, PartialEq, Debug)]
#[table_name="metadata"]
pub struct NewMetadata {
- pub created: NaiveDateTime,
pub created_by: i64,
}
@@ -93,10 +182,21 @@ pub struct AuditRecord { pub metadata_id: i32,
}
+impl AuditRecord {
+ pub fn create(conn: &PgConnection, metadata: i32, by_user: u64) -> Result<AuditRecord> {
+ ::diesel::insert_into(audit_records::table)
+ .values(&NewAuditRecord {
+ updated_by: by_user as i64,
+ metadata_id: metadata,
+ })
+ .get_result::<AuditRecord>(conn)
+ .map_err(Error::from)
+ }
+}
+
#[derive(Insertable, PartialEq, Debug)]
#[table_name="audit_records"]
pub struct NewAuditRecord {
- pub updated: NaiveDateTime,
pub updated_by: i64,
pub metadata_id: i32,
}
diff --git a/src/db/schema.rs b/src/db/schema.rs index cf15dcd..d4ba0fa 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -3,6 +3,7 @@ table! { id -> Int4, data -> Bytea, metadata_id -> Int4, + data_hash -> Bytea, } } @@ -20,6 +21,7 @@ table! { id -> Int4, data -> Bytea, metadata_id -> Int4, + data_hash -> Bytea, } } |
