From d8369eadd635bf28515bbf12ccd5570444fa532e Mon Sep 17 00:00:00 2001 From: xicilion Date: Sat, 26 Oct 2019 17:40:45 +0800 Subject: [PATCH] db, refactor: refactor query syntax. --- fibjs/src/db/db.cpp | 41 +++++++++---------- test/db_test.js | 95 +++++++++++++++++++++++++-------------------- 2 files changed, 72 insertions(+), 64 deletions(-) diff --git a/fibjs/src/db/db.cpp b/fibjs/src/db/db.cpp index 36b0af48ea..c2fb25d4d0 100644 --- a/fibjs/src/db/db.cpp +++ b/fibjs/src/db/db.cpp @@ -299,11 +299,15 @@ result_t _format_where(v8::Local val, bool mysql, bool mssql, exlib:: exlib::string op("="); exlib::string key; + if (s.length() == 0) + return CHECK_ERROR(Runtime::setError("db: Field name cannot be empty.")); + if (v->IsFunction()) return CHECK_ERROR(CALL_E_INVALIDARG); - if (len == 1 && bAnd && s.length() == 2 && !qstrcmp(*s, "or", 2)) { - bAnd = false; + key = _escape_field(*s, s.length()); + while (len == 1 && (!qstrcmp(key.c_str(), "$or", 3) || !qstrcmp(key.c_str(), "$and", 4))) { + bAnd = key[1] == 'a'; if (v->IsArray()) return _format_where(v8::Local::Cast(v), bAnd, mysql, mssql, retVal, retAnd); @@ -323,10 +327,6 @@ result_t _format_where(v8::Local val, bool mysql, bool mssql, exlib:: key = _escape_field(*s1, s1.length()); } else return CHECK_ERROR(Runtime::setError("db: The argument of the [or] operation must be an object or an array.")); - } else { - if (s.length() == 0) - return CHECK_ERROR(Runtime::setError("db: Field name cannot be empty.")); - key = _escape_field(*s, s.length()); } if (v->IsObject()) { @@ -343,32 +343,32 @@ result_t _format_where(v8::Local val, bool mysql, bool mssql, exlib:: if (!*_ops) return CHECK_ERROR(Runtime::setError("db: The condition of the field " + key + " is illegal.")); - if (!qstrcmp(*_ops, "eq")) + if (!qstrcmp(*_ops, "$eq")) op = "="; - else if (!qstrcmp(*_ops, "ne")) + else if (!qstrcmp(*_ops, "$ne")) op = "<>"; - else if (!qstrcmp(*_ops, "gt")) + else if (!qstrcmp(*_ops, "$gt")) op = ">"; - else if (!qstrcmp(*_ops, "gte")) + else if (!qstrcmp(*_ops, "$gte")) op = ">="; - else if (!qstrcmp(*_ops, "lt")) + else if (!qstrcmp(*_ops, "$lt")) op = "<"; - else if (!qstrcmp(*_ops, "lte")) + else if (!qstrcmp(*_ops, "$lte")) op = "<="; - else if (!qstrcmp(*_ops, "like")) + else if (!qstrcmp(*_ops, "$like")) op = " LIKE "; - else if (!qstrcmp(*_ops, "not_like")) + else if (!qstrcmp(*_ops, "$nlike")) op = " NOT LIKE "; - else if (!qstrcmp(*_ops, "in")) { + else if (!qstrcmp(*_ops, "$in")) { bIn = true; op = " IN "; - } else if (!qstrcmp(*_ops, "not_in")) { + } else if (!qstrcmp(*_ops, "$nin")) { bIn = true; op = " NOT IN "; - } else if (!qstrcmp(*_ops, "between")) { + } else if (!qstrcmp(*_ops, "$between")) { bBetween = true; op = " BETWEEN "; - } else if (!qstrcmp(*_ops, "not_between")) { + } else if (!qstrcmp(*_ops, "$nbetween")) { bBetween = true; op = " NOT BETWEEN "; } @@ -412,9 +412,6 @@ result_t _format_where(v8::Local val, bool mysql, bool mssql, exlib:: result_t _format(exlib::string table, v8::Local opts, bool mysql, bool mssql, exlib::string& retVal) { - if (table.find(']') != exlib::string::npos) - return CALL_E_INVALIDARG; - result_t hr; exlib::string str("SELECT "); Isolate* isolate = Isolate::current(); @@ -446,7 +443,7 @@ result_t _format(exlib::string table, v8::Local opts, bool mysql, bo } else str.append("*"); - str.append(" FROM [" + table + "]"); + str.append(" FROM `" + _escape_field(table.c_str(), table.length()) + "`"); hr = GetConfigValue(isolate->m_isolate, opts, "where", v); if (hr != CALL_E_PARAMNOTOPTIONAL) { diff --git a/test/db_test.js b/test/db_test.js index 2c5722932d..2fec7a05c8 100644 --- a/test/db_test.js +++ b/test/db_test.js @@ -29,13 +29,13 @@ describe("db", () => { describe("format.find", () => { it('basic', () => { - assert.equal(db.format("test", {}), "SELECT * FROM [test]"); + assert.equal(db.format("test", {}), "SELECT * FROM `test`"); }); it('keys', () => { assert.equal(db.format("test", { keys: ["a", "b", "c"] - }), "SELECT `a`,`b`,`c` FROM [test]"); + }), "SELECT `a`,`b`,`c` FROM `test`"); }); it('where', () => { @@ -43,25 +43,25 @@ describe("db", () => { where: { a: 100 } - }), "SELECT * FROM [test] WHERE `a`=100"); + }), "SELECT * FROM `test` WHERE `a`=100"); assert.equal(db.format("test", { where: { "aaa`ddd": 100 } - }), "SELECT * FROM [test] WHERE `aaa\\`ddd`=100"); + }), "SELECT * FROM `test` WHERE `aaa\\`ddd`=100"); }); it('operator', () => { var ops = { - eq: "=", - ne: "<>", - gt: ">", - gte: ">=", - lt: "<", - lte: "<=", - like: " LIKE ", - not_like: " NOT LIKE " + "$eq": "=", + "$ne": "<>", + "$gt": ">", + "$gte": ">=", + "$lt": "<", + "$lte": "<=", + "$like": " LIKE ", + "$nlike": " NOT LIKE " } for (var o in ops) { @@ -71,40 +71,40 @@ describe("db", () => { assert.equal(db.format("test", { where: opts - }), "SELECT * FROM [test] WHERE `" + o + "`" + ops[o] + "100"); + }), "SELECT * FROM `test` WHERE `" + o + "`" + ops[o] + "100"); } assert.equal(db.format("test", { where: { a: { - in: [100, 200, 300] + "$in": [100, 200, 300] } } - }), "SELECT * FROM [test] WHERE `a` IN (100,200,300)"); + }), "SELECT * FROM `test` WHERE `a` IN (100,200,300)"); assert.equal(db.format("test", { where: { a: { - not_in: [100, 200, 300] + "$nin": [100, 200, 300] } } - }), "SELECT * FROM [test] WHERE `a` NOT IN (100,200,300)"); + }), "SELECT * FROM `test` WHERE `a` NOT IN (100,200,300)"); assert.equal(db.format("test", { where: { a: { - between: [100, 200] + "$between": [100, 200] } } - }), "SELECT * FROM [test] WHERE `a` BETWEEN 100 AND 200"); + }), "SELECT * FROM `test` WHERE `a` BETWEEN 100 AND 200"); assert.equal(db.format("test", { where: { a: { - not_between: [100, 200] + "$nbetween": [100, 200] } } - }), "SELECT * FROM [test] WHERE `a` NOT BETWEEN 100 AND 200"); + }), "SELECT * FROM `test` WHERE `a` NOT BETWEEN 100 AND 200"); }); it('where and', () => { @@ -113,22 +113,22 @@ describe("db", () => { a: 100, b: 200 } - }), "SELECT * FROM [test] WHERE `a`=100 AND `b`=200"); + }), "SELECT * FROM `test` WHERE `a`=100 AND `b`=200"); }); it('where or', () => { assert.equal(db.format("test", { where: { - or: { + "$or": { a: 100, b: 200 } } - }), "SELECT * FROM [test] WHERE `a`=100 OR `b`=200"); + }), "SELECT * FROM `test` WHERE `a`=100 OR `b`=200"); assert.equal(db.format("test", { where: { - or: [{ + "$or": [{ a: 100 }, { @@ -136,13 +136,13 @@ describe("db", () => { } ] } - }), "SELECT * FROM [test] WHERE `a`=100 OR `b`=200"); + }), "SELECT * FROM `test` WHERE `a`=100 OR `b`=200"); }); it('where or/and', () => { assert.equal(db.format("test", { where: { - or: [{ + "$or": [{ a: 100, c: 300 }, @@ -152,12 +152,12 @@ describe("db", () => { } ] } - }), "SELECT * FROM [test] WHERE (`a`=100 AND `c`=300) OR (`b`=200 AND `d`=400)"); + }), "SELECT * FROM `test` WHERE (`a`=100 AND `c`=300) OR (`b`=200 AND `d`=400)"); assert.equal(db.format("test", { where: { - or: [{ - or: { + "$or": [{ + "$or": { a: 100, c: 300 } @@ -168,18 +168,29 @@ describe("db", () => { } ] } - }), "SELECT * FROM [test] WHERE `a`=100 OR `c`=300 OR (`b`=200 AND `d`=400)"); + }), "SELECT * FROM `test` WHERE `a`=100 OR `c`=300 OR (`b`=200 AND `d`=400)"); assert.equal(db.format("test", { where: { - or: [{ - or: { + "$or": { + "$or": { a: 100, c: 300 } - }] + } + } + }), "SELECT * FROM `test` WHERE `a`=100 OR `c`=300"); + + assert.equal(db.format("test", { + where: { + "$and": { + "$and": { + a: 100, + c: 300 + } + } } - }), "SELECT * FROM [test] WHERE `a`=100 OR `c`=300"); + }), "SELECT * FROM `test` WHERE `a`=100 AND `c`=300"); assert.equal(db.format("test", { where: [{ @@ -187,13 +198,13 @@ describe("db", () => { c: 300 }, { - or: { + "$or": { b: 200, d: 400 } } ] - }), "SELECT * FROM [test] WHERE `a`=100 AND `c`=300 AND (`b`=200 OR `d`=400)"); + }), "SELECT * FROM `test` WHERE `a`=100 AND `c`=300 AND (`b`=200 OR `d`=400)"); assert.equal(db.format("test", { where: [{ @@ -205,7 +216,7 @@ describe("db", () => { d: 400 } ] - }), "SELECT * FROM [test] WHERE `a`=100 AND `c`=300 AND `b`=200 AND `d`=400"); + }), "SELECT * FROM `test` WHERE `a`=100 AND `c`=300 AND `b`=200 AND `d`=400"); }); it('skip', () => { @@ -214,7 +225,7 @@ describe("db", () => { a: 200 }, skip: 100 - }), "SELECT * FROM [test] WHERE `a`=200 SKIP 100"); + }), "SELECT * FROM `test` WHERE `a`=200 SKIP 100"); }); it('limit', () => { @@ -223,7 +234,7 @@ describe("db", () => { a: 200 }, limit: 100 - }), "SELECT * FROM [test] WHERE `a`=200 LIMIT 100"); + }), "SELECT * FROM `test` WHERE `a`=200 LIMIT 100"); }); it('skip/limit', () => { @@ -233,7 +244,7 @@ describe("db", () => { }, skip: 100, limit: 100 - }), "SELECT * FROM [test] WHERE `a`=200 SKIP 100 LIMIT 100"); + }), "SELECT * FROM `test` WHERE `a`=200 SKIP 100 LIMIT 100"); }); it('order', () => { @@ -243,7 +254,7 @@ describe("db", () => { }, limit: 100, order: ['a', 'b', '-c'] - }), "SELECT * FROM [test] WHERE `a`=200 LIMIT 100 ORDER BY `a`,`b`,`c` DESC"); + }), "SELECT * FROM `test` WHERE `a`=200 LIMIT 100 ORDER BY `a`,`b`,`c` DESC"); }); });