summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Kossakowski <grek@google.com>2009-08-14 18:32:38 -0700
committerGrzegorz Kossakowski <grek@google.com>2009-08-14 18:32:38 -0700
commit489874e17eca60e806f0c7d92838ac55884d02c2 (patch)
treed4edcf93d9971c1674169fb9a79102f42db05ec8
parent73c749b3c9b2d2bd76dd32d0b66bbc61fe304de3 (diff)
downloadgimd-489874e17eca60e806f0c7d92838ac55884d02c2.tar.gz
Introduced concept of Handlers that are returned along with query results.
MessageQuery returns List[(Handler, U)] instead of just List[U]. The purpose of returning handlers is to keep track of mapping between instance of U and relevant place in Gimd's datastructure. This allows to implement casual operations like delete, add, modify in an efficient and easy way. Handlers can be implemented in a specific way to a given Database implementation which can carry additional information useful for optimization purposes. Adapted MessageQueryTestCases to these changes. Apart from changes strictly related to that adaption SimpleMessageType and ChildType has been changed to be objects as they are really always singletons carrying configuration only. Signed-off-by: Grzegorz Kossakowski <grek@google.com>
-rw-r--r--src/main/scala/com/google/gimd/jgit/JGitFileHandler.scala17
-rw-r--r--src/main/scala/com/google/gimd/jgit/JGitMessageHandler.scala21
-rw-r--r--src/main/scala/com/google/gimd/query/FileHandler.scala19
-rw-r--r--src/main/scala/com/google/gimd/query/Handler.scala17
-rw-r--r--src/main/scala/com/google/gimd/query/MessageHandler.scala21
-rw-r--r--src/main/scala/com/google/gimd/query/MessageQuery.scala16
-rw-r--r--src/test/scala/com/google/gimd/query/MessageQueryTestCase.scala33
7 files changed, 127 insertions, 17 deletions
diff --git a/src/main/scala/com/google/gimd/jgit/JGitFileHandler.scala b/src/main/scala/com/google/gimd/jgit/JGitFileHandler.scala
new file mode 100644
index 0000000..6e6c31b
--- /dev/null
+++ b/src/main/scala/com/google/gimd/jgit/JGitFileHandler.scala
@@ -0,0 +1,17 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gimd.jgit
+
+case class JGitFileHandler[T](file: JGitFile[T]) extends query.FileHandler(file)
diff --git a/src/main/scala/com/google/gimd/jgit/JGitMessageHandler.scala b/src/main/scala/com/google/gimd/jgit/JGitMessageHandler.scala
new file mode 100644
index 0000000..4c7e170
--- /dev/null
+++ b/src/main/scala/com/google/gimd/jgit/JGitMessageHandler.scala
@@ -0,0 +1,21 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gimd.jgit
+
+import query.{Handler, MessageHandler}
+
+case class JGitMessageHandler[T](parent: Either[JGitFileHandler[T], JGitMessageHandler[T]],
+ message: Message)
+ extends MessageHandler(parent.fold[Handler](identity, identity), message)
diff --git a/src/main/scala/com/google/gimd/query/FileHandler.scala b/src/main/scala/com/google/gimd/query/FileHandler.scala
new file mode 100644
index 0000000..1546db9
--- /dev/null
+++ b/src/main/scala/com/google/gimd/query/FileHandler.scala
@@ -0,0 +1,19 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gimd.query
+
+import file.File
+
+abstract class FileHandler[T](file: File[T]) extends Handler
diff --git a/src/main/scala/com/google/gimd/query/Handler.scala b/src/main/scala/com/google/gimd/query/Handler.scala
new file mode 100644
index 0000000..c0840a4
--- /dev/null
+++ b/src/main/scala/com/google/gimd/query/Handler.scala
@@ -0,0 +1,17 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gimd.query
+
+abstract class Handler
diff --git a/src/main/scala/com/google/gimd/query/MessageHandler.scala b/src/main/scala/com/google/gimd/query/MessageHandler.scala
new file mode 100644
index 0000000..5b83e64
--- /dev/null
+++ b/src/main/scala/com/google/gimd/query/MessageHandler.scala
@@ -0,0 +1,21 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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 com.google.gimd.query
+
+abstract class MessageHandler(parent: Handler, message: Message) extends Handler
+
+object MessageHandler {
+ type Factory = ((Handler, Message) => MessageHandler)
+}
diff --git a/src/main/scala/com/google/gimd/query/MessageQuery.scala b/src/main/scala/com/google/gimd/query/MessageQuery.scala
index ec3e0ca..967dd33 100644
--- a/src/main/scala/com/google/gimd/query/MessageQuery.scala
+++ b/src/main/scala/com/google/gimd/query/MessageQuery.scala
@@ -16,20 +16,24 @@ package com.google.gimd.query
object MessageQuery {
- def simpleQuery[U, W](ut: UserType[W], m: Message, p: Predicate[U]): List[U] = {
+ def simpleQuery[U, W](ut: UserType[W], m: Message, p: Predicate[U], parent: Handler,
+ factory: MessageHandler.Factory): List[(MessageHandler,U)] = {
+ val handler = factory(parent, m)
+
val matched = if (p.isType(ut.userTypeClass)) {
val value = ut.toUserObject(m).asInstanceOf[U]
if (p.isMatch(value))
- List(value)
+ List((handler, value))
else
Nil
} else Nil
- val childMatches = ut.children.flatMap(
- (nm: NestedMember[_]) => Message.filterMessageFields(m.filter(_.name == nm.name)).
- flatMap(simpleQuery(nm.userType, _, p))
- )
+ val childMatches = (for {
+ nm <- ut.children
+ childMessageFields = Message.filterMessageFields(m.all(nm.name))
+ matches = childMessageFields.flatMap(simpleQuery(nm.userType, _, p, handler, factory))
+ } yield matches).flatMap(identity[List[(MessageHandler,U)]])
matched ++ childMatches
}
diff --git a/src/test/scala/com/google/gimd/query/MessageQueryTestCase.scala b/src/test/scala/com/google/gimd/query/MessageQueryTestCase.scala
index 2753320..4b49ca7 100644
--- a/src/test/scala/com/google/gimd/query/MessageQueryTestCase.scala
+++ b/src/test/scala/com/google/gimd/query/MessageQueryTestCase.scala
@@ -14,7 +14,7 @@
package com.google.gimd.query
-
+import file.{File, FileType}
import org.junit.Test
import org.junit.Assert._
@@ -22,7 +22,7 @@ class MessageQueryTestCase {
case class Child(name: String, property1: Boolean)
- class ChildType extends UserType[Child] {
+ object ChildType extends UserType[Child] {
def toMessageBuffer(child: Child) = (new MessageBuffer()) ++
List(Field("name", child.name), Field("property1", child.property1.toString))
def toUserObject(m: Message): Child =
@@ -32,18 +32,21 @@ class MessageQueryTestCase {
case class SimpleMessage(name: String, children: List[Child])
- class SimpleMessageType extends UserType[SimpleMessage] {
+ object SimpleMessageType extends UserType[SimpleMessage] {
def toMessageBuffer(sm: SimpleMessage) = (new MessageBuffer()) ++
List(Field("name", sm.name))
def toUserObject(m: Message): SimpleMessage = {
- val childType = new ChildType()
- val children = m.all("child").map(_.messageField.value).map(childType.toUserObject(_))
+ val children = m.all("child").map(_.messageField.value).map(ChildType.toUserObject(_))
val name = m.one("name").stringField.value
new SimpleMessage(name, children.toList)
}
- override def children = Seq(new NestedMember("child", new ChildType()))
+ override def children = Seq(new NestedMember("child", ChildType))
}
+ object MockParentHandler extends Handler
+ case class MockMessageHandler(parent: Handler, message: Message)
+ extends MessageHandler(parent, message)
+
@Test
def simpleQuery = {
import Predicate.functionLiteral2Predicate
@@ -51,11 +54,19 @@ class MessageQueryTestCase {
this.getClass.getResourceAsStream("simpleMessage.gimd")
)
val message = gimd.text.Parser.parse(reader)
- val queryResult = MessageQuery.simpleQuery(new SimpleMessageType(), message,
- (child: Child) => child.property1 == true)
- val expectedResult = List(Child("Child1", true), Child("Child3", true),
- Child("Child5", true))
- assertEquals(expectedResult, queryResult)
+ val factory = MockMessageHandler(_, _)
+ val messageHandler = factory(MockParentHandler, message)
+
+ val predicate = (child: Child) => child.property1 == true
+ val queryResult = MessageQuery.simpleQuery(SimpleMessageType, message, predicate,
+ MockParentHandler, factory)
+
+ val expectedChildren = List(Child("Child1", true), Child("Child3", true), Child("Child5", true))
+ val expectedMessages = expectedChildren.map(ChildType.toMessageBuffer(_).readOnly)
+ val handlers = expectedMessages.map(factory(messageHandler, _))
+ val expectedResult = handlers zip expectedChildren
+
+ assertEquals(Set(expectedResult: _*), Set(queryResult: _*))
}
}