UNPKG

ren-framework

Version:
273 lines (255 loc) 5.82 kB
'use strict' const Model = require('../base/Model'); const Command = require('./Command'); const Components = require('../base/Components'); const InvalidMethodError = require('../errors/InvalidMethodError'); const objectHelper = require('../helpers/object'); const stringHelper = require('../helpers/string'); const ActiveQuery = require('./ActiveQuery'); /** * ActiveRecord * 动态记录 * ------------ * @author Verdient。 */ class ActiveRecord extends Model { /** * initProperty() * 初始化属性 * -------------- * @inheritdoc * ----------- * @return {Self} * @author Verdient。 */ initProperty(){ super.initProperty(); /** * @property _isNewRecord * 是否是新纪录 * ---------------------- * @author Verdient。 */ this._isNewRecord = true; return this; } /** * @getter isNewRecord() * 获取是否是新纪录 * --------------------- * @return {Boolean} * @author Verdient。 */ get isNewRecord(){ return this._isNewRecord; } /** * tableName() * 表名 * ----------- * @return {String} * @author Verdient。 */ static tableName(){ var className = this.className(); var name = className.substr(className.lastIndexOf('.') + 1); return stringHelper.snakeCase(name); } /** * tableName() * 表名 * ----------- * @return {String} * @author Verdient。 */ tableName(){ return this.constructor.tableName(); } /** * getDb() * 获取数据库对象 * ------------ * @return * @author Verdient。 */ static getDb(){ let db = Components.getComponent('db'); if(db){ return db.connection; } return null; } /** * getDb() * 获取数据库对象 * ------------ * @return * @author Verdient。 */ getDb(){ return this.constructor.getDb(); } /** * find() * 查找 * ------ * @author Verdient。 */ static find(){ return new ActiveQuery({class: this}); } /** * find() * 查找 * ------ * @author Verdient。 */ find(){ return this.constructor.find(); } /** * @getter primaryKey() * 获取主键 * -------------------- * @return {String} * @author Verdient。 */ get primaryKey(){ throw new InvalidMethodError('primaryKey method must be overridden by subclasses'); } /** * populate(Object data) * 数据落入模型 * --------------------- * @param {Object} data 数据 * ------------------------- * @return {Self} * @author Verdient。 */ populate(data){ super.populate(data); this._isNewRecord = false; return this; } /** * save(Boolean runValidation) * 保存 * --------------------------- * @param {Boolean} runValidation 是否运行校验 * ----------------------------------------- * @return {Promise} * @author Verdient。 */ save(runValidation){ if(runValidation !== false){ runValidation = true; } return this.isNewRecord ? this.insert(runValidation) : this.update(runValidation); } /** * insert(Boolean runValidation) * 插入记录 * ----------------------------- * @param {Boolean} runValidation 是否运行校验 * ----------------------------------------- * @return {Promise} * @author Verdient。 */ insert(runValidation){ if(runValidation !== false){ runValidation = true; } return new Promise((resolve, revoke) => { if(runValidation){ this.validate().then(() => { this._insertInternal().then(resolve).catch(revoke); }).catch(revoke); }else{ this._insertInternal().then(resolve).catch(revoke); } }); } /** * _insertInternal() * 插入 * ----------------- * @return {Promise} * @author Verdient。 */ _insertInternal(){ return new Promise((resolve, revoke) => { this._attributes['created_at'] = this._attributes['updated_at'] = Date.now(); let attribures = Object.keys(this._attributes); let values = []; attribures.forEach(attribure => { values.push(this._attributes[attribure]); }); let sql = Command.buildInsert(this.tableName(), attribures, values); this.trace(sql, 'INSERT SQL'); let db = this.getDb(); setTimeout(() => { db.query(sql).then(result => { if(Array.isArray(this.primaryKey) && this.primaryKey[0] && Array.isArray(result) && result[0]){ this._attributes[this.primaryKey[0]] = result[0].insertId; } resolve(result); }).catch(revoke); }); }); } /** * update(Boolean runValidation) * 更新记录 * ----------------------------- * @param {Boolean} runValidation 是否运行校验 * ----------------------------------------- * @return {Promise} * @author Verdient。 */ update(runValidation){ if(runValidation !== false){ runValidation = true; } return new Promise((resolve, revoke) => { if(runValidation){ this.validate().then(() => { this._updateInternal().then(resolve).catch(revoke); }).catch(revoke); }else{ this._updateInternal().then(resolve).catch(revoke); } }); } /** * _updateInternal() * 更新 * ----------------- * @return {Promise} * @author Verdient。 */ _updateInternal(){ return new Promise((resolve, revoke) => { let dirtyValues = this.dirtyValues; if(objectHelper.isEmptyObject(dirtyValues)){ resolve(0); }else{ dirtyValues['updated_at'] = Date.now(); let where = {}; this.primaryKey.forEach(attribure => { where[attribure] = this._oldAttributes[attribure]; }); let sql = Command.buildUpdate(this.tableName(), this.dirtyValues, ActiveQuery.formatWhere(where)); this.trace(sql, 'UPDATE SQL'); let db = this.getDb(); setTimeout(() => { db.query(sql).then(result => { this._oldAttributes = JSON.parse(JSON.stringify(this._attributes)); resolve(result); }).catch(revoke); }); } }); } } module.exports = ActiveRecord;