think-model-mysql2
Version:
Mysql adapter for ThinkJS 3.x
97 lines (93 loc) • 3.17 kB
JavaScript
const helper = require('think-helper');
const { Schema } = require('think-model-abstract');
const Debounce = require('think-debounce');
const debounce = new Debounce();
const SCHEMAS = {};
/**
* mysql Schema
*/
module.exports = class MysqlSchema extends Schema {
_getItemSchemaValidate(fieldData) {
const validate = {};
switch (fieldData.tinyType) {
case 'tinyint':
validate.int = { min: 0, max: 255 };
break;
case 'smallint':
validate.int = { min: fieldData.unsigned ? 0 : -32768, max: 32767 };
break;
case 'int':
validate.int = { min: fieldData.unsigned ? 0 : -2147483648, max: 2147483647 };
break;
// case 'bigint':
// validate.int = {min: fieldData.unique ? 0 : -9223372036854775808, max: 9223372036854775807};
// break;
case 'date':
validate.date = true;
break;
};
return validate;
}
_parseItemSchema(item) {
item.type = item.type || 'varchar(100)';
const pos = item.type.indexOf('(');
item.tinyType = (pos === -1 ? item.type : item.type.slice(0, pos)).toLowerCase();
if (item.default && !helper.isFunction(item.default) && item.tinyType.indexOf('int') > -1) {
item.default = parseInt(item.default);
}
if (item.type.indexOf('unsigned') > -1) {
item.unsigned = true;
item.type = item.type.replace('unsigned', '').trim();
}
if (!item.validate) {
item.validate = this._getItemSchemaValidate(item);
}
return item;
}
/**
* get table schema
* @param {String} table
*/
getSchema(table = this.table) {
const cacheKey = `${this.config.database}.${table}`;
if (SCHEMAS[cacheKey]) return Promise.resolve(SCHEMAS[cacheKey]);
return debounce.debounce(`getTable${table}Schema`, () => {
const columnSql = `SHOW COLUMNS FROM ${this.parser.parseKey(table)}`;
return this.query.query(columnSql).then(data => {
let ret = {};
data.forEach(item => {
ret[item.Field] = {
name: item.Field,
type: item.Type,
required: item.Null === 'NO',
default: '',
primary: item.Key === 'PRI',
unique: item.Key === 'UNI',
autoIncrement: item.Extra.toLowerCase() === 'auto_increment'
};
});
ret = helper.extend(ret, this.schema);
for (const key in ret) {
ret[key] = this._parseItemSchema(ret[key]);
}
SCHEMAS[cacheKey] = ret;
return ret;
});
});
}
/**
* parse type
* @param {String} tinyType
* @param {Mixed} value
*/
parseType(tinyType, value) {
if (tinyType === 'enum' || tinyType === 'set' || tinyType === 'bigint' || tinyType === 'bigint unsigned') return value;
if (tinyType.indexOf('int') > -1) return parseInt(value, 10) || 0;
if (['double', 'float', 'decimal'].indexOf(tinyType) > -1) return parseFloat(value, 10) || 0;
if (tinyType === 'bool') return value ? 1 : 0;
if (this.config.jsonFormat && tinyType === 'json') {
return helper.isNullOrUndefined(value) ? null : JSON.stringify(value);
}
return value;
}
};