Skip to content
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
and a bound to `QueryableByName<DB>` with `FromSqlRow<Untyped, DB>`.


* CLI flags of `only-tables` and `except-tables` are now interpreted as regular expressions.
Similary, `only_tabels` and `except_tables` in `diesel.toml` are treated as regular expressions.

### Fixed

* Many types were incorrectly considered non-aggregate when they should not
Expand Down
2 changes: 2 additions & 0 deletions diesel_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ url = { version = "2.1.0", optional = true }
barrel = { version = ">= 0.5.0", optional = true, features = ["diesel"] }
libsqlite3-sys = { version = ">=0.8.0, <0.21.0", optional = true, features = ["min_sqlite_version_3_7_16"] }
diffy = "0.2.0"
regex = "1.0.6"
serde_regex = "0.3.1"

[dependencies.diesel]
version = "~2.0.0"
Expand Down
22 changes: 2 additions & 20 deletions diesel_cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,32 +123,14 @@ pub fn build_cli() -> App<'static, 'static> {
Arg::with_name("only-tables")
.short("o")
.long("only-tables")
.help("Only include tables from table-name")
.conflicts_with("except-tables")
.conflicts_with("blacklist"),
)
.arg(
Arg::with_name("whitelist")
.short("w")
.long("whitelist")
.hidden(true)
.conflicts_with("blacklist")
.help("Only include tables from table-name that matches regexp")
.conflicts_with("except-tables"),
)
.arg(
Arg::with_name("except-tables")
.short("e")
.long("except-tables")
.help("Exclude tables from table-name")
.conflicts_with("only-tables")
.conflicts_with("whitelist"),
)
.arg(
Arg::with_name("blacklist")
.short("b")
.long("blacklist")
.hidden(true)
.conflicts_with("whitelist")
.help("Exclude tables from table-name that matches regex")
.conflicts_with("only-tables"),
)
.arg(
Expand Down
31 changes: 9 additions & 22 deletions diesel_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,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::fmt::Display;
Expand Down Expand Up @@ -383,7 +384,6 @@ fn convert_absolute_path_to_relative(target_path: &Path, mut current_path: &Path
}

fn run_infer_schema(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
use crate::infer_schema_internals::TableName;
use crate::print_schema::*;

let database_url = database::database_url(matches);
Expand All @@ -396,27 +396,14 @@ fn run_infer_schema(matches: &ArgMatches) -> Result<(), Box<dyn Error>> {
let filter = matches
.values_of("table-name")
.unwrap_or_default()
.map(|table_name| {
if let Some(schema) = config.schema_name() {
TableName::new(table_name, schema)
} else {
table_name.parse().unwrap()
}
})
.collect();

if matches.is_present("whitelist") {
eprintln!("The `whitelist` option has been deprecated and renamed to `only-tables`.");
}

if matches.is_present("blacklist") {
eprintln!("The `blacklist` option has been deprecated and renamed to `except-tables`.");
}

if matches.is_present("only-tables") || matches.is_present("whitelist") {
config.filter = Filtering::OnlyTables(filter)
} else if matches.is_present("except-tables") || matches.is_present("blacklist") {
config.filter = Filtering::ExceptTables(filter)
.map(|table_name_regex| Regex::new(table_name_regex).map(Into::into))
.collect::<Result<_, _>>()
.map_err(|e| format!("invalid argument for table filtering regex: {}", e));

if matches.is_present("only-tables") {
config.filter = Filtering::OnlyTables(filter?)
} else if matches.is_present("except-tables") {
config.filter = Filtering::ExceptTables(filter?)
}

if matches.is_present("with-docs") {
Expand Down
27 changes: 15 additions & 12 deletions diesel_cli/src/print_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ use crate::config;
use crate::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::io::Write as IoWrite;

const SCHEMA_HEADER: &str = "// @generated automatically by Diesel CLI.\n";

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

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

Expand All @@ -26,8 +29,8 @@ impl Filtering {
use self::Filtering::*;

match *self {
OnlyTables(ref names) => !names.contains(name),
ExceptTables(ref names) => names.contains(name),
OnlyTables(ref regexes) => !regexes.iter().any(|regex| regex.is_match(&name.sql_name)),
ExceptTables(ref regexes) => regexes.iter().any(|regex| regex.is_match(&name.sql_name)),
None => false,
}
}
Expand Down Expand Up @@ -318,21 +321,21 @@ impl<'de> Deserialize<'de> for Filtering {
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<Regex>>;
let mut except_tables = 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()?);
}
"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()?);
}
_ => {
return Err(de::Error::unknown_field(
Expand All @@ -343,10 +346,10 @@ impl<'de> Deserialize<'de> for Filtering {
}
}
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)),
(Some(t), None) => Ok(Filtering::OnlyTables(t)),
(None, Some(t)) => Ok(Filtering::ExceptTables(t)),
(None, None) => Ok(Filtering::None),
_ => Err(de::Error::duplicate_field("only_tables except_tables")),
}
}
}
Expand Down
20 changes: 18 additions & 2 deletions diesel_cli/tests/print_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,31 @@ fn run_infer_schema() {
fn run_infer_schema_include() {
test_print_schema(
"print_schema_only_tables",
vec!["--with-docs", "-w", "users1"],
vec!["--with-docs", "-o", "users1"],
);
}

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

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

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

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_tables = [".*1"] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @generated automatically by Diesel CLI.

diesel::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,15 @@
// @generated automatically by Diesel CLI.

diesel::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,15 @@
// @generated automatically by Diesel CLI.

diesel::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_tables = [".*1"] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @generated automatically by Diesel CLI.

diesel::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,15 @@
// @generated automatically by Diesel CLI.

diesel::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,15 @@
// @generated automatically by Diesel CLI.

diesel::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);