@pgsql/utils 13.9.0 → 13.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -9
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -16,6 +16,22 @@
|
|
|
16
16
|
|
|
17
17
|
`@pgsql/utils` is a companion utility library for `@pgsql/types`, offering convenient functions to work with PostgreSQL Abstract Syntax Tree (AST) nodes and enums in a type-safe manner. This library facilitates the creation of AST nodes and simplifies the process of converting between enum names and their respective integer values, as defined in the PostgreSQL parser output.
|
|
18
18
|
|
|
19
|
+
# Table of Contents
|
|
20
|
+
|
|
21
|
+
1. [@pgsql/utils](#pgsql-utils)
|
|
22
|
+
- [Features](#features)
|
|
23
|
+
2. [Installation](#installation)
|
|
24
|
+
3. [Usage](#usage)
|
|
25
|
+
- [AST Node Creation](#ast-node-creation)
|
|
26
|
+
- [JSON AST](#json-ast)
|
|
27
|
+
- [Select Statement](#select-statement)
|
|
28
|
+
- [Creating Table Schemas Dynamically](#creating-table-schemas-dynamically)
|
|
29
|
+
- [Enum Value Conversion](#enum-value-conversion)
|
|
30
|
+
- [Example 1: Converting Enum Name to Integer](#example-1-converting-enum-name-to-integer)
|
|
31
|
+
- [Example 2: Converting Integer to Enum Name](#example-2-converting-integer-to-enum-name)
|
|
32
|
+
4. [Related Projects](#related)
|
|
33
|
+
5. [Disclaimer](#disclaimer)
|
|
34
|
+
|
|
19
35
|
## Features
|
|
20
36
|
|
|
21
37
|
- **AST Node Creation**: Simplifies the process of constructing PostgreSQL AST nodes, allowing for easy assembly of SQL queries or statements programmatically.
|
|
@@ -38,25 +54,129 @@ npm install @pgsql/utils
|
|
|
38
54
|
|
|
39
55
|
With the AST helper methods, creating complex SQL ASTs becomes straightforward and intuitive.
|
|
40
56
|
|
|
57
|
+
#### JSON AST
|
|
58
|
+
|
|
59
|
+
Explore the PostgreSQL Abstract Syntax Tree (AST) as JSON objects with ease using `@pgsql/utils`. Below is an example of how you can generate a JSON AST using TypeScript:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import ast from '@pgsql/utils';
|
|
63
|
+
const selectStmt = ast.selectStmt({
|
|
64
|
+
targetList: [
|
|
65
|
+
ast.resTarget({
|
|
66
|
+
val: ast.columnRef({
|
|
67
|
+
fields: [ast.aStar()]
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
],
|
|
71
|
+
fromClause: [
|
|
72
|
+
ast.rangeVar({
|
|
73
|
+
relname: 'some_amazing_table',
|
|
74
|
+
inh: true,
|
|
75
|
+
relpersistence: 'p'
|
|
76
|
+
})
|
|
77
|
+
],
|
|
78
|
+
limitOption: 'LIMIT_OPTION_DEFAULT',
|
|
79
|
+
op: 'SETOP_NONE'
|
|
80
|
+
});
|
|
81
|
+
console.log(selectStmt);
|
|
82
|
+
// Output: { "SelectStmt": { "targetList": [ { "ResTarget": { "val": { "ColumnRef": { "fields": [ { "A_Star": {} } ] } } } } ], "fromClause": [ { "RangeVar": { "relname": "some_amazing_table", "inh": true, "relpersistence": "p" } } ], "limitOption": "LIMIT_OPTION_DEFAULT", "op": "SETOP_NONE" } }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Select Statement
|
|
86
|
+
|
|
41
87
|
```ts
|
|
42
88
|
import ast, { CreateStmt, ColumnDef } from '@pgsql/utils';
|
|
43
89
|
import { deparse } from 'pgsql-deparser';
|
|
44
90
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
91
|
+
const selectStmt: SelectStmt = ast.selectStmt({
|
|
92
|
+
targetList: [
|
|
93
|
+
ast.resTarget({
|
|
94
|
+
val: ast.columnRef({
|
|
95
|
+
fields: [ast.aStar()]
|
|
96
|
+
})
|
|
49
97
|
})
|
|
98
|
+
],
|
|
99
|
+
fromClause: [
|
|
100
|
+
ast.rangeVar({
|
|
101
|
+
schemaname: 'myschema',
|
|
102
|
+
relname: 'mytable',
|
|
103
|
+
inh: true,
|
|
104
|
+
relpersistence: 'p'
|
|
105
|
+
})
|
|
106
|
+
],
|
|
107
|
+
whereClause: ast.aExpr({
|
|
108
|
+
kind: 'AEXPR_OP',
|
|
109
|
+
name: [ast.string({ str: '=' })],
|
|
110
|
+
lexpr: ast.columnRef({
|
|
111
|
+
fields: [ast.string({ str: 'a' })]
|
|
112
|
+
}),
|
|
113
|
+
rexpr: ast.typeCast({
|
|
114
|
+
arg: ast.aConst({
|
|
115
|
+
val: ast.string({ str: 't' })
|
|
116
|
+
}),
|
|
117
|
+
typeName: ast.typeName({
|
|
118
|
+
names: [
|
|
119
|
+
ast.string({ str: 'pg_catalog' }),
|
|
120
|
+
ast.string({ str: 'bool' })
|
|
121
|
+
],
|
|
122
|
+
typemod: -1
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
}),
|
|
126
|
+
limitOption: 'LIMIT_OPTION_DEFAULT',
|
|
127
|
+
op: 'SETOP_NONE'
|
|
50
128
|
});
|
|
51
129
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
130
|
+
deparse(createStmt, {});
|
|
131
|
+
// SELECT * FROM myschema.mytable WHERE a = TRUE
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### Creating Table Schemas Dynamically
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
// Example JSON schema
|
|
138
|
+
const schema = {
|
|
139
|
+
"tableName": "users",
|
|
140
|
+
"columns": [
|
|
141
|
+
{ "name": "id", "type": "int", "constraints": ["PRIMARY KEY"] },
|
|
142
|
+
{ "name": "username", "type": "string" },
|
|
143
|
+
{ "name": "email", "type": "string", "constraints": ["UNIQUE"] },
|
|
144
|
+
{ "name": "created_at", "type": "timestamp", "constraints": ["NOT NULL"] }
|
|
145
|
+
]
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Construct the CREATE TABLE statement
|
|
149
|
+
const createStmt = ast.createStmt({
|
|
150
|
+
relation: ast.rangeVar({
|
|
151
|
+
relname: schema.tableName,
|
|
152
|
+
inh: true,
|
|
153
|
+
relpersistence: 'p'
|
|
154
|
+
}).RangeVar as RangeVar, // special case due to PG AST
|
|
155
|
+
tableElts: schema.columns.map(column => ast.columnDef({
|
|
156
|
+
colname: column.name,
|
|
157
|
+
typeName: ast.typeName({
|
|
158
|
+
names: [ast.string({ str: column.type })]
|
|
55
159
|
}),
|
|
56
|
-
|
|
160
|
+
constraints: column.constraints?.map(constraint =>
|
|
161
|
+
ast.constraint({
|
|
162
|
+
contype: constraint === "PRIMARY KEY" ? "CONSTR_PRIMARY" : constraint === "UNIQUE" ? "CONSTR_UNIQUE" : "CONSTR_NOTNULL"
|
|
163
|
+
})
|
|
164
|
+
)
|
|
165
|
+
}))
|
|
57
166
|
});
|
|
58
167
|
|
|
59
|
-
deparse
|
|
168
|
+
// `deparse` function converts AST to SQL string
|
|
169
|
+
const sql = deparse(createStmt, {});
|
|
170
|
+
|
|
171
|
+
console.log(sql);
|
|
172
|
+
// OUTPUT:
|
|
173
|
+
|
|
174
|
+
// CREATE TABLE users (
|
|
175
|
+
// id int PRIMARY KEY,
|
|
176
|
+
// username text,
|
|
177
|
+
// email text UNIQUE,
|
|
178
|
+
// created_at timestamp NOT NULL
|
|
179
|
+
// )
|
|
60
180
|
```
|
|
61
181
|
|
|
62
182
|
### Enum Value Conversion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgsql/utils",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.10.1",
|
|
4
4
|
"description": "PostgreSQL AST utils for pgsql-parser",
|
|
5
5
|
"author": "Dan Lynch <pyramation@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/launchql/pgsql-parser",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"esprima": "4.0.1",
|
|
67
67
|
"jest": "^29.5.0",
|
|
68
68
|
"pg-proto-parser": "^1.20.0",
|
|
69
|
-
"pgsql-deparser": "^13.
|
|
69
|
+
"pgsql-deparser": "^13.14.0",
|
|
70
70
|
"prettier": "^2.8.7",
|
|
71
71
|
"rimraf": "5.0.5",
|
|
72
72
|
"ts-jest": "^29.1.0",
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
"@pgsql/types": "^13.8.0",
|
|
78
78
|
"nested-obj": "0.0.1"
|
|
79
79
|
},
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "a4751a2635eaa353e45b0f8832ac77e80b2f114a"
|
|
81
81
|
}
|