Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

pcat.rs 2.7 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  1. use structopt::StructOpt;
  2. use std::io::prelude::*;
  3. use std::io;
  4. use std::fs::File;
  5. use std::path::{PathBuf, Path};
  6. use log::*;
  7. use indicatif::{ProgressBar, ProgressStyle};
  8. use sha1::Sha1;
  9. use anyhow::Result;
  10. use happylog::set_progress;
  11. use crate::db::{DbOpts, CopyRequest};
  12. use crate::tracking::{Stage, StageOpts};
  13. use crate::io::{HashWrite};
  14. use super::Command;
  15. const PB_STYLE: &'static str = "{prefix}: {elapsed_precise} {bar} {percent}% {bytes}/{total_bytes} (eta: {eta})";
  16. /// Concatenate one or more files with a progress bar
  17. #[derive(StructOpt, Debug)]
  18. #[structopt(name="pcat")]
  19. pub struct PCat {
  20. #[structopt(flatten)]
  21. dbo: DbOpts,
  22. #[structopt(flatten)]
  23. stage: StageOpts,
  24. /// Input file
  25. #[structopt(name = "FILE", parse(from_os_str))]
  26. infiles: Vec<PathBuf>,
  27. /// Destination table
  28. #[structopt(long="table", short="t")]
  29. table: Option<String>,
  30. /// Input format
  31. #[structopt(long="format", short="f")]
  32. format: Option<String>
  33. }
  34. /// Cat a file from input to output, hashing on the way.
  35. fn cat_file<'o, 'c, P: AsRef<Path>, W: Write>(stage: &mut Stage<'o, 'c>, inf: P, out: &mut W) -> Result<()> {
  36. let inf: &Path = inf.as_ref();
  37. let fstr = inf.to_string_lossy();
  38. info!("opening file {:?}", inf);
  39. let fs = File::open(inf)?;
  40. let pb = ProgressBar::new(fs.metadata().unwrap().len());
  41. pb.set_style(ProgressStyle::default_bar().template(PB_STYLE));
  42. pb.set_prefix(&fstr);
  43. let _pbs = set_progress(&pb);
  44. let mut sf = stage.source_file(inf);
  45. let read = sf.wrap_read(fs);
  46. let mut pbr = pb.wrap_read(read);
  47. io::copy(&mut pbr, out)?;
  48. drop(pbr);
  49. let hash = sf.record()?;
  50. write!(stage, "READ {:?} {}", inf, hash)?;
  51. Ok(())
  52. }
  53. impl Command for PCat {
  54. fn exec(self) -> Result<()> {
  55. match self.table {
  56. Some(ref t) => self.db_cat(t),
  57. None => self.raw_cat()
  58. }
  59. }
  60. }
  61. impl PCat {
  62. fn raw_cat(&self) -> Result<()> {
  63. let stdout = io::stdout();
  64. let mut out = stdout.lock();
  65. let mut stage = self.stage.empty();
  66. for inf in &self.infiles {
  67. cat_file(&mut stage, inf, &mut out)?;
  68. }
  69. Ok(())
  70. }
  71. fn db_cat(&self, table: &str) -> Result<()> {
  72. let db = self.dbo.open()?;
  73. let mut stage = self.stage.begin_stage(&db)?;
  74. let mut req = CopyRequest::new(&self.dbo, table)?.truncate(true);
  75. if let Some(ref fmt) = self.format {
  76. req = req.with_format(fmt);
  77. }
  78. info!("copying to table {}", table);
  79. writeln!(stage, "COPY TO {}", table)?;
  80. let out = req.open()?;
  81. let mut out_hash = Sha1::new();
  82. let mut out = HashWrite::create(out, &mut out_hash);
  83. for inf in &self.infiles {
  84. let inf = inf.as_path();
  85. cat_file(&mut stage, inf, &mut out)?;
  86. }
  87. drop(out);
  88. let hash = out_hash.hexdigest();
  89. stage.end(&Some(hash))?;
  90. Ok(())
  91. }
  92. }
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...