From bfc092ed494db9a3d86f0d291b10f1183f8155ed Mon Sep 17 00:00:00 2001 From: orangain Date: Fri, 9 Feb 2024 00:23:51 +0900 Subject: [PATCH] Enhance documentation (#337) * Add description to the configurations in README * Make it clear that this is a description of custom rules in README * Describe the feature to suggest fixes in README * Correct type of code snippet * Make it clear that 'singular' is the default setting in name-inflection * Add configuration snippets to the README of built-in rules * Add detailed instruction of the custom rules to the example/README --- README.md | 25 ++++++++++++++++++++----- example/README.md | 13 +++++++++++++ src/rules/README.md | 40 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index be2a927..6986001 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,13 @@ Run linting rules on your database schema. Read the intro to this idea in [this _Works with Postgres databases._ -This will give you errors like these: +This will give you errors and suggestions like these: ``` public.actor.first_name: error prefer-text-to-varchar : Prefer text to varchar types + +Suggested fix +ALTER TABLE "public"."actor" ALTER COLUMN "first_name" TYPE TEXT; ``` ## Usage @@ -28,6 +31,7 @@ Here is an example configuration file: ```javascript module.exports = { + // Connection configuration. See: https://node-postgres.com/apis/client connection: { host: "localhost", user: "postgres", @@ -36,8 +40,12 @@ module.exports = { charset: "utf8", }, - plugins: ["./custom-rules"], + // Schemas to lint. + schemas: [{ name: "public" }], + // Rules to be checked. The key is the rule name and the value is an array + // whose first value is the severity (only "error" is supported) and the + // rest are rule-specific parameters. rules: { "name-casing": ["error", "snake"], "name-inflection": ["error", "singular"], @@ -45,17 +53,24 @@ module.exports = { "prefer-text-to-varchar": ["error"], }, - schemas: [{ name: "public" }], - + // (Optional) Use the `ignores` array to exclude specific targets and + // rules. The targets are identified by the `identifier` (exact) or the + // `identifierPattern` (regex). For the rules, use the `rule` (exact) or + // the `rulePattern` (regex). ignores: [ + { identifier: "public.sessions", rule: "name-inflection" }, { identifierPattern: "public\\.knex_migrations.*", rulePattern: ".*" }, ], + + // (Optional) Use the `plugins` array to load custom rules. The paths are + // `require`d as Node.js modules from the current working directory. + plugins: ["./custom-rules"], }; ``` ## Rules -Schemalint includes a number of built-in rules, which you can read about [here](/src/rules). However, writing rules is easy and you will probably see the real value by doing so. The [example](/example) folder shows how to write these. +Schemalint includes a number of built-in rules, which you can read about [here](/src/rules). However, writing custom rules is easy and you will probably see the real value by doing so. The [example](/example) folder shows how to write these. ## Sponsors diff --git a/example/README.md b/example/README.md index f1f909f..6358348 100644 --- a/example/README.md +++ b/example/README.md @@ -1,5 +1,9 @@ # Example +This folder contains an example configuration file and custom rules for Schemalint. + +## Usage + If you want to try this, you can run it on the [Sample Database](https://www.postgresqltutorial.com/postgresql-sample-database/) from www.postgresqltutorial.com. I've created a Docker image that hosts it so if you have Docker installed, you can easily set up such a database locally by running @@ -63,3 +67,12 @@ error Command failed with exit code 1. ``` You can play around with the configuration options in `.schemalintrc.js` file to experiment. + +## Custom Rules + +Example custom rules are included in the [custom-rules](./custom-rules) folder. The folder contains the following files: + +- [identifierNaming.js](./custom-rules/identifierNaming.js): Defines the custom rule `identifier-naming`. +- [index.js](./custom-rules/index.js): Exports the custom rules. + +You can use these as a starting point to create your own custom rules. The type definition of the [Rule](/src/Rule.ts) object and the [Schema](https://kristiandupont.github.io/extract-pg-schema/api/extract-pg-schema.schema.html) object passed to the custom rules will help you understand how to write custom rules. diff --git a/src/rules/README.md b/src/rules/README.md index cb45679..538afca 100644 --- a/src/rules/README.md +++ b/src/rules/README.md @@ -12,15 +12,33 @@ If, for some reason or other, you want to use a different naming scheme, you can At the moment, this rule checks tables, views and columns. +```js + rules: { + 'name-casing': ['error', 'snake'], + }, +``` + ## 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: { + 'prefer-text-to-varchar': ['error'], + }, +``` + ## name-inflection 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'` or `'plural'`. +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: { + 'name-inflection': ['error', 'singular'], + }, +``` ## prefer-timestamptz-to-timestamp @@ -28,6 +46,12 @@ In Postgres when you insert a value into a `timestamptz` column, PostgreSQL conv 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 timezone data. You can learn more here: [Understanding PostgreSQL Timestamp Data Types](https://www.postgresqltutorial.com/postgresql-timestamp/) +```js + rules: { + 'prefer-timestamptz-to-timestamp': ['error'], + }, +``` + ## 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. @@ -38,6 +62,12 @@ While there are some caveats, the official PostgreSQL documentation states: You can learn more here: [JSON types](https://www.postgresql.org/docs/current/datatype-json.html) +```js + rules: { + 'prefer-jsonb-to-json': ['error'], + }, +``` + ## prefer-identity-to-serial Identity columns are a SQL standard-conforming variant of PostgreSQL's serial columns. They fix a few usability @@ -51,11 +81,17 @@ issues that serial columns have: You can learn more here: [Identity Columns Explained](https://www.2ndquadrant.com/en/blog/postgresql-10-identity-columns/) +```js + rules: { + 'prefer-identity-to-serial': ['error'], + }, +``` + ## require-primary-key Identity tables that do not have a primary key defined. Tables can be ignored by passing the `ignorePattern` rule argument. -```json +```js rules: { 'require-primary-key': ['error', { ignorePattern: 'information_schema.*'