Skip to content
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

feat: allow returning None for query interfaces (#255) #256

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions src/clinvar_genes/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@
Ok(())
}

/// Query for one gene annotation record.
pub fn query_for_gene(

Check warning on line 78 in src/clinvar_genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/clinvar_genes/cli/query.rs#L78

Added line #L78 was not covered by tests
hgnc_id: &str,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
cf_data: &Arc<rocksdb::BoundColumnFamily>,
) -> Result<Option<clinvar_genes::pbs::ClinvarPerGeneRecord>, anyhow::Error> {
let raw_value = db
.get_cf(cf_data, hgnc_id.as_bytes())
.map_err(|e| anyhow::anyhow!("error while querying for HGNC ID {}: {}", hgnc_id, e))?;
raw_value
.map(|raw_value| {
clinvar_genes::pbs::ClinvarPerGeneRecord::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| {
anyhow::anyhow!(

Check warning on line 90 in src/clinvar_genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/clinvar_genes/cli/query.rs#L83-L90

Added lines #L83 - L90 were not covered by tests
"error while decoding clinvar per gene record for HGNC ID {}: {}",
hgnc_id,
e
)
})
})
.transpose()
}

/// Implementation of `gene query` sub command.
pub fn run(common: &common::cli::Args, args: &Args) -> Result<(), anyhow::Error> {
tracing::info!("Starting 'gene query' command");
Expand All @@ -94,19 +117,11 @@
};

tracing::info!("Running query...");
let raw_value = db.get_cf(&cf_data, args.hgnc_id.as_bytes())?;
if let Some(raw_value) = raw_value {
print_record(
&mut out_writer,
args.out_format,
&clinvar_genes::pbs::ClinvarPerGeneRecord::decode(&mut std::io::Cursor::new(
&raw_value,
))?,
)?;
if let Some(record) = query_for_gene(&args.hgnc_id, &db, &cf_data)? {
print_record(&mut out_writer, args.out_format, &record)?;

Check warning on line 121 in src/clinvar_genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/clinvar_genes/cli/query.rs#L120-L121

Added lines #L120 - L121 were not covered by tests
} else {
tracing::info!("No data found for HGNC ID {}", args.hgnc_id);
tracing::info!("no record found for HGNC ID {:?}", args.hgnc_id);

Check warning on line 123 in src/clinvar_genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/clinvar_genes/cli/query.rs#L123

Added line #L123 was not covered by tests
}

tracing::info!("All done. Have a nice day!");
Ok(())
}
26 changes: 15 additions & 11 deletions src/clinvar_minimal/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
meta: &Meta,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
cf_data: &Arc<rocksdb::BoundColumnFamily>,
) -> Result<pbs::Record, anyhow::Error> {
) -> Result<Option<pbs::Record>, anyhow::Error> {
// Split off the genome release (checked) and convert to key as used in database.
let query = spdi::Var {
sequence: extract_chrom::from_var(variant, Some(&meta.genome_release))?,
Expand All @@ -113,11 +113,15 @@
let var: keys::Var = query.into();
let key: Vec<u8> = var.into();
let raw_value = db
.get_cf(cf_data, key)?
.ok_or_else(|| anyhow::anyhow!("could not find variant in database"))?;
// Decode via prost.
pbs::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))
.get_cf(cf_data, key)
.map_err(|e| anyhow::anyhow!("error while querying for variant {}: {}", variant, e))?;
raw_value
.map(|raw_value| {
// Decode via prost.
pbs::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))

Check warning on line 122 in src/clinvar_minimal/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/clinvar_minimal/cli/query.rs#L122

Added line #L122 was not covered by tests
})
.transpose()
}

/// Implementation of `tsv query` sub command.
Expand All @@ -141,11 +145,11 @@
tracing::info!("Running query...");
let before_query = std::time::Instant::now();
if let Some(variant) = args.query.variant.as_ref() {
print_record(
&mut out_writer,
args.out_format,
&query_for_variant(variant, &meta, &db, &cf_data)?,
)?;
if let Some(record) = query_for_variant(variant, &meta, &db, &cf_data)? {
print_record(&mut out_writer, args.out_format, &record)?;
} else {
tracing::info!("no record found for variant {:?}", &variant);

Check warning on line 151 in src/clinvar_minimal/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/clinvar_minimal/cli/query.rs#L151

Added line #L151 was not covered by tests
}
} else {
let (start, stop) = if let Some(position) = args.query.position.as_ref() {
let position = spdi::Pos {
Expand Down
26 changes: 15 additions & 11 deletions src/dbsnp/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
meta: &Meta,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
cf_data: &Arc<rocksdb::BoundColumnFamily>,
) -> Result<dbsnp::pbs::Record, anyhow::Error> {
) -> Result<Option<dbsnp::pbs::Record>, anyhow::Error> {
// Split off the genome release (checked) and convert to key as used in database.
let query = spdi::Var {
sequence: extract_chrom::from_var(variant, Some(&meta.genome_release))?,
Expand All @@ -129,11 +129,15 @@
let var: keys::Var = query.into();
let key: Vec<u8> = var.into();
let raw_value = db
.get_cf(cf_data, key)?
.ok_or_else(|| anyhow::anyhow!("could not find variant in database"))?;
// Decode via prost.
dbsnp::pbs::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))
.get_cf(cf_data, key)
.map_err(|e| anyhow::anyhow!("error while querying for variant {}: {}", variant, e))?;
raw_value
.map(|raw_value| {
// Decode via prost.
dbsnp::pbs::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))

Check warning on line 138 in src/dbsnp/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/dbsnp/cli/query.rs#L138

Added line #L138 was not covered by tests
})
.transpose()
}

/// Implementation of `tsv query` sub command.
Expand All @@ -157,11 +161,11 @@
tracing::info!("Running query...");
let before_query = std::time::Instant::now();
if let Some(variant) = args.query.variant.as_ref() {
print_record(
&mut out_writer,
args.out_format,
&query_for_variant(variant, &meta, &db, &cf_data)?,
)?;
if let Some(record) = query_for_variant(variant, &meta, &db, &cf_data)? {
print_record(&mut out_writer, args.out_format, &record)?;
} else {
tracing::info!("no record found for variant {}", variant);

Check warning on line 167 in src/dbsnp/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/dbsnp/cli/query.rs#L167

Added line #L167 was not covered by tests
}
} else {
let (start, stop) = if let Some(position) = args.query.position.as_ref() {
let position = spdi::Pos {
Expand Down
70 changes: 51 additions & 19 deletions src/freqs/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,46 +85,58 @@
)
}

/// Enumeration of possible result records.
pub enum Record {
/// Record for autosomal variant.
Autosomal(freqs::serialized::auto::Record),
/// Record for gonosomal variant.
Gonosomal(freqs::serialized::xy::Record),
/// Record for mitochondrial variant.
Mitochondrial(freqs::serialized::mt::Record),
}

/// Query for a single variant in the RocksDB database.
pub fn query_for_variant(
variant: &spdi::Var,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
out_writer: &mut dyn std::io::Write,
_out_format: common::cli::OutputFormat,
) -> Result<(), anyhow::Error> {
) -> Result<Option<Record>, anyhow::Error> {
let seq = variant.sequence.to_lowercase();
let var: keys::Var = variant.clone().into();
let key: Vec<u8> = var.into();
if seq.contains('m') {
let cf_mtdna: Arc<rocksdb::BoundColumnFamily> = db.cf_handle("mitochondrial").unwrap();
let raw_value = db.get_cf(&cf_mtdna, &key)?;
let raw_value = db
.get_cf(&cf_mtdna, &key)
.map_err(|e| anyhow::anyhow!("error reading from RocksDB: {}", e))?;

Check warning on line 111 in src/freqs/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/freqs/cli/query.rs#L111

Added line #L111 was not covered by tests
if let Some(raw_value) = raw_value {
let value = freqs::serialized::mt::Record::from_buf(&raw_value);
let json_value = serde_json::to_value(value)?;
let json = serde_json::to_string(&json_value)?;
writeln!(out_writer, "{}", &json)?;
return Ok(Some(Record::Mitochondrial(
freqs::serialized::mt::Record::from_buf(&raw_value),
)));
}
} else if seq.contains('x') || seq.contains('y') {
let cf_xy: Arc<rocksdb::BoundColumnFamily> = db.cf_handle("gonosomal").unwrap();
let raw_value = db.get_cf(&cf_xy, &key)?;
let raw_value = db
.get_cf(&cf_xy, &key)
.map_err(|e| anyhow::anyhow!("error reading from RocksDB: {}", e))?;

Check warning on line 121 in src/freqs/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/freqs/cli/query.rs#L121

Added line #L121 was not covered by tests
if let Some(raw_value) = raw_value {
let value = freqs::serialized::xy::Record::from_buf(&raw_value);
let json_value = serde_json::to_value(value)?;
let json = serde_json::to_string(&json_value)?;
writeln!(out_writer, "{}", &json)?;
return Ok(Some(Record::Gonosomal(
freqs::serialized::xy::Record::from_buf(&raw_value),
)));
}
} else {
let cf_auto: Arc<rocksdb::BoundColumnFamily> = db.cf_handle("autosomal").unwrap();
let raw_value = db.get_cf(&cf_auto, &key)?;
let raw_value = db
.get_cf(&cf_auto, &key)
.map_err(|e| anyhow::anyhow!("error reading from RocksDB: {}", e))?;

Check warning on line 131 in src/freqs/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/freqs/cli/query.rs#L131

Added line #L131 was not covered by tests
if let Some(raw_value) = raw_value {
let value = freqs::serialized::auto::Record::from_buf(&raw_value);
let json_value = serde_json::to_value(value)?;
let json = serde_json::to_string(&json_value)?;
writeln!(out_writer, "{}", &json)?;
return Ok(Some(Record::Autosomal(
freqs::serialized::auto::Record::from_buf(&raw_value),
)));
}
}

Ok(())
Ok(None)
}

/// Implementation of `tsv query` sub command.
Expand All @@ -146,7 +158,27 @@

tracing::info!("Running query...");
let before_query = std::time::Instant::now();
query_for_variant(&args.variant, &db, &mut out_writer, args.out_format)?;
if let Some(variant) = query_for_variant(&args.variant, &db, args.out_format)? {
match variant {
Record::Autosomal(record) => {
let json_value = serde_json::to_value(record)?;
let json = serde_json::to_string(&json_value)?;
writeln!(out_writer, "{}", &json)?;
}
Record::Gonosomal(record) => {
let json_value = serde_json::to_value(record)?;
let json = serde_json::to_string(&json_value)?;
writeln!(out_writer, "{}", &json)?;
}
Record::Mitochondrial(record) => {
let json_value = serde_json::to_value(record)?;
let json = serde_json::to_string(&json_value)?;
writeln!(out_writer, "{}", &json)?;
}
}
} else {
tracing::info!("no record found for variant {:?}", &args.variant);
}
tracing::info!("... done querying in {:?}", before_query.elapsed());

tracing::info!("All done. Have a nice day!");
Expand Down
34 changes: 25 additions & 9 deletions src/genes/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,28 @@
Ok(())
}

/// Query for one gene annotation record.
pub fn query_for_gene(

Check warning on line 78 in src/genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/genes/cli/query.rs#L78

Added line #L78 was not covered by tests
hgnc_id: &str,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
cf_data: &Arc<rocksdb::BoundColumnFamily>,
) -> Result<Option<pbs::Record>, anyhow::Error> {
let raw_value = db
.get_cf(cf_data, hgnc_id.as_bytes())
.map_err(|e| anyhow::anyhow!("error while querying for HGNC ID {}: {}", hgnc_id, e))?;
raw_value
.map(|raw_value| {
pbs::Record::decode(&mut std::io::Cursor::new(&raw_value)).map_err(|e| {
anyhow::anyhow!(

Check warning on line 89 in src/genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/genes/cli/query.rs#L83-L89

Added lines #L83 - L89 were not covered by tests
"error while decoding gene record for HGNC ID {}: {}",
hgnc_id,
e
)
})
})
.transpose()
}

/// Implementation of `gene query` sub command.
pub fn run(common: &common::cli::Args, args: &Args) -> Result<(), anyhow::Error> {
tracing::info!("Starting 'gene query' command");
Expand All @@ -94,17 +116,11 @@
};

tracing::info!("Running query...");
let raw_value = db.get_cf(&cf_data, args.hgnc_id.as_bytes())?;
if let Some(raw_value) = raw_value {
print_record(
&mut out_writer,
args.out_format,
&pbs::Record::decode(&mut std::io::Cursor::new(&raw_value))?,
)?;
if let Some(record) = query_for_gene(&args.hgnc_id, &db, &cf_data)? {
print_record(&mut out_writer, args.out_format, &record)?;

Check warning on line 120 in src/genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/genes/cli/query.rs#L119-L120

Added lines #L119 - L120 were not covered by tests
} else {
tracing::info!("No data found for HGNC ID {}", args.hgnc_id);
tracing::info!("no record found for HGNC ID {:?}", args.hgnc_id);

Check warning on line 122 in src/genes/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/genes/cli/query.rs#L122

Added line #L122 was not covered by tests
}

tracing::info!("All done. Have a nice day!");
Ok(())
}
26 changes: 15 additions & 11 deletions src/gnomad_mtdna/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
meta: &Meta,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
cf_data: &Arc<rocksdb::BoundColumnFamily>,
) -> Result<gnomad_pbs::mtdna::Record, anyhow::Error> {
) -> Result<Option<gnomad_pbs::mtdna::Record>, anyhow::Error> {
// Split off the genome release (checked) and convert to key as used in database.
let query = spdi::Var {
sequence: extract_chrom::from_var(variant, Some(&meta.genome_release))?,
Expand All @@ -113,11 +113,15 @@
let var: keys::Var = query.into();
let key: Vec<u8> = var.into();
let raw_value = db
.get_cf(cf_data, key)?
.ok_or_else(|| anyhow::anyhow!("could not find variant in database"))?;
// Decode via prost.
gnomad_pbs::mtdna::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))
.get_cf(cf_data, key)
.map_err(|e| anyhow::anyhow!("error reading from RocksDB: {}", e))?;

Check warning on line 117 in src/gnomad_mtdna/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/gnomad_mtdna/cli/query.rs#L117

Added line #L117 was not covered by tests
raw_value
.map(|raw_value| {
// Decode via prost.
gnomad_pbs::mtdna::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))

Check warning on line 122 in src/gnomad_mtdna/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/gnomad_mtdna/cli/query.rs#L122

Added line #L122 was not covered by tests
})
.transpose()
}

/// Implementation of `tsv query` sub command.
Expand All @@ -141,11 +145,11 @@
tracing::info!("Running query...");
let before_query = std::time::Instant::now();
if let Some(variant) = args.query.variant.as_ref() {
print_record(
&mut out_writer,
args.out_format,
&query_for_variant(variant, &meta, &db, &cf_data)?,
)?;
if let Some(record) = query_for_variant(variant, &meta, &db, &cf_data)? {
print_record(&mut out_writer, args.out_format, &record)?;
} else {
tracing::info!("no record found for variant {:?}", &variant);

Check warning on line 151 in src/gnomad_mtdna/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/gnomad_mtdna/cli/query.rs#L151

Added line #L151 was not covered by tests
}
} else {
let (start, stop) = if let Some(position) = args.query.position.as_ref() {
let position = spdi::Pos {
Expand Down
26 changes: 15 additions & 11 deletions src/gnomad_nuclear/cli/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
meta: &Meta,
db: &rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>,
cf_data: &Arc<rocksdb::BoundColumnFamily>,
) -> Result<gnomad_pbs::gnomad2::Record, anyhow::Error> {
) -> Result<Option<gnomad_pbs::gnomad2::Record>, anyhow::Error> {
// Split off the genome release (checked) and convert to key as used in database.
let query = spdi::Var {
sequence: extract_chrom::from_var(variant, Some(&meta.genome_release))?,
Expand All @@ -113,11 +113,15 @@
let var: keys::Var = query.into();
let key: Vec<u8> = var.into();
let raw_value = db
.get_cf(cf_data, key)?
.ok_or_else(|| anyhow::anyhow!("could not find variant in database"))?;
// Decode via prost.
gnomad_pbs::gnomad2::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))
.get_cf(cf_data, key)
.map_err(|e| anyhow::anyhow!("problem querying RocksDB: {}", e))?;

Check warning on line 117 in src/gnomad_nuclear/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/gnomad_nuclear/cli/query.rs#L117

Added line #L117 was not covered by tests
raw_value
.map(|raw_value| {
// Decode via prost.
gnomad_pbs::gnomad2::Record::decode(&mut std::io::Cursor::new(&raw_value))
.map_err(|e| anyhow::anyhow!("failed to decode record: {}", e))

Check warning on line 122 in src/gnomad_nuclear/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/gnomad_nuclear/cli/query.rs#L122

Added line #L122 was not covered by tests
})
.transpose()
}

/// Implementation of `tsv query` sub command.
Expand All @@ -141,11 +145,11 @@
tracing::info!("Running query...");
let before_query = std::time::Instant::now();
if let Some(variant) = args.query.variant.as_ref() {
print_record(
&mut out_writer,
args.out_format,
&query_for_variant(variant, &meta, &db, &cf_data)?,
)?;
if let Some(record) = query_for_variant(variant, &meta, &db, &cf_data)? {
print_record(&mut out_writer, args.out_format, &record)?
} else {
tracing::info!("no record found for variant {:?}", &variant);

Check warning on line 151 in src/gnomad_nuclear/cli/query.rs

View check run for this annotation

Codecov / codecov/patch

src/gnomad_nuclear/cli/query.rs#L151

Added line #L151 was not covered by tests
}
} else {
let (start, stop) = if let Some(position) = args.query.position.as_ref() {
let position = spdi::Pos {
Expand Down
Loading
Loading