You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2023/01/25 18:16:56 UTC

[couchdb] branch import-nouveau-query-as-json created (now a19514cc2)

This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a change to branch import-nouveau-query-as-json
in repository https://gitbox.apache.org/repos/asf/couchdb.git


      at a19514cc2 WIP query as json

This branch includes the following new commits:

     new a19514cc2 WIP query as json

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[couchdb] 01/01: WIP query as json

Posted by rn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch import-nouveau-query-as-json
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit a19514cc2bc53b051d5e1ce13effffd2944836cc
Author: Robert Newson <rn...@apache.org>
AuthorDate: Wed Jan 25 18:16:34 2023 +0000

    WIP query as json
---
 .../nouveau/core/ser/QueryDeserializer.java        |  40 +++++++
 .../couchdb/nouveau/core/ser/QuerySerializer.java  | 117 +++++++++++++++++++++
 .../nouveau/core/ser/SerializationTest.java        |  29 ++++-
 3 files changed, 185 insertions(+), 1 deletion(-)

diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/ser/QueryDeserializer.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/ser/QueryDeserializer.java
new file mode 100644
index 000000000..c8a7292dd
--- /dev/null
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/ser/QueryDeserializer.java
@@ -0,0 +1,40 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.couchdb.nouveau.core.ser;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.Query;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+public class QueryDeserializer extends StdDeserializer<Query> {
+
+    public QueryDeserializer() {
+        this(null);
+    }
+
+    public QueryDeserializer(Class<?> vc) {
+        super(vc);
+    }
+
+    @Override
+    public Query deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
+        return null;
+    }
+
+}
diff --git a/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/ser/QuerySerializer.java b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/ser/QuerySerializer.java
new file mode 100644
index 000000000..4cd08c8cb
--- /dev/null
+++ b/java/nouveau/server/src/main/java/org/apache/couchdb/nouveau/core/ser/QuerySerializer.java
@@ -0,0 +1,117 @@
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.couchdb.nouveau.core.ser;
+
+import java.io.IOException;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.WildcardQuery;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+public class QuerySerializer extends StdSerializer<Query> {
+
+    public QuerySerializer() {
+        this(null);
+    }
+
+    public QuerySerializer(Class<Query> vc) {
+        super(vc);
+    }
+
+    @Override
+    public void serialize(Query query, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        writeQuery(query, gen, provider);
+    }
+
+    private void writeQuery(Query query, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        if (query instanceof TermQuery) {
+            writeTermQuery((TermQuery) query, gen, provider);
+        } else if (query instanceof BooleanQuery) {
+            writeBooleanQuery((BooleanQuery) query, gen, provider);
+        } else if (query instanceof PrefixQuery) {
+            writePrefixQuery((PrefixQuery) query, gen, provider);
+        } else if (query instanceof WildcardQuery) {
+            writeWildcardQuery((WildcardQuery) query, gen, provider);
+        } else if (query instanceof MatchAllDocsQuery) {
+            writeMatchAllDocsQuery((MatchAllDocsQuery) query, gen, provider);
+        } else {
+            throw new IOException(query.getClass() + " not supported");
+        }
+    }
+
+    private void writeBooleanQuery(BooleanQuery query, JsonGenerator gen, SerializerProvider provider)
+            throws IOException {
+        gen.writeStartObject();
+        gen.writeStringField("@type", "boolean");
+        gen.writeArrayFieldStart("clauses");
+        for (BooleanClause clause : query.clauses()) {
+            writeBooleanClause(clause, gen, provider);
+        }
+        gen.writeEndArray();
+        gen.writeEndObject();
+    }
+
+    private void writeBooleanClause(BooleanClause clause, JsonGenerator gen, SerializerProvider provider)
+            throws IOException {
+        gen.writeStartObject();
+        gen.writeFieldName("query");
+        writeQuery(clause.getQuery(), gen, provider);
+        gen.writeBooleanField("prohibited", clause.isProhibited());
+        gen.writeBooleanField("required", clause.isRequired());
+        gen.writeBooleanField("scoring", clause.isScoring());
+        gen.writeEndObject();
+    }
+
+    private void writeTermQuery(TermQuery query, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        gen.writeStartObject();
+        gen.writeStringField("@type", "term");
+        writeTerm(query.getTerm(), gen, provider);
+        gen.writeEndObject();
+    }
+
+    private void writePrefixQuery(PrefixQuery query, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        gen.writeStartObject();
+        gen.writeStringField("@type", "prefix");
+        writeTerm(query.getPrefix(), gen, provider);
+        gen.writeEndObject();
+    }
+
+    private void writeWildcardQuery(WildcardQuery query, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        gen.writeStartObject();
+        gen.writeStringField("@type", "wild");
+        writeTerm(query.getTerm(), gen, provider);
+        gen.writeEndObject();
+    }
+
+    private void writeMatchAllDocsQuery(MatchAllDocsQuery query, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        gen.writeStartObject();
+        gen.writeStringField("@type", "all");
+        gen.writeEndObject();
+    }
+
+    private void writeTerm(Term term, JsonGenerator gen, SerializerProvider provider) throws IOException {
+        gen.writeStringField("field", term.field());
+        gen.writeStringField("text", term.text());
+    }
+
+}
diff --git a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/core/ser/SerializationTest.java b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/core/ser/SerializationTest.java
index b383f123d..bbc5fe682 100644
--- a/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/core/ser/SerializationTest.java
+++ b/java/nouveau/server/src/test/java/org/apache/couchdb/nouveau/core/ser/SerializationTest.java
@@ -14,8 +14,8 @@
 package org.apache.couchdb.nouveau.core.ser;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.apache.couchdb.nouveau.api.After;
 import org.apache.couchdb.nouveau.api.DoubleRange;
@@ -24,10 +24,20 @@ import org.apache.couchdb.nouveau.api.document.StoredDoubleField;
 import org.apache.couchdb.nouveau.api.document.StoredStringField;
 import org.apache.couchdb.nouveau.api.document.StringField;
 import org.apache.couchdb.nouveau.api.document.TextField;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.WildcardQuery;
+import org.apache.lucene.search.BooleanClause.Occur;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
 
 public class SerializationTest {
 
@@ -36,6 +46,10 @@ public class SerializationTest {
     @BeforeAll
     public static void setupMapper() {
         mapper = new ObjectMapper();
+        mapper.registerModule(new SimpleModule() {{
+            addSerializer(Query.class, new QuerySerializer());
+            addDeserializer(Query.class, new QueryDeserializer());
+        }});
     }
 
     @Test
@@ -153,4 +167,17 @@ public class SerializationTest {
         assertEquals(true, actual.isMaxInclusive());
     }
 
+    @Test
+    public void testSerializeQuery() throws Exception {
+        final String expected = "{}";
+        final BooleanQuery.Builder b = new BooleanQuery.Builder();
+        b.add(new TermQuery(new Term("foo", "bar")), Occur.MUST);
+        b.add(new PrefixQuery(new Term("foo", "bar")), Occur.SHOULD);
+        b.add(new WildcardQuery(new Term("foo", "bar*baz")), Occur.FILTER);
+        b.add(new MatchAllDocsQuery(), Occur.MUST_NOT);
+        final Query q = b.build();
+        final String actual = mapper.writeValueAsString(q);
+        assertEquals(expected, actual);
+    }
+
 }