leoric 2.3.0 → 2.4.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 +40 -0
- package/Readme.md +29 -3
- package/index.js +7 -0
- package/package.json +3 -1
- package/src/adapters/sequelize.js +11 -4
- package/src/bone.js +28 -13
- package/src/data_types.js +52 -12
- package/src/drivers/abstract/attribute.js +4 -0
- package/src/drivers/abstract/index.js +192 -1
- package/src/drivers/abstract/spellbook.js +403 -412
- package/src/drivers/index.js +15 -4
- package/src/drivers/mysql/attribute.js +11 -2
- package/src/drivers/mysql/index.js +101 -10
- package/src/drivers/mysql/spellbook.js +13 -11
- 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/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 +8 -6
- package/src/spell.js +2 -4
- package/types/data_types.d.ts +9 -1
- package/types/hint.d.ts +96 -0
- package/types/index.d.ts +246 -20
- package/src/drivers/abstract/schema.js +0 -140
- package/src/drivers/mysql/schema.js +0 -98
- package/src/drivers/postgres/schema.js +0 -119
- package/src/drivers/sqlite/schema.js +0 -203
|
@@ -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
|
};
|
|
@@ -195,7 +197,7 @@ class Realm {
|
|
|
195
197
|
throw new Error(`unable to replace: ${key}`);
|
|
196
198
|
}
|
|
197
199
|
values.push(replacements[key]);
|
|
198
|
-
return '?';
|
|
200
|
+
return ' ?';
|
|
199
201
|
});
|
|
200
202
|
|
|
201
203
|
const { rows, ...restRes } = await this.driver.query(query, values, opts);
|
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/types/data_types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export default class DataType {
|
|
|
11
11
|
static STRING: typeof STRING & INVOKABLE<STRING>;
|
|
12
12
|
static INTEGER: typeof INTEGER & INVOKABLE<INTEGER>;
|
|
13
13
|
static BIGINT: typeof BIGINT & INVOKABLE<BIGINT>;
|
|
14
|
+
static DECIMAL: typeof DECIMAL & INVOKABLE<DECIMAL>;
|
|
14
15
|
static TEXT: typeof TEXT & INVOKABLE<TEXT>;
|
|
15
16
|
static BLOB: typeof BLOB & INVOKABLE<BLOB>;
|
|
16
17
|
static JSON: typeof JSON & INVOKABLE<JSON>;
|
|
@@ -31,7 +32,7 @@ declare class STRING extends DataType {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
declare class INTEGER extends DataType {
|
|
34
|
-
dataType: 'integer' | 'bigint';
|
|
35
|
+
dataType: 'integer' | 'bigint' | 'decimal';
|
|
35
36
|
length: number;
|
|
36
37
|
constructor(length: number);
|
|
37
38
|
get UNSIGNED(): this;
|
|
@@ -42,6 +43,13 @@ declare class BIGINT extends INTEGER {
|
|
|
42
43
|
dataType: 'bigint';
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
declare class DECIMAL extends INTEGER {
|
|
47
|
+
dataType: 'decimal';
|
|
48
|
+
precision: number;
|
|
49
|
+
scale: number;
|
|
50
|
+
constructor(precision: number, scale: number);
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
declare class TEXT extends DataType {
|
|
46
54
|
dataType: 'text';
|
|
47
55
|
length: LENGTH_VARIANTS;
|
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
|
+
}
|