@pgsql/utils 17.5.1 → 17.6.0
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 +50 -79
- package/asts.d.ts +271 -813
- package/asts.js +272 -1627
- package/esm/asts.js +272 -1627
- package/esm/index.js +8 -3
- package/esm/runtime-schema.ts.js +11404 -0
- package/esm/wrapped.js +3031 -0
- package/index.d.ts +1095 -3
- package/index.js +8 -16
- package/package.json +5 -4
- package/runtime-schema.ts.d.ts +18 -0
- package/runtime-schema.ts.js +11407 -0
- package/wrapped.d.ts +817 -0
- package/wrapped.js +3036 -0
- package/esm/utils.js +0 -3917
- package/utils.d.ts +0 -7
- package/utils.js +0 -3921
package/README.md
CHANGED
|
@@ -59,17 +59,20 @@ With the AST helper methods, creating complex SQL ASTs becomes straightforward a
|
|
|
59
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
60
|
|
|
61
61
|
```ts
|
|
62
|
-
import
|
|
63
|
-
|
|
62
|
+
import * as t from '@pgsql/utils';
|
|
63
|
+
import { SelectStmt } from '@pgsql/types';
|
|
64
|
+
import { deparseSync as deparse } from 'pgsql-deparser';
|
|
65
|
+
|
|
66
|
+
const selectStmt: { SelectStmt: SelectStmt } = t.nodes.selectStmt({
|
|
64
67
|
targetList: [
|
|
65
|
-
|
|
66
|
-
val:
|
|
67
|
-
fields: [
|
|
68
|
+
t.nodes.resTarget({
|
|
69
|
+
val: t.nodes.columnRef({
|
|
70
|
+
fields: [t.nodes.aStar()]
|
|
68
71
|
})
|
|
69
72
|
})
|
|
70
73
|
],
|
|
71
74
|
fromClause: [
|
|
72
|
-
|
|
75
|
+
t.nodes.rangeVar({
|
|
73
76
|
relname: 'some_amazing_table',
|
|
74
77
|
inh: true,
|
|
75
78
|
relpersistence: 'p'
|
|
@@ -80,47 +83,45 @@ const selectStmt = ast.selectStmt({
|
|
|
80
83
|
});
|
|
81
84
|
console.log(selectStmt);
|
|
82
85
|
// 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" } }
|
|
86
|
+
console.log(deparse(stmt))
|
|
87
|
+
// Output: SELECT * FROM some_amazing_table
|
|
83
88
|
```
|
|
84
89
|
|
|
85
90
|
#### Select Statement
|
|
86
91
|
|
|
87
92
|
```ts
|
|
88
|
-
import
|
|
89
|
-
import {
|
|
93
|
+
import * as t from '@pgsql/utils';
|
|
94
|
+
import { RangeVar, SelectStmt } from '@pgsql/types';
|
|
95
|
+
import { deparseSync as deparse } from 'pgsql-deparser';
|
|
90
96
|
|
|
91
|
-
const
|
|
97
|
+
const query: { SelectStmt: SelectStmt } = t.nodes.selectStmt({
|
|
92
98
|
targetList: [
|
|
93
|
-
|
|
94
|
-
val:
|
|
95
|
-
fields: [
|
|
99
|
+
t.nodes.resTarget({
|
|
100
|
+
val: t.nodes.columnRef({
|
|
101
|
+
fields: [t.nodes.string({ sval: 'name' })]
|
|
102
|
+
})
|
|
103
|
+
}),
|
|
104
|
+
t.nodes.resTarget({
|
|
105
|
+
val: t.nodes.columnRef({
|
|
106
|
+
fields: [t.nodes.string({ sval: 'email' })]
|
|
96
107
|
})
|
|
97
108
|
})
|
|
98
109
|
],
|
|
99
110
|
fromClause: [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
relname: 'mytable',
|
|
111
|
+
t.nodes.rangeVar({
|
|
112
|
+
relname: 'users',
|
|
103
113
|
inh: true,
|
|
104
114
|
relpersistence: 'p'
|
|
105
115
|
})
|
|
106
116
|
],
|
|
107
|
-
whereClause:
|
|
117
|
+
whereClause: t.nodes.aExpr({
|
|
108
118
|
kind: 'AEXPR_OP',
|
|
109
|
-
name: [
|
|
110
|
-
lexpr:
|
|
111
|
-
fields: [
|
|
119
|
+
name: [t.nodes.string({ sval: '>' })],
|
|
120
|
+
lexpr: t.nodes.columnRef({
|
|
121
|
+
fields: [t.nodes.string({ sval: 'age' })]
|
|
112
122
|
}),
|
|
113
|
-
rexpr:
|
|
114
|
-
|
|
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
|
-
})
|
|
123
|
+
rexpr: t.nodes.aConst({
|
|
124
|
+
ival: t.ast.integer({ ival: 18 })
|
|
124
125
|
})
|
|
125
126
|
}),
|
|
126
127
|
limitOption: 'LIMIT_OPTION_DEFAULT',
|
|
@@ -128,7 +129,7 @@ const selectStmt: SelectStmt = ast.selectStmt({
|
|
|
128
129
|
});
|
|
129
130
|
|
|
130
131
|
deparse(createStmt, {});
|
|
131
|
-
// SELECT
|
|
132
|
+
// SELECT name, email FROM users WHERE age > 18
|
|
132
133
|
```
|
|
133
134
|
|
|
134
135
|
#### Creating Table Schemas Dynamically
|
|
@@ -139,26 +140,26 @@ const schema = {
|
|
|
139
140
|
"tableName": "users",
|
|
140
141
|
"columns": [
|
|
141
142
|
{ "name": "id", "type": "int", "constraints": ["PRIMARY KEY"] },
|
|
142
|
-
{ "name": "username", "type": "
|
|
143
|
-
{ "name": "email", "type": "
|
|
143
|
+
{ "name": "username", "type": "text" },
|
|
144
|
+
{ "name": "email", "type": "text", "constraints": ["UNIQUE"] },
|
|
144
145
|
{ "name": "created_at", "type": "timestamp", "constraints": ["NOT NULL"] }
|
|
145
146
|
]
|
|
146
147
|
};
|
|
147
148
|
|
|
148
149
|
// Construct the CREATE TABLE statement
|
|
149
|
-
const createStmt =
|
|
150
|
-
relation: ast.rangeVar({
|
|
150
|
+
const createStmt = t.nodes.createStmt({
|
|
151
|
+
relation: t.ast.rangeVar({
|
|
151
152
|
relname: schema.tableName,
|
|
152
153
|
inh: true,
|
|
153
154
|
relpersistence: 'p'
|
|
154
|
-
})
|
|
155
|
-
tableElts: schema.columns.map(column =>
|
|
155
|
+
}),
|
|
156
|
+
tableElts: schema.columns.map(column => t.nodes.columnDef({
|
|
156
157
|
colname: column.name,
|
|
157
|
-
typeName: ast.typeName({
|
|
158
|
-
names: [
|
|
158
|
+
typeName: t.ast.typeName({
|
|
159
|
+
names: [t.nodes.string({ sval: column.type })]
|
|
159
160
|
}),
|
|
160
161
|
constraints: column.constraints?.map(constraint =>
|
|
161
|
-
|
|
162
|
+
t.nodes.constraint({
|
|
162
163
|
contype: constraint === "PRIMARY KEY" ? "CONSTR_PRIMARY" : constraint === "UNIQUE" ? "CONSTR_UNIQUE" : "CONSTR_NOTNULL"
|
|
163
164
|
})
|
|
164
165
|
)
|
|
@@ -166,7 +167,7 @@ const createStmt = ast.createStmt({
|
|
|
166
167
|
});
|
|
167
168
|
|
|
168
169
|
// `deparse` function converts AST to SQL string
|
|
169
|
-
const sql = deparse(createStmt
|
|
170
|
+
const sql = deparse(createStmt);
|
|
170
171
|
|
|
171
172
|
console.log(sql);
|
|
172
173
|
// OUTPUT:
|
|
@@ -179,49 +180,19 @@ console.log(sql);
|
|
|
179
180
|
// )
|
|
180
181
|
```
|
|
181
182
|
|
|
182
|
-
### Enum Value Conversion
|
|
183
|
-
|
|
184
|
-
`@pgsql/utils` provides the `getEnumValue` function to convert between the string and integer representations of enum values.
|
|
185
|
-
|
|
186
|
-
Here are a couple of examples demonstrating how to use `@pgsql/utils` in real applications:
|
|
187
|
-
|
|
188
|
-
#### Example 1: Converting Enum Name to Integer
|
|
189
|
-
|
|
190
|
-
Suppose you are working with the A_Expr_Kind enum and you have the name of an enum value. You can get its integer representation like this:
|
|
191
|
-
|
|
192
|
-
```ts
|
|
193
|
-
import { getEnumValue } from '@pgsql/utils';
|
|
194
|
-
|
|
195
|
-
const enumName = 'AEXPR_OP';
|
|
196
|
-
const enumValue = getEnumValue('A_Expr_Kind', enumName);
|
|
197
|
-
|
|
198
|
-
console.log(enumValue); // Outputs the integer value corresponding to 'AEXPR_OP'
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
#### Example 2: Converting Integer to Enum Name
|
|
202
|
-
|
|
203
|
-
```ts
|
|
204
|
-
import { getEnumValue } from '@pgsql/utils';
|
|
205
|
-
|
|
206
|
-
const intValue = 1;
|
|
207
|
-
const enumName = getEnumValue('SortByDir', intValue);
|
|
208
|
-
|
|
209
|
-
console.log(enumName); // Outputs 'SORTBY_ASC' if 1 corresponds to 'SORTBY_ASC'
|
|
210
|
-
```
|
|
211
|
-
|
|
212
183
|
## Related
|
|
213
184
|
|
|
214
|
-
* [pgsql-parser](https://
|
|
215
|
-
* [pgsql-deparser](https://
|
|
216
|
-
* [pgsql
|
|
217
|
-
* [@pgsql/
|
|
218
|
-
* [@pgsql/
|
|
219
|
-
* [@pgsql/utils](https://
|
|
220
|
-
* [pg-proto-parser](https://
|
|
185
|
+
* [pgsql-parser](https://www.npmjs.com/package/pgsql-parser): The real PostgreSQL parser for Node.js, providing symmetric parsing and deparsing of SQL statements with actual PostgreSQL parser integration.
|
|
186
|
+
* [pgsql-deparser](https://www.npmjs.com/package/pgsql-deparser): A streamlined tool designed for converting PostgreSQL ASTs back into SQL queries, focusing solely on deparser functionality to complement `pgsql-parser`.
|
|
187
|
+
* [@pgsql/parser](https://www.npmjs.com/package/@pgsql/parser): Multi-version PostgreSQL parser with dynamic version selection at runtime, supporting PostgreSQL 15, 16, and 17 in a single package.
|
|
188
|
+
* [@pgsql/types](https://www.npmjs.com/package/@pgsql/types): Offers TypeScript type definitions for PostgreSQL AST nodes, facilitating type-safe construction, analysis, and manipulation of ASTs.
|
|
189
|
+
* [@pgsql/enums](https://www.npmjs.com/package/@pgsql/enums): Provides TypeScript enum definitions for PostgreSQL constants, enabling type-safe usage of PostgreSQL enums and constants in your applications.
|
|
190
|
+
* [@pgsql/utils](https://www.npmjs.com/package/@pgsql/utils): A comprehensive utility library for PostgreSQL, offering type-safe AST node creation and enum value conversions, simplifying the construction and manipulation of PostgreSQL ASTs.
|
|
191
|
+
* [pg-proto-parser](https://www.npmjs.com/package/pg-proto-parser): A TypeScript tool that parses PostgreSQL Protocol Buffers definitions to generate TypeScript interfaces, utility functions, and JSON mappings for enums.
|
|
221
192
|
* [libpg-query](https://github.com/launchql/libpg-query-node): The real PostgreSQL parser exposed for Node.js, used primarily in `pgsql-parser` for parsing and deparsing SQL queries.
|
|
222
193
|
|
|
223
194
|
## Disclaimer
|
|
224
195
|
|
|
225
|
-
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED
|
|
196
|
+
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
|
|
226
197
|
|
|
227
198
|
No developer or entity involved in creating Software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the Software code or Software CLI, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
|