Kouhei Sutou
null+****@clear*****
Tue Aug 14 17:16:46 JST 2012
Kouhei Sutou 2012-08-14 17:16:46 +0900 (Tue, 14 Aug 2012) New Revision: c505916ea52126521541588ab0c21087712e3969 https://github.com/groonga/gcs/commit/c505916ea52126521541588ab0c21087712e3969 Log: bq: support multi default fields Modified files: lib/bq-translator.js test/bq-translator.test.js Modified: lib/bq-translator.js (+27 -9) =================================================================== --- lib/bq-translator.js 2012-08-14 16:52:07 +0900 (858de3b) +++ lib/bq-translator.js 2012-08-14 17:16:46 +0900 (98b0bd5) @@ -17,7 +17,7 @@ function BooleanQueryTranslator(query) { this.query = query; this.offset = 0; - this.defaultField = null; + this.defaultFields = null; } BooleanQueryTranslator.prototype = { @@ -184,7 +184,7 @@ BooleanQueryTranslator.prototype = { } var startOffset = this.offset; - var field; + var field = null; if (/^[a-z0-9]$/.test(this.query[this.offset])) { field = ""; for (; this.offset < this.query.length; this.offset++) { @@ -198,8 +198,6 @@ BooleanQueryTranslator.prototype = { this.throwTranslateError("field value separator is missing"); } this.offset++; - } else { - field = this.defaultField; } if (this.query[this.offset] == "'") { @@ -269,7 +267,7 @@ BooleanQueryTranslator.prototype = { operator = "@^"; value = value.substring(0, value.length - 1); } - return field + " " + operator + " " + "\"" + value + "\""; + return this.constructBinaryOperation(field, operator, "\"" + value + "\""); }, translateExpressionValueStringPhrase: function(field) { if (this.query[this.offset] != "\"") { @@ -289,7 +287,7 @@ BooleanQueryTranslator.prototype = { value += character; } else if (character == "\"") { this.offset++; - return field + " @ " + "\"" + value + "\""; + return this.constructBinaryOperation(field, "@", "\"" + value + "\""); } else { value += character; } @@ -326,10 +324,10 @@ BooleanQueryTranslator.prototype = { this.throwTranslateError("both min and max are missing"); } if (min.length > 0) { - expressions.push(field + " >= " + min); + expressions.push(this.constructBinaryOperation(field, ">=", min)); } if (max.length > 0) { - expressions.push(field + " <= " + max); + expressions.push(this.constructBinaryOperation(field, "<=", max)); } if (expressions.length > 1) { return "(" + expressions.join(" && ") + ")"; @@ -337,7 +335,27 @@ BooleanQueryTranslator.prototype = { return expressions[0]; } } else { - return field + " == " + min; + return this.constructBinaryOperation(field, "==", min); + } + }, + constructBinaryOperation: function(field, operator, value) { + if (field) { + return field + " " + operator + " " + value; + } else { + if (!this.defaultFields) { + this.throwTranslateError("default fields are missing"); + } + if (this.defaultFields.length == 0) { + this.throwTranslateError("no default field"); + } + var expressions = this.defaultFields.map(function (field) { + return this.constructBinaryOperation(field, operator, value); + }, this); + if (expressions.length > 1) { + return "(" + expressions.join(" || ") + ")"; + } else { + return expressions[0]; + } } } }; Modified: test/bq-translator.test.js (+48 -6) =================================================================== --- test/bq-translator.test.js 2012-08-14 16:52:07 +0900 (2391453) +++ test/bq-translator.test.js 2012-08-14 17:16:46 +0900 (a1a8c94) @@ -9,7 +9,7 @@ function testQuery(label, query, expected) { test('query: ' + label + ': ' + '<' + query + '> -> <' + expected + '>', function() { var translator = new BooleanQueryTranslator(query); - translator.defaultField = "field"; + translator.defaultFields = ["field"]; assert.equal(translator.translate(), expected); }); @@ -18,7 +18,7 @@ function testQuery(label, query, expected) { function testQueryError(label, query, context, detail) { test('error: query: ' + label + ': ' + '<' + query + '>', function() { var translator = new BooleanQueryTranslator(query); - translator.defaultField = "field"; + translator.defaultFields = ["field"]; var actualError; assert.throw(function() { try { @@ -36,7 +36,7 @@ function testGroup(label, group, expectedOffset, expectedScriptGrnExpr) { test('gorup: ' + label + ': ' + '<' + group + '> -> <' + expectedScriptGrnExpr + '>', function() { var translator = new BooleanQueryTranslator(group); - translator.defaultField = "field"; + translator.defaultFields = ["field"]; var actualScriptGrnExpr = translator.translateGroup(); assert.deepEqual({ scriptGrnExpr: actualScriptGrnExpr, @@ -52,7 +52,7 @@ function testGroup(label, group, expectedOffset, expectedScriptGrnExpr) { function testGroupError(label, group, context, detail) { test('error: group: ' + label + ': ' + '<' + group + '>', function() { var translator = new BooleanQueryTranslator(group); - translator.defaultField = "field"; + translator.defaultFields = ["field"]; var actualError; assert.throw(function() { try { @@ -71,7 +71,7 @@ function testExpression(label, expression, test('expression: ' + label + ': ' + '<' + expression + '> -> <' + expectedScriptGrnExpr + '>', function() { var translator = new BooleanQueryTranslator(expression); - translator.defaultField = "field"; + translator.defaultFields = ["field"]; var actualScriptGrnExpr = translator.translateExpression(); assert.deepEqual({ @@ -89,7 +89,7 @@ function testExpressionError(label, expression, context, detail) { test('error: expression: ' + label + ': ' + '<' + expression + '>', function() { var translator = new BooleanQueryTranslator(expression); - translator.defaultField = "field"; + translator.defaultFields = ["field"]; var actualError; assert.throw(function() { try { @@ -103,6 +103,33 @@ function testExpressionError(label, expression, context, detail) { }); } +function testDefaultFields(label, query, defaultFields, expected) { + test('defaultFields: ' + label + ': ' + + '<' + query + '> -> <' + expected + '>', function() { + var translator = new BooleanQueryTranslator(query); + translator.defaultFields = defaultFields; + assert.equal(translator.translate(), + expected); + }); +} + +function testDefaultFieldsError(label, query, defaultFields, context, detail) { + test('error: defaultFields: ' + label + ': ' + '<' + query + '>', function() { + var translator = new BooleanQueryTranslator(query); + translator.defaultFields = defaultFields; + var actualError; + assert.throw(function() { + try { + translator.translate(); + } catch (error) { + actualError = error; + throw error; + } + }); + assert.equal(actualError.message, "<" + context + ">" + ": " + detail); + }); +} + suite('BoolanQueryTranslator', function() { testQuery("expression", "type:'ModelName'", @@ -287,4 +314,19 @@ suite('BoolanQueryTranslator', function() { "..", "..||", "both min and max are missing"); + + testDefaultFields("multi", + "'ModelName'", + ["type", "name"], + '(type @ "ModelName" || name @ "ModelName")'); + testDefaultFieldsError("null", + "'ModelName'", + null, + "'ModelName'||", + "default fields are missing"); + testDefaultFieldsError("empty", + "'ModelName'", + [], + "'ModelName'||", + "no default field"); }); -------------- next part -------------- HTML����������������������������...Download