From b7d9527b75eb5e70ed963f670bfbc8c694aa2d0b Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 22 Mar 2022 23:13:44 +0100 Subject: [PATCH] Dev (#6) * Add primary key to releases * Add cli bool flag to write sql indexes * Remove filler id for labels and artists * Add masters file parser * Add ci/cd test for masters file parser * Add info about indexes * Formatting and refactoring --- .github/workflows/ci.yml | 7 +- README.md | 24 +- discogs-load/src/artist.rs | 10 +- discogs-load/src/db.rs | 95 ++++++-- discogs-load/src/label.rs | 140 +++++------ discogs-load/src/main.rs | 12 +- discogs-load/src/master.rs | 289 +++++++++++++++++++++++ discogs-load/src/release.rs | 53 +++-- discogs-load/test_data/masters.xml | 323 ++++++++++++++++++++++++++ discogs-load/test_data/masters.xml.gz | Bin 0 -> 2095 bytes imgs/datamodel.png | Bin 0 -> 68233 bytes sql/indexes.sql | 16 ++ sql/indexes/release.sql | 3 - sql/tables/artist.sql | 2 +- sql/tables/label.sql | 2 +- sql/tables/master.sql | 21 ++ sql/tables/release.sql | 15 +- 17 files changed, 867 insertions(+), 145 deletions(-) create mode 100644 discogs-load/src/master.rs create mode 100644 discogs-load/test_data/masters.xml create mode 100644 discogs-load/test_data/masters.xml.gz create mode 100644 imgs/datamodel.png create mode 100644 sql/indexes.sql delete mode 100644 sql/indexes/release.sql create mode 100644 sql/tables/master.sql diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbdcd15..d931390 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,10 @@ jobs: run: cargo run --bin discogs-load discogs-load/test_data/releases.xml.gz - name: Run labels - run: cargo run --bin discogs-load discogs-load/test_data/releases.xml.gz + run: cargo run --bin discogs-load discogs-load/test_data/labels.xml.gz - name: Run artists - run: cargo run --bin discogs-load discogs-load/test_data/releases.xml.gz \ No newline at end of file + run: cargo run --bin discogs-load discogs-load/test_data/artists.xml.gz + + - name: Run masters + run: cargo run --bin discogs-load discogs-load/test_data/masters.xml.gz \ No newline at end of file diff --git a/README.md b/README.md index 1da848e..bbe700d 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,9 @@ USAGE: discogs-load [OPTIONS] [FILE(S)]... FLAGS: - -h, --help Prints help information - -V, --version Prints version information + --create-indexes Creates indexes + -h, --help Prints help information + -V, --version Prints version information OPTIONS: --batch-size Number of rows per insert [default: 10000] @@ -47,13 +48,23 @@ ARGS: ## Usage -Download the releases data dump [here](http://www.discogs.com/data/), and run the binary with the path to the gz compressed file as only argument. For the example below we'll use a dockerized postgres instance. +Download the releases data dump [here](http://www.discogs.com/data/), and run the binary with the path to the gz compressed file(s) as only argument. For the example below we'll use a dockerized postgres instance. ``` docker-compose up -d postgres ./discogs-load-aarch64-apple-darwin discogs_20211201_releases.xml.gz discogs_20220201_labels.xml.gz ``` +It is possible to afterwards run the innitalization of the project defined indexes. + +``` +./discogs-load-aarch64-apple-darwin --create-indexes +``` + +## Datamodel + +![Datamodel](imgs/datamodel.png) + ## Tests If you don't want to run the huge releases file, it is possible to run a smaller example file like so: @@ -69,9 +80,4 @@ And do a small manual test: docker exec -it discogs-load-postgres-1 /bin/bash psql -U dev discogs select * from release; -``` - -## Contributing/Remaining todo - -- Create a parser for the masters dataset -- Create a proper relational database schema \ No newline at end of file +``` \ No newline at end of file diff --git a/discogs-load/src/artist.rs b/discogs-load/src/artist.rs index c0d372b..095e18a 100644 --- a/discogs-load/src/artist.rs +++ b/discogs-load/src/artist.rs @@ -8,6 +8,7 @@ use crate::parser::Parser; #[derive(Clone, Debug)] pub struct Artist { + pub id: i32, pub name: String, pub real_name: String, pub profile: String, @@ -21,6 +22,7 @@ pub struct Artist { impl SqlSerialization for Artist { fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { let row: Vec<&'_ (dyn ToSql + Sync)> = vec![ + &self.id, &self.name, &self.real_name, &self.profile, @@ -37,6 +39,7 @@ impl SqlSerialization for Artist { impl Artist { pub fn new() -> Self { Artist { + id: 0, name: String::new(), real_name: String::new(), profile: String::new(), @@ -70,7 +73,6 @@ pub struct ArtistsParser<'a> { state: ParserState, artists: HashMap, current_artist: Artist, - current_id: i32, pb: ProgressBar, db_opts: &'a DbOpt, } @@ -81,7 +83,6 @@ impl<'a> ArtistsParser<'a> { state: ParserState::Artist, artists: HashMap::new(), current_artist: Artist::new(), - current_id: 0, pb: ProgressBar::new(7993954), db_opts, } @@ -94,7 +95,6 @@ impl<'a> Parser<'a> for ArtistsParser<'a> { state: ParserState::Artist, artists: HashMap::new(), current_artist: Artist::new(), - current_id: 0, pb: ProgressBar::new(7993954), db_opts, } @@ -126,7 +126,7 @@ impl<'a> Parser<'a> for ArtistsParser<'a> { Event::End(e) if e.local_name() == b"artist" => { self.artists - .entry(self.current_id) + .entry(self.current_artist.id) .or_insert(self.current_artist.clone()); if self.artists.len() >= self.db_opts.batch_size { // use drain? https://doc.rust-lang.org/std/collections/struct.HashMap.html#examples-13 @@ -149,7 +149,7 @@ impl<'a> Parser<'a> for ArtistsParser<'a> { ParserState::Id => match ev { Event::Text(e) => { - self.current_id = str::parse(str::from_utf8(&e.unescaped()?)?)?; + self.current_artist.id = str::parse(str::from_utf8(&e.unescaped()?)?)?; ParserState::Id } diff --git a/discogs-load/src/db.rs b/discogs-load/src/db.rs index bac1746..0ac963f 100644 --- a/discogs-load/src/db.rs +++ b/discogs-load/src/db.rs @@ -7,10 +7,14 @@ use structopt::StructOpt; use crate::artist::Artist; use crate::label::Label; +use crate::master::{Master, MasterArtist}; use crate::release::{Release, ReleaseLabel, ReleaseVideo}; #[derive(Debug, Clone, StructOpt)] pub struct DbOpt { + /// Creates indexes + #[structopt(long = "create-indexes")] + pub create_indexes: bool, /// Number of rows per insert #[structopt(long = "batch-size", default_value = "10000")] pub batch_size: usize, @@ -34,17 +38,19 @@ pub trait SqlSerialization { /// Initialize schema and close connection. pub fn init(db_opts: &DbOpt, schema_path: &str) -> Result<()> { + info!("Creating the tables."); let db = Db::connect(db_opts); - Db::create_schema(&mut db?, schema_path)?; + Db::execute_file(&mut db?, schema_path)?; Ok(()) } -// /// Initialize indexes and close connection. -// pub fn indexes(opts: &DbOpt) -> Result<()> { -// let db = Db::connect(opts); -// Db::create_indexes(&mut db?)?; -// Ok(()) -// } +/// Initialize indexes and close connection. +pub fn indexes(opts: &DbOpt, file_path: &str) -> Result<()> { + info!("Creating the indexes."); + let db = Db::connect(opts); + Db::execute_file(&mut db?, file_path)?; + Ok(()) +} pub fn write_releases( db_opts: &DbOpt, @@ -71,6 +77,17 @@ pub fn write_artists(db_opts: &DbOpt, artists: &HashMap) -> Result< Ok(()) } +pub fn write_masters( + db_opts: &DbOpt, + masters: &HashMap, + masters_artists: &HashMap, +) -> Result<()> { + let mut db = Db::connect(db_opts)?; + Db::write_master_rows(&mut db, masters)?; + Db::write_master_artists_rows(&mut db, masters_artists)?; + Ok(()) +} + struct Db { db_client: Client, } @@ -89,12 +106,13 @@ impl Db { fn write_release_rows(&mut self, data: &HashMap) -> Result<()> { let insert = InsertCommand::new( "release", - "(status, title, country, released, notes, genres, styles, master_id, data_quality)", + "(id, status, title, country, released, notes, genres, styles, master_id, data_quality)", )?; insert.execute( &mut self.db_client, data, &[ + Type::INT4, Type::TEXT, Type::TEXT, Type::TEXT, @@ -110,17 +128,21 @@ impl Db { } fn write_release_labels_rows(&mut self, data: &HashMap) -> Result<()> { - let insert = InsertCommand::new("release_label", "(label, catno)")?; - insert.execute(&mut self.db_client, data, &[Type::TEXT, Type::TEXT])?; + let insert = InsertCommand::new("release_label", "(release_id, label, catno, label_id)")?; + insert.execute( + &mut self.db_client, + data, + &[Type::INT4, Type::TEXT, Type::TEXT, Type::INT4], + )?; Ok(()) } fn write_release_videos_rows(&mut self, data: &HashMap) -> Result<()> { - let insert = InsertCommand::new("release_video", "(duration, src, title)")?; + let insert = InsertCommand::new("release_video", "(release_id, duration, src, title)")?; insert.execute( &mut self.db_client, data, - &[Type::INT4, Type::TEXT, Type::TEXT], + &[Type::INT4, Type::INT4, Type::TEXT, Type::TEXT], )?; Ok(()) } @@ -128,12 +150,13 @@ impl Db { fn write_label_rows(&mut self, data: &HashMap) -> Result<()> { let insert = InsertCommand::new( "label", - "(name, contactinfo, profile, parent_label, sublabels, urls, data_quality)", + "(id, name, contactinfo, profile, parent_label, sublabels, urls, data_quality)", )?; insert.execute( &mut self.db_client, data, &[ + Type::INT4, Type::TEXT, Type::TEXT, Type::TEXT, @@ -149,12 +172,13 @@ impl Db { fn write_artist_rows(&mut self, data: &HashMap) -> Result<()> { let insert = InsertCommand::new( "artist", - "(name, real_name, profile, data_quality, name_variations, urls, aliases, members)", + "(id, name, real_name, profile, data_quality, name_variations, urls, aliases, members)", )?; insert.execute( &mut self.db_client, data, &[ + Type::INT4, Type::TEXT, Type::TEXT, Type::TEXT, @@ -168,19 +192,44 @@ impl Db { Ok(()) } - fn create_schema(&mut self, schema_path: &str) -> Result<()> { - info!("Creating the tables."); + fn write_master_rows(&mut self, data: &HashMap) -> Result<()> { + let insert = InsertCommand::new( + "master", + "(id, title, release_id, year, notes, genres, styles, data_quality)", + )?; + insert.execute( + &mut self.db_client, + data, + &[ + Type::INT4, + Type::TEXT, + Type::INT4, + Type::INT4, + Type::TEXT, + Type::TEXT_ARRAY, + Type::TEXT_ARRAY, + Type::TEXT, + ], + )?; + Ok(()) + } + + fn write_master_artists_rows(&mut self, data: &HashMap) -> Result<()> { + let insert = + InsertCommand::new("master_artist", "(artist_id, master_id, name, anv, role)")?; + insert.execute( + &mut self.db_client, + data, + &[Type::INT4, Type::INT4, Type::TEXT, Type::TEXT, Type::TEXT], + )?; + Ok(()) + } + + fn execute_file(&mut self, schema_path: &str) -> Result<()> { let tables_structure = fs::read_to_string(schema_path).unwrap(); self.db_client.batch_execute(&tables_structure).unwrap(); Ok(()) } - - // fn create_indexes(&mut self) -> Result<()> { - // info!("Creating the indexes."); - // let tables_structure = fs::read_to_string("sql/indexes/release.sql").unwrap(); - // self.db_client.batch_execute(&tables_structure).unwrap(); - // Ok(()) - // } } struct InsertCommand { diff --git a/discogs-load/src/label.rs b/discogs-load/src/label.rs index a3808b8..0166352 100644 --- a/discogs-load/src/label.rs +++ b/discogs-load/src/label.rs @@ -8,6 +8,7 @@ use crate::parser::Parser; #[derive(Clone, Debug)] pub struct Label { + pub id: i32, pub name: String, pub contactinfo: String, pub profile: String, @@ -20,6 +21,7 @@ pub struct Label { impl SqlSerialization for Label { fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { let row: Vec<&'_ (dyn ToSql + Sync)> = vec![ + &self.id, &self.name, &self.contactinfo, &self.profile, @@ -35,6 +37,7 @@ impl SqlSerialization for Label { impl Label { pub fn new() -> Self { Label { + id: 0, name: String::new(), contactinfo: String::new(), profile: String::new(), @@ -48,24 +51,23 @@ impl Label { #[derive(Copy, Clone, Debug)] enum ParserState { - ReadLabel, - ReadName, - ReadId, - ReadContactinfo, - ReadProfile, - ReadParentLabel, - ReadSublabels, - ReadSublabel, - ReadUrls, - ReadUrl, - ReadDataQuality, + Label, + Name, + Id, + Contactinfo, + Profile, + ParentLabel, + Sublabels, + Sublabel, + Urls, + Url, + DataQuality, } pub struct LabelsParser<'a> { state: ParserState, labels: HashMap, current_label: Label, - current_id: i32, pb: ProgressBar, db_opts: &'a DbOpt, } @@ -73,10 +75,9 @@ pub struct LabelsParser<'a> { impl<'a> LabelsParser<'a> { pub fn new(db_opts: &'a DbOpt) -> Self { LabelsParser { - state: ParserState::ReadLabel, + state: ParserState::Label, labels: HashMap::new(), current_label: Label::new(), - current_id: 0, pb: ProgressBar::new(1821993), db_opts, } @@ -86,39 +87,38 @@ impl<'a> LabelsParser<'a> { impl<'a> Parser<'a> for LabelsParser<'a> { fn new(&self, db_opts: &'a DbOpt) -> Self { LabelsParser { - state: ParserState::ReadLabel, + state: ParserState::Label, labels: HashMap::new(), current_label: Label::new(), - current_id: 0, pb: ProgressBar::new(1821993), db_opts, } } fn process(&mut self, ev: Event) -> Result<(), Box> { self.state = match self.state { - ParserState::ReadLabel => { + ParserState::Label => { match ev { Event::Start(e) if e.local_name() == b"label" => { self.current_label.sublabels = Vec::new(); self.current_label.urls = Vec::new(); - ParserState::ReadLabel + ParserState::Label } Event::Start(e) => match e.local_name() { - b"name" => ParserState::ReadName, - b"id" => ParserState::ReadId, - b"contactinfo" => ParserState::ReadContactinfo, - b"profile" => ParserState::ReadProfile, - b"parent_label" => ParserState::ReadParentLabel, - b"sublabels" => ParserState::ReadSublabels, - b"urls" => ParserState::ReadUrls, - b"data_quality" => ParserState::ReadDataQuality, - _ => ParserState::ReadLabel, + b"name" => ParserState::Name, + b"id" => ParserState::Id, + b"contactinfo" => ParserState::Contactinfo, + b"profile" => ParserState::Profile, + b"parent_label" => ParserState::ParentLabel, + b"sublabels" => ParserState::Sublabels, + b"urls" => ParserState::Urls, + b"data_quality" => ParserState::DataQuality, + _ => ParserState::Label, }, Event::End(e) if e.local_name() == b"label" => { self.labels - .entry(self.current_id) + .entry(self.current_label.id) .or_insert(self.current_label.clone()); if self.labels.len() >= self.db_opts.batch_size { // use drain? https://doc.rust-lang.org/std/collections/struct.HashMap.html#examples-13 @@ -126,121 +126,121 @@ impl<'a> Parser<'a> for LabelsParser<'a> { self.labels = HashMap::new(); } self.pb.inc(1); - ParserState::ReadLabel + ParserState::Label } Event::End(e) if e.local_name() == b"labels" => { // write to db remainder of labels write_labels(self.db_opts, &self.labels)?; - ParserState::ReadLabel + ParserState::Label } - _ => ParserState::ReadLabel, + _ => ParserState::Label, } } - ParserState::ReadId => match ev { + ParserState::Id => match ev { Event::Text(e) => { - self.current_id = str::parse(str::from_utf8(&e.unescaped()?)?)?; - ParserState::ReadId + self.current_label.id = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserState::Id } - Event::End(e) if e.local_name() == b"id" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"id" => ParserState::Label, - _ => ParserState::ReadId, + _ => ParserState::Id, }, - ParserState::ReadName => match ev { + ParserState::Name => match ev { Event::Text(e) => { self.current_label.name = str::parse(str::from_utf8(&e.unescaped()?)?)?; - ParserState::ReadName + ParserState::Name } - Event::End(e) if e.local_name() == b"name" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"name" => ParserState::Label, - _ => ParserState::ReadName, + _ => ParserState::Name, }, - ParserState::ReadContactinfo => match ev { + ParserState::Contactinfo => match ev { Event::Text(e) => { self.current_label.contactinfo = str::parse(str::from_utf8(&e.unescaped()?)?)?; - ParserState::ReadContactinfo + ParserState::Contactinfo } - Event::End(e) if e.local_name() == b"contactinfo" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"contactinfo" => ParserState::Label, - _ => ParserState::ReadContactinfo, + _ => ParserState::Contactinfo, }, - ParserState::ReadProfile => match ev { + ParserState::Profile => match ev { Event::Text(e) => { self.current_label.profile = str::parse(str::from_utf8(&e.unescaped()?)?)?; - ParserState::ReadProfile + ParserState::Profile } - Event::End(e) if e.local_name() == b"profile" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"profile" => ParserState::Label, - _ => ParserState::ReadProfile, + _ => ParserState::Profile, }, - ParserState::ReadParentLabel => match ev { + ParserState::ParentLabel => match ev { Event::Text(e) => { self.current_label.parent_label = str::parse(str::from_utf8(&e.unescaped()?)?)?; - ParserState::ReadParentLabel + ParserState::ParentLabel } - Event::End(e) if e.local_name() == b"parent_label" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"parent_label" => ParserState::Label, - _ => ParserState::ReadParentLabel, + _ => ParserState::ParentLabel, }, - ParserState::ReadSublabels => match ev { - Event::Start(e) if e.local_name() == b"label" => ParserState::ReadSublabel, + ParserState::Sublabels => match ev { + Event::Start(e) if e.local_name() == b"label" => ParserState::Sublabel, - Event::End(e) if e.local_name() == b"sublabels" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"sublabels" => ParserState::Label, - _ => ParserState::ReadSublabels, + _ => ParserState::Sublabels, }, - ParserState::ReadSublabel => match ev { + ParserState::Sublabel => match ev { Event::Text(e) => { self.current_label .sublabels .extend(str::parse(str::from_utf8(&e.unescaped()?)?)); - ParserState::ReadSublabels + ParserState::Sublabels } - _ => ParserState::ReadSublabels, + _ => ParserState::Sublabels, }, - ParserState::ReadUrls => match ev { - Event::Start(e) if e.local_name() == b"url" => ParserState::ReadUrl, + ParserState::Urls => match ev { + Event::Start(e) if e.local_name() == b"url" => ParserState::Url, - Event::End(e) if e.local_name() == b"urls" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"urls" => ParserState::Label, - _ => ParserState::ReadUrls, + _ => ParserState::Urls, }, - ParserState::ReadUrl => match ev { + ParserState::Url => match ev { Event::Text(e) => { self.current_label .urls .extend(str::parse(str::from_utf8(&e.unescaped()?)?)); - ParserState::ReadUrls + ParserState::Urls } - _ => ParserState::ReadUrls, + _ => ParserState::Urls, }, - ParserState::ReadDataQuality => match ev { + ParserState::DataQuality => match ev { Event::Text(e) => { self.current_label.data_quality = str::parse(str::from_utf8(&e.unescaped()?)?)?; - ParserState::ReadDataQuality + ParserState::DataQuality } - Event::End(e) if e.local_name() == b"data_quality" => ParserState::ReadLabel, + Event::End(e) if e.local_name() == b"data_quality" => ParserState::Label, - _ => ParserState::ReadDataQuality, + _ => ParserState::DataQuality, }, }; diff --git a/discogs-load/src/main.rs b/discogs-load/src/main.rs index 447318e..ba47dce 100644 --- a/discogs-load/src/main.rs +++ b/discogs-load/src/main.rs @@ -8,6 +8,7 @@ use structopt::StructOpt; mod artist; mod db; mod label; +mod master; mod parser; mod release; @@ -71,6 +72,13 @@ fn read_files(opt: &Opt) -> Result<(), Box> { &opt.dbopts, )); } + b"masters" => { + db::init(&opt.dbopts, "sql/tables/master.sql")?; + break Box::new(parser::Parser::new( + &master::MastersParser::new(&opt.dbopts), + &opt.dbopts, + )); + } _ => (), }; buf.clear(); @@ -94,7 +102,9 @@ fn read_files(opt: &Opt) -> Result<(), Box> { } } - // db::indexes(&opt.dbopts)?; + if opt.dbopts.create_indexes { + db::indexes(&opt.dbopts, "sql/indexes.sql")?; + } Ok(()) } diff --git a/discogs-load/src/master.rs b/discogs-load/src/master.rs new file mode 100644 index 0000000..5bb6848 --- /dev/null +++ b/discogs-load/src/master.rs @@ -0,0 +1,289 @@ +use indicatif::ProgressBar; +use postgres::types::ToSql; +use quick_xml::events::Event; +use std::{collections::HashMap, error::Error, str}; + +use crate::db::{write_masters, DbOpt, SqlSerialization}; +use crate::parser::Parser; + +#[derive(Clone, Debug)] +pub struct Master { + pub id: i32, + pub title: String, + pub release_id: i32, + pub year: i32, + pub notes: String, + pub genres: Vec, + pub styles: Vec, + pub data_quality: String, +} + +impl SqlSerialization for Master { + fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { + let row: Vec<&'_ (dyn ToSql + Sync)> = vec![ + &self.id, + &self.title, + &self.release_id, + &self.year, + &self.notes, + &self.genres, + &self.styles, + &self.data_quality, + ]; + row + } +} + +impl Master { + pub fn new() -> Self { + Master { + id: 0, + title: String::new(), + release_id: 0, + year: 0, + notes: String::new(), + genres: Vec::new(), + styles: Vec::new(), + data_quality: String::new(), + } + } +} + +#[derive(Clone, Debug)] +pub struct MasterArtist { + pub id: i32, + pub master_id: i32, + pub name: String, + pub anv: String, + pub role: String, +} + +impl SqlSerialization for MasterArtist { + fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { + let row: Vec<&'_ (dyn ToSql + Sync)> = + vec![&self.id, &self.master_id, &self.name, &self.anv, &self.role]; + row + } +} + +impl MasterArtist { + pub fn new() -> Self { + MasterArtist { + id: 0, + master_id: 0, + name: String::new(), + anv: String::new(), + role: String::new(), + } + } +} + +#[derive(Copy, Clone, Debug)] +enum ParserReadState { + // master + Master, + MainRelease, + Artists, + Title, + DataQuality, + // master_artists + ArtistId, + ArtistName, + ArtistAnv, + ArtistRole, +} + +pub struct MastersParser<'a> { + state: ParserReadState, + masters: HashMap, + current_master: Master, + current_artist: MasterArtist, + current_master_id: i32, + master_artists: HashMap, + pb: ProgressBar, + db_opts: &'a DbOpt, +} + +impl<'a> MastersParser<'a> { + pub fn new(db_opts: &'a DbOpt) -> Self { + MastersParser { + state: ParserReadState::Master, + masters: HashMap::new(), + current_master: Master::new(), + current_artist: MasterArtist::new(), + current_master_id: 0, + master_artists: HashMap::new(), + pb: ProgressBar::new(1821993), + db_opts, + } + } +} + +impl<'a> Parser<'a> for MastersParser<'a> { + fn new(&self, db_opts: &'a DbOpt) -> Self { + MastersParser { + state: ParserReadState::Master, + masters: HashMap::new(), + current_master: Master::new(), + current_artist: MasterArtist::new(), + current_master_id: 0, + master_artists: HashMap::new(), + pb: ProgressBar::new(1821993), + db_opts, + } + } + fn process(&mut self, ev: Event) -> Result<(), Box> { + self.state = match self.state { + ParserReadState::Master => { + match ev { + Event::Start(e) if e.local_name() == b"master" => { + self.current_master.genres = Vec::new(); + self.current_master.styles = Vec::new(); + self.current_master.id = str::parse(str::from_utf8( + &e.attributes().next().unwrap()?.unescaped_value()?, + )?)?; + ParserReadState::Master + } + + Event::Start(e) => match e.local_name() { + b"main_release" => ParserReadState::MainRelease, + b"title" => ParserReadState::Title, + b"artists" => ParserReadState::Artists, + b"data_quality" => ParserReadState::DataQuality, + _ => ParserReadState::Master, + }, + + Event::End(e) if e.local_name() == b"master" => { + self.masters + .entry(self.current_master.id) + .or_insert(self.current_master.clone()); + if self.masters.len() >= self.db_opts.batch_size { + write_masters(self.db_opts, &self.masters, &self.master_artists)?; + self.masters = HashMap::new(); + self.master_artists = HashMap::new(); + } + self.pb.inc(1); + ParserReadState::Master + } + + Event::End(e) if e.local_name() == b"masters" => { + // write to db remainder of masters + write_masters(self.db_opts, &self.masters, &self.master_artists)?; + ParserReadState::Master + } + + _ => ParserReadState::Master, + } + } + + ParserReadState::MainRelease => match ev { + Event::Text(e) => { + self.current_master.release_id = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::MainRelease + } + + Event::End(e) if e.local_name() == b"main_release" => ParserReadState::Master, + + _ => ParserReadState::MainRelease, + }, + + ParserReadState::Artists => match ev { + Event::Start(e) => match e.local_name() { + b"artist" => { + self.current_artist = MasterArtist::new(); + self.current_artist.master_id = self.current_master.id; + ParserReadState::Artists + } + b"id" => ParserReadState::ArtistId, + b"name" => ParserReadState::ArtistName, + b"anv" => ParserReadState::ArtistAnv, + b"role" => ParserReadState::ArtistRole, + _ => ParserReadState::Artists, + }, + + Event::End(e) => match e.local_name() { + b"artist" => { + self.master_artists + .entry(self.current_master_id) + .or_insert(self.current_artist.clone()); + self.current_master_id += 1; + ParserReadState::Artists + } + b"artists" => ParserReadState::Master, + _ => ParserReadState::Artists, + }, + + _ => ParserReadState::Artists, + }, + + ParserReadState::ArtistId => match ev { + Event::Text(e) => { + self.current_artist.id = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::Artists + } + + Event::End(e) if e.local_name() == b"id" => ParserReadState::Artists, + + _ => ParserReadState::ArtistId, + }, + + ParserReadState::ArtistName => match ev { + Event::Text(e) => { + self.current_artist.name = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::Artists + } + + Event::End(e) if e.local_name() == b"name" => ParserReadState::Artists, + + _ => ParserReadState::ArtistName, + }, + + ParserReadState::ArtistAnv => match ev { + Event::Text(e) => { + self.current_artist.anv = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::Artists + } + + Event::End(e) if e.local_name() == b"anv" => ParserReadState::Artists, + + _ => ParserReadState::ArtistAnv, + }, + + ParserReadState::ArtistRole => match ev { + Event::Text(e) => { + self.current_artist.role = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::Artists + } + + Event::End(e) if e.local_name() == b"role" => ParserReadState::Artists, + + _ => ParserReadState::ArtistRole, + }, + + ParserReadState::Title => match ev { + Event::Text(e) => { + self.current_master.title = str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::Title + } + + Event::End(e) if e.local_name() == b"title" => ParserReadState::Master, + + _ => ParserReadState::Title, + }, + + ParserReadState::DataQuality => match ev { + Event::Text(e) => { + self.current_master.data_quality = + str::parse(str::from_utf8(&e.unescaped()?)?)?; + ParserReadState::DataQuality + } + + Event::End(e) if e.local_name() == b"data_quality" => ParserReadState::Master, + + _ => ParserReadState::DataQuality, + }, + }; + + Ok(()) + } +} diff --git a/discogs-load/src/release.rs b/discogs-load/src/release.rs index ac96bba..9675ddf 100644 --- a/discogs-load/src/release.rs +++ b/discogs-load/src/release.rs @@ -8,6 +8,7 @@ use crate::parser::Parser; #[derive(Clone, Debug)] pub struct Release { + pub id: i32, pub status: String, pub title: String, pub country: String, @@ -22,6 +23,7 @@ pub struct Release { impl SqlSerialization for Release { fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { let row: Vec<&'_ (dyn ToSql + Sync)> = vec![ + &self.id, &self.status, &self.title, &self.country, @@ -38,19 +40,23 @@ impl SqlSerialization for Release { #[derive(Clone, Debug)] pub struct ReleaseLabel { + pub release_id: i32, pub label: String, pub catno: String, + pub label_id: i32, } impl SqlSerialization for ReleaseLabel { fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { - let row: Vec<&'_ (dyn ToSql + Sync)> = vec![&self.label, &self.catno]; + let row: Vec<&'_ (dyn ToSql + Sync)> = + vec![&self.release_id, &self.label, &self.catno, &self.label_id]; row } } #[derive(Clone, Debug)] pub struct ReleaseVideo { + pub release_id: i32, pub duration: i32, pub src: String, pub title: String, @@ -58,7 +64,8 @@ pub struct ReleaseVideo { impl SqlSerialization for ReleaseVideo { fn to_sql(&self) -> Vec<&'_ (dyn ToSql + Sync)> { - let row: Vec<&'_ (dyn ToSql + Sync)> = vec![&self.duration, &self.src, &self.title]; + let row: Vec<&'_ (dyn ToSql + Sync)> = + vec![&self.release_id, &self.duration, &self.src, &self.title]; row } } @@ -66,6 +73,7 @@ impl SqlSerialization for ReleaseVideo { impl Release { pub fn new() -> Self { Release { + id: 0, status: String::new(), title: String::new(), country: String::new(), @@ -79,15 +87,6 @@ impl Release { } } -impl ReleaseLabel { - pub fn new() -> Self { - ReleaseLabel { - label: String::new(), - catno: String::new(), - } - } -} - #[derive(Copy, Clone, Debug)] enum ParserReadState { // release @@ -114,7 +113,7 @@ pub struct ReleasesParser<'a> { current_release: Release, current_id: i32, release_labels: HashMap, - current_release_label: ReleaseLabel, + current_video_id: i32, release_videos: HashMap, pb: ProgressBar, db_opts: &'a DbOpt, @@ -128,7 +127,7 @@ impl<'a> ReleasesParser<'a> { current_release: Release::new(), current_id: 0, release_labels: HashMap::new(), - current_release_label: ReleaseLabel::new(), + current_video_id: 0, release_videos: HashMap::new(), pb: ProgressBar::new(14976967), // https://api.discogs.com/ db_opts, @@ -144,7 +143,7 @@ impl<'a> Parser<'a> for ReleasesParser<'a> { current_release: Release::new(), current_id: 0, release_labels: HashMap::new(), - current_release_label: ReleaseLabel::new(), + current_video_id: 0, release_videos: HashMap::new(), pb: ProgressBar::new(14976967), // https://api.discogs.com/ db_opts, @@ -162,6 +161,7 @@ impl<'a> Parser<'a> for ReleasesParser<'a> { self.current_id = str::parse(str::from_utf8( &e.attributes().next().unwrap()?.unescaped_value()?, )?)?; + self.current_release.id = self.current_id; self.current_release.genres = Vec::new(); self.current_release.styles = Vec::new(); ParserReadState::Release @@ -324,18 +324,21 @@ impl<'a> Parser<'a> for ReleasesParser<'a> { ParserReadState::Labels => match ev { Event::Empty(e) => { - self.current_release_label.label = str::parse(str::from_utf8( - &e.attributes().next().unwrap()?.unescaped_value()?, - )?)?; - self.current_release_label.catno = str::parse(str::from_utf8( - &e.attributes().nth(1).unwrap()?.unescaped_value()?, - )?)?; let label_id = str::parse(str::from_utf8( &e.attributes().nth(2).unwrap()?.unescaped_value()?, )?)?; - self.release_labels - .entry(label_id) - .or_insert(self.current_release_label.clone()); + self.release_labels.entry(label_id).or_insert(ReleaseLabel { + release_id: self.current_release.id, + label: str::parse(str::from_utf8( + &e.attributes().next().unwrap()?.unescaped_value()?, + )?)?, + catno: str::parse(str::from_utf8( + &e.attributes().nth(1).unwrap()?.unescaped_value()?, + )?)?, + label_id: str::parse(str::from_utf8( + &e.attributes().nth(2).unwrap()?.unescaped_value()?, + )?)?, + }); ParserReadState::Labels } @@ -347,8 +350,9 @@ impl<'a> Parser<'a> for ReleasesParser<'a> { ParserReadState::Videos => match ev { Event::Start(e) if e.local_name() == b"video" => { self.release_videos - .entry(self.current_id) + .entry(self.current_video_id) .or_insert(ReleaseVideo { + release_id: self.current_release.id, duration: str::parse(str::from_utf8( &e.attributes().nth(1).unwrap()?.unescaped_value()?, )?)?, @@ -357,6 +361,7 @@ impl<'a> Parser<'a> for ReleasesParser<'a> { )?)?, title: String::new(), }); + self.current_video_id += 1; ParserReadState::Videos } diff --git a/discogs-load/test_data/masters.xml b/discogs-load/test_data/masters.xml new file mode 100644 index 0000000..9aedd40 --- /dev/null +++ b/discogs-load/test_data/masters.xml @@ -0,0 +1,323 @@ + + + + 116925 + + + + + + + + + + + + 3225 + Vince Watson + + + + + + + + Electronic + + + + + + 2002 + Moments In Time + Correct + + + + + + + + + + + + + + + + + + + 42056 + + + + + + + + + + + + 3225 + Vince Watson + + + + + + + + Electronic + + + + + + + 1999 + Biologique + Correct + + + + + + + + + + + + + + + + + 336873 + + + + + + 233125 + Soleil (2) + + + + + + + + Electronic + + + + + + 2004 + Soleil + Correct + + \ No newline at end of file diff --git a/discogs-load/test_data/masters.xml.gz b/discogs-load/test_data/masters.xml.gz new file mode 100644 index 0000000000000000000000000000000000000000..51095d65911f2d98cc5992804743eb99b48b10e3 GIT binary patch literal 2095 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

`Y=LY}OC^H$yr5&s? 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