Skip to content

Commit 5891c8a

Browse files
add that
1 parent 150f1a2 commit 5891c8a

File tree

6 files changed

+78
-2
lines changed

6 files changed

+78
-2
lines changed

crates/pglt_analyser/src/lint/safety.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
use pglt_analyse::declare_lint_group;
44
pub mod ban_drop_column;
55
pub mod ban_drop_not_null;
6-
declare_lint_group! { pub Safety { name : "safety" , rules : [self :: ban_drop_column :: BanDropColumn , self :: ban_drop_not_null :: BanDropNotNull ,] } }
6+
pub mod ban_drop_table;
7+
declare_lint_group! { pub Safety { name : "safety" , rules : [self :: ban_drop_column :: BanDropColumn , self :: ban_drop_not_null :: BanDropNotNull , self :: ban_drop_table :: BanDropTable ,] } }
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use pglt_analyse::{context::RuleContext, declare_lint_rule, Rule, RuleDiagnostic, RuleSource};
2+
use pglt_console::markup;
3+
4+
declare_lint_rule! {
5+
/// Dropping a table may break existing clients.
6+
///
7+
/// Update your application code to no longer read or write the table.
8+
///
9+
/// Once the table is no longer needed, you can delete it by running the command "DROP TABLE mytable;".
10+
///
11+
/// This command will permanently remove the table from the database and all its contents.
12+
/// Be sure to back up the table before deleting it, just in case you need to restore it in the future.
13+
///
14+
/// ## Examples
15+
/// ```sql,expect_diagnostic
16+
/// drop table some_table;
17+
/// ```
18+
pub BanDropTable {
19+
version: "next",
20+
name: "banDropTable",
21+
recommended: false,
22+
sources: &[RuleSource::Squawk("ban-drop-table")],
23+
}
24+
}
25+
26+
impl Rule for BanDropTable {
27+
type Options = ();
28+
29+
fn run(ctx: &RuleContext<Self>) -> Vec<RuleDiagnostic> {
30+
let mut diagnostics = vec![];
31+
32+
if let pglt_query_ext::NodeEnum::DropStmt(stmt) = &ctx.stmt() {
33+
if stmt.remove_type() == pglt_query_ext::protobuf::ObjectType::ObjectTable {
34+
diagnostics.push(
35+
RuleDiagnostic::new(
36+
rule_category!(),
37+
None,
38+
markup! {
39+
"Dropping a table may break existing clients."
40+
},
41+
)
42+
.detail(
43+
None,
44+
"Update your application code to no longer read or write the table, and only then delete the table. Be sure to create a backup.",
45+
),
46+
);
47+
}
48+
}
49+
50+
diagnostics
51+
}
52+
}

crates/pglt_analyser/src/options.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub type BanDropColumn =
55
<lint::safety::ban_drop_column::BanDropColumn as pglt_analyse::Rule>::Options;
66
pub type BanDropNotNull =
77
<lint::safety::ban_drop_not_null::BanDropNotNull as pglt_analyse::Rule>::Options;
8+
pub type BanDropTable = <lint::safety::ban_drop_table::BanDropTable as pglt_analyse::Rule>::Options;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- expect_only_lint/safety/banDropTable
2+
-- select 1;

crates/pglt_configuration/src/analyser/linter/rules.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,14 @@ pub struct Safety {
149149
#[doc = "Dropping a NOT NULL constraint may break existing clients."]
150150
#[serde(skip_serializing_if = "Option::is_none")]
151151
pub ban_drop_not_null: Option<RuleConfiguration<pglt_analyser::options::BanDropNotNull>>,
152+
#[doc = "Succinct description of the rule."]
153+
#[serde(skip_serializing_if = "Option::is_none")]
154+
pub ban_drop_table: Option<RuleConfiguration<pglt_analyser::options::BanDropTable>>,
152155
}
153156
impl Safety {
154157
const GROUP_NAME: &'static str = "safety";
155-
pub(crate) const GROUP_RULES: &'static [&'static str] = &["banDropColumn", "banDropNotNull"];
158+
pub(crate) const GROUP_RULES: &'static [&'static str] =
159+
&["banDropColumn", "banDropNotNull", "banDropTable"];
156160
const RECOMMENDED_RULES: &'static [&'static str] = &["banDropColumn", "banDropNotNull"];
157161
const RECOMMENDED_RULES_AS_FILTERS: &'static [RuleFilter<'static>] = &[
158162
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[0]),
@@ -161,6 +165,7 @@ impl Safety {
161165
const ALL_RULES_AS_FILTERS: &'static [RuleFilter<'static>] = &[
162166
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[0]),
163167
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[1]),
168+
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[2]),
164169
];
165170
#[doc = r" Retrieves the recommended rules"]
166171
pub(crate) fn is_recommended_true(&self) -> bool {
@@ -187,6 +192,11 @@ impl Safety {
187192
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[1]));
188193
}
189194
}
195+
if let Some(rule) = self.ban_drop_table.as_ref() {
196+
if rule.is_enabled() {
197+
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[2]));
198+
}
199+
}
190200
index_set
191201
}
192202
pub(crate) fn get_disabled_rules(&self) -> FxHashSet<RuleFilter<'static>> {
@@ -201,6 +211,11 @@ impl Safety {
201211
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[1]));
202212
}
203213
}
214+
if let Some(rule) = self.ban_drop_table.as_ref() {
215+
if rule.is_disabled() {
216+
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[2]));
217+
}
218+
}
204219
index_set
205220
}
206221
#[doc = r" Checks if, given a rule name, matches one of the rules contained in this category"]
@@ -245,6 +260,10 @@ impl Safety {
245260
.ban_drop_not_null
246261
.as_ref()
247262
.map(|conf| (conf.level(), conf.get_options())),
263+
"banDropTable" => self
264+
.ban_drop_table
265+
.as_ref()
266+
.map(|conf| (conf.level(), conf.get_options())),
248267
_ => None,
249268
}
250269
}

crates/pglt_diagnostics_categories/src/categories.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
define_categories! {
1616
"lint/safety/banDropColumn": "https://pglt.dev/linter/rules/ban-drop-column",
1717
"lint/safety/banDropNotNull": "https://pglt.dev/linter/rules/ban-drop-not-null",
18+
"lint/safety/banDropTable": "https://pglt.dev/linter/rules/ban-drop-table",
1819
// end lint rules
1920
;
2021
// General categories

0 commit comments

Comments
 (0)