[Groonga-commit] groonga/gcs [master] bq: pass query as property instead of argument

Back to archive index

null+****@clear***** null+****@clear*****
2012年 8月 3日 (金) 21:43:16 JST


Kouhei Sutou	2012-08-03 21:43:16 +0900 (Fri, 03 Aug 2012)

  New Revision: 6f79ed1c6601231e6bcc5170b14bd6cbce3261fb
  https://github.com/groonga/gcs/commit/6f79ed1c6601231e6bcc5170b14bd6cbce3261fb

  Log:
    bq: pass query as property instead of argument

  Modified files:
    lib/bq-translator.js
    test/bq-translator.test.js

  Modified: lib/bq-translator.js (+99 -105)
===================================================================
--- lib/bq-translator.js    2012-08-03 21:31:56 +0900 (e001cf3)
+++ lib/bq-translator.js    2012-08-03 21:43:16 +0900 (4cf3daf)
@@ -17,84 +17,81 @@
 */
 
 
-function BooleanQueryTranslator() {
+function BooleanQueryTranslator(query) {
+  this.query = query;
+  this.offset = 0;
+  this.defaultField = null;
 }
 
-function throwTranslateError(query, context, detail) {
-  var message = "";
-  message += "<";
-  message += query.substring(0, context.offset);
-  message += "|" + query[context.offset] + "|";
-  message += query.substring(context.offset + 1);
-  message += ">";
-  message += ": " + detail;
-  throw new Error(message);
-};
-
 BooleanQueryTranslator.prototype = {
-  translate: function(query, defaultField) {
-    var context = {
-      defaultField: defaultField,
-      offset: 0
-    };
+  translate: function() {
     var expression;
-    if (query[0] == "(") {
-      expression = this.translateGroup(query, context);
+    if (this.query[0] == "(") {
+      expression = this.translateGroup();
     } else {
-      expression = this.translateExpression(query, context);
+      expression = this.translateExpression();
     }
-    if (context.offset != query.length) {
-      throwTranslateError(query, context,
-                          "garbages exist after valid boolean query");
+    if (this.offset != this.query.length) {
+      this.throwTranslateError("garbages exist after valid boolean query");
     }
     return expression;
   },
-  skipSpaces: function(query, context) {
-    for (; context.offset < query.length; context.offset++) {
-      if (query[context.offset] != " ") {
+  throwTranslateError: function(detail) {
+    var message = "";
+    message += "<";
+    message += this.query.substring(0, this.offset);
+    message += "|" + this.query[this.offset] + "|";
+    message += this.query.substring(this.offset + 1);
+    message += ">";
+    message += ": " + detail;
+    throw new Error(message);
+  },
+  skipSpaces: function() {
+    for (; this.offset < this.query.length; this.offset++) {
+      if (this.query[this.offset] != " ") {
         return;
       }
     }
   },
-  translateGroup: function(query, context) {
-    if (query[context.offset] != "(") {
+  translateGroup: function() {
+    if (this.query[this.offset] != "(") {
       // TODO: report error
       return "";
     }
 
-    context.offset++;
+    this.offset++;
     var operator = "";
-    for (; context.offset < query.length; context.offset++) {
-      var character = query[context.offset];
+    for (; this.offset < this.query.length; this.offset++) {
+      var character = this.query[this.offset];
       if (/^[a-z]$/.test(character)) {
         operator += character;
       } else if (character == " ") {
-        this.skipSpaces(query, context);
+        this.skipSpaces();
         var expression;
         switch (operator) {
         case "field":
-          expression = this.translateGroupField(query, context);
+          expression = this.translateGroupField();
           break;
         case "filter":
-          expression = this.translateGroupFilter(query, context);
+          expression = this.translateGroupFilter();
           break;
         case "and":
-          expression = this.translateGroupSetOperation(query, "&&", context);
+          expression = this.translateGroupSetOperation("&&");
           break;
         case "or":
-          expression = this.translateGroupSetOperation(query, "||", context);
+          expression = this.translateGroupSetOperation("||");
           break;
         default:
           // TODO: report error: unknown operator
           return "";
           break;
         }
-        this.skipSpaces(query, context);
-        if (query[context.offset] != ")") {
+        this.skipSpaces();
+        if (this.query[this.offset] != ")") {
           // TODO: report error: have garbage
           return "";
         }
-        context.offset++;
+        this.offset++;
         return expression;
       } else if (character == ")") {
         // TODO: report error: no arguments for operator
@@ -108,19 +105,17 @@ BooleanQueryTranslator.prototype = {
     // TODO: report error: missing close paren <)>
     return "";
   },
-  translateGroupField: function(query, context) {
+  translateGroupField: function() {
     var field = "";
-    for (; context.offset < query.length; context.offset++) {
-      var character = query[context.offset];
+    for (; this.offset < this.query.length; this.offset++) {
+      var character = this.query[this.offset];
       if (/^[\-a-z0-9]$/.test(character)) {
         field += character;
       } else if (character == " ") {
-        this.skipSpaces(query, context);
-        var expression = this.translateExpressionValueString(query,
-                                                             field,
-                                                             context);
-        this.skipSpaces(query, context);
-        if (query[context.offset] != ")") {
+        this.skipSpaces();
+        var expression = this.translateExpressionValueString(field);
+        this.skipSpaces();
+        if (this.query[this.offset] != ")") {
           // TODO: report error: have garbage
           return "";
         }
@@ -137,19 +132,17 @@ BooleanQueryTranslator.prototype = {
     // TODO: report error: missing close paren <)>
     return "";
   },
-  translateGroupFilter: function(query, context) {
+  translateGroupFilter: function() {
     var field = "";
-    for (; context.offset < query.length; context.offset++) {
-      var character = query[context.offset];
+    for (; this.offset < this.query.length; this.offset++) {
+      var character = this.query[this.offset];
       if (/^[\-a-z0-9]$/.test(character)) {
         field += character;
       } else if (character == " ") {
-        this.skipSpaces(query, context);
-        var expression = this.translateExpressionValueUnsignedInteger(query,
-                                                                      field,
-                                                                      context);
-        this.skipSpaces(query, context);
-        if (query[context.offset] != ")") {
+        this.skipSpaces();
+        var expression = this.translateExpressionValueUnsignedInteger(field);
+        this.skipSpaces();
+        if (this.query[this.offset] != ")") {
           // TODO: report error: have garbage
           return "";
         }
@@ -166,77 +159,77 @@ BooleanQueryTranslator.prototype = {
     // TODO: report error: missing close paren <)>
     return "";
   },
-  translateGroupSetOperation: function(query, setOperator, context) {
+  translateGroupSetOperation: function(setOperator) {
     var expressions = [];
-    while (context.offset < query.length) {
-      this.skipSpaces(query, context);
-      if (query[context.offset] == ")") {
+    while (this.offset < this.query.length) {
+      this.skipSpaces();
+      if (this.query[this.offset] == ")") {
         return "(" + expressions.join(" " + setOperator + " ") + ")";
       } else {
-        expressions.push(this.translateExpression(query, context));
+        expressions.push(this.translateExpression());
       }
     }
 
     // TODO: report error: missing close paren <)>
     return "";
   },
-  translateExpression: function(query, context) {
-    if (query[context.offset] == "(") {
-      return this.translateGroup(query, context);
+  translateExpression: function() {
+    if (this.query[this.offset] == "(") {
+      return this.translateGroup();
     }
 
-    var startOffset = context.offset;
+    var startOffset = this.offset;
     var field;
-    if (/^[a-z0-9]$/.test(query[context.offset])) {
+    if (/^[a-z0-9]$/.test(this.query[this.offset])) {
       field = "";
-      for (; context.offset < query.length; context.offset++) {
-        var character = query[context.offset];
+      for (; this.offset < this.query.length; this.offset++) {
+        var character = this.query[this.offset];
         if (!/^[\-a-z0-9]$/.test(character)) {
           break;
         }
         field += character;
       }
-      if (query[context.offset] == ":") {
-        context.offset++;
+      if (this.query[this.offset] == ":") {
+        this.offset++;
       } else {
         var is_unsigned_integer_value = /^[0-9]+$/.test(field);
         if (is_unsigned_integer_value) {
-          field = context.defaultField;
-          context.offset = startOffset;
+          field = this.defaultField;
+          this.offset = startOffset;
         } else {
           // TODO: report error: field and value separator ":" is missing
           return "";
         }
       }
     } else {
-      field = context.defaultField;
+      field = this.defaultField;
     }
 
-    if (query[context.offset] == "'") {
-      return this.translateExpressionValueString(query, field, context);
+    if (this.query[this.offset] == "'") {
+      return this.translateExpressionValueString(field);
     }
-    if (/^[0-9.]/.test(query[context.offset])) {
-      return this.translateExpressionValueUnsignedInteger(query, field, context);
+    if (/^[0-9.]/.test(this.query[this.offset])) {
+      return this.translateExpressionValueUnsignedInteger(field);
     }
     // TODO: report error
     return "";
   },
-  translateExpressionValueString: function(query, field, context) {
-    if (query[context.offset] != "'") {
+  translateExpressionValueString: function(field) {
+    if (this.query[this.offset] != "'") {
       // TODO: report error
       return "";
     }
-    if (query[context.offset + 1] == "\"") {
-      return this.translateExpressionValuePhrase(query, field, context);
+    if (this.query[this.offset + 1] == "\"") {
+      return this.translateExpressionValuePhrase(field);
     }
 
-    context.offset++;
+    this.offset++;
     var values = [];
     var value = "";
-    for (; context.offset < query.length; context.offset++) {
-      var character = query[context.offset];
+    for (; this.offset < this.query.length; this.offset++) {
+      var character = this.query[this.offset];
       if (character == "'") {
-        context.offset++;
+        this.offset++;
         values.push("\"" + value + "\"");
         var expressions = values.map(function (value) {
           return field + " @ " + value;
@@ -250,8 +243,8 @@ BooleanQueryTranslator.prototype = {
           value = "";
         }
       } else if (character == "\\") {
-        context.offset++;
-        character = query[context.offset];
+        this.offset++;
+        character = this.query[this.offset];
         value += character;
       } else if (character == "\"") {
         value += "\\\"";
@@ -263,32 +256,33 @@ BooleanQueryTranslator.prototype = {
     // TODO: report error: missing close quote <'>
     return "";
   },
-  translateExpressionValuePhrase: function(query, field, context) {
-    if (!(query[context.offset] == "'" && query[context.offset + 1] == "\"")) {
+  translateExpressionValuePhrase: function(field) {
+    if (!(this.query[this.offset] == "'" &&
+          this.query[this.offset + 1] == "\"")) {
       // TODO: report error
       return "";
     }
 
-    context.offset += 2;
+    this.offset += 2;
     var value = "";
-    for (; context.offset < query.length; context.offset++) {
-      var character = query[context.offset];
+    for (; this.offset < this.query.length; this.offset++) {
+      var character = this.query[this.offset];
       if (character == "'") {
         // TODO: report error: missing close quote <">
         return "";
       }
 
       if (character == "\\") {
-        context.offset++;
-        character = query[context.offset];
+        this.offset++;
+        character = this.query[this.offset];
         value += character;
       } else if (character == "\"") {
-        context.offset++;
-        if (query[context.offset] != "'") {
+        this.offset++;
+        if (this.query[this.offset] != "'") {
           // TODO: report error: missing close quote <'> after <">
           return "";
         }
-        context.offset++;
+        this.offset++;
         return field + " @ " + "\"" + value + "\"";
       } else {
         value += character;
@@ -298,22 +292,22 @@ BooleanQueryTranslator.prototype = {
     // TODO: report error: missing close quote <"'>
     return "";
   },
-  translateExpressionValueUnsignedInteger: function(query, field, context) {
+  translateExpressionValueUnsignedInteger: function(field) {
     var is_range = false;
     var min = "";
     var max = "";
-    for (; context.offset < query.length; context.offset++) {
-      var character = query[context.offset];
+    for (; this.offset < this.query.length; this.offset++) {
+      var character = this.query[this.offset];
       if (!/^[0-9]$/.test(character)) {
         break;
       }
       min += character;
     }
-    if (query[context.offset] == "." && query[context.offset + 1] == ".") {
+    if (this.query[this.offset] == "." && this.query[this.offset + 1] == ".") {
       is_range = true;
-      context.offset += 2;
-      for (; context.offset < query.length; context.offset++) {
-        var character = query[context.offset];
+      this.offset += 2;
+      for (; this.offset < this.query.length; this.offset++) {
+        var character = this.query[this.offset];
         if (!/^[0-9]$/.test(character)) {
           break;
         }

  Modified: test/bq-translator.test.js (+14 -18)
===================================================================
--- test/bq-translator.test.js    2012-08-03 21:31:56 +0900 (85c6ec3)
+++ test/bq-translator.test.js    2012-08-03 21:43:16 +0900 (0dfba86)
@@ -8,19 +8,21 @@ var BooleanQueryTranslator = require('../lib/bq-translator').BooleanQueryTransla
 function testQuery(label, query, expected) {
   test('query: ' + label + ': ' +
        '<' + query + '> -> <' + expected + '>', function() {
-    var translator = new BooleanQueryTranslator();
-    assert.equal(translator.translate(query, "field"),
+    var translator = new BooleanQueryTranslator(query);
+    translator.defaultField = "field";
+    assert.equal(translator.translate(),
                  expected);
   });
 }
 
 function testQueryError(label, query, context, detail) {
   test('error: query: ' + label + ': ' + '<' + query + '>', function() {
-    var translator = new BooleanQueryTranslator();
+    var translator = new BooleanQueryTranslator(query);
+    translator.defaultField = "field";
     var actualError;
     assert.throw(function() {
       try {
-        translator.translate(query, "field");
+        translator.translate();
       } catch (error) {
         actualError = error;
         throw error;
@@ -33,15 +35,12 @@ function testQueryError(label, query, context, detail) {
 function testGroup(label, group, expectedOffset, expectedScriptGrnExpr) {
   test('gorup: ' + label + ': ' +
        '<' + group + '> -> <' + expectedScriptGrnExpr + '>', function() {
-    var translator = new BooleanQueryTranslator();
-    var context = {
-      defaultField: "field",
-      offset: 0
-    };
-    var actualScriptGrnExpr = translator.translateGroup(group, context);
+    var translator = new BooleanQueryTranslator(group);
+    translator.defaultField = "field";
+    var actualScriptGrnExpr = translator.translateGroup();
     assert.deepEqual({
                        scriptGrnExpr: actualScriptGrnExpr,
-                       offset: context.offset
+                       offset: translator.offset
                      },
                      {
                        scriptGrnExpr: expectedScriptGrnExpr,
@@ -54,16 +53,13 @@ function testExpression(label, expression,
                         expectedOffset, expectedScriptGrnExpr) {
   test('expression: ' + label + ': ' +
        '<' + expression + '> -> <' + expectedScriptGrnExpr + '>', function() {
-    var translator = new BooleanQueryTranslator();
-    var context = {
-      defaultField: "field",
-      offset: 0
-    };
+    var translator = new BooleanQueryTranslator(expression);
+    translator.defaultField = "field";
     var actualScriptGrnExpr =
-          translator.translateExpression(expression, context);
+          translator.translateExpression();
     assert.deepEqual({
                        scriptGrnExpr: actualScriptGrnExpr,
-                       offset: context.offset
+                       offset: translator.offset
                      },
                      {
                        scriptGrnExpr: expectedScriptGrnExpr,
-------------- next part --------------
HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B...
Download 



Groonga-commit メーリングリストの案内
Back to archive index