@grest-ts/sql 0.0.6 → 0.0.7

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.
@@ -1,283 +1,283 @@
1
- import {escape} from "./escape";
2
-
3
- export class MysqlTableStructureParser {
4
-
5
- public static getSchemaRowsQuery(database: string): string {
6
- return "SELECT " +
7
- " table_schema as tableSchema, \n" +
8
- " table_name as tableName, \n" +
9
- " is_nullable as isNullable, \n" +
10
- " column_default as columnDefault, \n" +
11
- " column_name as columnName, \n" +
12
- " collation_name as collationName, \n" +
13
- " column_type as columnType, \n" +
14
- " column_key as columnKey, \n" +
15
- " ordinal_position as ordinalPosition, \n" +
16
- " character_octet_length as characterOctetLength, \n" +
17
- " numeric_precision as numericPrecision, \n" +
18
- " numeric_scale as numericScale, \n" +
19
- " data_type as dataType, \n" +
20
- " character_maximum_length as characterMaximumLength, \n" +
21
- " datetime_precision as datetimePrecision, \n" +
22
- " character_set_name as characterSetName, \n" +
23
- " extra as extra, \n" +
24
- " column_comment as columnComment \n" +
25
- "FROM INFORMATION_SCHEMA.columns \n" +
26
- "WHERE table_schema LIKE " + escape(database) + " " +
27
- "ORDER BY table_schema, table_name, ordinal_position ";
28
- }
29
-
30
- public static parse(schema: SchemaRow[]): TableStructure[] {
31
- const tables: Map<string, TableStructure> = new Map()
32
- for (const row of schema) {
33
- if (!tables.has(row.tableName)) {
34
- tables.set(row.tableName, {name: row.tableName, columns: []})
35
- }
36
- tables.get(row.tableName).columns.push(this.parseColumn(row));
37
- }
38
- return Array.from(tables.values()).sort((a, b) => a.name >= b.name ? 1 : -1);
39
- }
40
-
41
- private static parseColumn(row: SchemaRow): AnyColumn {
42
- const type = row.dataType.toUpperCase() as ColumnDataType;
43
- const column: Column = {
44
- type: type,
45
- name: row.columnName,
46
- dataType: row.dataType.toUpperCase(),
47
- columnType: row.columnType,
48
- tsType: MYSQL_TYPE_TO_TS_TYPE.get(type),
49
- isNullable: row.isNullable.toUpperCase().indexOf("YES") >= 0,
50
- default: this.parseDefault(row.columnDefault),
51
- columnKey: this.parseColumnKey(row.columnKey),
52
- extra: row.extra,
53
- comment: row.columnComment
54
- };
55
- if (type === ColumnDataType.MEDIUMTEXT || type === ColumnDataType.TEXT || type === ColumnDataType.LONGTEXT) {
56
- const res: ColumnText = {
57
- ...column,
58
- type: type,
59
- characterSetName: row.characterSetName,
60
- collationName: row.collationName
61
- }
62
- return res;
63
-
64
- } else if (type === ColumnDataType.CHAR || type === ColumnDataType.VARCHAR) {
65
- const res: ColumnChar = {
66
- ...column,
67
- type: type,
68
- characterSetName: row.characterSetName,
69
- collationName: row.collationName,
70
- characterMaximumLength: row.characterMaxLength,
71
- characterOctetLength: row.characterOctetLength
72
- }
73
- return res;
74
-
75
- } else if (type === ColumnDataType.TINYINT || type === ColumnDataType.SMALLINT || type === ColumnDataType.INT || type === ColumnDataType.MEDIUMINT
76
- || type === ColumnDataType.BIGINT || type === ColumnDataType.DECIMAL || type === ColumnDataType.FLOAT || type === ColumnDataType.BIT) {
77
- const typeNum = Number(row.columnType.split("(").pop().split(")").shift());
78
- const res: ColumnNumber = {
79
- ...column,
80
- type: type,
81
- typeNum: isNaN(typeNum) ? undefined : typeNum,
82
- scale: row.numericScale,
83
- precision: row.numericPos,
84
- isUnsigned: row.columnType.toUpperCase().indexOf("UNSIGNED") >= 0,
85
- isAutoIncrement: row.extra.toUpperCase().indexOf("AUTO_INCREMENT") >= 0
86
- }
87
- return res;
88
-
89
- } else if (type === ColumnDataType.ENUM) {
90
- const res: ColumnEnum = {
91
- ...column,
92
- type: type,
93
- values: row.columnType.match(/'([^']+)'/g).map(e => e.replace(/'/g, "").replace(/"/g, ""))
94
- }
95
- return res;
96
- } else if (type === ColumnDataType.SET) {
97
- const res: ColumnSet = {
98
- ...column,
99
- type: type,
100
- values: row.columnType.match(/'([^']+)'/g).map(e => e.replace(/'/g, "").replace(/"/g, ""))
101
- }
102
- return res;
103
- } else {
104
- return column as AnyColumn;
105
- }
106
- }
107
-
108
- private static parseDefault(def: string): string | number {
109
- if (!def || def === "NULL") {
110
- return null;
111
- } else if (!isNaN(Number(def))) {
112
- return def;
113
- } else {
114
- return String(def).split("'").join("");
115
- }
116
- }
117
-
118
- private static parseColumnKey(columnKey: string): KeyType[] {
119
- return columnKey.split(",").map((e) => {
120
- const key = e.toUpperCase();
121
- if (key === "PRI") {
122
- return KeyType.PRIMARY
123
- } else if (key === "UNI") {
124
- return KeyType.UNIQUE
125
- } else if (key === "MUL") {
126
- return KeyType.MULTIPLE
127
- } else {
128
- return null;
129
- }
130
- }).filter(e => e);
131
- }
132
- }
133
-
134
- export interface TableStructure {
135
- name: string;
136
- columns: AnyColumn[];
137
- }
138
-
139
- export enum ColumnDataType {
140
- TINYINT = "TINYINT",
141
- SMALLINT = "SMALLINT",
142
- MEDIUMINT = "MEDIUMINT",
143
- INT = "INT",
144
- BIGINT = "BIGINT",
145
- DECIMAL = "DECIMAL",
146
- FLOAT = "FLOAT",
147
- CHAR = "CHAR",
148
- VARCHAR = "VARCHAR",
149
- MEDIUMTEXT = "MEDIUMTEXT",
150
- TEXT = "TEXT",
151
- LONGTEXT = "LONGTEXT",
152
- TIMESTAMP = "TIMESTAMP",
153
- DATETIME = "DATETIME",
154
- DATE = "DATE",
155
- TIME = "TIME",
156
- YEAR = "YEAR",
157
- ENUM = "ENUM",
158
- SET = "SET",
159
- BIT = "BIT",
160
- LONGBLOB = "LONGBLOB",
161
- JSON = "JSON"
162
- }
163
-
164
- const MYSQL_TYPE_TO_TS_TYPE: Map<ColumnDataType, string> = new Map([
165
- [ColumnDataType.TINYINT, "number"],
166
- [ColumnDataType.SMALLINT, "number"],
167
- [ColumnDataType.MEDIUMINT, "number"],
168
- [ColumnDataType.INT, "number"],
169
- [ColumnDataType.BIGINT, "number"],
170
- [ColumnDataType.DECIMAL, "number"],
171
- [ColumnDataType.FLOAT, "number"],
172
- [ColumnDataType.CHAR, "string"],
173
- [ColumnDataType.VARCHAR, "string"],
174
- [ColumnDataType.MEDIUMTEXT, "string"],
175
- [ColumnDataType.TEXT, "string"],
176
- [ColumnDataType.LONGTEXT, "string"],
177
- [ColumnDataType.TIMESTAMP, "string"],
178
- [ColumnDataType.DATETIME, "string"],
179
- [ColumnDataType.DATE, "string"],
180
- [ColumnDataType.TIME, "number"],
181
- [ColumnDataType.YEAR, "number"],
182
- [ColumnDataType.ENUM, "string"],
183
- [ColumnDataType.SET, "string"],
184
- [ColumnDataType.BIT, "number"],
185
- [ColumnDataType.LONGBLOB, "string"],
186
- [ColumnDataType.JSON, "string"]
187
- ])
188
-
189
-
190
- export type AnyColumn = ColumnText | ColumnChar | ColumnNumber | ColumnSet | ColumnEnum | ColumnDateTimeLike
191
-
192
- export interface Column {
193
- type: ColumnDataType;
194
- name: string;
195
- tsType: string;
196
- dataType: string // Type like INT
197
- columnType: string; // Type like INT(11)
198
- typeNum?: number | undefined // for INT(11), this would be 11
199
- default: string | number;
200
- isNullable: boolean;
201
- columnKey: KeyType[];
202
- extra: string;
203
- comment: string;
204
- }
205
-
206
- export interface ColumnDateTimeLike extends Column {
207
- type: ColumnDataType.DATE |
208
- ColumnDataType.DATETIME |
209
- ColumnDataType.TIMESTAMP |
210
- ColumnDataType.YEAR
211
- }
212
-
213
- export interface ColumnText extends Column {
214
- type: ColumnDataType.CHAR |
215
- ColumnDataType.VARCHAR |
216
- ColumnDataType.MEDIUMTEXT |
217
- ColumnDataType.TEXT |
218
- ColumnDataType.LONGTEXT;
219
- characterSetName: string;
220
- collationName: string;
221
- }
222
-
223
- export interface ColumnChar extends ColumnText {
224
- type: ColumnDataType.VARCHAR |
225
- ColumnDataType.CHAR;
226
- characterMaximumLength: number;
227
- characterOctetLength: number;
228
- }
229
-
230
- export interface ColumnNumber extends Column {
231
- type:
232
- ColumnDataType.TINYINT |
233
- ColumnDataType.SMALLINT |
234
- ColumnDataType.MEDIUMINT |
235
- ColumnDataType.INT |
236
- ColumnDataType.BIGINT |
237
- ColumnDataType.DECIMAL |
238
- ColumnDataType.FLOAT |
239
- ColumnDataType.BIT
240
- isUnsigned: boolean;
241
- isAutoIncrement: boolean;
242
- precision: number;
243
- scale: number;
244
- }
245
-
246
- export interface ColumnEnum extends Column {
247
- type: ColumnDataType.ENUM;
248
- values: string[];
249
- }
250
-
251
- export interface ColumnSet extends Column {
252
- type: ColumnDataType.SET;
253
- values: string[];
254
- }
255
-
256
- export enum KeyType {
257
- PRIMARY = "primary",
258
- UNIQUE = "unique",
259
- MULTIPLE = "multiple"
260
- }
261
-
262
- interface SchemaRow {
263
- tableSchema: string;
264
- tableName: string;
265
- columnName: string;
266
- ordinalPosition: number;
267
- columnDefault: string;
268
- isNullable: string;
269
- dataType: string;
270
- characterMaxLength: number;
271
- characterOctetLength: number;
272
- numericPos: number;
273
- numericScale: number;
274
- dateTimePrecision: number;
275
- characterSetName: string;
276
- collationName: string;
277
- columnType: string;
278
- columnKey: string;
279
- extra: string;
280
- columnComment: string;
281
- isGenerated: string;
282
- generationExpression: string;
283
- }
1
+ import {escape} from "./escape";
2
+
3
+ export class MysqlTableStructureParser {
4
+
5
+ public static getSchemaRowsQuery(database: string): string {
6
+ return "SELECT " +
7
+ " table_schema as tableSchema, \n" +
8
+ " table_name as tableName, \n" +
9
+ " is_nullable as isNullable, \n" +
10
+ " column_default as columnDefault, \n" +
11
+ " column_name as columnName, \n" +
12
+ " collation_name as collationName, \n" +
13
+ " column_type as columnType, \n" +
14
+ " column_key as columnKey, \n" +
15
+ " ordinal_position as ordinalPosition, \n" +
16
+ " character_octet_length as characterOctetLength, \n" +
17
+ " numeric_precision as numericPrecision, \n" +
18
+ " numeric_scale as numericScale, \n" +
19
+ " data_type as dataType, \n" +
20
+ " character_maximum_length as characterMaximumLength, \n" +
21
+ " datetime_precision as datetimePrecision, \n" +
22
+ " character_set_name as characterSetName, \n" +
23
+ " extra as extra, \n" +
24
+ " column_comment as columnComment \n" +
25
+ "FROM INFORMATION_SCHEMA.columns \n" +
26
+ "WHERE table_schema LIKE " + escape(database) + " " +
27
+ "ORDER BY table_schema, table_name, ordinal_position ";
28
+ }
29
+
30
+ public static parse(schema: SchemaRow[]): TableStructure[] {
31
+ const tables: Map<string, TableStructure> = new Map()
32
+ for (const row of schema) {
33
+ if (!tables.has(row.tableName)) {
34
+ tables.set(row.tableName, {name: row.tableName, columns: []})
35
+ }
36
+ tables.get(row.tableName).columns.push(this.parseColumn(row));
37
+ }
38
+ return Array.from(tables.values()).sort((a, b) => a.name >= b.name ? 1 : -1);
39
+ }
40
+
41
+ private static parseColumn(row: SchemaRow): AnyColumn {
42
+ const type = row.dataType.toUpperCase() as ColumnDataType;
43
+ const column: Column = {
44
+ type: type,
45
+ name: row.columnName,
46
+ dataType: row.dataType.toUpperCase(),
47
+ columnType: row.columnType,
48
+ tsType: MYSQL_TYPE_TO_TS_TYPE.get(type),
49
+ isNullable: row.isNullable.toUpperCase().indexOf("YES") >= 0,
50
+ default: this.parseDefault(row.columnDefault),
51
+ columnKey: this.parseColumnKey(row.columnKey),
52
+ extra: row.extra,
53
+ comment: row.columnComment
54
+ };
55
+ if (type === ColumnDataType.MEDIUMTEXT || type === ColumnDataType.TEXT || type === ColumnDataType.LONGTEXT) {
56
+ const res: ColumnText = {
57
+ ...column,
58
+ type: type,
59
+ characterSetName: row.characterSetName,
60
+ collationName: row.collationName
61
+ }
62
+ return res;
63
+
64
+ } else if (type === ColumnDataType.CHAR || type === ColumnDataType.VARCHAR) {
65
+ const res: ColumnChar = {
66
+ ...column,
67
+ type: type,
68
+ characterSetName: row.characterSetName,
69
+ collationName: row.collationName,
70
+ characterMaximumLength: row.characterMaxLength,
71
+ characterOctetLength: row.characterOctetLength
72
+ }
73
+ return res;
74
+
75
+ } else if (type === ColumnDataType.TINYINT || type === ColumnDataType.SMALLINT || type === ColumnDataType.INT || type === ColumnDataType.MEDIUMINT
76
+ || type === ColumnDataType.BIGINT || type === ColumnDataType.DECIMAL || type === ColumnDataType.FLOAT || type === ColumnDataType.BIT) {
77
+ const typeNum = Number(row.columnType.split("(").pop().split(")").shift());
78
+ const res: ColumnNumber = {
79
+ ...column,
80
+ type: type,
81
+ typeNum: isNaN(typeNum) ? undefined : typeNum,
82
+ scale: row.numericScale,
83
+ precision: row.numericPos,
84
+ isUnsigned: row.columnType.toUpperCase().indexOf("UNSIGNED") >= 0,
85
+ isAutoIncrement: row.extra.toUpperCase().indexOf("AUTO_INCREMENT") >= 0
86
+ }
87
+ return res;
88
+
89
+ } else if (type === ColumnDataType.ENUM) {
90
+ const res: ColumnEnum = {
91
+ ...column,
92
+ type: type,
93
+ values: row.columnType.match(/'([^']+)'/g).map(e => e.replace(/'/g, "").replace(/"/g, ""))
94
+ }
95
+ return res;
96
+ } else if (type === ColumnDataType.SET) {
97
+ const res: ColumnSet = {
98
+ ...column,
99
+ type: type,
100
+ values: row.columnType.match(/'([^']+)'/g).map(e => e.replace(/'/g, "").replace(/"/g, ""))
101
+ }
102
+ return res;
103
+ } else {
104
+ return column as AnyColumn;
105
+ }
106
+ }
107
+
108
+ private static parseDefault(def: string): string | number {
109
+ if (!def || def === "NULL") {
110
+ return null;
111
+ } else if (!isNaN(Number(def))) {
112
+ return def;
113
+ } else {
114
+ return String(def).split("'").join("");
115
+ }
116
+ }
117
+
118
+ private static parseColumnKey(columnKey: string): KeyType[] {
119
+ return columnKey.split(",").map((e) => {
120
+ const key = e.toUpperCase();
121
+ if (key === "PRI") {
122
+ return KeyType.PRIMARY
123
+ } else if (key === "UNI") {
124
+ return KeyType.UNIQUE
125
+ } else if (key === "MUL") {
126
+ return KeyType.MULTIPLE
127
+ } else {
128
+ return null;
129
+ }
130
+ }).filter(e => e);
131
+ }
132
+ }
133
+
134
+ export interface TableStructure {
135
+ name: string;
136
+ columns: AnyColumn[];
137
+ }
138
+
139
+ export enum ColumnDataType {
140
+ TINYINT = "TINYINT",
141
+ SMALLINT = "SMALLINT",
142
+ MEDIUMINT = "MEDIUMINT",
143
+ INT = "INT",
144
+ BIGINT = "BIGINT",
145
+ DECIMAL = "DECIMAL",
146
+ FLOAT = "FLOAT",
147
+ CHAR = "CHAR",
148
+ VARCHAR = "VARCHAR",
149
+ MEDIUMTEXT = "MEDIUMTEXT",
150
+ TEXT = "TEXT",
151
+ LONGTEXT = "LONGTEXT",
152
+ TIMESTAMP = "TIMESTAMP",
153
+ DATETIME = "DATETIME",
154
+ DATE = "DATE",
155
+ TIME = "TIME",
156
+ YEAR = "YEAR",
157
+ ENUM = "ENUM",
158
+ SET = "SET",
159
+ BIT = "BIT",
160
+ LONGBLOB = "LONGBLOB",
161
+ JSON = "JSON"
162
+ }
163
+
164
+ const MYSQL_TYPE_TO_TS_TYPE: Map<ColumnDataType, string> = new Map([
165
+ [ColumnDataType.TINYINT, "number"],
166
+ [ColumnDataType.SMALLINT, "number"],
167
+ [ColumnDataType.MEDIUMINT, "number"],
168
+ [ColumnDataType.INT, "number"],
169
+ [ColumnDataType.BIGINT, "number"],
170
+ [ColumnDataType.DECIMAL, "number"],
171
+ [ColumnDataType.FLOAT, "number"],
172
+ [ColumnDataType.CHAR, "string"],
173
+ [ColumnDataType.VARCHAR, "string"],
174
+ [ColumnDataType.MEDIUMTEXT, "string"],
175
+ [ColumnDataType.TEXT, "string"],
176
+ [ColumnDataType.LONGTEXT, "string"],
177
+ [ColumnDataType.TIMESTAMP, "string"],
178
+ [ColumnDataType.DATETIME, "string"],
179
+ [ColumnDataType.DATE, "string"],
180
+ [ColumnDataType.TIME, "number"],
181
+ [ColumnDataType.YEAR, "number"],
182
+ [ColumnDataType.ENUM, "string"],
183
+ [ColumnDataType.SET, "string"],
184
+ [ColumnDataType.BIT, "number"],
185
+ [ColumnDataType.LONGBLOB, "string"],
186
+ [ColumnDataType.JSON, "string"]
187
+ ])
188
+
189
+
190
+ export type AnyColumn = ColumnText | ColumnChar | ColumnNumber | ColumnSet | ColumnEnum | ColumnDateTimeLike
191
+
192
+ export interface Column {
193
+ type: ColumnDataType;
194
+ name: string;
195
+ tsType: string;
196
+ dataType: string // Type like INT
197
+ columnType: string; // Type like INT(11)
198
+ typeNum?: number | undefined // for INT(11), this would be 11
199
+ default: string | number;
200
+ isNullable: boolean;
201
+ columnKey: KeyType[];
202
+ extra: string;
203
+ comment: string;
204
+ }
205
+
206
+ export interface ColumnDateTimeLike extends Column {
207
+ type: ColumnDataType.DATE |
208
+ ColumnDataType.DATETIME |
209
+ ColumnDataType.TIMESTAMP |
210
+ ColumnDataType.YEAR
211
+ }
212
+
213
+ export interface ColumnText extends Column {
214
+ type: ColumnDataType.CHAR |
215
+ ColumnDataType.VARCHAR |
216
+ ColumnDataType.MEDIUMTEXT |
217
+ ColumnDataType.TEXT |
218
+ ColumnDataType.LONGTEXT;
219
+ characterSetName: string;
220
+ collationName: string;
221
+ }
222
+
223
+ export interface ColumnChar extends ColumnText {
224
+ type: ColumnDataType.VARCHAR |
225
+ ColumnDataType.CHAR;
226
+ characterMaximumLength: number;
227
+ characterOctetLength: number;
228
+ }
229
+
230
+ export interface ColumnNumber extends Column {
231
+ type:
232
+ ColumnDataType.TINYINT |
233
+ ColumnDataType.SMALLINT |
234
+ ColumnDataType.MEDIUMINT |
235
+ ColumnDataType.INT |
236
+ ColumnDataType.BIGINT |
237
+ ColumnDataType.DECIMAL |
238
+ ColumnDataType.FLOAT |
239
+ ColumnDataType.BIT
240
+ isUnsigned: boolean;
241
+ isAutoIncrement: boolean;
242
+ precision: number;
243
+ scale: number;
244
+ }
245
+
246
+ export interface ColumnEnum extends Column {
247
+ type: ColumnDataType.ENUM;
248
+ values: string[];
249
+ }
250
+
251
+ export interface ColumnSet extends Column {
252
+ type: ColumnDataType.SET;
253
+ values: string[];
254
+ }
255
+
256
+ export enum KeyType {
257
+ PRIMARY = "primary",
258
+ UNIQUE = "unique",
259
+ MULTIPLE = "multiple"
260
+ }
261
+
262
+ interface SchemaRow {
263
+ tableSchema: string;
264
+ tableName: string;
265
+ columnName: string;
266
+ ordinalPosition: number;
267
+ columnDefault: string;
268
+ isNullable: string;
269
+ dataType: string;
270
+ characterMaxLength: number;
271
+ characterOctetLength: number;
272
+ numericPos: number;
273
+ numericScale: number;
274
+ dateTimePrecision: number;
275
+ characterSetName: string;
276
+ collationName: string;
277
+ columnType: string;
278
+ columnKey: string;
279
+ extra: string;
280
+ columnComment: string;
281
+ isGenerated: string;
282
+ generationExpression: string;
283
+ }