You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@s2graph.apache.org by st...@apache.org on 2018/04/05 08:41:29 UTC
[2/6] incubator-s2graph git commit: Changing query more intuitively
by using `columnName` instead of `from/to` in label field name
Changing query more intuitively by using `columnName` instead of `from/to` in label field name
Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/da15232c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/da15232c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/da15232c
Branch: refs/heads/master
Commit: da15232cf151a89184f9be498db31e2f3877edf8
Parents: afc22d7
Author: daewon <da...@apache.org>
Authored: Tue Apr 3 15:27:58 2018 +0900
Committer: daewon <da...@apache.org>
Committed: Wed Apr 4 14:43:05 2018 +0900
----------------------------------------------------------------------
.../apache/s2graph/graphql/GraphQLServer.scala | 1 +
.../apache/s2graph/graphql/bind/AstHelper.scala | 9 +
.../s2graph/graphql/bind/Unmarshaller.scala | 159 +++++++++
.../s2graph/graphql/marshaller/package.scala | 124 -------
.../graphql/repository/GraphRepository.scala | 5 -
.../s2graph/graphql/resolver/Resolver.scala | 28 --
.../s2graph/graphql/types/ManagementType.scala | 312 +++++++++++++++++
.../graphql/types/S2ManagementType.scala | 339 -------------------
.../apache/s2graph/graphql/types/S2Type.scala | 143 ++++----
.../types/SangriaPlayJsonScalarType.scala | 76 -----
.../s2graph/graphql/types/SchemaDef.scala | 4 +-
.../s2graph/graphql/types/StaticType.scala | 149 ++++++++
.../apache/s2graph/graphql/types/package.scala | 137 +-------
.../apache/s2graph/graphql/ScenarioTest.scala | 52 +--
.../org/apache/s2graph/graphql/SchemaTest.scala | 12 +-
.../org/apache/s2graph/graphql/TestGraph.scala | 1 +
16 files changed, 735 insertions(+), 816 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
index e4b43cc..dcddd01 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/GraphQLServer.scala
@@ -29,6 +29,7 @@ import com.typesafe.config.ConfigFactory
import org.apache.s2graph.core.S2Graph
import org.apache.s2graph.core.utils.SafeUpdateCache
import org.apache.s2graph.graphql.repository.GraphRepository
+import org.apache.s2graph.graphql.types.SchemaDef
import org.slf4j.LoggerFactory
import sangria.ast.Document
import sangria.execution._
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/AstHelper.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/AstHelper.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/AstHelper.scala
new file mode 100644
index 0000000..ec1c04c
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/AstHelper.scala
@@ -0,0 +1,9 @@
+package org.apache.s2graph.graphql.bind
+
+object AstHelper {
+ def selectedFields(astFields: Seq[sangria.ast.Field]): Vector[String] = {
+ astFields.flatMap { f =>
+ f.selections.map(s => s.asInstanceOf[sangria.ast.Field].name)
+ }.toVector
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
new file mode 100644
index 0000000..f7a360a
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/bind/Unmarshaller.scala
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.s2graph.graphql.bind
+
+import org.apache.s2graph.core.Management.JsonModel._
+import org.apache.s2graph.core.mysqls.ServiceColumn
+import org.apache.s2graph.core.{S2EdgeLike, S2VertexLike}
+import org.apache.s2graph.graphql.repository.GraphRepository
+import org.apache.s2graph.graphql.types.S2Type._
+import sangria.marshalling._
+import sangria.schema.Context
+
+object Unmarshaller {
+ type RawNode = Map[String, Any]
+
+ def unwrap(any: Any): Any = any match {
+ case s: Some[_] => unwrap(s.get)
+ case v: Seq[_] => v.map(unwrap)
+ case m: Map[_, _] => m.mapValues(unwrap)
+ case _ => any
+ }
+
+ implicit object AddVertexParamFromInput extends FromInput[List[AddVertexParam]] {
+ val marshaller = CoercedScalaResultMarshaller.default
+
+ def fromResult(node: marshaller.Node) = {
+ val now = System.currentTimeMillis()
+ val map = unwrap(node).asInstanceOf[RawNode]
+
+ val params = map.flatMap { case (columnName, vls: Vector[_]) =>
+ vls.map { _m =>
+ val m = _m.asInstanceOf[RawNode]
+ val id = m("id")
+ val ts = m.getOrElse("timestamp", now).asInstanceOf[Long]
+
+ AddVertexParam(ts, id, columnName, props = m)
+ }
+ }
+
+ params.toList
+ }
+ }
+
+ implicit object AddEdgeParamFromInput extends FromInput[AddEdgeParam] {
+ val marshaller = CoercedScalaResultMarshaller.default
+
+ def fromResult(node: marshaller.Node) = {
+ val inputMap = unwrap(node).asInstanceOf[RawNode]
+ val now = System.currentTimeMillis()
+
+ val from = inputMap("from")
+ val to = inputMap("to")
+ val ts = inputMap.get("timestamp").map(_.asInstanceOf[Long]).getOrElse(now)
+ val dir = inputMap.get("direction").map(_.asInstanceOf[String]).getOrElse("out")
+ val props = inputMap
+
+ AddEdgeParam(ts, from, to, dir, props)
+ }
+ }
+
+ implicit object IndexFromInput extends FromInput[Index] {
+ val marshaller = CoercedScalaResultMarshaller.default
+
+ def fromResult(node: marshaller.Node) = {
+ val input = node.asInstanceOf[RawNode]
+ Index(input("name").asInstanceOf[String], input("propNames").asInstanceOf[Seq[String]])
+ }
+ }
+
+ implicit object PropFromInput extends FromInput[Prop] {
+ val marshaller = CoercedScalaResultMarshaller.default
+
+ def fromResult(node: marshaller.Node) = {
+ val input = node.asInstanceOf[RawNode]
+
+ val name = input("name").asInstanceOf[String]
+ val defaultValue = input("defaultValue").asInstanceOf[String]
+ val dataType = input("dataType").asInstanceOf[String]
+ val storeInGlobalIndex = input("storeInGlobalIndex").asInstanceOf[Boolean]
+
+ Prop(name, defaultValue, dataType, storeInGlobalIndex)
+ }
+ }
+
+ implicit object ServiceColumnParamFromInput extends FromInput[ServiceColumnParam] {
+ val marshaller = CoercedScalaResultMarshaller.default
+
+ def fromResult(node: marshaller.Node) = ServiceColumnParamsFromInput.fromResult(node).head
+ }
+
+ implicit object ServiceColumnParamsFromInput extends FromInput[Vector[ServiceColumnParam]] {
+ val marshaller = CoercedScalaResultMarshaller.default
+
+ def fromResult(node: marshaller.Node) = {
+ val input = unwrap(node.asInstanceOf[Map[String, Any]]).asInstanceOf[Map[String, Any]]
+
+ val partialServiceColumns = input.map { case (serviceName, serviceColumnMap) =>
+ val innerMap = serviceColumnMap.asInstanceOf[Map[String, Any]]
+ val columnName = innerMap("columnName").asInstanceOf[String]
+ val props = innerMap.get("props").toSeq.flatMap { case vs: Vector[_] =>
+ vs.map(PropFromInput.fromResult)
+ }
+
+ ServiceColumnParam(serviceName, columnName, props)
+ }
+
+ partialServiceColumns.toVector
+ }
+ }
+
+ def labelField(c: Context[GraphRepository, Any]): (S2VertexLike, String) = {
+ val vertex = c.value.asInstanceOf[S2VertexLike]
+ val dir = c.arg[String]("direction")
+
+ (vertex, dir)
+ }
+
+ def serviceColumnFieldOnService(column: ServiceColumn, c: Context[GraphRepository, Any]): (Seq[S2VertexLike], Boolean) = {
+ val ids = c.argOpt[Any]("id").toSeq ++ c.argOpt[List[Any]]("ids").toList.flatten
+ val vertices = ids.map(vid => c.ctx.toS2VertexLike(vid, column))
+
+ val columnFields = column.metasInvMap.keySet
+ val selectedFields = AstHelper.selectedFields(c.astFields)
+
+ val canSkipFetch = selectedFields.forall(f => f == "id" || !columnFields(f))
+
+ (vertices, canSkipFetch)
+ }
+
+ def serviceColumnFieldOnLabel(column: ServiceColumn, c: Context[GraphRepository, Any]): (S2VertexLike, Boolean) = {
+ val edge = c.value.asInstanceOf[S2EdgeLike]
+ val vertex = if (edge.getDirection() == "in") edge.srcForVertex else edge.tgtForVertex
+
+ val selectedFields = AstHelper.selectedFields(c.astFields)
+ val columnFields = column.metasInvMap.keySet
+
+ val canSkipFetch = selectedFields.forall(f => f == "id" || !columnFields(f))
+
+ (vertex, canSkipFetch)
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/marshaller/package.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/marshaller/package.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/marshaller/package.scala
deleted file mode 100644
index 3b675b3..0000000
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/marshaller/package.scala
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.s2graph.graphql
-
-import org.apache.s2graph.core.Management.JsonModel._
-import org.apache.s2graph.graphql.types.S2Type._
-import sangria.marshalling._
-import sangria.schema.Args
-
-package object marshaller {
- type RawNode = Map[String, Any]
-
- def unwrap(any: Any): Any = any match {
- case s: Some[_] => unwrap(s.get)
- case v: Seq[_] => v.map(unwrap)
- case m: Map[_, _] => m.mapValues(unwrap)
- case _ => any
- }
-
- implicit object AddVertexParamFromInput extends FromInput[List[AddVertexParam]] {
- val marshaller = CoercedScalaResultMarshaller.default
-
- def fromResult(node: marshaller.Node) = {
- val now = System.currentTimeMillis()
- val map = unwrap(node).asInstanceOf[RawNode]
-
- val params = map.flatMap { case (columnName, vls: Vector[_]) =>
- vls.map { _m =>
- val m = _m.asInstanceOf[RawNode]
- val id = m("id")
- val ts = m.getOrElse("timestamp", now).asInstanceOf[Long]
-
- AddVertexParam(ts, id, columnName, props = m)
- }
- }
-
- params.toList
- }
- }
-
- implicit object AddEdgeParamFromInput extends FromInput[AddEdgeParam] {
- val marshaller = CoercedScalaResultMarshaller.default
-
- def fromResult(node: marshaller.Node) = {
- val inputMap = unwrap(node).asInstanceOf[RawNode]
- val now = System.currentTimeMillis()
-
- val from = inputMap("from")
- val to = inputMap("to")
- val ts = inputMap.get("timestamp").map(_.asInstanceOf[Long]).getOrElse(now)
- val dir = inputMap.get("direction").map(_.asInstanceOf[String]).getOrElse("out")
- val props = inputMap
-
- AddEdgeParam(ts, from, to, dir, props)
- }
- }
-
- implicit object IndexFromInput extends FromInput[Index] {
- val marshaller = CoercedScalaResultMarshaller.default
-
- def fromResult(node: marshaller.Node) = {
- val input = node.asInstanceOf[RawNode]
- Index(input("name").asInstanceOf[String], input("propNames").asInstanceOf[Seq[String]])
- }
- }
-
- implicit object PropFromInput extends FromInput[Prop] {
- val marshaller = CoercedScalaResultMarshaller.default
-
- def fromResult(node: marshaller.Node) = {
- val input = node.asInstanceOf[RawNode]
-
- val name = input("name").asInstanceOf[String]
- val defaultValue = input("defaultValue").asInstanceOf[String]
- val dataType = input("dataType").asInstanceOf[String]
- val storeInGlobalIndex = input("storeInGlobalIndex").asInstanceOf[Boolean]
-
- Prop(name, defaultValue, dataType, storeInGlobalIndex)
- }
- }
-
- implicit object ServiceColumnParamFromInput extends FromInput[ServiceColumnParam] {
- val marshaller = CoercedScalaResultMarshaller.default
-
- def fromResult(node: marshaller.Node) = ServiceColumnParamsFromInput.fromResult(node).head
- }
-
- implicit object ServiceColumnParamsFromInput extends FromInput[Vector[ServiceColumnParam]] {
- val marshaller = CoercedScalaResultMarshaller.default
-
- def fromResult(node: marshaller.Node) = {
- val input = unwrap(node.asInstanceOf[Map[String, Any]]).asInstanceOf[Map[String, Any]]
-
- val partialServiceColumns = input.map { case (serviceName, serviceColumnMap) =>
- val innerMap = serviceColumnMap.asInstanceOf[Map[String, Any]]
- val columnName = innerMap("columnName").asInstanceOf[String]
- val props = innerMap.get("props").toSeq.flatMap { case vs: Vector[_] =>
- vs.map(PropFromInput.fromResult)
- }
-
- ServiceColumnParam(serviceName, columnName, props)
- }
-
- partialServiceColumns.toVector
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
index a29d0fb..ca06bc8 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
@@ -42,13 +42,8 @@ object GraphRepository {
tryObj
}
-
}
-/**
- *
- * @param graph
- */
class GraphRepository(val graph: S2GraphLike) {
implicit val logger = LoggerFactory.getLogger(this.getClass)
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/resolver/Resolver.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/resolver/Resolver.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/resolver/Resolver.scala
deleted file mode 100644
index 1a96d84..0000000
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/resolver/Resolver.scala
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.s2graph.graphql.resolver
-
-import org.apache.s2graph.core.S2VertexLike
-import org.apache.s2graph.graphql.repository.GraphRepository
-
-object Resolver {
- def vertexResolver(v: S2VertexLike)(implicit repo: GraphRepository) {
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/ManagementType.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/ManagementType.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/ManagementType.scala
new file mode 100644
index 0000000..d07feeb
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/ManagementType.scala
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.s2graph.graphql.types
+
+import org.apache.s2graph.core.mysqls._
+import org.apache.s2graph.graphql.repository.GraphRepository
+import sangria.schema._
+
+import scala.language.existentials
+import scala.util.{Failure, Success, Try}
+import org.apache.s2graph.graphql.types.S2Type.{ServiceColumnParam}
+
+object ManagementType {
+
+ import sangria.schema._
+
+ case class MutationResponse[T](result: Try[T])
+
+ def makeMutationResponseType[T](name: String, desc: String, tpe: ObjectType[_, T]): ObjectType[Unit, MutationResponse[T]] = {
+ val retType = ObjectType(
+ name,
+ desc,
+ () => fields[Unit, MutationResponse[T]](
+ Field("isSuccess",
+ BooleanType,
+ resolve = _.value.result.isSuccess
+ ),
+ Field("message",
+ StringType,
+ resolve = _.value.result match {
+ case Success(_) => s"Mutation successful"
+ case Failure(ex) => ex.getMessage
+ }
+ ),
+ Field("object",
+ OptionType(tpe),
+ resolve = _.value.result.toOption
+ )
+ )
+ )
+
+ retType
+ }
+}
+
+class ManagementType(repo: GraphRepository) {
+
+ import ManagementType._
+ import sangria.macros.derive._
+ import org.apache.s2graph.graphql.bind.Unmarshaller._
+ import org.apache.s2graph.graphql.types.StaticTypes._
+
+ lazy val serviceColumnOnServiceWithPropInputObjectFields = repo.allServices.map { service =>
+ InputField(service.serviceName, OptionInputType(InputObjectType(
+ s"Input_${service.serviceName}_ServiceColumn_Props",
+ description = "desc here",
+ fields = List(
+ InputField("columnName", makeServiceColumnEnumTypeOnService(service)),
+ InputField("props", ListInputType(InputPropType))
+ )
+ )))
+ }
+
+ lazy val serviceColumnOnServiceInputObjectFields = repo.allServices.map { service =>
+ InputField(service.serviceName, OptionInputType(InputObjectType(
+ s"Input_${service.serviceName}_ServiceColumn",
+ description = "desc here",
+ fields = List(
+ InputField("columnName", makeServiceColumnEnumTypeOnService(service))
+ )
+ )))
+ }
+
+ def makeServiceColumnEnumTypeOnService(service: Service): EnumType[String] = {
+ val columns = service.serviceColumns(false).toList
+ EnumType(
+ s"Enum_${service.serviceName}_ServiceColumn",
+ description = Option("desc here"),
+ values = dummyEnum +: columns.map { column =>
+ EnumValue(column.columnName, value = column.columnName)
+ }
+ )
+ }
+
+ lazy val labelPropsInputFields = repo.allLabels().map { label =>
+ InputField(label.label, OptionInputType(InputObjectType(
+ s"Input_${label.label}_props",
+ description = "desc here",
+ fields = List(
+ InputField("props", ListInputType(InputPropType))
+ )
+ )))
+ }
+
+ lazy val ServiceType = deriveObjectType[GraphRepository, Service](
+ ObjectTypeName("Service"),
+ ObjectTypeDescription("desc here"),
+ RenameField("serviceName", "name"),
+ AddFields(
+ Field("serviceColumns", ListType(ServiceColumnType), resolve = c => c.value.serviceColumns(false).toList)
+ )
+ )
+
+ lazy val ServiceColumnType = deriveObjectType[GraphRepository, ServiceColumn](
+ ObjectTypeName("ServiceColumn"),
+ ObjectTypeDescription("desc here"),
+ RenameField("columnName", "name"),
+ AddFields(
+ Field("props", ListType(ColumnMetaType),
+ resolve = c => c.value.metasWithoutCache.filter(ColumnMeta.isValid)
+ )
+ )
+ )
+
+ val dummyEnum = EnumValue("_", value = "_")
+
+ lazy val ServiceListType = EnumType(
+ s"Enum_Service",
+ description = Option("desc here"),
+ values =
+ dummyEnum +: repo.allServices.map { service =>
+ EnumValue(service.serviceName, value = service.serviceName)
+ }
+ )
+
+ lazy val ServiceColumnListType = EnumType(
+ s"Enum_ServiceColumn",
+ description = Option("desc here"),
+ values =
+ dummyEnum +: repo.allServiceColumns.map { serviceColumn =>
+ EnumValue(serviceColumn.columnName, value = serviceColumn.columnName)
+ }
+ )
+
+ lazy val EnumLabelsType = EnumType(
+ s"Enum_Label",
+ description = Option("desc here"),
+ values =
+ dummyEnum +: repo.allLabels().map { label =>
+ EnumValue(label.label, value = label.label)
+ }
+ )
+
+ lazy val ServiceMutationResponseType = makeMutationResponseType[Service](
+ "MutateService",
+ "desc here",
+ ServiceType
+ )
+
+ lazy val ServiceColumnMutationResponseType = makeMutationResponseType[ServiceColumn](
+ "MutateServiceColumn",
+ "desc here",
+ ServiceColumnType
+ )
+
+ lazy val LabelMutationResponseType = makeMutationResponseType[Label](
+ "MutateLabel",
+ "desc here",
+ LabelType
+ )
+
+ lazy val labelsField: Field[GraphRepository, Any] = Field(
+ "Labels",
+ ListType(LabelType),
+ description = Option("desc here"),
+ arguments = List(LabelNameArg),
+ resolve = { c =>
+ c.argOpt[String]("name") match {
+ case Some(name) => c.ctx.allLabels().filter(_.label == name)
+ case None => c.ctx.allLabels()
+ }
+ }
+ )
+
+ val serviceOptArgs = List(
+ "compressionAlgorithm" -> CompressionAlgorithmType,
+ "cluster" -> StringType,
+ "hTableName" -> StringType,
+ "preSplitSize" -> IntType,
+ "hTableTTL" -> IntType
+ ).map { case (name, _type) => Argument(name, OptionInputType(_type)) }
+
+ val AddPropServiceType = InputObjectType[ServiceColumnParam](
+ "Input_Service_ServiceColumn_Props",
+ description = "desc",
+ fields = DummyInputField +: serviceColumnOnServiceWithPropInputObjectFields
+ )
+
+ val ServiceColumnSelectType = InputObjectType[ServiceColumnParam](
+ "Input_Service_ServiceColumn",
+ description = "desc",
+ fields = DummyInputField +: serviceColumnOnServiceInputObjectFields
+ )
+
+ val InputServiceType = InputObjectType[ServiceColumnParam](
+ "Input_Service",
+ description = "desc",
+ fields = DummyInputField +: serviceColumnOnServiceInputObjectFields
+ )
+
+ lazy val servicesField: Field[GraphRepository, Any] = Field(
+ "Services",
+ ListType(ServiceType),
+ description = Option("desc here"),
+ arguments = List(ServiceNameArg),
+ resolve = { c =>
+ c.argOpt[String]("name") match {
+ case Some(name) => c.ctx.allServices.filter(_.serviceName == name)
+ case None => c.ctx.allServices
+ }
+ }
+ )
+
+ /**
+ * Query Fields
+ * Provide s2graph management query API
+ */
+ lazy val queryFields: List[Field[GraphRepository, Any]] = List(servicesField, labelsField)
+
+ /**
+ * Mutation fields
+ * Provide s2graph management mutate API
+ *
+ * - createService
+ * - createLabel
+ * - ...
+ */
+
+ lazy val labelRequiredArg = List(
+ Argument("sourceService", InputServiceType),
+ Argument("targetService", InputServiceType)
+ )
+
+ val labelOptsArgs = List(
+ Argument("serviceName", OptionInputType(ServiceListType)),
+ Argument("consistencyLevel", OptionInputType(ConsistencyLevelType)),
+ Argument("isDirected", OptionInputType(BooleanType)),
+ Argument("isAsync", OptionInputType(BooleanType)),
+ Argument("schemaVersion", OptionInputType(StringType))
+ )
+
+ val NameArg = Argument("name", StringType, description = "desc here")
+
+ lazy val ServiceNameArg = Argument("name", OptionInputType(ServiceListType), description = "desc here")
+
+ lazy val ServiceNameRawArg = Argument("serviceName", ServiceListType, description = "desc here")
+
+ lazy val ColumnNameArg = Argument("columnName", OptionInputType(ServiceColumnListType), description = "desc here")
+
+ lazy val ColumnTypeArg = Argument("columnType", DataTypeType, description = "desc here")
+
+ lazy val LabelNameArg = Argument("name", OptionInputType(EnumLabelsType), description = "desc here")
+
+ lazy val PropArg = Argument("props", OptionInputType(ListInputType(InputPropType)), description = "desc here")
+
+ lazy val IndicesArg = Argument("indices", OptionInputType(ListInputType(InputIndexType)), description = "desc here")
+
+ lazy val mutationFields: List[Field[GraphRepository, Any]] = List(
+ Field("createService",
+ ServiceMutationResponseType,
+ arguments = NameArg :: serviceOptArgs,
+ resolve = c => MutationResponse(c.ctx.createService(c.args))
+ ),
+ Field("createLabel",
+ LabelMutationResponseType,
+ arguments = NameArg :: PropArg :: IndicesArg :: labelRequiredArg ::: labelOptsArgs,
+ resolve = c => MutationResponse(c.ctx.createLabel(c.args))
+ ),
+ Field("deleteLabel",
+ LabelMutationResponseType,
+ arguments = LabelNameArg :: Nil,
+ resolve = c => MutationResponse(c.ctx.deleteLabel(c.args))
+ ),
+ Field("createServiceColumn",
+ ServiceColumnMutationResponseType,
+ arguments = List(ServiceNameRawArg, Argument("columnName", StringType), ColumnTypeArg, PropArg),
+ resolve = c => MutationResponse(c.ctx.createServiceColumn(c.args))
+ ),
+ Field("deleteServiceColumn",
+ ServiceColumnMutationResponseType,
+ arguments = Argument("service", ServiceColumnSelectType) :: Nil,
+ resolve = c => MutationResponse(c.ctx.deleteServiceColumn(c.args))
+ ),
+ Field("addPropsToServiceColumn",
+ ServiceColumnMutationResponseType,
+ arguments = Argument("service", AddPropServiceType) :: Nil,
+ resolve = c => MutationResponse(c.ctx.addPropsToServiceColumn(c.args))
+ ),
+ Field("addPropsToLabel",
+ LabelMutationResponseType,
+ arguments = Argument("labelName", EnumLabelsType) :: PropArg :: Nil,
+ resolve = c => MutationResponse(c.ctx.addPropsToLabel(c.args))
+ )
+ )
+}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
deleted file mode 100644
index 18df00b..0000000
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.s2graph.graphql.types
-
-import org.apache.s2graph.core.Management.JsonModel._
-import org.apache.s2graph.core._
-import org.apache.s2graph.core.mysqls._
-import org.apache.s2graph.core.storage.MutateResponse
-import org.apache.s2graph.graphql._
-import org.apache.s2graph.graphql.repository.GraphRepository
-import play.api.libs.json.JsValue
-import sangria.marshalling._
-import sangria.schema._
-
-import scala.language.existentials
-import scala.util.{Failure, Success, Try}
-import org.apache.s2graph.graphql.marshaller._
-import org.apache.s2graph.graphql.types.S2Type.{ServiceColumnParam}
-
-object S2ManagementType {
-
- import sangria.schema._
-
- case class MutationResponse[T](result: Try[T])
-
- def makeMutationResponseType[T](name: String, desc: String, tpe: ObjectType[_, T]): ObjectType[Unit, MutationResponse[T]] = {
- val retType = ObjectType(
- name,
- desc,
- () => fields[Unit, MutationResponse[T]](
- Field("isSuccess",
- BooleanType,
- resolve = _.value.result.isSuccess
- ),
- Field("message",
- StringType,
- resolve = _.value.result match {
- case Success(_) => s"Mutation successful"
- case Failure(ex) => ex.getMessage
- }
- ),
- Field("object",
- OptionType(tpe),
- resolve = _.value.result.toOption
- )
- )
- )
-
- retType
- }
-}
-
-class S2ManagementType(repo: GraphRepository) {
-
- import S2ManagementType._
-
- import sangria.macros.derive._
-
- lazy val serviceColumnOnServiceWithPropInputObjectFields = repo.allServices.map { service =>
- InputField(service.serviceName, OptionInputType(InputObjectType(
- s"Input_${service.serviceName}_ServiceColumn_Props",
- description = "desc here",
- fields = List(
- InputField("columnName", makeServiceColumnEnumTypeOnService(service)),
- InputField("props", ListInputType(InputPropType))
- )
- )))
- }
-
- lazy val serviceColumnOnServiceInputObjectFields = repo.allServices.map { service =>
- InputField(service.serviceName, OptionInputType(InputObjectType(
- s"Input_${service.serviceName}_ServiceColumn",
- description = "desc here",
- fields = List(
- InputField("columnName", makeServiceColumnEnumTypeOnService(service))
- )
- )))
- }
-
- def makeServiceColumnEnumTypeOnService(service: Service): EnumType[String] = {
- val columns = service.serviceColumns(false).toList
- EnumType(
- s"Enum_${service.serviceName}_ServiceColumn",
- description = Option("desc here"),
- values = dummyEnum +: columns.map { column =>
- EnumValue(column.columnName, value = column.columnName)
- }
- )
- }
-
- lazy val labelPropsInputFields = repo.allLabels().map { label =>
- InputField(label.label, OptionInputType(InputObjectType(
- s"Input_${label.label}_props",
- description = "desc here",
- fields = List(
- InputField("props", ListInputType(InputPropType))
- )
- )))
- }
-
- lazy val ServiceType = deriveObjectType[GraphRepository, Service](
- ObjectTypeName("Service"),
- ObjectTypeDescription("desc here"),
- RenameField("serviceName", "name"),
- AddFields(
- Field("serviceColumns", ListType(ServiceColumnType), resolve = c => c.value.serviceColumns(false).toList)
- )
- )
-
- lazy val ServiceColumnType = deriveObjectType[GraphRepository, ServiceColumn](
- ObjectTypeName("ServiceColumn"),
- ObjectTypeDescription("desc here"),
- RenameField("columnName", "name"),
- AddFields(
- Field("props", ListType(ColumnMetaType),
- resolve = c => c.value.metasWithoutCache.filter(ColumnMeta.isValid)
- )
- )
- )
-
- val dummyEnum = EnumValue("_", value = "_")
-
- lazy val ServiceListType = EnumType(
- s"Enum_Service",
- description = Option("desc here"),
- values =
- dummyEnum +: repo.allServices.map { service =>
- EnumValue(service.serviceName, value = service.serviceName)
- }
- )
-
- lazy val ServiceColumnListType = EnumType(
- s"Enum_ServiceColumn",
- description = Option("desc here"),
- values =
- dummyEnum +: repo.allServiceColumns.map { serviceColumn =>
- EnumValue(serviceColumn.columnName, value = serviceColumn.columnName)
- }
- )
-
- lazy val EnumLabelsType = EnumType(
- s"Enum_Label",
- description = Option("desc here"),
- values =
- dummyEnum +: repo.allLabels().map { label =>
- EnumValue(label.label, value = label.label)
- }
- )
-
- lazy val ServiceMutationResponseType = makeMutationResponseType[Service](
- "MutateService",
- "desc here",
- ServiceType
- )
-
- lazy val ServiceColumnMutationResponseType = makeMutationResponseType[ServiceColumn](
- "MutateServiceColumn",
- "desc here",
- ServiceColumnType
- )
-
- lazy val LabelMutationResponseType = makeMutationResponseType[Label](
- "MutateLabel",
- "desc here",
- LabelType
- )
-
- lazy val labelField: Field[GraphRepository, Any] = Field(
- "Label",
- OptionType(LabelType),
- description = Option("desc here"),
- arguments = Argument("name", EnumLabelsType, description = "desc here") :: Nil,
- resolve = { c =>
- val labelName = c.arg[String]("name")
- c.ctx.allLabels().find(_.label == labelName)
- }
- )
-
- lazy val labelsField: Field[GraphRepository, Any] = Field(
- "Labels",
- ListType(LabelType),
- description = Option("desc here"),
- arguments = List(LabelNameArg),
- resolve = { c =>
- c.argOpt[String]("name") match {
- case Some(name) => c.ctx.allLabels().filter(_.label == name)
- case None => c.ctx.allLabels()
- }
- }
- )
-
- val serviceOptArgs = List(
- "compressionAlgorithm" -> CompressionAlgorithmType,
- "cluster" -> StringType,
- "hTableName" -> StringType,
- "preSplitSize" -> IntType,
- "hTableTTL" -> IntType
- ).map { case (name, _type) => Argument(name, OptionInputType(_type)) }
-
- val AddPropServiceType = InputObjectType[ServiceColumnParam](
- "Input_Service_ServiceColumn_Props",
- description = "desc",
- fields = DummyInputField +: serviceColumnOnServiceWithPropInputObjectFields
- )
-
- val ServiceColumnSelectType = InputObjectType[ServiceColumnParam](
- "Input_Service_ServiceColumn",
- description = "desc",
- fields = DummyInputField +: serviceColumnOnServiceInputObjectFields
- )
-
- val InputServiceType = InputObjectType[ServiceColumnParam](
- "Input_Service",
- description = "desc",
- fields = DummyInputField +: serviceColumnOnServiceInputObjectFields
- )
-
- lazy val serviceField: Field[GraphRepository, Any] = Field(
- "Service",
- OptionType(ServiceType),
- description = Option("desc here"),
- arguments = Argument("name", ServiceListType, description = "desc here") :: Nil,
- resolve = { c =>
- val serviceName = c.arg[String]("name")
- c.ctx.allServices.find(_.serviceName == serviceName)
- }
- )
-
- lazy val servicesField: Field[GraphRepository, Any] = Field(
- "Services",
- ListType(ServiceType),
- description = Option("desc here"),
- arguments = List(ServiceNameArg),
- resolve = { c =>
- c.argOpt[String]("name") match {
- case Some(name) => c.ctx.allServices.filter(_.serviceName == name)
- case None => c.ctx.allServices
- }
- }
- )
- /**
- * Query Fields
- * Provide s2graph management query API
- */
- lazy val queryFields: List[Field[GraphRepository, Any]] = List(serviceField, servicesField, labelField, labelsField)
-
- /**
- * Mutation fields
- * Provide s2graph management mutate API
- *
- * - createService
- * - createLabel
- * - ...
- */
-
- lazy val labelRequiredArg = List(
- Argument("sourceService", InputServiceType),
- Argument("targetService", InputServiceType)
- )
-
- val labelOptsArgs = List(
- Argument("serviceName", OptionInputType(ServiceListType)),
- Argument("consistencyLevel", OptionInputType(ConsistencyLevelType)),
- Argument("isDirected", OptionInputType(BooleanType)),
- Argument("isAsync", OptionInputType(BooleanType)),
- Argument("schemaVersion", OptionInputType(StringType))
- )
-
- val NameArg = Argument("name", StringType, description = "desc here")
-
- lazy val ServiceNameArg = Argument("name", OptionInputType(ServiceListType), description = "desc here")
-
- lazy val ServiceNameRawArg = Argument("serviceName", ServiceListType, description = "desc here")
-
- lazy val ColumnNameArg = Argument("columnName", OptionInputType(ServiceColumnListType), description = "desc here")
-
- lazy val ColumnTypeArg = Argument("columnType", DataTypeType, description = "desc here")
-
- lazy val LabelNameArg = Argument("name", OptionInputType(EnumLabelsType), description = "desc here")
-
- lazy val PropArg = Argument("props", OptionInputType(ListInputType(InputPropType)), description = "desc here")
-
- lazy val IndicesArg = Argument("indices", OptionInputType(ListInputType(InputIndexType)), description = "desc here")
-
- lazy val mutationFields: List[Field[GraphRepository, Any]] = List(
- Field("createService",
- ServiceMutationResponseType,
- arguments = NameArg :: serviceOptArgs,
- resolve = c => MutationResponse(c.ctx.createService(c.args))
- ),
- Field("createLabel",
- LabelMutationResponseType,
- arguments = NameArg :: PropArg :: IndicesArg :: labelRequiredArg ::: labelOptsArgs,
- resolve = c => MutationResponse(c.ctx.createLabel(c.args))
- ),
- Field("deleteLabel",
- LabelMutationResponseType,
- arguments = LabelNameArg :: Nil,
- resolve = c => MutationResponse(c.ctx.deleteLabel(c.args))
- ),
- Field("createServiceColumn",
- ServiceColumnMutationResponseType,
- arguments = List(ServiceNameRawArg, Argument("columnName", StringType), ColumnTypeArg, PropArg),
- resolve = c => MutationResponse(c.ctx.createServiceColumn(c.args))
- ),
- Field("deleteServiceColumn",
- ServiceColumnMutationResponseType,
- arguments = Argument("service", ServiceColumnSelectType) :: Nil,
- resolve = c => MutationResponse(c.ctx.deleteServiceColumn(c.args))
- ),
- Field("addPropsToServiceColumn",
- ServiceColumnMutationResponseType,
- arguments = Argument("service", AddPropServiceType) :: Nil,
- resolve = c => MutationResponse(c.ctx.addPropsToServiceColumn(c.args))
- ),
- Field("addPropsToLabel",
- LabelMutationResponseType,
- arguments = Argument("labelName", EnumLabelsType) :: PropArg :: Nil,
- resolve = c => MutationResponse(c.ctx.addPropsToLabel(c.args))
- )
- )
-}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
index dc00ce2..eff0350 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
@@ -19,14 +19,16 @@
package org.apache.s2graph.graphql.types
+import scala.concurrent._
import org.apache.s2graph.core.Management.JsonModel.{Index, Prop}
import org.apache.s2graph.core._
import org.apache.s2graph.core.mysqls._
import org.apache.s2graph.graphql.repository.GraphRepository
import sangria.schema._
+import org.apache.s2graph.graphql.bind.{AstHelper, Unmarshaller}
+import org.apache.s2graph.graphql.types.StaticTypes._
import scala.language.existentials
-import org.apache.s2graph.graphql.marshaller._
object S2Type {
@@ -81,9 +83,9 @@ object S2Type {
def makeInputFieldsOnService(service: Service): Seq[InputField[Any]] = {
val inputFields = service.serviceColumns(false).map { serviceColumn =>
- val idField = InputField("id", s2TypeToScalarType(serviceColumn.columnType))
+ val idField = InputField("id", toScalarType(serviceColumn.columnType))
val propFields = serviceColumn.metasWithoutCache.filter(ColumnMeta.isValid).map { lm =>
- InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
+ InputField(lm.name, OptionInputType(toScalarType(lm.dataType)))
}
val vertexMutateType = InputObjectType[Map[String, Any]](
@@ -100,68 +102,62 @@ object S2Type {
def makeInputFieldsOnLabel(label: Label): Seq[InputField[Any]] = {
val propFields = label.labelMetaSet.toList.map { lm =>
- InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
+ InputField(lm.name, OptionInputType(toScalarType(lm.dataType)))
}
val labelFields = List(
InputField("timestamp", OptionInputType(LongType)),
- InputField("from", s2TypeToScalarType(label.srcColumnType)),
- InputField("to", s2TypeToScalarType(label.srcColumnType)),
- InputField("direction", OptionInputType(DirectionType))
+ InputField("from", toScalarType(label.srcColumnType)),
+ InputField("to", toScalarType(label.srcColumnType)),
+ InputField("direction", OptionInputType(BothDirectionType))
)
labelFields.asInstanceOf[Seq[InputField[Any]]] ++ propFields.asInstanceOf[Seq[InputField[Any]]]
}
- def makeServiceColumnFields(column: ServiceColumn): List[Field[GraphRepository, Any]] = {
+ def makeServiceColumnFields(column: ServiceColumn, allLabels: Seq[Label]): List[Field[GraphRepository, Any]] = {
val reservedFields = List("id" -> column.columnType, "timestamp" -> "long")
val columnMetasKv = column.metasWithoutCache.filter(ColumnMeta.isValid).map { columnMeta => columnMeta.name -> columnMeta.dataType }
- (reservedFields ++ columnMetasKv).map { case (k, v) => makePropField(k, v) }
- }
+ val (sameLabel, diffLabel) = allLabels.toList.partition(l => l.srcColumn == l.tgtColumn)
- def makeServiceField(service: Service, allLabels: List[Label])(implicit repo: GraphRepository): List[Field[GraphRepository, Any]] = {
- lazy val columnsOnService = service.serviceColumns(false).toList.map { column =>
+ val outLabels = diffLabel.filter(l => column == l.srcColumn).distinct.toList
+ val inLabels = diffLabel.filter(l => column == l.tgtColumn).distinct.toList
+ val inOutLabels = sameLabel.filter(l => l.srcColumn == column && l.tgtColumn == column)
- val outLabels = allLabels.filter { lb => column.id.get == lb.srcColumn.id.get }.distinct
- val inLabels = allLabels.filter { lb => column.id.get == lb.tgtColumn.id.get }.distinct
+ lazy val columnFields = (reservedFields ++ columnMetasKv).map { case (k, v) => makePropField(k, v) }
- lazy val vertexPropFields = makeServiceColumnFields(column)
+ lazy val outLabelFields: List[Field[GraphRepository, Any]] = outLabels.map(l => makeLabelField("out", l, allLabels))
+ lazy val inLabelFields: List[Field[GraphRepository, Any]] = inLabels.map(l => makeLabelField("in", l, allLabels))
+ lazy val inOutLabelFields: List[Field[GraphRepository, Any]] = inOutLabels.map(l => makeLabelField("both", l, allLabels))
+ lazy val propsType = wrapField(s"ServiceColumn_${column.service.serviceName}_${column.columnName}_props", "props", columnFields)
- lazy val outLabelFields: List[Field[GraphRepository, Any]] =
- outLabels.map(l => makeLabelField("out", l, allLabels))
+ lazy val labelFieldNameSet = (outLabels ++ inLabels ++ inOutLabels).map(_.label).toSet
- lazy val inLabelFields: List[Field[GraphRepository, Any]] =
- inLabels.map(l => makeLabelField("in", l, allLabels))
+ propsType :: inLabelFields ++ outLabelFields ++ inOutLabelFields ++ columnFields.filterNot(cf => labelFieldNameSet(cf.name))
+ }
- lazy val connectedLabelType = ObjectType(
- s"Input_${service.serviceName}_${column.columnName}",
- () => fields[GraphRepository, Any](vertexPropFields ++ (inLabelFields ++ outLabelFields): _*)
+ def makeServiceField(service: Service, allLabels: List[Label])(implicit repo: GraphRepository): List[Field[GraphRepository, Any]] = {
+ lazy val columnsOnService = service.serviceColumns(false).toList.map { column =>
+ lazy val serviceColumnFields = makeServiceColumnFields(column, allLabels)
+ lazy val ColumnType = ObjectType(
+ s"ServiceColumn_${service.serviceName}_${column.columnName}",
+ () => fields[GraphRepository, Any](serviceColumnFields: _*)
)
val v = Field(column.columnName,
- ListType(connectedLabelType),
+ ListType(ColumnType),
arguments = List(
- Argument("id", OptionInputType(s2TypeToScalarType(column.columnType))),
- Argument("ids", OptionInputType(ListInputType(s2TypeToScalarType(column.columnType)))),
- Argument("search", OptionInputType(StringType))
+ Argument("id", OptionInputType(toScalarType(column.columnType))),
+ Argument("ids", OptionInputType(ListInputType(toScalarType(column.columnType))))
),
description = Option("desc here"),
resolve = c => {
implicit val ec = c.ctx.ec
+ val (vertices, canSkipFetchVertex) = Unmarshaller.serviceColumnFieldOnService(column, c)
- val ids = c.argOpt[Any]("id").toSeq ++ c.argOpt[List[Any]]("ids").toList.flatten
- val vertices = ids.map(vid => c.ctx.toS2VertexLike(vid, column))
-
- val columnFields = column.metasInvMap.keySet
- val selectedFields = c.astFields.flatMap { f =>
- f.selections.map(s => s.asInstanceOf[sangria.ast.Field].name)
- }
-
- val passFetchVertex = selectedFields.forall(f => f == "id" || !columnFields(f))
-
- if (passFetchVertex) scala.concurrent.Future.successful(vertices)
- else repo.getVertices(vertices) // fill props
+ if (canSkipFetchVertex) Future.successful(vertices)
+ else c.ctx.getVertices(vertices)
}
): Field[GraphRepository, Any]
@@ -171,72 +167,48 @@ object S2Type {
columnsOnService
}
- def fillPartialVertex(vertex: S2VertexLike,
- column: ServiceColumn,
- c: Context[GraphRepository, Any]): scala.concurrent.Future[S2VertexLike] = {
- implicit val ec = c.ctx.ec
-
- val columnFields = column.metasInvMap.keySet
- val selectedFields = c.astFields.flatMap { f =>
- f.selections.map(s => s.asInstanceOf[sangria.ast.Field].name)
- }
-
- // Vertex on edge has invalid `serviceColumn` info
- lazy val newVertex = c.ctx.toS2VertexLike(vertex.innerId, column)
-
- val passFetchVertex = selectedFields.forall(f => f == "id" || !columnFields(f))
-
- if (passFetchVertex) scala.concurrent.Future.successful(vertex)
- else c.ctx.getVertices(Seq(newVertex)).map(_.head) // fill props
- }
-
- def makeLabelField(dir: String, label: Label, allLabels: List[Label]): Field[GraphRepository, Any] = {
+ def makeLabelField(dir: String, label: Label, allLabels: Seq[Label]): Field[GraphRepository, Any] = {
val labelReserved = List("direction" -> "string", "timestamp" -> "long")
val labelProps = label.labelMetas.map { lm => lm.name -> lm.dataType }
- lazy val edgeFields: List[Field[GraphRepository, Any]] =
- (labelReserved ++ labelProps).map { case (k, v) => makePropField(k, v) }
-
val column = if (dir == "out") label.tgtColumn else label.srcColumn
- lazy val toType = ObjectType(s"Label_${label.label}_${column.columnName}", () => {
- lazy val linked = if (dir == "out") {
- val inLabels = allLabels.filter { lb => column.id.get == lb.tgtColumn.id.get }.distinct
- inLabels.map(l => makeLabelField("in", l, allLabels))
- } else {
- val outLabels = allLabels.filter { lb => column.id.get == lb.srcColumn.id.get }.distinct
- outLabels.map(l => makeLabelField("out", l, allLabels))
- }
+ lazy val labelFields: List[Field[GraphRepository, Any]] =
+ (labelReserved ++ labelProps).map { case (k, v) => makePropField(k, v) }
- makeServiceColumnFields(column) ++ linked
- })
+ lazy val labelPropField = wrapField(s"Label_${label.label}_props", "props", labelFields)
- lazy val toField: Field[GraphRepository, Any] = Field(column.columnName, toType, resolve = c => {
- val vertex = if (dir == "out") {
- c.value.asInstanceOf[S2EdgeLike].tgtVertex
- } else {
- c.value.asInstanceOf[S2EdgeLike].srcVertex
- }
+ lazy val labelColumnType = ObjectType(s"Label_${label.label}_${column.columnName}",
+ () => makeServiceColumnFields(column, allLabels)
+ )
- fillPartialVertex(vertex, column, c)
+ lazy val serviceColumnField: Field[GraphRepository, Any] = Field(column.columnName, labelColumnType, resolve = c => {
+ implicit val ec = c.ctx.ec
+ val (vertex, canSkipFetchVertex) = Unmarshaller.serviceColumnFieldOnLabel(column, c)
+
+ if (canSkipFetchVertex) Future.successful(vertex)
+ else c.ctx.getVertices(Seq(vertex)).map(_.head) // fill props
})
lazy val EdgeType = ObjectType(
s"Label_${label.label}_${column.columnName}_${dir}",
- () => fields[GraphRepository, Any](List(toField) ++ edgeFields: _*)
+ () => fields[GraphRepository, Any](
+ List(serviceColumnField, labelPropField) ++ labelFields.filterNot(_.name == column.columnName): _*)
)
+ val dirArgs = dir match {
+ case "in" => Argument("direction", OptionInputType(InDirectionType), "desc here", defaultValue = "in") :: Nil
+ case "out" => Argument("direction", OptionInputType(OutDirectionType), "desc here", defaultValue = "out") :: Nil
+ case "both" => Argument("direction", OptionInputType(BothDirectionType), "desc here", defaultValue = "out") :: Nil
+ }
+
lazy val edgeTypeField: Field[GraphRepository, Any] = Field(
s"${label.label}",
ListType(EdgeType),
- arguments = Argument("direction", OptionInputType(DirectionType), "desc here", defaultValue = "out") :: Nil,
+ arguments = dirArgs,
description = Some("fetch edges"),
resolve = { c =>
- val vertex: S2VertexLike = c.value match {
- case v: S2VertexLike => v
- case _ => throw new IllegalArgumentException(s"ERROR: ${c.value.getClass}")
- }
-
+ val (vertex, dir) = Unmarshaller.labelField(c)
c.ctx.getEdges(vertex, label, dir)
}
)
@@ -249,6 +221,7 @@ object S2Type {
class S2Type(repo: GraphRepository) {
import S2Type._
+ import org.apache.s2graph.graphql.bind.Unmarshaller._
implicit val graphRepository = repo
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
deleted file mode 100644
index 723392c..0000000
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
+++ /dev/null
@@ -1,76 +0,0 @@
-///*
-// * Licensed to the Apache Software Foundation (ASF) under one
-// * or more contributor license agreements. See the NOTICE file
-// * distributed with this work for additional information
-// * regarding copyright ownership. The ASF licenses this file
-// * to you 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.s2graph.graphql.types
-//
-//import sangria.ast._
-//import sangria.validation.ValueCoercionViolation
-//
-//// https://gist.github.com/OlegIlyenko/5b96f4b54f656aac226d3c4bc33fd2a6
-//
-//object PlayJsonPolyType {
-//
-// import play.api.libs.json._
-// import sangria.ast
-// import sangria.schema._
-//
-// case object JsonCoercionViolation extends ValueCoercionViolation("Not valid JSON")
-//
-// def scalarTypeToJsValue(v: sangria.ast.Value): JsValue = v match {
-// case v: IntValue => JsNumber(v.value)
-// case v: BigIntValue => JsNumber(BigDecimal(v.value.bigInteger))
-// case v: FloatValue => JsNumber(v.value)
-// case v: BigDecimalValue => JsNumber(v.value)
-// case v: StringValue => JsString(v.value)
-// case v: BooleanValue => JsBoolean(v.value)
-// case v: ListValue => JsNull
-// case v: VariableValue => JsNull
-// case v: NullValue => JsNull
-// case v: ObjectValue => JsNull
-// case _ => throw new RuntimeException("Error!")
-// }
-//
-// implicit val PolyType = ScalarType[JsValue]("Poly",
-// description = Some("Type Poly = String | Number | Boolean"),
-// coerceOutput = (value, _) ⇒ value match {
-// case JsString(s) => s
-// case JsNumber(n) => n
-// case JsBoolean(b) => b
-// case JsNull => null
-// case _ => value
-// },
-// coerceUserInput = {
-// case v: String => Right(JsString(v))
-// case v: Boolean => Right(JsBoolean(v))
-// case v: Int => Right(JsNumber(v))
-// case v: Long => Right(JsNumber(v))
-// case v: Float => Right(JsNumber(v.toDouble))
-// case v: Double => Right(JsNumber(v))
-// case v: BigInt => Right(JsNumber(BigDecimal(v)))
-// case v: BigDecimal => Right(JsNumber(v))
-// case _ => Left(JsonCoercionViolation)
-// },
-// coerceInput = {
-// case value: ast.StringValue => Right(JsString(value.value))
-// case value: ast.IntValue => Right(JsNumber(value.value))
-// case value: ast.FloatValue => Right(JsNumber(value.value))
-// case value: ast.BigIntValue => Right(JsNumber(BigDecimal(value.value.bigInteger)))
-// case _ => Left(JsonCoercionViolation)
-// })
-//}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
index 6fa1bd1..27b0c50 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.s2graph.graphql
+package org.apache.s2graph.graphql.types
import org.apache.s2graph.graphql.repository.GraphRepository
import org.apache.s2graph.graphql.types._
@@ -33,7 +33,7 @@ class SchemaDef(g: GraphRepository) {
import sangria.schema._
val s2Type = new S2Type(g)
- val s2ManagementType = new S2ManagementType(g)
+ val s2ManagementType = new ManagementType(g)
val queryManagementFields = List(wrapField("QueryManagement", "Management", s2ManagementType.queryFields))
val S2QueryType = ObjectType[GraphRepository, Any](
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/StaticType.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/StaticType.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/StaticType.scala
new file mode 100644
index 0000000..aca832c
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/StaticType.scala
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.s2graph.graphql.types
+
+import org.apache.s2graph.core.Management.JsonModel._
+import org.apache.s2graph.core.{JSONParser, S2EdgeLike, S2VertexLike}
+import org.apache.s2graph.core.mysqls._
+import org.apache.s2graph.core.storage.MutateResponse
+import org.apache.s2graph.graphql.repository.GraphRepository
+import sangria.macros.derive._
+import sangria.schema._
+
+import scala.util.{Failure, Random, Success, Try}
+
+object StaticTypes {
+ val MutateResponseType = deriveObjectType[GraphRepository, MutateResponse](
+ ObjectTypeName("MutateGraphElement"),
+ ObjectTypeDescription("desc here"),
+ AddFields(
+ Field("isSuccess", BooleanType, resolve = c => c.value.isSuccess)
+ )
+ )
+
+ val DataTypeType = EnumType(
+ "Enum_DataType",
+ description = Option("desc here"),
+ values = List(
+ EnumValue("string", value = "string"),
+ EnumValue("int", value = "int"),
+ EnumValue("long", value = "long"),
+ EnumValue("double", value = "double"),
+ EnumValue("boolean", value = "boolean")
+ )
+ )
+
+ val InDirectionType = EnumType(
+ "Enum_Direction_In",
+ description = Option("desc here"),
+ values = List(
+ EnumValue("in", value = "in")
+ )
+ )
+
+ val OutDirectionType = EnumType(
+ "Enum_Direction_Out",
+ description = Option("desc here"),
+ values = List(
+ EnumValue("out", value = "out")
+ )
+ )
+ val BothDirectionType = EnumType(
+ "Enum_Direction_Both",
+ description = Option("desc here"),
+ values = List(
+ EnumValue("out", value = "out"),
+ EnumValue("in", value = "in")
+ )
+ )
+
+ val LabelMetaType = deriveObjectType[GraphRepository, LabelMeta](
+ ObjectTypeName("LabelMeta"),
+ ExcludeFields("seq", "labelId")
+ )
+
+ val ColumnMetaType = deriveObjectType[GraphRepository, ColumnMeta](
+ ObjectTypeName("ColumnMeta"),
+ ExcludeFields("seq", "columnId")
+ )
+
+ val InputIndexType = InputObjectType[Index](
+ "Input_Index",
+ description = "desc here",
+ fields = List(
+ InputField("name", StringType),
+ InputField("propNames", ListInputType(StringType))
+ )
+ )
+
+ val InputPropType = InputObjectType[Prop](
+ "Input_Prop",
+ description = "desc here",
+ fields = List(
+ InputField("name", StringType),
+ InputField("dataType", DataTypeType),
+ InputField("defaultValue", StringType),
+ InputField("storeInGlobalIndex", BooleanType)
+ )
+ )
+
+ val CompressionAlgorithmType = EnumType(
+ "Enum_CompressionAlgorithm",
+ description = Option("desc here"),
+ values = List(
+ EnumValue("gz", description = Option("desc here"), value = "gz"),
+ EnumValue("lz4", description = Option("desc here"), value = "lz4")
+ )
+ )
+
+ val ConsistencyLevelType = EnumType(
+ "Enum_Consistency",
+ description = Option("desc here"),
+ values = List(
+ EnumValue("weak", description = Option("desc here"), value = "weak"),
+ EnumValue("strong", description = Option("desc here"), value = "strong")
+ )
+ )
+
+ val LabelIndexType = deriveObjectType[GraphRepository, LabelIndex](
+ ObjectTypeName("LabelIndex"),
+ ObjectTypeDescription("desc here"),
+ ExcludeFields("seq", "metaSeqs", "formulars", "labelId")
+ )
+
+ val LabelType = deriveObjectType[GraphRepository, Label](
+ ObjectTypeName("Label"),
+ ObjectTypeDescription("desc here"),
+ AddFields(
+ Field("indices", ListType(LabelIndexType), resolve = c => c.value.indices),
+ Field("props", ListType(LabelMetaType), resolve = c => c.value.labelMetas)
+ ),
+ RenameField("label", "name")
+ )
+
+ val DummyInputField = InputField("_", OptionInputType(LongType))
+
+ val DummyObjectTypeField: Field[GraphRepository, Any] = Field(
+ "_",
+ OptionType(LongType),
+ description = Some("dummy field"),
+ resolve = _ => None
+ )
+}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
index 754f377..2b648e2 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
@@ -1,43 +1,16 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.s2graph.graphql
-import org.apache.s2graph.core.Management.JsonModel._
-import org.apache.s2graph.core.{JSONParser, S2EdgeLike, S2VertexLike}
-import org.apache.s2graph.core.mysqls._
-import org.apache.s2graph.core.storage.MutateResponse
import org.apache.s2graph.graphql.repository.GraphRepository
-import sangria.macros.derive._
import sangria.schema._
-import scala.util.{Failure, Random, Success, Try}
-
package object types {
- def wrapField(objectName: String, fieldName: String, fields: List[Field[GraphRepository, Any]]): Field[GraphRepository, Any] = {
- val ManagementType = ObjectType(objectName, fields = fields)
- val f: Field[GraphRepository, Any] = Field(fieldName, ManagementType, resolve = c => c.value)
- f
+ def wrapField(objectName: String, fieldName: String, fields: Seq[Field[GraphRepository, Any]]): Field[GraphRepository, Any] = {
+ val tpe = ObjectType(objectName, fields = fields.toList)
+ Field(fieldName, tpe, resolve = c => c.value): Field[GraphRepository, Any]
}
- def s2TypeToScalarType(from: String): ScalarType[_] = from match {
+ def toScalarType(from: String): ScalarType[_] = from match {
case "string" => StringType
case "int" => IntType
case "integer" => IntType
@@ -47,106 +20,4 @@ package object types {
case "boolean" => BooleanType
case "bool" => BooleanType
}
-
- val MutateResponseType = deriveObjectType[GraphRepository, MutateResponse](
- ObjectTypeName("MutateGraphElement"),
- ObjectTypeDescription("desc here"),
- AddFields(
- Field("isSuccess", BooleanType, resolve = c => c.value.isSuccess)
- )
- )
-
- val DataTypeType = EnumType(
- "Enum_DataType",
- description = Option("desc here"),
- values = List(
- EnumValue("string", value = "string"),
- EnumValue("int", value = "int"),
- EnumValue("long", value = "long"),
- EnumValue("double", value = "double"),
- EnumValue("boolean", value = "boolean")
- )
- )
-
- val DirectionType = EnumType(
- "Enum_Direction",
- description = Option("desc here"),
- values = List(
- EnumValue("out", value = "out"),
- EnumValue("in", value = "in")
- )
- )
-
- val LabelMetaType = deriveObjectType[GraphRepository, LabelMeta](
- ObjectTypeName("LabelMeta"),
- ExcludeFields("seq", "labelId")
- )
-
- val ColumnMetaType = deriveObjectType[GraphRepository, ColumnMeta](
- ObjectTypeName("ColumnMeta"),
- ExcludeFields("seq", "columnId")
- )
-
- val InputIndexType = InputObjectType[Index](
- "Input_Index",
- description = "desc here",
- fields = List(
- InputField("name", StringType),
- InputField("propNames", ListInputType(StringType))
- )
- )
-
- val InputPropType = InputObjectType[Prop](
- "Input_Prop",
- description = "desc here",
- fields = List(
- InputField("name", StringType),
- InputField("dataType", DataTypeType),
- InputField("defaultValue", StringType),
- InputField("storeInGlobalIndex", BooleanType)
- )
- )
-
- val CompressionAlgorithmType = EnumType(
- "Enum_CompressionAlgorithm",
- description = Option("desc here"),
- values = List(
- EnumValue("gz", description = Option("desc here"), value = "gz"),
- EnumValue("lz4", description = Option("desc here"), value = "lz4")
- )
- )
-
- val ConsistencyLevelType = EnumType(
- "Enum_Consistency",
- description = Option("desc here"),
- values = List(
- EnumValue("weak", description = Option("desc here"), value = "weak"),
- EnumValue("strong", description = Option("desc here"), value = "strong")
- )
- )
-
- val LabelIndexType = deriveObjectType[GraphRepository, LabelIndex](
- ObjectTypeName("LabelIndex"),
- ObjectTypeDescription("desc here"),
- ExcludeFields("seq", "metaSeqs", "formulars", "labelId")
- )
-
- val LabelType = deriveObjectType[GraphRepository, Label](
- ObjectTypeName("Label"),
- ObjectTypeDescription("desc here"),
- AddFields(
- Field("indices", ListType(LabelIndexType), resolve = c => c.value.indices),
- Field("props", ListType(LabelMetaType), resolve = c => c.value.labelMetas)
- ),
- RenameField("label", "name")
- )
-
- val DummyInputField = InputField("_", OptionInputType(LongType))
-
- val DummyObjectTypeField: Field[GraphRepository, Any] = Field(
- "_",
- OptionType(LongType),
- description = Some("dummy field"),
- resolve = _ => None
- )
}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/test/scala/org/apache/s2graph/graphql/ScenarioTest.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/test/scala/org/apache/s2graph/graphql/ScenarioTest.scala b/s2graphql/src/test/scala/org/apache/s2graph/graphql/ScenarioTest.scala
index 8cbff19..81bf884 100644
--- a/s2graphql/src/test/scala/org/apache/s2graph/graphql/ScenarioTest.scala
+++ b/s2graphql/src/test/scala/org/apache/s2graph/graphql/ScenarioTest.scala
@@ -179,7 +179,7 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
query {
Management {
- Service(name: kakao) {
+ Services(name: kakao) {
name
serviceColumns {
name
@@ -200,7 +200,7 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
{
"data": {
"Management": {
- "Service": {
+ "Services": [{
"name": "kakao",
"serviceColumns": [{
"name": "user",
@@ -209,7 +209,7 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
{ "name": "gender", "dataType": "string" }
]
}]
- }
+ }]
}
}
}
@@ -307,7 +307,7 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
query {
Management {
- Label(name: friends) {
+ Labels(name: friends) {
name
props {
name
@@ -325,13 +325,13 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
{
"data": {
"Management": {
- "Label": {
+ "Labels": [{
"name": "friends",
"props": [{
"name": "score",
"dataType": "double"
}]
- }
+ }]
}
}
}
@@ -392,6 +392,9 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
id
age
gender
+ props {
+ age
+ }
}
}
}
@@ -406,11 +409,17 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
"user": [{
"id": "daewon",
"age": 20,
- "gender": "M"
+ "gender": "M",
+ "props": {
+ "age": 20
+ }
}, {
"id": "shon",
"age": 19,
- "gender": "F"
+ "gender": "F",
+ "props": {
+ "age": 19
+ }
}]
}
}
@@ -464,13 +473,16 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
kakao {
user(id: "daewon") {
id
- friends {
- score
- to {
+ friends(direction: out) {
+ props {
+ score
+ }
+ score # shorcut score props
+ user {
id
age
friends(direction: in) {
- to {
+ user {
id
age
}
@@ -492,12 +504,15 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
"user" : [ {
"id" : "daewon",
"friends" : [ {
+ "props" : {
+ "score" : 0.9
+ },
"score" : 0.9,
- "to" : {
+ "user" : {
"id" : "shon",
"age" : 19,
"friends" : [ {
- "to" : {
+ "user" : {
"id" : "daewon",
"age" : 20
},
@@ -564,14 +579,13 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
query {
Management {
- Label(name: friends) {
+ Labels(name: friends) {
name
props {
name
dataType
}
}
-
}
}
"""
@@ -586,7 +600,7 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
query {
Management {
- Service(name: kakao) {
+ Services(name: kakao) {
serviceColumns {
name
}
@@ -602,9 +616,9 @@ class ScenarioTest extends FunSpec with Matchers with BeforeAndAfterAll {
{
"data": {
"Management": {
- "Service": {
+ "Services": [{
"serviceColumns": []
- }
+ }]
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala b/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
index fdedfe9..8b2b3fe 100644
--- a/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
+++ b/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
@@ -69,7 +69,7 @@ class SchemaTest extends FunSuite with Matchers with BeforeAndAfterAll {
Map("name" -> "Enum_CompressionAlgorithm"),
Map("name" -> "Enum_Consistency"),
Map("name" -> "Enum_DataType"),
- Map("name" -> "Enum_Direction"),
+ Map("name" -> "Enum_Direction_Both"),
Map("name" -> "Enum_Service"),
Map("name" -> "Enum_Label"),
Map("name" -> "Enum_kakao_ServiceColumn"),
@@ -102,14 +102,16 @@ class SchemaTest extends FunSuite with Matchers with BeforeAndAfterAll {
Map("name" -> "Input_kakao_ServiceColumn_Props"),
Map("name" -> "Input_kakao_ServiceColumn"),
- Map("name" -> "Input_kakao_user"),
Map("name" -> "Input_kakao_user_vertex_mutate"),
Map("name" -> "Service_kakao"),
- Map("name" -> "Label_friends"),
- Map("name" -> "Label_friends_from"),
- Map("name" -> "Label_friends_to"),
+ Map("name" -> "Label_friends_user"),
+ Map("name" -> "Label_friends_user_both"),
+
+ Map("name" -> "ServiceColumn_kakao_user_props"),
+ Map("name" -> "ServiceColumn_kakao_user"),
+ Map("name" -> "Label_friends_props"),
// root object type
Map("name" -> "Query"),
http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/da15232c/s2graphql/src/test/scala/org/apache/s2graph/graphql/TestGraph.scala
----------------------------------------------------------------------
diff --git a/s2graphql/src/test/scala/org/apache/s2graph/graphql/TestGraph.scala b/s2graphql/src/test/scala/org/apache/s2graph/graphql/TestGraph.scala
index 8b3c0ae..46db9fc 100644
--- a/s2graphql/src/test/scala/org/apache/s2graph/graphql/TestGraph.scala
+++ b/s2graphql/src/test/scala/org/apache/s2graph/graphql/TestGraph.scala
@@ -25,6 +25,7 @@ import org.apache.s2graph.core.mysqls.{Label, Model, Service}
import org.apache.s2graph.core.rest.RequestParser
import org.apache.s2graph.core.{Management, S2Graph}
import org.apache.s2graph.graphql.repository.GraphRepository
+import org.apache.s2graph.graphql.types.SchemaDef
import play.api.libs.json._
import sangria.ast.Document
import sangria.execution.Executor