From 40631aa7c4bbfec2a7dfcdf1e4a731934424059b Mon Sep 17 00:00:00 2001 From: Johannes Hoermann <j.hoermann@adito.de> Date: Tue, 8 Oct 2019 09:47:35 +0200 Subject: [PATCH] improve sql builder, add some tests --- .../children/sqltests/onActionProcess.js | 106 +++++++++--------- process/Sql_lib/process.js | 9 +- 2 files changed, 64 insertions(+), 51 deletions(-) diff --git a/entity/Person_entity/entityfields/campaignactiongroup/children/sqltests/onActionProcess.js b/entity/Person_entity/entityfields/campaignactiongroup/children/sqltests/onActionProcess.js index 1e272ce959..1faa5af6eb 100644 --- a/entity/Person_entity/entityfields/campaignactiongroup/children/sqltests/onActionProcess.js +++ b/entity/Person_entity/entityfields/campaignactiongroup/children/sqltests/onActionProcess.js @@ -93,7 +93,7 @@ var validAndUsageTests = new TestSuite([ .from("PERSON") .where("PERSON.FIRSTNAME", "Tim") .and("PERSON.LASTNAME", "Admin"), - "exists ?") + "exists ?") // Note: you can use SqlBuilder.EXISTS() instead of "exists ?" pTester.assert("exists ( select FIRSTNAME from PERSON where PERSON.FIRSTNAME = ? and PERSON.LASTNAME = ? ) ", actual._where._sqlStorage, "prepared sql"); pTester.assert(2, actual._where.preparedValues.length, "number of params"); @@ -582,155 +582,143 @@ var mandatoryErrorTests = new TestSuite([ // and ["and without parameter should error", function(pTester) { - new SqlBuilder().where(); + new SqlBuilder().where().or(); }, SqlBuilder.ERROR_NO_PARAMETER_PROVIDED()], ["and with '' as value should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", ""); + new SqlBuilder().where().or("PERSON.FIRSTNAME", ""); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], ["and with null as value should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", null); + new SqlBuilder().where().or("PERSON.FIRSTNAME", null); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], ["and with a jdito-var containing null should error", function(pTester) { vars.set("$global.TestingVarNull", null); - new SqlBuilder().where("PERSON.FIRSTNAME", "$global.TestingVarNull"); + new SqlBuilder().where().or("PERSON.FIRSTNAME", "$global.TestingVarNull"); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR()], ["and with a jdito-var containing '' should error", function(pTester) { vars.set("$global.TestingVarEmptyString", ""); - new SqlBuilder().where("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); + new SqlBuilder().where().or("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR()], ["and with a jdito-var containing '' should error", function(pTester) { vars.set("$global.TestingVarEmptyString", ""); - new SqlBuilder().where("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); + new SqlBuilder().where().or("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR()], ["and with an empty sql-builder as subquery should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", new SqlBuilder()); + new SqlBuilder().where().or("PERSON.FIRSTNAME", new SqlBuilder()); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], ["and with an empty prepared statement as subquery should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", ["", []]); + new SqlBuilder().where().or("PERSON.FIRSTNAME", ["", []]); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], // or ["or without parameter should error", function(pTester) { - new SqlBuilder().where(); + new SqlBuilder().where().or(); }, SqlBuilder.ERROR_NO_PARAMETER_PROVIDED()], ["or with '' as value should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", ""); + new SqlBuilder().where().or("PERSON.FIRSTNAME", ""); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], ["or with null as value should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", null); + new SqlBuilder().where().or("PERSON.FIRSTNAME", null); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], ["or with a jdito-var containing null should error", function(pTester) { vars.set("$global.TestingVarNull", null); - new SqlBuilder().where("PERSON.FIRSTNAME", "$global.TestingVarNull"); + new SqlBuilder().where().or("PERSON.FIRSTNAME", "$global.TestingVarNull"); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR()], ["or with a jdito-var containing '' should error", function(pTester) { vars.set("$global.TestingVarEmptyString", ""); - new SqlBuilder().where("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); + new SqlBuilder().where().or("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR()], ["or with a jdito-var containing '' should error", function(pTester) { vars.set("$global.TestingVarEmptyString", ""); - new SqlBuilder().where("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); + new SqlBuilder().where().or("PERSON.FIRSTNAME", "$global.TestingVarEmptyString"); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR()], ["or with an empty sql-builder as subquery should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", new SqlBuilder()); + new SqlBuilder().where().or("PERSON.FIRSTNAME", new SqlBuilder()); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], ["or with an empty prepared statement as subquery should error", function(pTester) { - new SqlBuilder().where("PERSON.FIRSTNAME", ["", []]); + new SqlBuilder().where().or("PERSON.FIRSTNAME", ["", []]); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], -]) - +]); var inStatementTests = new TestSuite([ -// and ["simple and in", function(pTester) { var actual = new SqlBuilder() - .where("PERSON.LASTNAME", ["Franz", "Fritz"]); + .where("PERSON.LASTNAME", ["Franz", "Fritz"]) // Note: you can use SqlBuilder.IN() or "# in ?" as 3rd parameter + .or("PERSON.LASTNAME", ["Peter", "Mayer"]); - pTester.assert(" ( PERSON.LASTNAME in (?, ?) ) ", actual._where._sqlStorage, "prepared sql"); - pTester.assert(2, actual._where.preparedValues.length, "number of params"); + pTester.assert(" ( PERSON.LASTNAME in (?, ?) ) or ( PERSON.LASTNAME in (?, ?) ) ", actual._where._sqlStorage, "prepared sql"); + pTester.assert(4, actual._where.preparedValues.length, "number of params"); }], ["simple and not in", function(pTester) { var actual = new SqlBuilder() - .where("PERSON.LASTNAME", ["Franz", "Fritz"], "# not in ?"); + .where("PERSON.LASTNAME", ["Franz", "Fritz"], "# not in ?"); // Note: you can use SqlBuilder.NOT_IN() instead of "# not in ?" pTester.assert(" ( PERSON.LASTNAME not in (?, ?) ) ", actual._where._sqlStorage, "prepared sql"); pTester.assert(2, actual._where.preparedValues.length, "number of params"); }], - ["andIfSet should ignore empty array", function(pTester) + ["in with subquery", function(pTester) { var actual = new SqlBuilder() - .whereIfSet("PERSON.LASTNAME", []); + .where("PERSON.FIRSTNAME", new SqlBuilder() + .select("PERSON.FIRSTNAME") + .from("PERSON") + .where("PERSON.LASTNAME", "Fritz") + , "# in ?"); // Note: you can use SqlBuilder.IN() instead of "# in ?" - pTester.assert("", actual._where._sqlStorage, "prepared sql should be empty"); - pTester.assert(0, actual._where.preparedValues.length, "number of params should be 0"); - }], - - ["and should error on an empty array", function(pTester) - { - new SqlBuilder() - .where("PERSON.LASTNAME", []); - }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()], - -// or - ["simple or in", function(pTester) - { - var actual = new SqlBuilder() - .where("PERSON.LASTNAME", ["Franz", "Fritz"]); - - pTester.assert(" ( PERSON.LASTNAME in (?, ?) ) ", actual._where._sqlStorage, "prepared sql"); - pTester.assert(2, actual._where.preparedValues.length, "number of params"); + pTester.assert("PERSON.FIRSTNAME in ( select PERSON.FIRSTNAME from PERSON where PERSON.LASTNAME = ? ) ", actual._where._sqlStorage, "prepared sql"); + pTester.assert(1, actual._where.preparedValues.length, "number of params"); }], - ["simple or not in", function(pTester) + ["in with prepared statement-array", function(pTester) { var actual = new SqlBuilder() - .where("PERSON.LASTNAME", ["Franz", "Fritz"], "# not in ?"); + .where("PERSON.FIRSTNAME", ["select PERSON.FIRSTNAME from PERSON where PERSON.LASTNAME = ?", [["Fritz", SQLTYPES.VARCHAR]]] + , "# in ?"); // Note: you can use SqlBuilder.IN() instead of "# in ?" - pTester.assert(" ( PERSON.LASTNAME not in (?, ?) ) ", actual._where._sqlStorage, "prepared sql"); - pTester.assert(2, actual._where.preparedValues.length, "number of params"); + pTester.assert("PERSON.FIRSTNAME in ( select PERSON.FIRSTNAME from PERSON where PERSON.LASTNAME = ? ) ", actual._where._sqlStorage, "prepared sql"); + pTester.assert(1, actual._where.preparedValues.length, "number of params"); }], - ["orIfSet should ignore empty array", function(pTester) + ["andIfSet should ignore empty array", function(pTester) { var actual = new SqlBuilder() .whereIfSet("PERSON.LASTNAME", []); @@ -739,13 +727,30 @@ var inStatementTests = new TestSuite([ pTester.assert(0, actual._where.preparedValues.length, "number of params should be 0"); }], - ["or should error on an empty array", function(pTester) + ["and should error on an empty array", function(pTester) { new SqlBuilder() .where("PERSON.LASTNAME", []); }, SqlBuilder.ERROR_VALUE_IS_MANDATORY()] ]); +var testConstantFunctions = new TestSuite([ + ["SqlBuilder.IN()", function(pTester) + { + pTester.assert("# in ?", SqlBuilder.IN()); + }], + + ["SqlBuilder.NOT_IN()", function(pTester) + { + pTester.assert("# not in ?", SqlBuilder.NOT_IN()); + }], + + ["SqlBuilder.EXISTS()", function(pTester) + { + pTester.assert("exists ?", SqlBuilder.EXISTS()); + }] +]); + var tester = new Tester("Test SqlBuilder"); tester.test(validAndUsageTests); tester.test(validOrUsageTests); @@ -754,6 +759,7 @@ tester.test(ifSetTests); tester.test(dbWrapperTests); tester.test(mandatoryErrorTests); tester.test(inStatementTests); +tester.test(testConstantFunctions); logging.log("-------------------------"); tester.printResults(); diff --git a/process/Sql_lib/process.js b/process/Sql_lib/process.js index e24a5f5ea0..54d0a299df 100644 --- a/process/Sql_lib/process.js +++ b/process/Sql_lib/process.js @@ -1190,7 +1190,6 @@ SqlBuilder.prototype._addWhere = function(pFieldOrCond, pValue, pMandatory, pCon if (typeofValue == "string" && pValue[0] == "$") { pValue = this._resolveJditoVariable(pValue) - // TODO: mandatory if (pMandatory && !pValue) throw SqlBuilder.ERROR_VALUE_IS_MANDATORY_JDITO_VAR(); @@ -1202,7 +1201,10 @@ SqlBuilder.prototype._addWhere = function(pFieldOrCond, pValue, pMandatory, pCon // ... everything else -> just pass it if (pValue === false || pValue === 0 || pValue) + { this._whereCondition(this._prepare(field, pValue, pCond, pFieldType), undefined, pAddPreparedConditionCallback); + } + return this; } @@ -1283,6 +1285,11 @@ SqlBuilder.IN = function() return "# in ?"; } +SqlBuilder.EXISTS = function() +{ + return "exists ?"; +} + //TODO: more detailed comments with examples /** -- GitLab