All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.opencypher.spark.schema.CAPSSchema.scala Maven / Gradle / Ivy
/*
* Copyright (c) 2016-2018 "Neo4j, Inc." [https://neo4j.com]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opencypher.spark.schema
import org.opencypher.okapi.api.schema.PropertyKeys.PropertyKeys
import org.opencypher.okapi.api.schema.{LabelPropertyMap, RelTypePropertyMap, Schema}
import org.opencypher.okapi.api.types.{CTRelationship, CypherType}
import org.opencypher.okapi.impl.exception.SchemaException
import org.opencypher.okapi.impl.schema.SchemaUtils._
import org.opencypher.okapi.impl.schema.{ImpliedLabels, LabelCombinations}
import org.opencypher.spark.impl.convert.CAPSCypherType._
object CAPSSchema {
val empty: CAPSSchema = Schema.empty.asCaps
implicit class CAPSSchemaConverter(schema: Schema) {
/**
* Converts a given schema into a CAPS specific schema. The conversion fails if the schema specifies property types
* that cannot be represented in CAPS and throws a [[org.opencypher.okapi.impl.exception.SchemaException]].
*/
def asCaps: CAPSSchema = {
schema match {
case s: CAPSSchema => s
case _ =>
val combosByLabel = schema.foldAndProduce(Map.empty[String, Set[Set[String]]])(
(set, combos, _) => set + combos,
(combos, _) => Set(combos))
combosByLabel.foreach {
case (_, combos) =>
val keysForAllCombosOfLabel = combos.map(combo => combo -> schema.nodeKeys(combo))
for {
(combo1, keys1) <- keysForAllCombosOfLabel
(combo2, keys2) <- keysForAllCombosOfLabel
} yield {
(keys1.keySet intersect keys2.keySet).foreach { k =>
val t1 = keys1(k)
val t2 = keys2(k)
val join = t1.join(t2)
if (!join.isSparkCompatible) {
val explanation = if (combo1 == combo2) {
s"The unsupported type is specified on label combination ${combo1.mkString("[", ", ", "]")}."
} else {
s"The conflict appears between label combinations ${combo1.mkString("[", ", ", "]")} and ${combo2.mkString("[", ", ", "]")}."
}
throw SchemaException(s"The property type '$join' for property '$k' can not be stored in a Spark column. " + explanation)
}
}
}
}
new CAPSSchema(schema)
}
}
}
}
case class CAPSSchema private[schema](schema: Schema) extends Schema {
override def labels: Set[String] = schema.labels
override def relationshipTypes: Set[String] = schema.relationshipTypes
override def labelPropertyMap: LabelPropertyMap = schema.labelPropertyMap
override def relTypePropertyMap: RelTypePropertyMap = schema.relTypePropertyMap
override def impliedLabels: ImpliedLabels = schema.impliedLabels
override def labelCombinations: LabelCombinations = schema.labelCombinations
override def impliedLabels(knownLabels: Set[String]): Set[String] = schema.impliedLabels(knownLabels)
override def nodeKeys(labels: Set[String]): PropertyKeys = schema.nodeKeys(labels)
override def allNodeKeys: PropertyKeys = schema.allNodeKeys
override def allLabelCombinations: Set[Set[String]] = schema.allLabelCombinations
override def combinationsFor(knownLabels: Set[String]): Set[Set[String]] = schema.combinationsFor(knownLabels)
override def nodeKeyType(labels: Set[String], key: String): Option[CypherType] = schema.nodeKeyType(labels, key)
override def keysFor(labelCombinations: Set[Set[String]]): PropertyKeys = schema.keysFor(labelCombinations)
override def relationshipKeyType(types: Set[String], key: String): Option[CypherType] = schema.relationshipKeyType(types, key)
override def relationshipKeys(typ: String): PropertyKeys = schema.relationshipKeys(typ)
override def withNodePropertyKeys(nodeLabels: Set[String], keys: PropertyKeys): Schema = schema.withNodePropertyKeys(nodeLabels, keys)
override def withRelationshipPropertyKeys(typ: String, keys: PropertyKeys): Schema = schema.withRelationshipPropertyKeys(typ, keys)
override def ++(other: Schema): Schema = schema ++ other
override def fromNodeEntity(labels: Set[String]): Schema = schema.fromNodeEntity(labels)
override def pretty: String = schema.pretty
override def isEmpty: Boolean = schema.isEmpty
override def forNodeScan(labelConstraints: Set[String]): Schema = schema.forNodeScan(labelConstraints)
override def forRelationship(relType: CTRelationship): Schema = schema.forRelationship(relType)
}