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/History.md +31 -0
- package/Readme.md +1 -1
- package/index.js +14 -0
- package/package.json +3 -1
- package/src/bone.js +11 -11
- package/src/constants.js +8 -1
- package/src/data_types.js +32 -32
- package/src/drivers/abstract/attribute.js +1 -1
- package/src/drivers/abstract/index.js +201 -1
- package/src/drivers/abstract/spellbook.js +403 -412
- package/src/drivers/index.js +15 -4
- package/src/drivers/mysql/index.js +101 -10
- package/src/drivers/mysql/spellbook.js +13 -11
- package/src/drivers/postgres/data_types.js +2 -2
- package/src/drivers/postgres/index.js +103 -109
- package/src/drivers/postgres/spellbook.js +9 -9
- package/src/drivers/postgres/sqlstring.js +124 -0
- package/src/drivers/sqlite/data_types.js +9 -9
- package/src/drivers/sqlite/index.js +124 -13
- package/src/drivers/sqlite/spellbook.js +6 -6
- package/src/drivers/sqlite/sqlstring.js +88 -0
- package/src/hint.js +2 -1
- package/src/realm.js +13 -5
- package/src/spell.js +2 -4
- package/src/utils/invokable.js +3 -0
- package/types/data_types.d.ts +35 -32
- package/types/hint.d.ts +96 -0
- package/types/index.d.ts +266 -26
- package/src/drivers/abstract/schema.js +0 -143
- package/src/drivers/mysql/schema.js +0 -98
- package/src/drivers/postgres/schema.js +0 -125
- package/src/drivers/sqlite/schema.js +0 -211
|
@@ -34,8 +34,8 @@ class Sqlite_DATEONLY extends DataTypes.DATEONLY {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
class Sqlite_INTEGER extends DataTypes.INTEGER {
|
|
37
|
-
constructor(
|
|
38
|
-
super(
|
|
37
|
+
constructor(dataLength) {
|
|
38
|
+
super(dataLength);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
uncast(value) {
|
|
@@ -54,24 +54,24 @@ class Sqlite_BIGINT extends DataTypes.BIGINT {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
class Sqlite_BINARY extends DataTypes {
|
|
57
|
-
constructor(
|
|
58
|
-
super(
|
|
59
|
-
this.
|
|
57
|
+
constructor(dataLength = 255) {
|
|
58
|
+
super(dataLength);
|
|
59
|
+
this.dataLength = dataLength;
|
|
60
60
|
this.dataType = 'binary';
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
toSqlString() {
|
|
64
|
-
const {
|
|
64
|
+
const { dataLength } = this;
|
|
65
65
|
const dataType = this.dataType.toUpperCase();
|
|
66
66
|
const chunks = [];
|
|
67
67
|
chunks.push('VARCHAR');
|
|
68
|
-
chunks.push(
|
|
68
|
+
chunks.push(dataLength > 0 ? `${dataType}(${dataLength})` : dataType);
|
|
69
69
|
return chunks.join(' ');
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
class Sqlite_VARBINARY extends Sqlite_BINARY {
|
|
73
|
-
constructor(
|
|
74
|
-
super(
|
|
73
|
+
constructor(dataLength) {
|
|
74
|
+
super(dataLength);
|
|
75
75
|
this.dataType = 'varbinary';
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -6,17 +6,29 @@ const { performance } = require('perf_hooks');
|
|
|
6
6
|
const AbstractDriver = require('../abstract');
|
|
7
7
|
const Attribute = require('./attribute');
|
|
8
8
|
const DataTypes = require('./data_types');
|
|
9
|
-
const { escapeId, escape } = require('./sqlstring');
|
|
10
|
-
const
|
|
11
|
-
const spellbook = require('./spellbook');
|
|
9
|
+
const { escapeId, escape, alterTableWithChangeColumn, parseDefaultValue } = require('./sqlstring');
|
|
10
|
+
const Spellbook = require('./spellbook');
|
|
12
11
|
const Pool = require('./pool');
|
|
13
12
|
const { calculateDuration } = require('../../utils');
|
|
13
|
+
const { heresql } = require('../../utils/string');
|
|
14
14
|
|
|
15
15
|
class SqliteDriver extends AbstractDriver {
|
|
16
|
+
|
|
17
|
+
// define static properties as this way IDE will prompt
|
|
18
|
+
static Spellbook = Spellbook;
|
|
19
|
+
static Attribute = Attribute;
|
|
20
|
+
static DataTypes = DataTypes;
|
|
21
|
+
|
|
16
22
|
constructor(opts = {}) {
|
|
17
23
|
super(opts);
|
|
18
24
|
this.type = 'sqlite';
|
|
19
25
|
this.pool = this.createPool(opts);
|
|
26
|
+
this.Attribute = this.constructor.Attribute;
|
|
27
|
+
this.DataTypes = this.constructor.DataTypes;
|
|
28
|
+
this.spellbook = new this.constructor.Spellbook();
|
|
29
|
+
|
|
30
|
+
this.escape = escape;
|
|
31
|
+
this.escapeId = escapeId;
|
|
20
32
|
}
|
|
21
33
|
|
|
22
34
|
createPool(opts) {
|
|
@@ -58,17 +70,116 @@ class SqliteDriver extends AbstractDriver {
|
|
|
58
70
|
return result;
|
|
59
71
|
}
|
|
60
72
|
|
|
61
|
-
|
|
62
|
-
|
|
73
|
+
async querySchemaInfo(database, tables) {
|
|
74
|
+
tables = [].concat(tables);
|
|
75
|
+
|
|
76
|
+
const queries = tables.map(table => {
|
|
77
|
+
return this.query(`PRAGMA table_info(${this.escapeId(table)})`);
|
|
78
|
+
});
|
|
79
|
+
const results = await Promise.all(queries);
|
|
80
|
+
const schemaInfo = {};
|
|
81
|
+
const rColumnType = /^(\w+)(?:\(([^)]+)\))?/i;
|
|
82
|
+
const rDateType = /(?:date|datetime|timestamp)/i;
|
|
83
|
+
|
|
84
|
+
for (let i = 0; i < tables.length; i++) {
|
|
85
|
+
const table = tables[i];
|
|
86
|
+
const { rows } = results[i];
|
|
87
|
+
const columns = rows.map(row => {
|
|
88
|
+
const { name, type, notnull, dflt_value, pk } = row;
|
|
89
|
+
const columnType = type.toLowerCase();
|
|
90
|
+
const [, dataType, precision ] = columnType.match(rColumnType);
|
|
91
|
+
const primaryKey = pk === 1;
|
|
92
|
+
|
|
93
|
+
const result = {
|
|
94
|
+
columnName: name,
|
|
95
|
+
columnType,
|
|
96
|
+
defaultValue: parseDefaultValue(dflt_value, type),
|
|
97
|
+
dataType: dataType,
|
|
98
|
+
allowNull: primaryKey ? false : notnull == 0,
|
|
99
|
+
primaryKey,
|
|
100
|
+
datetimePrecision: rDateType.test(dataType) ? parseInt(precision, 10) : null,
|
|
101
|
+
};
|
|
102
|
+
return result;
|
|
103
|
+
});
|
|
104
|
+
if (columns.length > 0) schemaInfo[table] = columns;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return schemaInfo;
|
|
63
108
|
}
|
|
64
|
-
};
|
|
65
109
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
});
|
|
110
|
+
async createTable(table, attributes, opts = {}) {
|
|
111
|
+
const chunks = [ `CREATE TABLE ${escapeId(table)}` ];
|
|
112
|
+
const columns = Object.keys(attributes).map(name => {
|
|
113
|
+
const attribute = new this.constructor.Attribute(name, attributes[name]);
|
|
114
|
+
return attribute.toSqlString();
|
|
115
|
+
});
|
|
116
|
+
chunks.push(`(${columns.join(', ')})`);
|
|
117
|
+
await this.query(chunks.join(' '), [], opts);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async alterTable(table, changes) {
|
|
121
|
+
const chunks = [ `ALTER TABLE ${escapeId(table)}` ];
|
|
122
|
+
const attributes = Object.keys(changes).map(name => {
|
|
123
|
+
const options = changes[name];
|
|
124
|
+
if (options.remove) return { columnName: name, remove: true };
|
|
125
|
+
return new this.constructor.Attribute(name, changes[name]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// SQLite doesn't support altering column attributes with MODIFY COLUMN and adding a PRIMARY KEY column
|
|
129
|
+
if (attributes.some(entry => entry.modify || entry.primaryKey)) {
|
|
130
|
+
await alterTableWithChangeColumn(this, table, attributes);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// SQLite can only add one column a time
|
|
135
|
+
// - https://www.sqlite.org/lang_altertable.html
|
|
136
|
+
for (const attribute of attributes) {
|
|
137
|
+
if (attribute.remove) {
|
|
138
|
+
const { columnName } = attribute;
|
|
139
|
+
await this.query(chunks.concat(`DROP COLUMN ${this.escapeId(columnName)}`).join(' '));
|
|
140
|
+
} else {
|
|
141
|
+
await this.query(chunks.concat(`ADD COLUMN ${attribute.toSqlString()}`).join(' '));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async addColumn(table, name, params) {
|
|
147
|
+
const attribute = new this.constructor.Attribute(name, params);
|
|
148
|
+
const sql = heresql(`
|
|
149
|
+
ALTER TABLE ${escapeId(table)}
|
|
150
|
+
ADD COLUMN ${attribute.toSqlString()}
|
|
151
|
+
`);
|
|
152
|
+
await this.query(sql);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async changeColumn(table, name, params) {
|
|
156
|
+
const attribute = new this.Attribute(name, params);
|
|
157
|
+
const schemaInfo = await this.querySchemaInfo(null, table);
|
|
158
|
+
const columns = schemaInfo[table];
|
|
159
|
+
|
|
160
|
+
for (const entry of columns) {
|
|
161
|
+
if (entry.columnName === attribute.columnName) {
|
|
162
|
+
Object.assign(entry, attribute, { modify: true });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
await this.alterTable(table, columns);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async removeColumn(table, name) {
|
|
170
|
+
const attribute = new this.Attribute(name);
|
|
171
|
+
attribute.remove = true;
|
|
172
|
+
const changes = [ attribute ];
|
|
173
|
+
await alterTableWithChangeColumn(this, table, changes);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* SQLite has only got implicit table truncation.
|
|
178
|
+
* - https://sqlite.org/lang_delete.html#the_truncate_optimization
|
|
179
|
+
*/
|
|
180
|
+
async truncateTable(table) {
|
|
181
|
+
await this.query(`DELETE FROM ${escapeId(table)}`);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
73
184
|
|
|
74
185
|
module.exports = SqliteDriver;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const Spellbook = require('../abstract/spellbook');
|
|
4
4
|
|
|
5
5
|
function renameSelectExpr(spell) {
|
|
6
6
|
const { Model, columns, joins, groups } = spell;
|
|
@@ -40,14 +40,14 @@ function renameSelectExpr(spell) {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
...spellbook,
|
|
45
|
-
|
|
43
|
+
class SQLiteSpellBook extends Spellbook {
|
|
46
44
|
formatSelect(spell) {
|
|
47
45
|
if (Object.keys(spell.joins).length > 0) {
|
|
48
46
|
spell = spell.dup;
|
|
49
47
|
renameSelectExpr(spell);
|
|
50
48
|
}
|
|
51
|
-
return
|
|
49
|
+
return super.formatSelect(spell);
|
|
52
50
|
}
|
|
53
|
-
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
module.exports = SQLiteSpellBook;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const SqlString = require('sqlstring');
|
|
4
|
+
const debug = require('debug')('leoric');
|
|
5
|
+
|
|
6
|
+
const { parseExpr } = require('../../expr');
|
|
7
|
+
const { heresql } = require('../../utils/string');
|
|
4
8
|
|
|
5
9
|
exports.escape = function escape(value) {
|
|
6
10
|
if (typeof value === 'boolean') return +value;
|
|
@@ -10,3 +14,87 @@ exports.escape = function escape(value) {
|
|
|
10
14
|
exports.escapeId = function escapeId(identifier) {
|
|
11
15
|
return `"${identifier.replace(/"/g, '""')}"`;
|
|
12
16
|
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Schema altering commands other than RENAME COLUMN or ADD COLUMN
|
|
20
|
+
* - https://www.sqlite.org/lang_altertable.html
|
|
21
|
+
* @param {string} table
|
|
22
|
+
* @param {Object} attributes the changed attributes
|
|
23
|
+
*/
|
|
24
|
+
exports.alterTableWithChangeColumn = async function alterTableWithChangeColumn(driver, table, changes) {
|
|
25
|
+
const { escapeId } = driver;
|
|
26
|
+
const schemaInfo = await driver.querySchemaInfo(null, table);
|
|
27
|
+
const columns = schemaInfo[table];
|
|
28
|
+
|
|
29
|
+
const changeMap = changes.reduce((result, entry) => {
|
|
30
|
+
result[entry.columnName] = entry;
|
|
31
|
+
return result;
|
|
32
|
+
}, {});
|
|
33
|
+
|
|
34
|
+
const newAttributes = [];
|
|
35
|
+
for (const column of columns) {
|
|
36
|
+
const { columnName } = column;
|
|
37
|
+
const change = changeMap[columnName];
|
|
38
|
+
if (!change || !change.remove) {
|
|
39
|
+
newAttributes.push(Object.assign(column, change));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (const attribute of changes) {
|
|
44
|
+
if (!attribute.modify && !attribute.remove) {
|
|
45
|
+
newAttributes.push(attribute);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const newColumns = [];
|
|
50
|
+
for (const attribute of newAttributes) {
|
|
51
|
+
const { columnName, defaultValue } = attribute;
|
|
52
|
+
const change = changeMap[columnName];
|
|
53
|
+
if (!change || change.modify) {
|
|
54
|
+
newColumns.push(escapeId(columnName));
|
|
55
|
+
} else {
|
|
56
|
+
newColumns.push(SqlString.escape(defaultValue));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const connection = await driver.getConnection();
|
|
61
|
+
await connection.query('BEGIN');
|
|
62
|
+
try {
|
|
63
|
+
const newTable = `new_${table}`;
|
|
64
|
+
await driver.createTable(newTable, newAttributes, { connection });
|
|
65
|
+
await connection.query(heresql(`
|
|
66
|
+
INSERT INTO ${escapeId(newTable)}
|
|
67
|
+
SELECT ${newColumns.join(', ')}
|
|
68
|
+
FROM ${escapeId(table)}
|
|
69
|
+
`));
|
|
70
|
+
await connection.query(`DROP TABLE ${escapeId(table)}`);
|
|
71
|
+
await connection.query(heresql(`
|
|
72
|
+
ALTER TABLE ${escapeId(newTable)}
|
|
73
|
+
RENAME TO ${escapeId(table)}
|
|
74
|
+
`));
|
|
75
|
+
await connection.query('COMMIT');
|
|
76
|
+
} catch (err) {
|
|
77
|
+
await connection.query('ROLLBACK');
|
|
78
|
+
throw err;
|
|
79
|
+
} finally {
|
|
80
|
+
await connection.release();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// eslint-disable-next-line no-unused-vars
|
|
85
|
+
exports.parseDefaultValue = function parseDefaultValue(text, type) {
|
|
86
|
+
if (typeof text !== 'string') return text;
|
|
87
|
+
if (type === 'boolean') return text === 'true';
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const ast = parseExpr(text);
|
|
91
|
+
if (ast.type === 'literal') {
|
|
92
|
+
return ast.value;
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
debug('[parseDefaultValue] [%s] %s', text, err);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return text;
|
|
99
|
+
};
|
|
100
|
+
|
package/src/hint.js
CHANGED
package/src/realm.js
CHANGED
|
@@ -4,7 +4,7 @@ const fs = require('fs').promises;
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
6
|
const Bone = require('./bone');
|
|
7
|
-
const { findDriver } = require('./drivers');
|
|
7
|
+
const { findDriver, AbstractDriver } = require('./drivers');
|
|
8
8
|
const { camelCase } = require('./utils/string');
|
|
9
9
|
const sequelize = require('./adapters/sequelize');
|
|
10
10
|
const Raw = require('./raw');
|
|
@@ -97,7 +97,7 @@ const rReplacementKey = /\s:(\w+)\b/g;
|
|
|
97
97
|
|
|
98
98
|
class Realm {
|
|
99
99
|
constructor(opts = {}) {
|
|
100
|
-
|
|
100
|
+
let { client, dialect, database, driver: CustomDriver, ...restOpts } = {
|
|
101
101
|
dialect: 'mysql',
|
|
102
102
|
database: opts.db || opts.storage,
|
|
103
103
|
...opts
|
|
@@ -109,16 +109,18 @@ class Realm {
|
|
|
109
109
|
for (const model of opts.models) models[model.name] = model;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
const
|
|
112
|
+
const DriverClass = CustomDriver && CustomDriver.prototype instanceof AbstractDriver? CustomDriver : findDriver(dialect);
|
|
113
|
+
const driver = new DriverClass({
|
|
113
114
|
client,
|
|
114
115
|
database,
|
|
115
|
-
...restOpts
|
|
116
|
+
...restOpts,
|
|
116
117
|
});
|
|
117
118
|
|
|
118
119
|
const options = {
|
|
119
120
|
client,
|
|
120
|
-
dialect,
|
|
121
|
+
dialect: driver.dialect,
|
|
121
122
|
database,
|
|
123
|
+
driver: CustomDriver,
|
|
122
124
|
...restOpts,
|
|
123
125
|
define: { underscored: true, ...opts.define },
|
|
124
126
|
};
|
|
@@ -158,6 +160,12 @@ class Realm {
|
|
|
158
160
|
return this.Bone;
|
|
159
161
|
}
|
|
160
162
|
|
|
163
|
+
async disconnect(callback) {
|
|
164
|
+
if (this.connected && this.driver) {
|
|
165
|
+
return await this.driver.disconnect(callback);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
161
169
|
async sync(options) {
|
|
162
170
|
if (!this.connected) await this.connect();
|
|
163
171
|
const { models } = this;
|
package/src/spell.js
CHANGED
|
@@ -450,10 +450,8 @@ class Spell {
|
|
|
450
450
|
}
|
|
451
451
|
|
|
452
452
|
async ignite() {
|
|
453
|
-
const { Model,
|
|
454
|
-
|
|
455
|
-
const query = { sql, nestTables: command === 'select' };
|
|
456
|
-
let result = await Model.driver.query(query, values, this);
|
|
453
|
+
const { Model, laters } = this;
|
|
454
|
+
let result = await Model.driver.cast(this);
|
|
457
455
|
result = { ...result, spell: this };
|
|
458
456
|
for (const later of laters) {
|
|
459
457
|
result = await later(result);
|
package/src/utils/invokable.js
CHANGED
|
@@ -18,6 +18,9 @@ function invokable(DataType) {
|
|
|
18
18
|
|
|
19
19
|
// INTEGER.UNSIGNED
|
|
20
20
|
get(target, p) {
|
|
21
|
+
// ref: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/length
|
|
22
|
+
// The length property indicates the number of parameters expected by the function.
|
|
23
|
+
// invokable INTEGER.toSqlString() will default to return "INTEGER(1)"
|
|
21
24
|
return target.hasOwnProperty(p) ? target[p] : new target()[p];
|
|
22
25
|
}
|
|
23
26
|
});
|
package/types/data_types.d.ts
CHANGED
|
@@ -1,65 +1,68 @@
|
|
|
1
1
|
type LENGTH_VARIANTS = 'tiny' | '' | 'medium' | 'long';
|
|
2
2
|
|
|
3
|
-
interface INVOKABLE<T> {
|
|
4
|
-
(
|
|
5
|
-
(
|
|
3
|
+
interface INVOKABLE<T> extends DataType {
|
|
4
|
+
(dataLength?: LENGTH_VARIANTS): T;
|
|
5
|
+
(dataLength?: number): T;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export default class DataType {
|
|
9
9
|
toSqlString(): string;
|
|
10
10
|
|
|
11
|
-
static STRING:
|
|
12
|
-
static INTEGER:
|
|
13
|
-
static BIGINT:
|
|
14
|
-
static DECIMAL:
|
|
15
|
-
static TEXT:
|
|
16
|
-
static BLOB:
|
|
17
|
-
static JSON:
|
|
18
|
-
static JSONB:
|
|
19
|
-
static BINARY:
|
|
20
|
-
static VARBINARY:
|
|
21
|
-
static DATE:
|
|
22
|
-
static DATEONLY:
|
|
23
|
-
static BOOLEAN:
|
|
24
|
-
static VIRTUAL:
|
|
11
|
+
static STRING: INVOKABLE<STRING>;
|
|
12
|
+
static INTEGER: INTEGER & INVOKABLE<INTEGER>;
|
|
13
|
+
static BIGINT: BIGINT & INVOKABLE<BIGINT>;
|
|
14
|
+
static DECIMAL: DECIMAL & INVOKABLE<DECIMAL>;
|
|
15
|
+
static TEXT: INVOKABLE<TEXT>;
|
|
16
|
+
static BLOB: INVOKABLE<BLOB>;
|
|
17
|
+
static JSON: JSON;
|
|
18
|
+
static JSONB: JSONB;
|
|
19
|
+
static BINARY: BINARY & INVOKABLE<BINARY>;
|
|
20
|
+
static VARBINARY: VARBINARY & INVOKABLE<VARBINARY>;
|
|
21
|
+
static DATE: DATE & INVOKABLE<DATE>;
|
|
22
|
+
static DATEONLY: DATEONLY;
|
|
23
|
+
static BOOLEAN: BOOLEAN;
|
|
24
|
+
static VIRTUAL: VIRTUAL;
|
|
25
25
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
declare class STRING extends DataType {
|
|
29
29
|
dataType: 'varchar';
|
|
30
|
-
|
|
31
|
-
constructor(
|
|
30
|
+
dataLength: number;
|
|
31
|
+
constructor(dataLength: number);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
declare class INTEGER extends DataType {
|
|
35
35
|
dataType: 'integer' | 'bigint' | 'decimal';
|
|
36
|
-
|
|
37
|
-
constructor(
|
|
38
|
-
|
|
39
|
-
get
|
|
36
|
+
dataLength: number;
|
|
37
|
+
constructor(dataLength: number);
|
|
38
|
+
// avoid INTEGER.UNSIGNED.ZEROFILL.UNSIGNED.UNSIGNED
|
|
39
|
+
get UNSIGNED(): Omit<this, 'UNSIGNED' | 'ZEROFILL'>;
|
|
40
|
+
get ZEROFILL(): Omit<this, 'UNSIGNED' | 'ZEROFILL'>;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
declare class BIGINT extends INTEGER {
|
|
43
44
|
dataType: 'bigint';
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
declare class
|
|
47
|
+
declare class DECIMAL_INNER extends INTEGER {
|
|
47
48
|
dataType: 'decimal';
|
|
48
49
|
precision: number;
|
|
49
50
|
scale: number;
|
|
50
51
|
constructor(precision: number, scale: number);
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
declare type DECIMAL = Omit<DECIMAL_INNER, 'dataLength'>;
|
|
55
|
+
|
|
53
56
|
declare class TEXT extends DataType {
|
|
54
57
|
dataType: 'text';
|
|
55
|
-
|
|
56
|
-
constructor(
|
|
58
|
+
dataLength: LENGTH_VARIANTS;
|
|
59
|
+
constructor(dataLength: LENGTH_VARIANTS);
|
|
57
60
|
}
|
|
58
61
|
|
|
59
62
|
declare class BLOB extends DataType {
|
|
60
63
|
dataType: 'blob';
|
|
61
|
-
|
|
62
|
-
constructor(
|
|
64
|
+
dataLength: LENGTH_VARIANTS;
|
|
65
|
+
constructor(dataLength: LENGTH_VARIANTS)
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
declare class JSON extends DataType {
|
|
@@ -72,14 +75,14 @@ declare class JSONB extends JSON {
|
|
|
72
75
|
|
|
73
76
|
declare class BINARY extends DataType {
|
|
74
77
|
dataType: 'binary';
|
|
75
|
-
|
|
76
|
-
constructor(
|
|
78
|
+
dataLength: number;
|
|
79
|
+
constructor(dataLength: number);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
declare class VARBINARY extends DataType {
|
|
80
83
|
dataType: 'varbinary';
|
|
81
|
-
|
|
82
|
-
constructor(
|
|
84
|
+
dataLength: number;
|
|
85
|
+
constructor(dataLength: number);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
declare class DATE extends DataType {
|
package/types/hint.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export class Hint {
|
|
2
|
+
static build(hint: Hint | { index: string } | string): typeof Hint;
|
|
3
|
+
|
|
4
|
+
constructor(text: string);
|
|
5
|
+
|
|
6
|
+
set text(value: string);
|
|
7
|
+
|
|
8
|
+
get text(): string;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {Hint} hint
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
* @memberof Hint
|
|
15
|
+
*/
|
|
16
|
+
isEqual(hint: Hint): boolean;
|
|
17
|
+
|
|
18
|
+
toSqlString(): string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @enum
|
|
23
|
+
*/
|
|
24
|
+
export enum INDEX_HINT_TYPE {
|
|
25
|
+
use = 'use',
|
|
26
|
+
force = 'force',
|
|
27
|
+
ignore = 'ignore'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @enum
|
|
32
|
+
*/
|
|
33
|
+
export enum INDEX_HINT_SCOPE {
|
|
34
|
+
join = 'join',
|
|
35
|
+
orderBy = 'order by',
|
|
36
|
+
groupBy = 'group by',
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class IndexHint {
|
|
40
|
+
/**
|
|
41
|
+
* build index hint
|
|
42
|
+
*
|
|
43
|
+
* @static
|
|
44
|
+
* @param {object | string} obj
|
|
45
|
+
* @param {string} indexHintType
|
|
46
|
+
* @returns {IndexHint}
|
|
47
|
+
* @example
|
|
48
|
+
* build('idx_title')
|
|
49
|
+
* build('idx_title', INDEX_HINT_TYPE.force, INDEX_HINT_SCOPE.groupBy)
|
|
50
|
+
* build({
|
|
51
|
+
* index: 'idx_title',
|
|
52
|
+
* type: INDEX_HINT_TYPE.ignore,
|
|
53
|
+
* scope: INDEX_HINT_SCOPE.groupBy,
|
|
54
|
+
* })
|
|
55
|
+
*/
|
|
56
|
+
static build(hint: string | Array<string> | { index: string, type?: INDEX_HINT_TYPE, scope?: INDEX_HINT_SCOPE }, type?: INDEX_HINT_TYPE, scope?: INDEX_HINT_SCOPE): IndexHint;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates an instance of IndexHint.
|
|
60
|
+
* @param {Array<string> | string} index
|
|
61
|
+
* @param {INDEX_HINT_TYPE} type
|
|
62
|
+
* @param {INDEX_HINT_SCOPE?} scope
|
|
63
|
+
* @memberof IndexHint
|
|
64
|
+
*/
|
|
65
|
+
constructor(index: string, type?: INDEX_HINT_TYPE, scope?: INDEX_HINT_SCOPE);
|
|
66
|
+
|
|
67
|
+
set index(values: string | Array<string>);
|
|
68
|
+
|
|
69
|
+
get index(): Array<string>;
|
|
70
|
+
|
|
71
|
+
set type(value: string);
|
|
72
|
+
|
|
73
|
+
get type(): string;
|
|
74
|
+
|
|
75
|
+
set scope(value: string);
|
|
76
|
+
|
|
77
|
+
get scope(): string;
|
|
78
|
+
|
|
79
|
+
toSqlString(): string;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
*
|
|
83
|
+
* @param {IndexHint} hint
|
|
84
|
+
* @returns {boolean}
|
|
85
|
+
* @memberof IndexHint
|
|
86
|
+
*/
|
|
87
|
+
isEqual(hint: IndexHint): boolean;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @static
|
|
91
|
+
* @param {IndexHint} hints
|
|
92
|
+
* @returns {Array<IndexHint>}
|
|
93
|
+
* @memberof IndexHint
|
|
94
|
+
*/
|
|
95
|
+
static merge(hints: Array<IndexHint>): Array<IndexHint>;
|
|
96
|
+
}
|