Repository: incubator-s2graph
Updated Branches:
  refs/heads/master bb9738f26 -> a4059dfe0


http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/bab13a32/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
new file mode 100644
index 0000000..478d37e
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
@@ -0,0 +1,328 @@
+/*
+ * 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.{Index, Prop}
+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 org.apache.s2graph.graphql.types.S2ManagementType._
+import play.api.libs.json.JsValue
+import sangria.marshalling.{CoercedScalaResultMarshaller, FromInput}
+import sangria.schema._
+
+import scala.language.existentials
+import scala.util.{Failure, Success, Try}
+import org.apache.s2graph.graphql.marshaller._
+
+object S2Type {
+
+  case class PartialServiceParam(service: Service,
+                                 vid: Any)
+
+  case class PartialVertexParam(ts: Long,
+                                id: Any,
+                                props: Map[String, Any])
+
+  case class PartialServiceVertexParam(columnName: String,
+                                       vertexParam: PartialVertexParam)
+
+  case class PartialEdgeParam(ts: Long,
+                              from: Any,
+                              to: Any,
+                              direction: String,
+                              props: Map[String, Any])
+
+  val DirArg = Argument("direction", OptionInputType(DirectionType), "desc 
here", defaultValue = "out")
+
+  def makePropFields(fieldNameWithTypes: List[(String, String)]): 
List[Field[GraphRepository, Any]] = {
+    def makeField[A](name: String, cType: String, tpe: ScalarType[A]): 
Field[GraphRepository, Any] =
+      Field(name,
+        OptionType(tpe),
+        description = Option("desc here"),
+        resolve = _.value match {
+          case v: S2VertexLike =>
+            name match {
+              case "timestamp" => v.ts.asInstanceOf[A]
+              case _ =>
+                val innerVal = v.propertyValue(name).get
+                JSONParser.innerValToAny(innerVal, cType).asInstanceOf[A]
+            }
+
+          case e: S2EdgeLike =>
+            name match {
+              case "timestamp" => e.ts.asInstanceOf[A]
+              case _ =>
+                val innerVal = e.propertyValue(name).get.innerVal
+                JSONParser.innerValToAny(innerVal, cType).asInstanceOf[A]
+            }
+
+          case _ => throw new RuntimeException("Error !!!!")
+        })
+
+    fieldNameWithTypes.map { case (cName, cType) =>
+      cType match {
+        case "boolean" | "bool" => makeField[Boolean](cName, cType, 
BooleanType)
+        case "string" | "str" | "s" => makeField[String](cName, cType, 
StringType)
+        case "int" | "integer" | "i" | "int32" | "integer32" => 
makeField[Int](cName, cType, IntType)
+        case "long" | "l" | "int64" | "integer64" => makeField[Long](cName, 
cType, LongType)
+        case "double" | "d" | "float64" | "float" | "f" | "float32" => 
makeField[Double](cName, cType, FloatType)
+        case _ => throw new RuntimeException(s"Cannot support data type: 
${cType}")
+      }
+    }
+  }
+
+  def makeInputPartialVertexParamType(service: Service,
+                                      serviceColumn: ServiceColumn): 
InputObjectType[PartialVertexParam] = {
+    lazy val InputPropsType = InputObjectType[Map[String, ScalarType[_]]](
+      s"${service.serviceName}_${serviceColumn.columnName}_props",
+      description = "desc here",
+      () => serviceColumn.metas.filter(ColumnMeta.isValid).map { lm =>
+        InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
+      }
+    )
+
+    lazy val fields = List(
+      InputField("_", OptionInputType(LongType))
+    )
+
+    InputObjectType[PartialVertexParam](
+      s"${service.serviceName}_on_${serviceColumn.columnName}_mutate",
+      description = "desc here",
+      () =>
+        if (!serviceColumn.metas.exists(ColumnMeta.isValid)) fields
+        else List(InputField("props", OptionInputType(InputPropsType)))
+    )
+  }
+
+  def makeInputPartialEdgeParamType(label: Label): 
InputObjectType[PartialEdgeParam] = {
+    lazy val InputPropsType = InputObjectType[Map[String, ScalarType[_]]](
+      s"${label.label}_props",
+      description = "desc here",
+      () => label.labelMetaSet.toList.map { lm =>
+        InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
+      }
+    )
+
+    lazy val labelFields = List(
+      InputField("timestamp", OptionInputType(LongType)),
+      InputField("from", s2TypeToScalarType(label.srcColumnType)),
+      InputField("to", s2TypeToScalarType(label.srcColumnType)),
+      InputField("direction", OptionInputType(DirectionType))
+    )
+
+    InputObjectType[PartialEdgeParam](
+      s"${label.label}_mutate",
+      description = "desc here",
+      () =>
+        if (label.labelMetaSet.isEmpty) labelFields
+        else labelFields ++ Seq(InputField("props", 
OptionInputType(InputPropsType)))
+    )
+  }
+
+  def makeServiceField(service: Service, allLabels: List[Label])(implicit 
repo: GraphRepository): List[Field[GraphRepository, Any]] = {
+    lazy val columnsOnService = service.serviceColumns(false).toList.map { 
column =>
+      val connectedLabels = allLabels.filter { lb =>
+        column.id.get == lb.srcColumn.id.get || column.id.get == 
lb.tgtColumn.id.get
+      }.distinct
+
+      lazy val connectedLabelFields: List[Field[GraphRepository, Any]] = 
connectedLabels.map(makeLabelField(_, connectedLabelFields))
+      val columnMetasKv = column.metas.filter(ColumnMeta.isValid).map { 
columnMeta => columnMeta.name -> columnMeta.dataType }
+      val reservedFields = List("id" -> column.columnType, "timestamp" -> 
"long")
+
+      val vertexPropFields = makePropFields(reservedFields ++ columnMetasKv)
+      lazy val LabelType = ObjectType(
+        s"${service.serviceName}_${column.columnName}",
+        () => fields[GraphRepository, Any](vertexPropFields ++ 
connectedLabelFields: _*)
+      )
+
+      Field(column.columnName,
+        ListType(LabelType),
+        arguments = List(
+          Argument("id", 
OptionInputType(s2TypeToScalarType(column.columnType))),
+          Argument("ids", 
OptionInputType(ListInputType(s2TypeToScalarType(column.columnType)))),
+          Argument("search", OptionInputType(StringType))
+        ),
+        description = Option("desc here"),
+        resolve = c => {
+          println(c.parentType.name)
+          c.astFields.foreach { f =>
+            f.selections.foreach(s => {
+              println(s)
+            })
+          }
+          val id = c.argOpt[Any]("id").toSeq
+          val ids = c.argOpt[List[Any]]("ids").toList.flatten
+          val svc = c.ctx.findServiceByName(service.serviceName).get
+
+          val vids = (id ++ ids).map { vid =>
+            val vp = PartialServiceParam(svc, vid)
+            c.ctx.partialServiceParamToVertex(column, vp)
+          }
+
+          repo.getVertex(vids.head)
+        }
+      ): Field[GraphRepository, Any]
+    }
+
+    columnsOnService
+  }
+
+  def makeLabelField(label: Label, connectedLabelFields: => 
List[Field[GraphRepository, Any]]): Field[GraphRepository, Any] = {
+    val labelColumns = List("from" -> label.srcColumnType, "to" -> 
label.tgtColumnType, "timestamp" -> "long")
+    val labelProps = label.labelMetas.map { lm => lm.name -> lm.dataType }
+
+    lazy val EdgeType = ObjectType(label.label, () => fields[GraphRepository, 
Any](edgeFields ++ connectedLabelFields: _*))
+    lazy val edgeFields: List[Field[GraphRepository, Any]] = 
makePropFields(labelColumns ++ labelProps)
+    lazy val edgeTypeField: Field[GraphRepository, Any] = Field(
+      label.label,
+      ListType(EdgeType),
+      arguments = DirArg :: Nil,
+      description = Some("edges"),
+      resolve = { c =>
+        val dir = c.argOpt("direction").getOrElse("out")
+
+        val vertex: S2VertexLike = c.value match {
+          case v: S2VertexLike => v
+          case e: S2Edge => if (dir == "out") e.tgtVertex else e.srcVertex
+          case vp: PartialServiceParam =>
+            if (dir == "out") 
c.ctx.partialServiceParamToVertex(label.tgtColumn, vp)
+            else c.ctx.partialServiceParamToVertex(label.srcColumn, vp)
+        }
+
+        c.ctx.getEdges(vertex, label, dir)
+      }
+    )
+
+    edgeTypeField
+  }
+
+}
+
+class S2Type(repo: GraphRepository) {
+
+  import S2Type._
+
+  implicit val graphRepository = repo
+
+  /**
+    * fields
+    */
+  lazy val serviceFields: List[Field[GraphRepository, Any]] = 
repo.allServices.map { service =>
+    lazy val serviceFields = paddingDummyField(makeServiceField(service, 
repo.allLabels))
+    lazy val ServiceType = ObjectType(
+      service.serviceName,
+      fields[GraphRepository, Any](serviceFields: _*)
+    )
+
+    Field(
+      service.serviceName,
+      ServiceType,
+      description = Some(s"serviceName: ${service.serviceName}"),
+      resolve = _ => service
+    ): Field[GraphRepository, Any]
+  }
+
+  /**
+    * arguments
+    */
+  lazy val addVertexArg = repo.allServices.map { service =>
+    val columnFields = service.serviceColumns(false).map { serviceColumn =>
+
+      val columnMetas = serviceColumn.metas.filter(ColumnMeta.isValid).map { 
lm =>
+        InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
+      }
+
+      lazy val InputPropsType = InputObjectType[Map[String, ScalarType[_]]](
+        s"${service.serviceName}_${serviceColumn.columnName}_props",
+        description = "desc here",
+        () => if (columnMetas.isEmpty) List(DummyInputField) else 
columnMetas.toList
+      )
+
+      val tpe = InputObjectType[PartialServiceVertexParam](
+        serviceColumn.columnName,
+        fields = List(
+          InputField("id", s2TypeToScalarType(serviceColumn.columnType)),
+          InputField("timestamp", OptionInputType(LongType)),
+          InputField("props", OptionInputType(InputPropsType))
+        )
+      )
+
+      InputField(serviceColumn.columnName, OptionInputType(tpe))
+    }
+
+    val vertexParamType = InputObjectType[Vector[PartialServiceVertexParam]](
+      s"${service.serviceName}_column",
+      description = "desc here",
+      fields = if (columnFields.isEmpty) List(DummyInputField) else 
columnFields.toList
+    )
+
+    Argument(service.serviceName, OptionInputType(vertexParamType))
+  }
+
+  lazy val addVerticesArg = repo.allServices.flatMap { service =>
+    service.serviceColumns(false).map { serviceColumn =>
+      val inputPartialVertexParamType = 
makeInputPartialVertexParamType(service, serviceColumn)
+      Argument(serviceColumn.columnName, 
OptionInputType(ListInputType(inputPartialVertexParamType)))
+    }
+  }
+
+  lazy val addEdgeArg = repo.allLabels.map { label =>
+    val inputPartialEdgeParamType = makeInputPartialEdgeParamType(label)
+    Argument(label.label, OptionInputType(inputPartialEdgeParamType))
+  }
+
+  lazy val addEdgesArg = repo.allLabels.map { label =>
+    val inputPartialEdgeParamType = makeInputPartialEdgeParamType(label)
+    Argument(label.label, 
OptionInputType(ListInputType(inputPartialEdgeParamType)))
+  }
+
+  /**
+    * Query fields
+    * Provide s2graph query / mutate API
+    * - Fields is created(or changed) for metadata is changed.
+    */
+  lazy val queryFields = serviceFields
+
+  lazy val mutationFields: List[Field[GraphRepository, Any]] = List(
+    Field("addVertex",
+      OptionType(MutateResponseType),
+      arguments = addVertexArg,
+      resolve = c => c.ctx.addVertex(c.args)
+    ),
+    Field("addVertices",
+      ListType(MutateResponseType),
+      arguments = addVerticesArg,
+      resolve = c => c.ctx.addVertices(c.args)
+    ),
+    Field("addEdge",
+      OptionType(MutateResponseType),
+      arguments = addEdgeArg,
+      resolve = c => c.ctx.addEdge(c.args)
+    ),
+    Field("addEdges",
+      ListType(MutateResponseType),
+      arguments = addEdgesArg,
+      resolve = c => c.ctx.addEdges(c.args)
+    )
+  )
+}

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/bab13a32/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
new file mode 100644
index 0000000..dcb3621
--- /dev/null
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
@@ -0,0 +1,76 @@
+/*
+ * 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/bab13a32/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
new file mode 100644
index 0000000..6fa1bd1
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SchemaDef.scala
@@ -0,0 +1,51 @@
+/*
+ * 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.graphql.repository.GraphRepository
+import org.apache.s2graph.graphql.types._
+
+
+/**
+  * S2Graph GraphQL schema.
+  *
+  * When a Label or Service is created, the GraphQL schema is created 
dynamically.
+  */
+class SchemaDef(g: GraphRepository) {
+
+  import sangria.schema._
+
+  val s2Type = new S2Type(g)
+  val s2ManagementType = new S2ManagementType(g)
+
+  val queryManagementFields = List(wrapField("QueryManagement", "Management", 
s2ManagementType.queryFields))
+  val S2QueryType = ObjectType[GraphRepository, Any](
+    "Query",
+    fields(s2Type.queryFields ++ queryManagementFields: _*)
+  )
+
+  val mutateManagementFields = List(wrapField("MutationManagement", 
"Management", s2ManagementType.mutationFields))
+  val S2MutationType = ObjectType[GraphRepository, Any](
+    "Mutation",
+    fields(s2Type.mutationFields ++ mutateManagementFields: _*)
+  )
+
+  val S2GraphSchema = Schema(S2QueryType, Option(S2MutationType))
+}

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/bab13a32/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
new file mode 100644
index 0000000..46b3114
--- /dev/null
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
@@ -0,0 +1,156 @@
+/*
+ * 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 org.apache.s2graph.graphql.types.S2Type.PartialServiceParam
+import sangria.macros.derive._
+import sangria.schema._
+
+import scala.util.Random
+
+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 s2TypeToScalarType(from: String): ScalarType[_] = from match {
+    case "string" => StringType
+    case "int" => IntType
+    case "integer" => IntType
+    case "long" => LongType
+    case "float" => FloatType
+    case "double" => FloatType
+    case "boolean" => BooleanType
+    case "bool" => BooleanType
+  }
+
+  val MutateResponseType = deriveObjectType[GraphRepository, MutateResponse](
+    ObjectTypeName("MutateResponse"),
+    ObjectTypeDescription("desc here"),
+    AddFields(
+      Field("isSuccess", BooleanType, resolve = c => c.value.isSuccess)
+    )
+  )
+
+  val DataTypeType = EnumType(
+    "DataType",
+    description = Option("desc here"),
+    values = List(
+      EnumValue("string", value = "string"),
+      EnumValue("int", value = "int"),
+      EnumValue("long", value = "long"),
+      EnumValue("float", value = "float"),
+      EnumValue("boolean", value = "boolean")
+    )
+  )
+
+  val DirectionType = EnumType(
+    "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](
+    "Index",
+    description = "desc here",
+    fields = List(
+      InputField("name", StringType),
+      InputField("propNames", ListInputType(StringType))
+    )
+  )
+
+  val InputPropType = InputObjectType[Prop](
+    "Prop",
+    description = "desc here",
+    fields = List(
+      InputField("name", StringType),
+      InputField("dataType", DataTypeType),
+      InputField("defaultValue", StringType)
+    )
+  )
+
+  val CompressionAlgorithmType = EnumType(
+    "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(
+    "ConsistencyList",
+    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("indexes", ListType(LabelIndexType), resolve = c => Nil),
+      Field("props", ListType(LabelMetaType), resolve = c => Nil)
+    ),
+    RenameField("label", "name")
+  )
+
+  val DummyInputField = InputField("_", OptionInputType(LongType))
+
+  val DummyObjectTypeField: Field[GraphRepository, Any] = Field(
+    "_",
+    OptionType(LongType),
+    description = Some("dummy field"),
+    resolve = _ => None
+  )
+
+  def paddingDummyField(fields: List[Field[GraphRepository, Any]]): 
List[Field[GraphRepository, Any]] = {
+    if (fields.nonEmpty) fields else List(DummyObjectTypeField)
+  }
+}

Reply via email to