From f276ee1c13e9a5e09b8e260ea43ef660be6956fe Mon Sep 17 00:00:00 2001 From: orangain Date: Thu, 22 Feb 2024 22:56:35 +0900 Subject: [PATCH 1/3] Categorize built-in rules --- src/rules/README.md | 60 +++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/rules/README.md b/src/rules/README.md index c2c7d43..f329417 100644 --- a/src/rules/README.md +++ b/src/rules/README.md @@ -3,7 +3,9 @@ This folder contains the built-in rules for Schemalint. While there is value in these, the true benefit is achieved by writing custom rules that enforce the specific architecture that you are aiming for. -## name-casing +## Naming Conventions + +### name-casing Check that your names are cased correctly. The default setting is `"snake"` (i.e. tables should be named with underscores as word boundaries: `member_profile`). The reasoning for this is outlined in the Postgres wiki: [Don't use upper case table or column names ](https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_upper_case_table_or_column_names). @@ -18,29 +20,31 @@ At the moment, this rule checks tables, views and columns. }, ``` -## prefer-text-to-varchar +### name-inflection -In Postgres there is no performance penalty on using the `text` type which has no maximum length, so you will generally want to choose that over `varchar`. -The reasoning for this is outlined in the Postgres wiki: [Don't use varchar(n) by default](https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_varchar.28n.29_by_default) +If you want to enforce singular or plural naming for your tables, this rule can enforce it. +Which one to choose is a matter of great debate but in the end it comes down to personal preference. You can choose `'singular'` (default) or `'plural'`. ```js rules: { - 'prefer-text-to-varchar': ['error'], + 'name-inflection': ['error', 'singular'], }, ``` -## name-inflection +## Data Types -If you want to enforce singular or plural naming for your tables, this rule can enforce it. -Which one to choose is a matter of great debate but in the end it comes down to personal preference. You can choose `'singular'` (default) or `'plural'`. +### prefer-text-to-varchar + +In Postgres there is no performance penalty on using the `text` type which has no maximum length, so you will generally want to choose that over `varchar`. +The reasoning for this is outlined in the Postgres wiki: [Don't use varchar(n) by default](https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_varchar.28n.29_by_default) ```js rules: { - 'name-inflection': ['error', 'singular'], + 'prefer-text-to-varchar': ['error'], }, ``` -## prefer-timestamptz-to-timestamp +### prefer-timestamptz-to-timestamp In Postgres when you insert a value into a `timestamptz` column, PostgreSQL converts the `timestamptz` value into a UTC value and stores the UTC value in the table, and when you query `timestamptz` from the database, PostgreSQL converts the UTC value back to the time value of the timezone set by the database server, the user, or the current database connection, whereas `timestamp` does not save any @@ -52,7 +56,7 @@ timezone data. You can learn more here: [Understanding PostgreSQL Timestamp Data }, ``` -## prefer-jsonb-to-json +### prefer-jsonb-to-json `json` data is stored as a copy of the input text which processing functions need to reparse on each execution. `jsonb` data is stored in a binary format which is faster to process, and also supports indexing. @@ -68,7 +72,7 @@ You can learn more here: [JSON types](https://www.postgresql.org/docs/current/da }, ``` -## prefer-identity-to-serial +### prefer-identity-to-serial Identity columns are a SQL standard-conforming variant of PostgreSQL's serial columns. They fix a few usability issues that serial columns have: @@ -87,7 +91,9 @@ You can learn more here: [Identity Columns Explained](https://www.2ndquadrant.co }, ``` -## require-primary-key +## Table Structures + +### require-primary-key Identity tables that do not have a primary key defined. Tables can be ignored by passing the `ignorePattern` rule argument. @@ -99,7 +105,7 @@ Identity tables that do not have a primary key defined. Tables can be ignored by }, ``` -## index-referencing-column +### index-referencing-column PostgreSQL does not automatically create an index on the referencing column (not the referenced column) of a foreign key constraint. This rule can enforce that you create an index on the referencing column. @@ -115,7 +121,7 @@ rules: { } ``` -## reference-actions +### reference-actions This rule enforces that foreign key constraints have specific `ON UPDATE` and `ON DELETE` actions. Available actions are: `NO ACTION`, `RESTRICT`, `CASCADE`, `SET NULL`, `SET DEFAULT`. When `onUpdate` or `onDelete` is not specified, the rule allows any action for the unspecified action. @@ -128,17 +134,7 @@ rules: { } ``` -## row-level-security - -[Row-level security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) (RLS) is a feature that enables you to control which rows in a table are visible to different users. This rule checks that tables have row-level security enabled. You can also check that it is enforced by setting the `enforced` option to `true`. - -```js -rules: { - 'row-level-security': ['error', {enforced: true}], -} -``` - -## mandatory-columns +### mandatory-columns This rule enforces that a table has certain columns. The option is an object, where the key is the column name and the value is the object representing the required properties. Any property of the [TableColumn](https://kristiandupont.github.io/extract-pg-schema/api/extract-pg-schema.tablecolumn.html) object can be used as a required property. For example, you can specify `ordinalPosition` to ensure that the column is in the expected position, but note that PostgreSQL always adds a new column to the very back. @@ -152,3 +148,15 @@ rules: { }], } ``` + +## Security + +### row-level-security + +[Row-level security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) (RLS) is a feature that enables you to control which rows in a table are visible to different users. This rule checks that tables have row-level security enabled. You can also check that it is enforced by setting the `enforced` option to `true`. + +```js +rules: { + 'row-level-security': ['error', {enforced: true}], +} +``` From ec35a96575e4178259af5d217398f2ebcd32d444 Mon Sep 17 00:00:00 2001 From: orangain Date: Thu, 22 Feb 2024 23:16:40 +0900 Subject: [PATCH 2/3] Align the indentation --- src/rules/README.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/rules/README.md b/src/rules/README.md index f329417..d60bd7e 100644 --- a/src/rules/README.md +++ b/src/rules/README.md @@ -98,7 +98,7 @@ You can learn more here: [Identity Columns Explained](https://www.2ndquadrant.co Identity tables that do not have a primary key defined. Tables can be ignored by passing the `ignorePattern` rule argument. ```js - rules: { + rules: { 'require-primary-key': ['error', { ignorePattern: 'information_schema.*' }], @@ -116,9 +116,9 @@ As the official PostgreSQL documentation states, it is not always needed to inde You can learn more here: [Foreign Keys](https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-FK) ```js -rules: { - 'index-referencing-column': ['error'], -} + rules: { + 'index-referencing-column': ['error'], + } ``` ### reference-actions @@ -126,12 +126,12 @@ rules: { This rule enforces that foreign key constraints have specific `ON UPDATE` and `ON DELETE` actions. Available actions are: `NO ACTION`, `RESTRICT`, `CASCADE`, `SET NULL`, `SET DEFAULT`. When `onUpdate` or `onDelete` is not specified, the rule allows any action for the unspecified action. ```js -rules: { - 'reference-actions': ['error', { - onUpdate: 'NO ACTION', - onDelete: 'CASCADE', - }], -} + rules: { + 'reference-actions': ['error', { + onUpdate: 'NO ACTION', + onDelete: 'CASCADE', + }], + } ``` ### mandatory-columns @@ -139,14 +139,14 @@ rules: { This rule enforces that a table has certain columns. The option is an object, where the key is the column name and the value is the object representing the required properties. Any property of the [TableColumn](https://kristiandupont.github.io/extract-pg-schema/api/extract-pg-schema.tablecolumn.html) object can be used as a required property. For example, you can specify `ordinalPosition` to ensure that the column is in the expected position, but note that PostgreSQL always adds a new column to the very back. ```js -rules: { - 'mandatory-columns': ['error', { - created_at: { - expandedType: 'pg_catalog.timestamptz', - isNullable: false, - } - }], -} + rules: { + 'mandatory-columns': ['error', { + created_at: { + expandedType: 'pg_catalog.timestamptz', + isNullable: false, + } + }], + } ``` ## Security @@ -156,7 +156,7 @@ rules: { [Row-level security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) (RLS) is a feature that enables you to control which rows in a table are visible to different users. This rule checks that tables have row-level security enabled. You can also check that it is enforced by setting the `enforced` option to `true`. ```js -rules: { - 'row-level-security': ['error', {enforced: true}], -} + rules: { + 'row-level-security': ['error', {enforced: true}], + } ``` From 2e4b5af8201526c36ce26160749c10aca931d235 Mon Sep 17 00:00:00 2001 From: orangain Date: Thu, 22 Feb 2024 23:19:09 +0900 Subject: [PATCH 3/3] Fix typo --- src/rules/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/README.md b/src/rules/README.md index d60bd7e..de3cd0f 100644 --- a/src/rules/README.md +++ b/src/rules/README.md @@ -95,7 +95,7 @@ You can learn more here: [Identity Columns Explained](https://www.2ndquadrant.co ### require-primary-key -Identity tables that do not have a primary key defined. Tables can be ignored by passing the `ignorePattern` rule argument. +Identify tables that do not have a primary key defined. Tables can be ignored by passing the `ignorePattern` rule argument. ```js rules: {