瀏覽代碼

sqlbuilder新增对update的支持

olym 7 年之前
父節點
當前提交
d5a1a83fca
共有 2 個文件被更改,包括 169 次插入36 次删除
  1. 149 36
      app/lib/sql_builder.js
  2. 20 0
      test/app/lib/sql_builder.test.js

+ 149 - 36
app/lib/sql_builder.js

@@ -33,6 +33,20 @@ class SqlBuilder {
     }
 
     /**
+     * 更新字段设置
+     *
+     * @param {String} field - set的字段
+     * @param {Object} data - set中的字段
+     * @return {void}
+     */
+    setUpdateData(field, data) {
+        if (Object.keys(data).length <= 0) {
+            return;
+        }
+        this.setData.push({ field, data});
+    }
+
+    /**
      * 重置条件
      *
      * @return {void}
@@ -44,57 +58,156 @@ class SqlBuilder {
         this.limit = -1;
         this.offset = -1;
         this.orderBy = [];
-        this.groupBy = [];
+        this.setData = [];
+
+        this.sql = '';
+        this.sqlParam = [];
+        this.type = 'select';
     }
 
     /**
-     * 构建sql
+     * 类型设置
      *
      * @param {String} tableName - 表名
-     * @return {Array} - 返回数组,第一个元素为sql语句,第二个元素为sql中问号部分的param
+     * @return {void}
      */
-    build(tableName) {
-        let sql = this.columns.length === 0 ? 'SELECT * FROM ??' : 'SELECT ?? FROM ??';
-        const sqlParam = this.columns.length === 0 ? [tableName] : [this.columns, tableName];
-
-        if (this.andWhere.length > 0) {
-            const whereArr = [];
-            for (const where of this.andWhere) {
-                whereArr.push(' ?? ' + where.data.operate + ' ' + where.data.value);
-                sqlParam.push(where.field);
-            }
-            const whereString = whereArr.join(' AND ');
-            sql += ' WHERE ' + whereString;
+    _typeBuild(tableName) {
+        switch (this.type) {
+            case 'select':
+                this.sql = this.columns.length === 0 ? 'SELECT * FROM ??' : 'SELECT ?? FROM ??';
+                this.sqlParam = this.columns.length === 0 ? [tableName] : [this.columns, tableName];
+                break;
+            case 'update':
+                this.sql = 'UPDATE ?? SET ';
+                this.sqlParam = [tableName];
+                break;
+            default:
+                break;
         }
+    }
 
-        if (this.orWhere.length > 0) {
-            const whereArr = [];
-            for (const where in this.orWhere) {
-                whereArr.push(' ?? ' + where.data.operate + ' ' + where.data.value);
-                sqlParam.push(where.field);
+    /**
+     * 设置update数据
+     *
+     * @return {void}
+     */
+    _setDataBuild() {
+        if (this.setData.length <= 0) {
+            return;
+        }
+        const setDataArr = [];
+        for (const set of this.setData) {
+            const tmp = set.data.selfOperate !== undefined ?
+                ' ?? = ?? ' + set.data.selfOperate + ' ' + set.data.value : ' ?? = ' + set.data.value;
+            setDataArr.push(tmp);
+            // 如果是自身操作则压多一次字段进数组
+            if (set.data.selfOperate !== undefined) {
+                this.sqlParam.push(set.field);
             }
-            const whereString = whereArr.join(' OR ');
-            // 如果前面已经有设置过WHERE则不需要再重复添加
-            sql += sql.indexOf('WHERE') > 0 ? whereString : ' WHERE ' + whereString;
+            this.sqlParam.push(set.field);
         }
 
-        if (typeof this.limit === 'number' && this.limit > 0) {
-            this.offset = parseInt(this.offset);
-            this.offset = isNaN(this.offset) || this.offset < 0 ? 0 : this.offset;
-            const limitString = this.offset >= 0 ? this.offset + ',' + this.limit : this.limit;
-            sql += ' LIMIT ' + limitString;
+        const setString = setDataArr.join(',');
+        this.sql += setString;
+    }
+
+    /**
+     * andWhere设置
+     *
+     * @return {void}
+     */
+    _andWhereBuild() {
+        if (this.andWhere.length <= 0) {
+            return;
         }
 
-        if (this.orderBy.length > 0) {
-            const orderArr = [];
-            for (const index in this.orderBy) {
-                orderArr.push(' ?? ' + this.orderBy[index][1]);
-                sqlParam.push(this.orderBy[index][0]);
-            }
-            const orderByString = orderArr.join(',');
-            sql += ' ORDER BY ' + orderByString;
+        const whereArr = [];
+        for (const where of this.andWhere) {
+            whereArr.push(' ?? ' + where.data.operate + ' ' + where.data.value);
+            this.sqlParam.push(where.field);
         }
+        const whereString = whereArr.join(' AND ');
+        this.sql += this.sql.indexOf('WHERE') > 0 ? whereString : ' WHERE ' + whereString;
+    }
+
+    /**
+     * orWhere设置
+     *
+     * @return {void}
+     */
+    _orWhereBuild() {
+        if (this.orWhere.length <= 0) {
+            return;
+        }
+
+        const whereArr = [];
+        for (const where in this.orWhere) {
+            whereArr.push(' ?? ' + where.data.operate + ' ' + where.data.value);
+            this.sqlParam.push(where.field);
+        }
+        const whereString = whereArr.join(' OR ');
+        // 如果前面已经有设置过WHERE则不需要再重复添加
+        this.sql += this.sql.indexOf('WHERE') > 0 ? whereString : ' WHERE ' + whereString;
+    }
+
+    /**
+     * limit设置
+     *
+     * @return {void}
+     */
+    _limitBuild() {
+        if (typeof this.limit !== 'number' || this.limit <= 0) {
+            return;
+        }
+
+        this.offset = parseInt(this.offset);
+        this.offset = isNaN(this.offset) || this.offset < 0 ? 0 : this.offset;
+        const limitString = this.offset >= 0 ? this.offset + ',' + this.limit : this.limit;
+        this.sql += ' LIMIT ' + limitString;
+    }
+
+    /**
+     * orderby 设置
+     *
+     * @return {void}
+     */
+    _orderByBuild() {
+        if (this.orderBy.length <= 0) {
+            return;
+        }
+
+        const orderArr = [];
+        for (const index in this.orderBy) {
+            orderArr.push(' ?? ' + this.orderBy[index][1]);
+            this.sqlParam.push(this.orderBy[index][0]);
+        }
+        const orderByString = orderArr.join(',');
+        this.sql += ' ORDER BY ' + orderByString;
+    }
+
+    /**
+     * 构建sql
+     *
+     * @param {String} tableName - 表名
+     * @param {String} type - 类型
+     * @return {Array} - 返回数组,第一个元素为sql语句,第二个元素为sql中问号部分的param
+     */
+    build(tableName, type = 'select') {
+        this.type = type;
+        this._typeBuild(tableName);
+        if (this.sql === '') {
+            throw '类型错误';
+        }
+
+        this._setDataBuild();
+        this._andWhereBuild();
+        this._orWhereBuild();
+
+        this._limitBuild();
+        this._orderByBuild();
 
+        const sql = this.sql;
+        const sqlParam = this.sqlParam;
         // 重置数据
         this.resetCondition();
 

+ 20 - 0
test/app/lib/sql_builder.test.js

@@ -39,4 +39,24 @@ describe('test/app/lib/sql_builder.test.js', () => {
         const matchSql = 'SELECT `id` FROM `table` LIMIT 1,10 ORDER BY  `id` DESC';
         assert(finalSql === matchSql);
     });
+
+    it('update sql', function* () {
+        const sqlBuilder = new SqlBuilder();
+        sqlBuilder.setUpdateData('create_time', {
+            value: 1,
+            selfOperate: '+',
+        });
+        sqlBuilder.setUpdateData('office', {
+            value: 2,
+        });
+        sqlBuilder.setAndWhere('group_id', {
+            value: 1,
+            operate: '>=',
+        });
+        const [sql, sqlParam] = sqlBuilder.build('table', 'update');
+        const finalSql = app.mysql.format(sql, sqlParam);
+
+        const matchSql = 'UPDATE `table` SET  `create_time` = `create_time` + 1, `office` = 2 WHERE  `group_id` >= 1';
+        assert(finalSql === matchSql);
+    });
 });