Skip to content

Commit f3d511c

Browse files
committed
updated SqlDoc to be able to build from a vec of PathBuf; fixes #19
1 parent 64cea99 commit f3d511c

File tree

2 files changed

+85
-22
lines changed

2 files changed

+85
-22
lines changed

fuzz/fuzz_targets/sql_docs.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,62 +6,62 @@ use std::str;
66
use sql_docs::SqlDoc;
77

88
fuzz_target!(|data: String| {
9-
let _ = SqlDoc::from_str(&data).build();
9+
let _ = SqlDoc::builder_from_str(&data).build();
1010

11-
let _ = SqlDoc::from_str(&data)
11+
let _ = SqlDoc::builder_from_str(&data)
1212
.deny(&data)
1313
.build();
1414

15-
let _ = SqlDoc::from_str(&data)
15+
let _ = SqlDoc::builder_from_str(&data)
1616
.flatten_multiline()
1717
.build();
1818

19-
let _ = SqlDoc::from_str(&data)
19+
let _ = SqlDoc::builder_from_str(&data)
2020
.flatten_multiline_with("")
2121
.build();
2222

23-
let _ = SqlDoc::from_str(&data)
23+
let _ = SqlDoc::builder_from_str(&data)
2424
.flatten_multiline_with(" ")
2525
.build();
2626

27-
let _ = SqlDoc::from_str(&data)
27+
let _ = SqlDoc::builder_from_str(&data)
2828
.flatten_multiline_with("\n")
2929
.build();
3030

31-
let _ = SqlDoc::from_str(&data)
31+
let _ = SqlDoc::builder_from_str(&data)
3232
.flatten_multiline_with(" | ")
3333
.build();
3434

35-
let _ = SqlDoc::from_str(&data)
35+
let _ = SqlDoc::builder_from_str(&data)
3636
.preserve_multiline()
3737
.build();
3838

39-
let _ = SqlDoc::from_str(&data)
39+
let _ = SqlDoc::builder_from_str(&data)
4040
.flatten_multiline()
4141
.preserve_multiline()
4242
.build();
4343

44-
let _ = SqlDoc::from_str(&data)
44+
let _ = SqlDoc::builder_from_str(&data)
4545
.preserve_multiline()
4646
.flatten_multiline()
4747
.build();
4848

49-
let _ = SqlDoc::from_str(&data)
49+
let _ = SqlDoc::builder_from_str(&data)
5050
.deny("nonexistent.sql")
5151
.flatten_multiline()
5252
.build();
5353

54-
let _ = SqlDoc::from_str(&data)
54+
let _ = SqlDoc::builder_from_str(&data)
5555
.deny("nonexistent.sql")
5656
.flatten_multiline_with(" ")
5757
.build();
5858

59-
let _ = SqlDoc::from_str(&data)
59+
let _ = SqlDoc::builder_from_str(&data)
6060
.deny(&data)
6161
.flatten_multiline_with("\n")
6262
.build();
6363

64-
let _ = SqlDoc::from_str(&data)
64+
let _ = SqlDoc::builder_from_str(&data)
6565
.deny("a.sql")
6666
.deny("b.sql")
6767
.flatten_multiline_with(" | ")

src/sql_doc.rs

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Public entry point for building [`SqlDoc`] from a directory, file, or string.
22
3-
use std::{path::{Path, PathBuf}, str::FromStr};
3+
use std::{
4+
path::{Path, PathBuf},
5+
str::FromStr,
6+
};
47

58
use crate::{
69
ast::ParsedSqlFile,
@@ -44,6 +47,7 @@ pub enum MultiFlatten {
4447
enum SqlFileDocSource<'a> {
4548
Dir(PathBuf),
4649
File(PathBuf),
50+
Files(Vec<PathBuf>),
4751
FromString(&'a str),
4852
}
4953

@@ -54,7 +58,7 @@ impl SqlDoc {
5458
Self { tables }
5559
}
5660
/// Method for generating builder from a directory.
57-
pub fn from_dir<P: AsRef<Path> + ?Sized>(root: &P) -> SqlDocBuilder<'_> {
61+
pub fn from_dir<P: AsRef<Path>>(root: &P) -> SqlDocBuilder<'_> {
5862
SqlDocBuilder {
5963
source: SqlFileDocSource::Dir(root.as_ref().to_path_buf()),
6064
deny: Vec::new(),
@@ -70,6 +74,17 @@ impl SqlDoc {
7074
}
7175
}
7276

77+
/// Method for generating builder from a [`[Path]`]
78+
pub fn from_paths<P: AsRef<Path>>(paths: &[P]) -> SqlDocBuilder<'_> {
79+
SqlDocBuilder {
80+
source: SqlFileDocSource::Files(
81+
paths.iter().map(|p| p.as_ref().to_path_buf()).collect(),
82+
),
83+
deny: Vec::new(),
84+
multiline_flat: MultiFlatten::NoFlat,
85+
}
86+
}
87+
7388
/// Creates a builder from SQL text (no filesystem path is associated) from a [`str`]
7489
#[must_use]
7590
pub const fn builder_from_str(content: &str) -> SqlDocBuilder<'_> {
@@ -148,7 +163,7 @@ impl FromStr for SqlDoc {
148163
type Err = DocError;
149164

150165
fn from_str(s: &str) -> Result<Self, Self::Err> {
151-
SqlDoc::builder_from_str(s).build()
166+
Self::builder_from_str(s).build()
152167
}
153168
}
154169

@@ -200,6 +215,7 @@ impl SqlDocBuilder<'_> {
200215
let sql_docs = generate_docs_str(content)?;
201216
vec![sql_docs]
202217
}
218+
SqlFileDocSource::Files(files) => generate_docs_from_files(files)?,
203219
};
204220
let num_of_tables = docs.iter().map(super::docs::SqlFileDoc::number_of_tables).sum();
205221
let mut tables = Vec::with_capacity(num_of_tables);
@@ -263,6 +279,15 @@ fn generate_docs_from_dir<P: AsRef<Path>, S: AsRef<str>>(
263279
Ok(sql_docs)
264280
}
265281

282+
fn generate_docs_from_files(files: &[PathBuf]) -> Result<Vec<SqlFileDoc>, DocError> {
283+
let mut sql_docs = Vec::new();
284+
for file in files {
285+
let docs = generate_docs_from_file(file)?;
286+
sql_docs.push(docs);
287+
}
288+
Ok(sql_docs)
289+
}
290+
266291
fn generate_docs_from_file<P: AsRef<Path>>(source: P) -> Result<SqlFileDoc, DocError> {
267292
let file = SqlFile::new(source.as_ref())?;
268293
let parsed_file = ParsedSqlFile::parse(file)?;
@@ -695,10 +720,48 @@ mod tests {
695720
}
696721

697722
#[test]
698-
fn test_fromstr_parse_sql_doc() -> Result<(), Box<dyn std::error::Error>> {
699-
let doc: SqlDoc = "CREATE TABLE t(id INTEGER);".parse()?;
700-
assert_eq!(doc.tables().len(), 1);
701-
Ok(())
702-
}
723+
fn test_fromstr_parse_sql_doc() -> Result<(), Box<dyn std::error::Error>> {
724+
let doc: SqlDoc = "CREATE TABLE t(id INTEGER);".parse()?;
725+
assert_eq!(doc.tables().len(), 1);
726+
Ok(())
727+
}
728+
729+
#[test]
730+
fn test_build_sql_doc_from_paths() -> Result<(), Box<dyn std::error::Error>> {
731+
let base = env::temp_dir().join("build_sql_doc_from_paths");
732+
let _ = fs::remove_dir_all(&base);
733+
fs::create_dir_all(&base)?;
734+
let sample = sample_sql();
735+
let (sql1, doc1) = &sample[0];
736+
let (sql2, doc2) = &sample[1];
737+
738+
let file1 = base.join("one.sql");
739+
let file2 = base.join("two.sql");
740+
fs::write(&file1, sql1)?;
741+
fs::write(&file2, sql2)?;
742+
743+
let paths = vec![file1.clone(), file2.clone()];
744+
let sql_doc = SqlDoc::from_paths(&paths).build()?;
745+
746+
let mut expected_tables: Vec<TableDoc> = Vec::new();
703747

748+
let mut t1 = doc1.clone().into_tables();
749+
stamp_table_paths(&mut t1, &file1);
750+
expected_tables.extend(t1);
751+
752+
let mut t2 = doc2.clone().into_tables();
753+
stamp_table_paths(&mut t2, &file2);
754+
expected_tables.extend(t2);
755+
756+
let mut actual_tables = sql_doc.into_tables();
757+
assert_eq!(actual_tables.len(), expected_tables.len());
758+
759+
sort_tables(&mut actual_tables);
760+
sort_tables(&mut expected_tables);
761+
762+
assert_eq!(actual_tables, expected_tables);
763+
764+
let _ = fs::remove_dir_all(&base);
765+
Ok(())
766+
}
704767
}

0 commit comments

Comments
 (0)