leoric 2.3.2 → 2.5.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/types/index.d.ts CHANGED
@@ -1,12 +1,24 @@
1
1
  import DataType from './data_types';
2
+ import { Hint, IndexHint } from './hint';
2
3
 
3
4
  export { DataType as DataTypes };
4
5
  export * from '../src/decorators';
5
6
 
7
+ export type command = 'select' | 'insert' | 'bulkInsert' | 'update' | 'delete' | 'upsert';
8
+ export type Literal = null | undefined | boolean | number | bigint | string | Date | object | ArrayBuffer;
9
+
10
+ export class Raw {
11
+ value: string;
12
+ type: 'raw';
13
+ }
14
+
15
+
6
16
  type DataTypes<T> = {
7
17
  [Property in keyof T as Exclude<Property, "toSqlString">]: T[Property]
8
18
  }
9
19
 
20
+ type RawQueryResult = typeof Bone | ResultSet | boolean | number;
21
+
10
22
  interface ExprIdentifier {
11
23
  type: 'id';
12
24
  value: string;
@@ -37,20 +49,35 @@ interface ExprTernaryOperator {
37
49
  }
38
50
 
39
51
  type ExprOperator = ExprBinaryOperator | ExprTernaryOperator;
52
+ type SpellColumn = ExprIdentifier | Raw;
53
+
54
+ interface Join {
55
+ [key: string]: {
56
+ Model: typeof Bone;
57
+ on: ExprBinaryOperator
58
+ }
59
+ }
40
60
 
41
61
  interface SpellOptions {
42
- command?: string;
43
- columns: Object[];
62
+ command?: command;
63
+ columns: SpellColumn[];
44
64
  table: ExprIdentifier;
45
65
  whereConditions: ExprOperator[];
46
66
  groups: (ExprIdentifier | ExprFunc)[];
47
67
  orders: (ExprIdentifier | ExprFunc)[];
48
68
  havingCondtions: ExprOperator[];
49
- joins: Object;
69
+ joins: Join;
50
70
  skip: number;
51
71
  scopes: Function[];
52
72
  subqueryIndex: number;
53
- rowCount: 0;
73
+ rowCount?: number;
74
+ connection?: Connection;
75
+ sets?: { [key: string]: Literal } | { [key: string]: Literal }[];
76
+ hints?: Array<Hint | IndexHint>;
77
+ }
78
+
79
+ export interface SpellMeta extends SpellOptions {
80
+ Model: typeof Bone;
54
81
  }
55
82
 
56
83
  type OrderOptions = { [name: string]: 'desc' | 'asc' };
@@ -64,7 +91,10 @@ type WithOptions = {
64
91
  export class Spell<T extends typeof Bone, U = InstanceType<T> | Collection<InstanceType<T>> | ResultSet | number | null> extends Promise<U> {
65
92
  constructor(Model: T, opts: SpellOptions);
66
93
 
67
- select(...names: Array<string | RawSql> | Array<(name: string) => boolean>): Spell<T, U>;
94
+ command: string;
95
+ scopes: Function[];
96
+
97
+ select(...names: Array<string | Raw> | Array<(name: string) => boolean>): Spell<T, U>;
68
98
  insert(opts: SetOptions): Spell<T, QueryResult>;
69
99
  update(opts: SetOptions): Spell<T, QueryResult>;
70
100
  upsert(opts: SetOptions): Spell<T, QueryResult>;
@@ -86,7 +116,7 @@ export class Spell<T extends typeof Bone, U = InstanceType<T> | Collection<Insta
86
116
  orWhere(conditions: WhereConditions<T>): Spell<T, U>;
87
117
  orWhere(conditions: string, ...values: Literal[]): Spell<T, U>;
88
118
 
89
- group(...names: Array<string | RawSql>): Spell<T, ResultSet>;
119
+ group(...names: Array<string | Raw>): Spell<T, ResultSet>;
90
120
 
91
121
  having(conditions: string, ...values: Literal[]): Spell<T, ResultSet>;
92
122
  having(conditions: WhereConditions<T>): Spell<T, ResultSet>;
@@ -115,7 +145,6 @@ export class Spell<T extends typeof Bone, U = InstanceType<T> | Collection<Insta
115
145
  toString(): string;
116
146
  }
117
147
 
118
- type Literal = null | undefined | boolean | number | bigint | string | Date | object | ArrayBuffer;
119
148
 
120
149
  type OperatorCondition = {
121
150
  [key in '$eq' | '$ne']?: Literal;
@@ -141,16 +170,28 @@ type InstanceValues<T> = {
141
170
  [Property in keyof Extract<T, Literal>]?: Extract<T, Literal>[Property]
142
171
  }
143
172
 
144
- export interface AttributeMeta {
173
+ export interface ColumnMeta {
145
174
  columnName?: string;
146
175
  columnType?: string;
147
176
  allowNull?: boolean;
148
177
  defaultValue?: Literal;
149
178
  primaryKey?: boolean;
179
+ unique?: boolean;
150
180
  dataType?: string;
181
+ comment?: string;
182
+ datetimePrecision?: string;
183
+ }
184
+
185
+ declare type validator = Literal | Function | Array<Literal | Literal[]>;
186
+
187
+ export interface AttributeMeta extends ColumnMeta {
151
188
  jsType?: Literal;
152
189
  type: DataType;
190
+ virtual?: boolean,
153
191
  toSqlString: () => string;
192
+ validate: {
193
+ [key: string]: validator;
194
+ }
154
195
  }
155
196
 
156
197
  interface RelateOptions {
@@ -187,7 +228,59 @@ declare class Pool {
187
228
  getConnection(): Connection;
188
229
  }
189
230
 
190
- declare class Driver {
231
+ declare class Attribute {
232
+ /**
233
+ * attribute name
234
+ */
235
+ name: string;
236
+ /**
237
+ * primaryKey tag
238
+ */
239
+ primaryKey: boolean;
240
+ allowNull: boolean;
241
+ /**
242
+ * attribute column name in table
243
+ */
244
+ columnName: string;
245
+ columnType: string;
246
+ type: typeof DataType;
247
+ defaultValue: Literal;
248
+ dataType: string;
249
+ jsType: Literal;
250
+ virtual: boolean;
251
+
252
+ euals(columnInfo: ColumnMeta): boolean;
253
+ cast(value: Literal): Literal;
254
+ uncast(value: Literal): Literal;
255
+ }
256
+
257
+ interface SpellBookFormatStandardResult {
258
+ sql?: string;
259
+ values?: Array<Literal> | {
260
+ [key: string]: Literal
261
+ };
262
+ [key: string]: Literal
263
+ }
264
+
265
+ export type SpellBookFormatResult<T> = SpellBookFormatStandardResult | T;
266
+
267
+ declare class Spellbook {
268
+
269
+ format(spell: SpellMeta): SpellBookFormatResult<SpellBookFormatStandardResult>;
270
+
271
+ formatInsert(spell: SpellMeta): SpellBookFormatResult<SpellBookFormatStandardResult>;
272
+ formatSelect(spell: SpellMeta): SpellBookFormatResult<SpellBookFormatStandardResult>;
273
+ formatUpdate(spell: SpellMeta): SpellBookFormatResult<SpellBookFormatStandardResult>;
274
+ formatDelete(spell: SpellMeta): SpellBookFormatResult<SpellBookFormatStandardResult>;
275
+ formatUpsert(spell: SpellMeta): SpellBookFormatResult<SpellBookFormatStandardResult>;
276
+ }
277
+
278
+ declare class AbstractDriver {
279
+
280
+ static Spellbook: typeof Spellbook;
281
+ static DataType: typeof DataType;
282
+ static Attribute: typeof Attribute;
283
+
191
284
  /**
192
285
  * The type of driver, currently there are mysql, sqlite, and postgres
193
286
  */
@@ -203,10 +296,153 @@ declare class Driver {
203
296
  */
204
297
  pool: Pool;
205
298
 
299
+ /**
300
+ * The SQL dialect
301
+ */
302
+ dialect: string;
303
+
304
+ spellbook: Spellbook;
305
+
306
+ DataType: DataType;
307
+
308
+ Attribute: Attribute;
309
+
310
+ constructor(options: ConnectOptions);
311
+
312
+ escape: (v: string) => string;
313
+ escapeId: (v: string) => string;
314
+
206
315
  /**
207
316
  * Grab a connection and query the database
208
317
  */
209
- query(sql: string, values?: Array<Literal | Literal[]>): Promise<QueryResult>;
318
+ query(sql: string | { sql: string, nestTables?: boolean}, values?: Array<Literal | Literal[]>, opts?: SpellMeta): Promise<QueryResult>;
319
+
320
+ /**
321
+ * disconnect manually
322
+ * @param callback
323
+ */
324
+ disconnect(callback?: Function): Promise<boolean | void>;
325
+
326
+ /**
327
+ * query with spell
328
+ * @param spell
329
+ */
330
+ cast(spell: Spell<typeof Bone, ResultSet | number | null>): Promise<QueryResult>;
331
+
332
+ /**
333
+ * format spell
334
+ * @param spell SpellMeta
335
+ */
336
+ format(spell: SpellMeta): any;
337
+
338
+ /**
339
+ * create table
340
+ * @param tabe table name
341
+ * @param attributes attributes
342
+ */
343
+ createTable(tabe: string, attributes: { [key: string]: DataTypes<DataType> | AttributeMeta }): Promise<void>;
344
+
345
+ /**
346
+ * alter table
347
+ * @param tabe table name
348
+ * @param attributes alter attributes
349
+ */
350
+ alterTable(tabe: string, attributes: { [key: string]: DataTypes<DataType> | AttributeMeta }): Promise<void>;
351
+
352
+ /**
353
+ * describe table
354
+ * @param table table name
355
+ */
356
+ describeTable(table: string): Promise<{ [key: string]: ColumnMeta }>;
357
+
358
+ /**
359
+ * query table schemas
360
+ * @param database database name
361
+ * @param table table name or table name array
362
+ */
363
+ querySchemaInfo(database: string, table: string | string[]): Promise<{ [key: string] : { [key: string]: ColumnMeta }[]}>;
364
+
365
+ /**
366
+ * add column to table
367
+ * @param table table name
368
+ * @param name column name
369
+ * @param params column meta info
370
+ */
371
+ addColumn(table: string, name: string, params: ColumnMeta): Promise<void>;
372
+
373
+ /**
374
+ * change column meta in table
375
+ * @param table table name
376
+ * @param name column name
377
+ * @param params column meta info
378
+ */
379
+ changeColumn(table: string, name: string, params: ColumnMeta): Promise<void>;
380
+
381
+ /**
382
+ * remove column in table
383
+ * @param table table name
384
+ * @param name column name
385
+ */
386
+ removeColumn(table: string, name: string): Promise<void>;
387
+
388
+ /**
389
+ * rename column in table
390
+ * @param table table name
391
+ * @param name column name
392
+ * @param newName new column name
393
+ */
394
+ renameColumn(table: string, name: string, newName: string): Promise<void>;
395
+
396
+ /**
397
+ * rename table
398
+ * @param table table name
399
+ * @param newTable new table name
400
+ */
401
+ renameTable(table: string, newTable: string): Promise<void>;
402
+
403
+ /**
404
+ * drop table
405
+ * @param table table name
406
+ */
407
+ dropTable(table: string): Promise<void>;
408
+
409
+ /**
410
+ * truncate table
411
+ * @param table table name
412
+ */
413
+ truncateTable(table: string): Promise<void>;
414
+
415
+ /**
416
+ * add index in table
417
+ * @param table table name
418
+ * @param attributes attributes name
419
+ * @param opts
420
+ */
421
+ addIndex(table: string, attributes: string[], opts?: { unique?: boolean, type?: string }): Promise<void>;
422
+
423
+ /**
424
+ * remove index in table
425
+ * @param table string
426
+ * @param attributes attributes name
427
+ * @param opts
428
+ */
429
+ removeIndex(table: string, attributes: string[], opts?: { unique?: boolean, type?: string }): Promise<void>;
430
+
431
+ }
432
+
433
+ export class MysqlDriver extends AbstractDriver {
434
+ type: 'mysql';
435
+ dialect: 'mysql';
436
+ }
437
+
438
+ export class PostgresDriver extends AbstractDriver {
439
+ type: 'postgres';
440
+ dialect: 'postgres';
441
+ }
442
+
443
+ export class SqliteDriver extends AbstractDriver {
444
+ type: 'sqlite';
445
+ dialect: 'sqlite';
210
446
  }
211
447
 
212
448
  type ResultSet = {
@@ -220,7 +456,7 @@ export class Collection<T extends Bone> extends Array<T> {
220
456
  }
221
457
 
222
458
  export class Bone {
223
- static DataTypes: DataType;
459
+ static DataTypes: typeof DataType;
224
460
 
225
461
  /**
226
462
  * get the connection pool of the driver
@@ -230,7 +466,7 @@ export class Bone {
230
466
  /**
231
467
  * The driver that powers the model
232
468
  */
233
- static driver: Driver;
469
+ static driver: AbstractDriver;
234
470
 
235
471
  /**
236
472
  * The connected models structured as `{ [model.name]: model }`, e.g. `Bone.model.Post => Post`
@@ -303,6 +539,7 @@ export class Bone {
303
539
 
304
540
  static alias(name: string): string;
305
541
  static alias(data: Record<string, Literal>): Record<string, Literal>;
542
+ static unalias(name: string): string;
306
543
 
307
544
  static hasOne(name: string, opts?: RelateOptions): void;
308
545
  static hasMany(name: string, opts?: RelateOptions): void;
@@ -457,8 +694,8 @@ export class Bone {
457
694
  * yield Muscle.create({ boneId: bone.id, bar: 1 })
458
695
  * });
459
696
  */
460
- static transaction(callback: GeneratorFunction): Promise<void>;
461
- static transaction(callback: (connection: Connection) => Promise<void>): Promise<void>;
697
+ static transaction(callback: GeneratorFunction): Promise<RawQueryResult>;
698
+ static transaction(callback: (connection: Connection) => Promise<RawQueryResult>): Promise<RawQueryResult>;
462
699
 
463
700
  /**
464
701
  * DROP the table
@@ -474,7 +711,7 @@ export class Bone {
474
711
 
475
712
  static initialize(): void;
476
713
 
477
- constructor(values: { [key: string]: Literal });
714
+ constructor(values: { [key: string]: Literal }, opts?: { isNewRecord?: boolean });
478
715
 
479
716
  /**
480
717
  * @example
@@ -609,6 +846,7 @@ export interface ConnectOptions {
609
846
  charset?: string;
610
847
  models?: string | (typeof Bone)[];
611
848
  subclass?: boolean;
849
+ driver?: typeof AbstractDriver;
612
850
  }
613
851
 
614
852
  interface InitOptions {
@@ -626,12 +864,6 @@ interface SyncOptions {
626
864
  alter?: boolean;
627
865
  }
628
866
 
629
- type RawSql = {
630
- __raw: true,
631
- value: string,
632
- type: 'raw',
633
- };
634
-
635
867
  interface RawQueryOptions {
636
868
  replacements?: { [key:string]: Literal | Literal[] };
637
869
  model: Bone;
@@ -641,11 +873,14 @@ interface RawQueryOptions {
641
873
  export default class Realm {
642
874
  Bone: typeof Bone;
643
875
  DataTypes: typeof DataType;
644
- driver: Driver;
876
+ driver: AbstractDriver;
645
877
  models: Record<string, Bone>;
878
+ connected?: boolean;
646
879
 
647
880
  constructor(options: ConnectOptions);
648
881
 
882
+ connect(): Promise<Bone>;
883
+
649
884
  define(
650
885
  name: string,
651
886
  attributes: Record<string, DataTypes<DataType> | AttributeMeta>,
@@ -653,14 +888,14 @@ export default class Realm {
653
888
  descriptors?: Record<string, Function>,
654
889
  ): typeof Bone;
655
890
 
656
- raw(sql: string): RawSql;
891
+ raw(sql: string): Raw;
657
892
 
658
893
  escape(value: Literal): string;
659
894
 
660
- query(sql: string, values?: Array<Literal>, options?: RawQueryOptions): ResultSet;
895
+ query(sql: string, values?: Array<Literal>, options?: RawQueryOptions): RawQueryResult;
661
896
 
662
- transaction(callback: GeneratorFunction): Promise<void>;
663
- transaction(callback: (connection: Connection) => Promise<void>): Promise<void>;
897
+ transaction(callback: GeneratorFunction): Promise<RawQueryResult>;
898
+ transaction(callback: (connection: Connection) => Promise<RawQueryResult>): Promise<RawQueryResult>;
664
899
 
665
900
  sync(options?: SyncOptions): Promise<void>;
666
901
  }
@@ -676,3 +911,8 @@ export default class Realm {
676
911
  * })
677
912
  */
678
913
  export function connect(opts: ConnectOptions): Promise<Realm>;
914
+ export function disconnect(realm: Realm, callback?: Function): Promise<boolean | void>;
915
+ export {
916
+ Hint,
917
+ IndexHint,
918
+ }
@@ -1,143 +0,0 @@
1
- 'use strict';
2
-
3
- const { heresql } = require('../../utils/string');
4
-
5
- module.exports = {
6
- async createTable(table, attributes) {
7
- const { escapeId, Attribute } = this;
8
- const chunks = [ `CREATE TABLE ${escapeId(table)}` ];
9
- const columns = Object.keys(attributes).map(name => {
10
- const attribute = new Attribute(name, attributes[name]);
11
- return attribute.toSqlString();
12
- });
13
- chunks.push(`(${columns.join(', ')})`);
14
- await this.query(chunks.join(' '));
15
- },
16
-
17
- async alterTable(table, attributes) {
18
- const { escapeId, Attribute } = this;
19
- const chunks = [ `ALTER TABLE ${escapeId(table)}` ];
20
-
21
- const actions = Object.keys(attributes).map(name => {
22
- const options = attributes[name];
23
- // { [columnName]: { remove: true } }
24
- if (options.remove) return `DROP COLUMN ${escapeId(name)}`;
25
- const attribute = new Attribute(name, options);
26
- return [
27
- options.modify ? 'MODIFY COLUMN' : 'ADD COLUMN',
28
- attribute.toSqlString(),
29
- ].join(' ');
30
- });
31
- chunks.push(actions.join(', '));
32
- await this.query(chunks.join(' '));
33
- },
34
-
35
- async describeTable(table) {
36
- const { database } = this.options;
37
- const schemaInfo = await this.querySchemaInfo(database, table);
38
- return schemaInfo[table].reduce(function(result, column) {
39
- result[column.columnName] = column;
40
- return result;
41
- }, {});
42
- },
43
-
44
- async addColumn(table, name, params) {
45
- const { escapeId, Attribute } = this;
46
- const attribute = new Attribute(name, params);
47
- const sql = heresql(`
48
- ALTER TABLE ${escapeId(table)}
49
- ADD COLUMN ${attribute.toSqlString()}
50
- `);
51
- await this.query(sql);
52
- },
53
-
54
- async changeColumn(table, name, params) {
55
- const { escapeId, Attribute } = this;
56
- const attribute = new Attribute(name, params);
57
- const sql = heresql(`
58
- ALTER TABLE ${escapeId(table)}
59
- MODIFY COLUMN ${attribute.toSqlString()}
60
- `);
61
- await this.query(sql);
62
- },
63
-
64
- async removeColumn(table, name) {
65
- const { escapeId, Attribute } = this;
66
- const { columnName } = new Attribute(name);
67
- const sql = heresql(`
68
- ALTER TABLE ${escapeId(table)} DROP COLUMN ${escapeId(columnName)}
69
- `);
70
- await this.query(sql);
71
- },
72
-
73
- async renameColumn(table, name, newName) {
74
- const { escapeId, Attribute } = this;
75
- const { columnName } = new Attribute(name);
76
- const attribute = new Attribute(newName);
77
- const sql = heresql(`
78
- ALTER TABLE ${escapeId(table)}
79
- RENAME COLUMN ${escapeId(columnName)} TO ${escapeId(attribute.columnName)}
80
- `);
81
- await this.query(sql);
82
- },
83
-
84
- async renameTable(table, newTable) {
85
- const { escapeId } = this;
86
- const sql = heresql(`
87
- ALTER TABLE ${escapeId(table)} RENAME TO ${escapeId(newTable)}
88
- `);
89
- await this.query(sql);
90
- },
91
-
92
- async dropTable(table) {
93
- const { escapeId } = this;
94
- await this.query(`DROP TABLE IF EXISTS ${escapeId(table)}`);
95
- },
96
-
97
- async truncateTable(table) {
98
- const { escapeId } = this;
99
- await this.query(`TRUNCATE TABLE ${escapeId(table)}`);
100
- },
101
-
102
- async addIndex(table, attributes, opts = {}) {
103
- const { escapeId, Attribute } = this;
104
- const columns = attributes.map(name => new Attribute(name).columnName);
105
- const type = opts.unique ? 'UNIQUE' : opts.type;
106
- const prefix = type === 'UNIQUE' ? 'uk' : 'idx';
107
- const { name } = {
108
- name: [ prefix, table ].concat(columns).join('_'),
109
- ...opts,
110
- };
111
-
112
- if (type != null && ![ 'UNIQUE', 'FULLTEXT', 'SPATIAL' ].includes(type)) {
113
- throw new Error(`Unexpected index type: ${type}`);
114
- }
115
-
116
- const sql = heresql(`
117
- CREATE ${type ? `${type} INDEX` : 'INDEX'} ${escapeId(name)}
118
- ON ${escapeId(table)} (${columns.map(escapeId).join(', ')})
119
- `);
120
- await this.query(sql);
121
- },
122
-
123
- async removeIndex(table, attributes, opts = {}) {
124
- const { escapeId, Attribute } = this;
125
- let name;
126
- if (Array.isArray(attributes)) {
127
- const columns = attributes.map(entry => new Attribute(entry).columnName);
128
- const type = opts.unique ? 'UNIQUE' : opts.type;
129
- const prefix = type === 'UNIQUE' ? 'uk' : 'idx';
130
- name = [ prefix, table ].concat(columns).join('_');
131
- } else if (typeof attributes === 'string') {
132
- name = attributes;
133
- } else {
134
- throw new Error(`Unexpected index name: ${attributes}`);
135
- }
136
-
137
- const sql = this.type === 'mysql'
138
- ? `DROP INDEX ${escapeId(name)} ON ${escapeId(table)}`
139
- : `DROP INDEX IF EXISTS ${escapeId(name)}`;
140
- await this.query(sql);
141
- },
142
-
143
- };
@@ -1,98 +0,0 @@
1
- 'use strict';
2
-
3
- const Attribute = require('./attribute');
4
- const schema = require('../abstract/schema');
5
- const { heresql } = require('../../utils/string');
6
-
7
- module.exports = {
8
- ...schema,
9
-
10
- /**
11
- * Fetch columns of give tables from database
12
- * - https://dev.mysql.com/doc/mysql-infoschema-excerpt/5.6/en/columns-table.html
13
- * @param {string} database
14
- * @param {string|string[]} tables
15
- */
16
- async querySchemaInfo(database, tables) {
17
- tables = [].concat(tables);
18
- const sql = heresql(`
19
- SELECT table_name, column_name, column_type, data_type, is_nullable,
20
- column_default, column_key, column_comment,
21
- datetime_precision
22
- FROM information_schema.columns
23
- WHERE table_schema = ? AND table_name in (?)
24
- ORDER BY table_name, column_name
25
- `);
26
-
27
- const { rows } = await this.query(sql, [ database, tables ]);
28
- const schemaInfo = {};
29
-
30
- for (const entry of rows) {
31
- // make sure the column names are in lower case
32
- const row = Object.keys(entry).reduce((obj, name) => {
33
- obj[name.toLowerCase()] = entry[name];
34
- return obj;
35
- }, {});
36
- const tabelName = row.table_name;
37
- const columns = schemaInfo[tabelName] || (schemaInfo[tabelName] = []);
38
- columns.push({
39
- columnName: row.column_name,
40
- columnType: row.column_type,
41
- comment: row.column_comment,
42
- defaultValue: row.column_default,
43
- dataType: row.data_type,
44
- allowNull: row.is_nullable === 'YES',
45
- primaryKey: row.column_key == 'PRI',
46
- unique: row.column_key == 'PRI' || row.column_key == 'UNI',
47
- datetimePrecision: row.datetime_precision,
48
- });
49
- }
50
-
51
- return schemaInfo;
52
- },
53
-
54
- /**
55
- * Rename column with SQL that works on older versions of MySQL
56
- * - https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
57
- * - https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
58
- * @param {string} table
59
- * @param {string} column the old column name
60
- * @param {string} newColumn the new column name
61
- */
62
- async renameColumn(table, name, newName) {
63
- const { escapeId } = this;
64
- const { database } = this.options;
65
- const { columnName } = new Attribute(name);
66
- const schemaInfo = await this.querySchemaInfo(database, table);
67
- const { columnName: _, ...columnInfo } = schemaInfo[table].find(entry => {
68
- return entry.columnName == columnName;
69
- });
70
-
71
- if (!columnInfo) {
72
- throw new Error(`Unable to find column ${table}.${columnName}`);
73
- }
74
-
75
- const attribute = new Attribute(newName, columnInfo);
76
- const sql = heresql(`
77
- ALTER TABLE ${escapeId(table)}
78
- CHANGE COLUMN ${escapeId(columnName)} ${attribute.toSqlString()}
79
- `);
80
- await this.query(sql);
81
- },
82
-
83
- async describeTable(table) {
84
- const { escapeId } = this;
85
- const { rows } = await this.query(`DESCRIBE ${escapeId(table)}`);
86
- const result = {};
87
- for (const row of rows) {
88
- result[row.Field] = {
89
- columnName: row.Field,
90
- columnType: row.Type,
91
- allowNull: row.Null === 'YES',
92
- defaultValue: row.Default,
93
- autoIncrement: row.Extra === 'auto_increment',
94
- };
95
- }
96
- return result;
97
- },
98
- };