Skip to content
Closed
Show file tree
Hide file tree
Changes from 11 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
3 changes: 2 additions & 1 deletion diesel_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ toml = "0.4.6"
url = { version = "1.4.0", optional = true }
barrel = { version = "<= 0.2.0", optional = true, features = ["diesel-filled"] }
libsqlite3-sys = { version = ">=0.8.0, <0.13.0", optional = true, features = ["min_sqlite_version_3_7_16"] }
regex = "1.0.6"
serde_regex = "0.3.1"

[dev-dependencies]
difference = "1.0"
tempdir = "0.3.4"
regex = "0.2"
url = { version = "1.4.0" }

[features]
Expand Down
34 changes: 31 additions & 3 deletions diesel_cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,32 +124,60 @@ pub fn build_cli() -> App<'static, 'static> {
.short("o")
.long("only-tables")
.help("Only include tables from table-name")
.conflicts_with("only-table-regexes")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next release will be 2.0 so we can make a breaking change here. Therefore I would prefer to just introduce this functionality under the old flags.

cc @diesel-rs/core as information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the old flags mean?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking of just replacing the old flag (only-tables) with the regex filtering.

.conflicts_with("except-tables")
.conflicts_with("except-table-regexes")
.conflicts_with("blacklist"),
)
.arg(
Arg::with_name("only-table-regexes")
.long("only-table-regexes")
.help("Only include tables from table-name that matches regexp")
.conflicts_with("only-tables")
.conflicts_with("whitelist")
.conflicts_with("except-tables")
.conflicts_with("except-table-regexes")
.conflicts_with("blacklist"),
)
.arg(
Arg::with_name("whitelist")
.short("w")
.long("whitelist")
.hidden(true)
.conflicts_with("only-table-regexes")
.conflicts_with("blacklist")
.conflicts_with("except-tables"),
.conflicts_with("except-tables")
.conflicts_with("except-table-regexes"),
)
.arg(
Arg::with_name("except-tables")
.short("e")
.long("except-tables")
.help("Exclude tables from table-name")
.conflicts_with("only-tables")
.conflicts_with("whitelist"),
.conflicts_with("only-table-regexes")
.conflicts_with("whitelist")
.conflicts_with("except-table-regexes"),
)
.arg(
Arg::with_name("except-table-regexes")
.long("except-table-regexes")
.help("Exclude tables from table-name that matches regex")
.conflicts_with("only-tables")
.conflicts_with("whitelist")
.conflicts_with("only-table-regexes")
.conflicts_with("except-tables")
.conflicts_with("blacklist"),
)
.arg(
Arg::with_name("blacklist")
.short("b")
.long("blacklist")
.hidden(true)
.conflicts_with("whitelist")
.conflicts_with("only-tables"),
.conflicts_with("only-tables")
.conflicts_with("only-table-regexes")
.conflicts_with("except-table-regexes"),
)
.arg(
Arg::with_name("with-docs")
Expand Down
13 changes: 13 additions & 0 deletions diesel_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ extern crate dotenv;
extern crate migrations_internals;
#[macro_use]
extern crate serde;
extern crate regex;
extern crate serde_regex;
extern crate tempfile;
extern crate toml;
#[cfg(feature = "url")]
Expand All @@ -45,6 +47,7 @@ mod query_helper;
use chrono::*;
use clap::{ArgMatches, Shell};
use migrations_internals::{self as migrations, MigrationConnection};
use regex::Regex;
use std::any::Any;
use std::error::Error;
use std::io::stdout;
Expand Down Expand Up @@ -368,6 +371,12 @@ fn run_infer_schema(matches: &ArgMatches) -> Result<(), Box<Error>> {
})
.collect();

let filter_regex = matches
.values_of("table-name-regexpes")
.unwrap_or_default()
.map(|table_name_regex| Regex::new(table_name_regex).unwrap().into())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we print a nicer error message here if the provided string is no valid regex?

(Hint: If that map returns a Result it is possible to collect into a Result<Vec<_>, _>)

.collect();

if matches.is_present("whitelist") {
eprintln!("The `whitelist` option has been deprecated and renamed to `only-tables`.");
}
Expand All @@ -378,8 +387,12 @@ fn run_infer_schema(matches: &ArgMatches) -> Result<(), Box<Error>> {

if matches.is_present("only-tables") || matches.is_present("whitelist") {
config.filter = Filtering::OnlyTables(filter)
} else if matches.is_present("only-table-regexes") {
config.filter = Filtering::OnlyTableRegexes(filter_regex)
} else if matches.is_present("except-tables") || matches.is_present("blacklist") {
config.filter = Filtering::ExceptTables(filter)
} else if matches.is_present("except-table-regexes") {
config.filter = Filtering::ExceptTableRegexes(filter_regex)
}

if matches.is_present("with-docs") {
Expand Down
63 changes: 51 additions & 12 deletions diesel_cli/src/print_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use config;
use infer_schema_internals::*;
use serde::de::{self, MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use serde_regex::Serde as RegexWrapper;
use std::error::Error;
use std::fmt::{self, Display, Formatter, Write};
use std::fs::File;
Expand All @@ -11,9 +12,13 @@ use std::path::Path;
use std::process::Command;
use tempfile::NamedTempFile;

type Regex = RegexWrapper<::regex::Regex>;

pub enum Filtering {
OnlyTables(Vec<TableName>),
OnlyTableRegexes(Vec<Regex>),
ExceptTables(Vec<TableName>),
ExceptTableRegexes(Vec<Regex>),
None,
}

Expand All @@ -29,7 +34,13 @@ impl Filtering {

match *self {
OnlyTables(ref names) => !names.contains(name),
OnlyTableRegexes(ref regexes) => {
!regexes.iter().any(|regex| regex.is_match(&name.name))
}
ExceptTables(ref names) => names.contains(name),
ExceptTableRegexes(ref regexes) => {
regexes.iter().any(|regex| regex.is_match(&name.name))
}
None => false,
}
}
Expand Down Expand Up @@ -309,42 +320,70 @@ impl<'de> Deserialize<'de> for Filtering {
type Value = Filtering;

fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("either only_tables or except_tables")
f.write_str("either only_tables, only_table_regexes, except_tables, or except_table_regexes")
}

fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
let mut only_tables = None;
let mut except_tables = None;
while let Some((key, value)) = map.next_entry()? {
let mut only_tables = None::<Vec<TableName>>;
let mut only_table_regexes = None::<Vec<Regex>>;
let mut except_tables = None::<Vec<TableName>>;
let mut except_table_regexes = None::<Vec<Regex>>;
while let Some(key) = map.next_key()? {
match key {
"only_tables" => {
if only_tables.is_some() {
return Err(de::Error::duplicate_field("only_tables"));
}
only_tables = Some(value);
only_tables = Some(map.next_value()?);
}
"only_table_regexes" => {
if only_table_regexes.is_some() {
return Err(de::Error::duplicate_field("only_table_regexes"));
}
only_table_regexes = Some(map.next_value()?);
}
"except_tables" => {
if except_tables.is_some() {
return Err(de::Error::duplicate_field("except_tables"));
}
except_tables = Some(value);
except_tables = Some(map.next_value()?);
}
"except_table_regexes" => {
if except_table_regexes.is_some() {
return Err(de::Error::duplicate_field("except_table_regexes"));
}
except_table_regexes = Some(map.next_value()?);
}
_ => {
return Err(de::Error::unknown_field(
key,
&["only_tables", "except_tables"],
&[
"only_tables",
"only_table_regexes",
"except_tables",
"except_table_regexes",
],
))
}
}
}
match (only_tables, except_tables) {
(Some(_), Some(_)) => Err(de::Error::duplicate_field("except_tables")),
(Some(w), None) => Ok(Filtering::OnlyTables(w)),
(None, Some(b)) => Ok(Filtering::ExceptTables(b)),
(None, None) => Ok(Filtering::None),
match (
only_tables,
only_table_regexes,
except_tables,
except_table_regexes,
) {
(Some(t), None, None, None) => Ok(Filtering::OnlyTables(t)),
(None, Some(t), None, None) => Ok(Filtering::OnlyTableRegexes(t)),
(None, None, Some(t), None) => Ok(Filtering::ExceptTables(t)),
(None, None, None, Some(t)) => Ok(Filtering::ExceptTableRegexes(t)),
(None, None, None, None) => Ok(Filtering::None),
_ => Err(de::Error::duplicate_field(
"only_tables, only_table_regexes, except_tables, except_table_regexes",
)),
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions diesel_cli/tests/print_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ fn run_infer_schema_include() {
);
}

#[test]
fn run_infer_schema_include_regex() {
test_print_schema(
"print_schema_only_table_regexes",
vec!["--with-docs", "-w", "users1"],
);
}

#[test]
fn run_infer_schema_exclude() {
test_print_schema(
Expand All @@ -30,6 +38,14 @@ fn run_infer_schema_exclude() {
);
}

#[test]
fn run_infer_schema_exclude_regex() {
test_print_schema(
"print_schema_except_table_regexes",
vec!["--with-docs", "-b", "users1"],
);
}

#[test]
fn run_infer_schema_order() {
test_print_schema("print_schema_order", vec!["--with-docs"]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[print_schema]
file = "src/schema.rs"
with_docs = true
filter = { except_table_regexes = [".*1"] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
table! {
/// Representation of the `users2` table.
///
/// (Automatically generated by Diesel.)
users2 (id) {
/// The `id` column of the `users2` table.
///
/// Its SQL type is `Integer`.
///
/// (Automatically generated by Diesel.)
id -> Integer,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE users1 (id INTEGER PRIMARY KEY);
CREATE TABLE users2 (id INTEGER PRIMARY KEY);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
table! {
/// Representation of the `users2` table.
///
/// (Automatically generated by Diesel.)
users2 (id) {
/// The `id` column of the `users2` table.
///
/// Its SQL type is `Int4`.
///
/// (Automatically generated by Diesel.)
id -> Int4,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE users1 (id SERIAL PRIMARY KEY);
CREATE TABLE users2 (id SERIAL PRIMARY KEY);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
table! {
/// Representation of the `users2` table.
///
/// (Automatically generated by Diesel.)
users2 (id) {
/// The `id` column of the `users2` table.
///
/// Its SQL type is `Nullable<Integer>`.
///
/// (Automatically generated by Diesel.)
id -> Nullable<Integer>,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE users1 (id INTEGER PRIMARY KEY);
CREATE TABLE users2 (id INTEGER PRIMARY KEY);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[print_schema]
file = "src/schema.rs"
with_docs = true
filter = { only_table_regexes = [".*1"] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
table! {
/// Representation of the `users1` table.
///
/// (Automatically generated by Diesel.)
users1 (id) {
/// The `id` column of the `users1` table.
///
/// Its SQL type is `Integer`.
///
/// (Automatically generated by Diesel.)
id -> Integer,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE users1 (id INTEGER PRIMARY KEY);
CREATE TABLE users2 (id INTEGER PRIMARY KEY);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
table! {
/// Representation of the `users1` table.
///
/// (Automatically generated by Diesel.)
users1 (id) {
/// The `id` column of the `users1` table.
///
/// Its SQL type is `Int4`.
///
/// (Automatically generated by Diesel.)
id -> Int4,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE users1 (id SERIAL PRIMARY KEY);
CREATE TABLE users2 (id SERIAL PRIMARY KEY);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
table! {
/// Representation of the `users1` table.
///
/// (Automatically generated by Diesel.)
users1 (id) {
/// The `id` column of the `users1` table.
///
/// Its SQL type is `Nullable<Integer>`.
///
/// (Automatically generated by Diesel.)
id -> Nullable<Integer>,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE TABLE users1 (id INTEGER PRIMARY KEY);
CREATE TABLE users2 (id INTEGER PRIMARY KEY);