Generate a array of DataTypes from a Bond\Pg\Catalog\PgClass object
@param Bond\Pg\Catalog\PgRelation $relation
@return array
486713
public static function makeFromRelation( PgClass $relation )
    {

        $output = array();

        foreach( $relation->getAttributes() as $attribute ) {
            $dataType = static::makeFromAttribute( $attribute );
            $output[$dataType->name] = $dataType;
        }

        return $output;

    }
797280
private function processParentRelation(Schema\Relation $relation)
    {
        $prefixRegex = '/^'.preg_quote($this->name, '/').'\.(\d+\.)*(?P<sub>.*)/';
        if (!preg_match($prefixRegex, $relation->getLocalProperty(), $matches)) {
            return null;
        }

        $clone = clone $relation;
        $clone->setLocalProperty($matches['sub']);
        return $clone;
    }
475723
public function get(string $relation): RelationInterface
    {
        if (isset($this->relations[$relation]) && $this->relations[$relation] instanceof RelationInterface) {
            return $this->relations[$relation];
        }

        $instance = $this->orm->makeRelation($this->class, $relation);
        if (array_key_exists($relation, $this->relations)) {
            //Indicating that relation is loaded
            $instance = $instance->withContext($this->parent, true, $this->relations[$relation]);
        } else {
            //Not loaded relation
            $instance = $instance->withContext($this->parent, false);
        }

        return $this->relations[$relation] = $instance;
    }
894762
protected function nestedRelations( $relation )
	{
		$nested = [];

		// We are basically looking for any relationships that are nested deeper than
		// the given top-level relationship. We will just check for any relations
		// that start with the given top relations and adds them to our arrays.
		foreach ( $this->eagerLoad as $name => $constraints )
		{
			if ( $this->isNested( $name, $relation ) )
			{
				$nested[substr( $name, strlen( $relation . '.' ) )] = $constraints;
			}
		}

		return $nested;
	}
622037
protected function getMorphManyData($relation, $foreignKeyIds)
    {
        $relatedClass = $relation->getRelated();
        $foreignKeyUse = $relatedClass->getKeyName();
        $foreignKeyIdsUse = $relatedClass::withTrashed()->where($relation->getMorphType(), $relation->getMorphClass())
            ->whereIn($relation->getQualifiedForeignKeyName(), $foreignKeyIds)
            ->select($foreignKeyUse)
            ->get()->toArray();
        $foreignKeyIdsUse = array_column($foreignKeyIdsUse, $foreignKeyUse);

        return [
            'foreignKeyIdsUse' => collect($foreignKeyIdsUse),
            'foreignKeyUse'    => $relation->getRelated()->getKeyName(),
        ];
    }
189191
protected function joinParameters(Relation $relation)
    {
        $relatedTable = $relation->getRelated()->getTable();

        if ($relation instanceof BelongsTo) {
            $foreignKeyMethod = (app()->version() < '5.8.0') ? 'getForeignKey' : 'getForeignKeyName';

            return [
                $relatedTable,
                $relation->{$foreignKeyMethod}(),
                '=',
                $relatedTable.'.'.$relation->getRelated()->getKeyName(),
            ];
        }

        if ($relation instanceof HasOne) {
            return [
                $relatedTable,
                $relation->getQualifiedParentKeyName(),
                '=',
                $relation->getQualifiedForeignKeyName(),
            ];
        }

        throw new \Exception('Related sortable only support `HasOne` and `BelongsTo` relation.');
    }
876924
protected function getRelationCondition($relation, $value)
    {
        /** @var \yii\db\ActiveRecord $relationClass */
        $relationClass = $relation->modelClass;
        if ($relation->via !== null) {
            /* @var $viaRelation \yii\db\ActiveQuery */
            $viaRelation = is_array($relation->via) ? $relation->via[1] : $relation->via;
            /** @var \yii\db\ActiveRecord $viaClass */
            $viaClass = $viaRelation->modelClass;
            $subquery = (new Query)
                ->select(array_map(function ($key) {
                    return 'j.' . $key;
                }, array_keys($viaRelation->link)))
                ->from(['t' => $relationClass::tableName()])
                ->innerJoin(['j' => $viaClass::tableName()], implode(' AND ', array_map(function ($leftKey, $rightKey) {
                    return 't.' . $leftKey .' = j.' . $rightKey;
                }, array_keys($relation->link), array_values($relation->link))))
                ->where(['IN', array_map(function ($key) {
                    return 't.' . $key;
                }, $relationClass::primaryKey()), $value]);
            $linkKeys = array_values($viaRelation->link);
        } else {
            $subquery = (new Query)
                ->select(array_keys($relation->link))
                ->from(['t' => $relationClass::tableName()])
                ->where(['IN', array_map(function ($key) {
                    return 't.' . $key;
                }, $relationClass::primaryKey()), $value]);
            $linkKeys = array_values($relation->link);
        }
        return ['IN', array_map(function ($key) {
            return 't.' . $key;
        }, $linkKeys), $subquery];
    }
1350877
protected function getForeignKeyAttributesFromNonLoadedRelation(string $relation): array
    {
        $keys = $this->entityMap->getLocalKeys($relation);

        // We'll treat single and composite keys (polymorphic) the same way.
        if (!is_array($keys)) {
            $keys = [$keys];
        }

        $foreignKey = [];

        foreach ($keys as $key) {
            $foreignKey[$key] = $this->getEntityAttribute($key);
        }

        return $foreignKey;
    }
1091179
public static function related_class($relation)
	{
		$class = get_called_class();

		foreach (static::$_valid_relations as $rel_name => $rel_class)
		{
			if (property_exists($class, '_'.$rel_name))
			{
				if (isset(static::${'_'.$rel_name}[$relation]))
				{
					return static::${'_'.$rel_name}[$relation]['model_to'];
				}
			}
		}

		return null;
	}
844222
protected function relationResolver($relation)
    {
        $return = ['relation' => '', 'action' => 'update'];

        try {
            list($relation, $action) = explode('@', $relation);
            $return = ['relation' => $relation, 'action' => $action];
        } catch (\Exception $e) {
            $return['relation'] = $relation;
        }

        if (!in_array($return['action'], $this->availableActions)) {
            DB::rollBack(); //Rollback the transaction before throw exception
            throw (new SoftCascadeNonExistentRelationActionException())->setRelation(implode('@', $return));
        }

        return $return;
    }
160794
public function initRelation(array $models, $relation)
    {
        foreach ($models as $model) {
            $model->setRelation($relation, $this->getDefaultFor($model));
        }

        return $models;
    }
484716
protected function parseSingleRelationship(string $relation): bool
    {
        if (!$value = $this->parseForCommonValues($relation)) {
            return true;
        }

        if ($value instanceof Collection || is_array($value) || $value instanceof CollectionProxy) {
            throw new MappingException("Entity's attribute $relation should not be array, or collection");
        }

        if ($value instanceof LazyLoadingInterface && !$value->isProxyInitialized()) {
            $this->relationships[$relation] = [];

            return true;
        }

        // If the attribute is a loaded proxy, swap it for its
        // loaded entity.
        if ($value instanceof LazyLoadingInterface && $value->isProxyInitialized()) {
            $value = $value->getWrappedValueHolderValue();
        }

        if ($this->isParentOrRoot($value)) {
            $this->relationships[$relation] = [];

            return true;
        }

        // At this point, we can assume the attribute is an Entity instance
        // so we'll treat it as such.
        $subAggregate = $this->createSubAggregate($value, $relation);

        // Even if it's a single entity, we'll store it as an array
        // just for consistency with other relationships
        $this->relationships[$relation] = [$subAggregate];

        // We always need to check a loaded relation is in sync
        // with its local key
        $this->needSync[] = $relation;

        return true;
    }
926033
private function relationToArray(RelationOverride $relation)
    {
        if ($relation->type && !is_numeric($relation->type)) {
            $relation->type = constant(ClassMetadata::class . '::' . $relation->type);
        }

        return array_filter([
            'type' => $relation->type,
            'targetEntity' => $relation->targetEntity,
            'fieldName' => $relation->name,
            'inversedBy' => $relation->inversedBy,
            'mappedBy' => $relation->mappedBy,
            'fetch' => $relation->fetch,
            'cascade' => $relation->cascade,
            'orphanRemoval' => $relation->orphanRemoval,
        ]);
    }
1269239
public function getEmptyValueForLocalKey(string $relation)
    {
        if ($this->isPolymorphic($relation)) {
            $key = $this->localForeignKeys[$relation];

            return [
                $key['type'] => null,
                $key['id']   => null,
            ];
        }

        if ($this->isManyRelationship($relation)) {
            return [];
        }
    }
909238
public function _setType(string $type, array $relation)
    {
        $this->type = $type;
        $this->relation = $relation;
        return $this;
    }
994955
protected function getJoinKeys(Relation $relation)
    {
        if ($relation instanceof MorphTo) {
            throw new LogicException("MorphTo relation cannot be joined.");
        }

        if ($relation instanceof HasOneOrMany) {
            return [$relation->getQualifiedForeignKeyName(), $relation->getQualifiedParentKeyName()];
        }

        if ($relation instanceof BelongsTo) {
            return [$relation->getQualifiedForeignKeyName(), $relation->getQualifiedOwnerKeyName()];
        }

        if ($relation instanceof BelongsToMany) {
            return [$relation->getQualifiedRelatedPivotKeyName(), $relation->getRelated()->getQualifiedKeyName()];
        }

        if ($relation instanceof HasManyThrough) {
            $fk = $relation->getQualifiedFarKeyName();

            return [$fk, $relation->getParent()->getQualifiedKeyName()];
        }
    }
1052949
protected function getRelationshipValue(string $relation)
    {
        $value = $this->getEntityAttribute($relation);

        if (is_scalar($value)) {
            throw new MappingException("Entity's attribute $relation should be array, object, collection or null");
        }

        return $value;
    }