当前位置: 首页 > 工具软件 > CmsWing > 使用案例 >

CmsWing源码分析(六)

邵沛
2023-12-01

2021SC@SDUSC


此次分析文件src/model/csmwing/model.js
与之前分析的model文件不同,该文件虽仍是模型相关的操作,但是模型内的操作,而不是整个模型的创建、删除等操作。

首先获取表结构。

async getSchema() {
    return await this.db().getSchema();
  }

一、del()

此方法用于删除数据。
根据传进来的 id ,查找单条数据的 name 和 extend 字段,赋值给 model 。
判断model是否继承了其他模型,以便对 table_name 进行赋值。table_name 主要用于在删除数据之后进行确认。
实例化模型 attribute ,删除属性数据和模型数据。
实例化模型 mysql ,在里面查找表 table_name,若能查询到,将 table_name 删除。
方法结束,返回布尔值 true,数据删除成功。

async del(id) {
    let table_name;
    const model = await this.field('name,extend').find(id);
    console.log(model);
    if (model.extend == 0) {
      table_name = think.config('model.mysql.prefix') + model.name.toLowerCase();
    } else if (model.extend == 1) {
      table_name = think.config('model.mysql.prefix') + 'document_' + model.name.toLowerCase();
    } else {
      return false;
    }
    console.log(table_name);
    await this.model('attribute').where({model_id: id}).delete();
    await this.delete(id);
    let sql = `SHOW TABLES LIKE '${table_name}'`;
    const istable = await this.model('mysql').query(sql);
    if (!think.isEmpty(istable)) {
      sql = `DROP TABLE ${table_name}`;
      const res = await this.model('mysql').execute(sql);
    }

    return true;
  }

二、checkName()

此方法用于查询是否有相同的表名。
在新建表的时候,该方法具有很重要的意义。重复的表名可能会在项目运行时造成极大的混乱(更大可能是项目根本运行不起来orz)。
通过对 map 的赋值可以看到,我们要查找的是数据库中是否存在名字相同但 id 不同即主键不同的表。若存在,我们不能再新建一个名字为 name 的表,否则在后续的数据库操作中,开发人员将很难区分这些名字相同但内容不同的表,极易造成无数个难以找到的 bug,这简直是地狱。
若存在,方法返回布尔值 false ;若不存在,方法返回布尔值 true 。

async checkName(name, id) {
    const map = {'name': name};
    if (!think.isEmpty(id)) {
      map.id = ['!=', id];
    }
    const res = await this.where(map).find();
    return think.isEmpty(res);
  }

三、get_table_name()

此方法用于获取表名。
方法参数 model_id 为模型id;参数 extend 默认为false,表示是否继承。方法返回表名。
首先对模型存在进行判断:若模型不存在,返回 false,方法执行失败。
查询 id=model_id 的单条数据。判断数据是否继承了其他模型,以便于确定表名。
若 extend 为 true,返回表名时添加继承信息;若 extend 为 false,直接返回表名。

async get_table_name(model_id, extend = false) {
    model_id = model_id || null;
    if (think.isEmpty(model_id)) {
      return false;
    }
    let name;
    const info = await this.where({id: model_id}).find();
    if (info.extend != 0) {
      name = await this.where({id: info.extend}).find();
      name = name.name + '_';
    }
    name += info.name;
    if (extend) {
      return {
        table: name.replace(/undefined/, ''),
        extend: info.extend
      };
    } else {
      return name.replace(/undefined/, '');
    }
  }

四、get_document_model()

该方法用于获取文档模型信息并缓存。
方法参数 id 为模型id,参数 field 为模型字段,方法返回一个数组。
首先读取缓存信息,然后根据参数 id 和 field 进行条件判断,返回所需要的信息。

async get_document_model(id, field) {
    id = id || null, field = field || null;
    const list = await think.cache('get_document_model', () => {
      return this._get_document_model();
    }, {timeout: 365 * 24 * 3600});
    if (think.isEmpty(id)) {
      return list;
    } else if (think.isEmpty(field)) {
      return list[id];
    } else {
      try {
        return list[id][field];
      } catch (err) {
        return false;
      }
    }
  }
 类似资料: