Get inherited properties.

@param string $type
@param array  $schema
@param bool   $isRoot

@return array

@throws \Exception
548482
protected function getInheritedProperties($type, array $schema, $isRoot = true)
    {
        if (!isset($schema['types'][$type])) {
            throw new \Exception('Unknown type '.$type);
        }

        $typeSchema = $schema['types'][$type];
        $properties = [];
        if (!$isRoot) {
            foreach ($typeSchema['specific_properties'] as $property) {
                if (!isset($schema['properties'][$property])) {
                    continue;
                }

                $properties[$property] = $property;
            }
        }

        if ($typeSchema['ancestors']) {
            $properties = array_merge(
                $properties,
                $this->getInheritedProperties(end($typeSchema['ancestors']), $schema, false)
            );
        }

        ksort($properties);

        return $properties;
    }
378624
protected static function getDbKey($schema)
    {
        static $keys = [];
        
        if ($schema === null) {
            return null;
        }
        if (!$keys) {
            foreach (self::getDbConfig() as $key => $conf) {
                $keys[$conf['database']] = $key;
            }
        }
        return isset($keys[$schema]) ? $keys[$schema] : null;
    }
784854
protected function parseRelationsFromSchema(array $schema, $path='')
    {
        $results = [];

        foreach ($schema as $key => $value) {
            if (! is_numeric($key)) {
                // join relation
                if (substr($key, 0, 3) != '...') {
                    $childPath = ($path)
                        ? $path.'.'.$key
                        : $key;
                    $results[$childPath] = (isset($this->constraints[$this->root.'.'.$childPath]))
                        ? $this->constraints[$this->root.'.'.$childPath]
                        : function () {};
                } else {
                    $childPath = $path;
                }

                // recursive call
                $results = array_merge($results, $this->parseRelationsFromSchema($value, $childPath));
            }
        }

        return $results;
    }
508103
protected function callSchema($schema)
    {
        if (!$schema instanceof Schema && is_callable($schema)) {
            $s = $this->getSchema();

            $schema($s);

            $schema = $s;
        }

        if (!$schema instanceof Schema) {
            throw new \InvalidArgumentException('Argument 1 should be Schema object.');
        }

        return $schema;
    }
120569
public static function getValidType($type, $xsdTypesPath = null, $fallback = null)
    {
        return XsdTypes::instance($xsdTypesPath)->isXsd(str_replace('[]', '', $type)) ? $fallback : $type;
    }
774228
protected function getRootTypes() {
    $types = null;
    $config = $this->getConfiguration();

    // get root types from configuration
    // try request value first
    $request = $this->getRequest();
    $rootTypeVar = $request->getValue('rootTypes');
    if ($config->hasValue($rootTypeVar, 'application')) {
      $types = $config->getValue($rootTypeVar, 'application');
      if (!is_array($types)) {
        $types = null;
      }
    }
    if ($types == null) {
      // fall back to root types
      $types = $config->hasValue('rootTypes', 'application');
    }

    // filter types by read permission
    $permissionManager = $this->getPermissionManager();
    $persistenceFacade = $this->getPersistenceFacade();
    $nodes = [];
    foreach($types as $type) {
      if ($permissionManager->authorize($type, '', PersistenceAction::READ)) {
        $node = $persistenceFacade->create($type, BuildDepth::SINGLE);
        $nodes[] = $node;
      }
    }
    return $nodes;
  }
451464
protected function mergeSchemaObjectArrays($parent, $schema)
    {
        // Directives used that exist in the schema being extended, that are arrays, should be merged.
        foreach (array_intersect_key($schema, $parent) as $key => $value) {
            # Simple merge on non-multidimensional arrays...
            if (is_array($value) && count($value) === count($value, COUNT_RECURSIVE)) {
                $schema[$key] = array_merge($parent[$key], $value);
            # Recursive merge on multidimensional arrays...
            } elseif (is_array($value)) {
                $schema[$key] = array_merge_recursive($parent[$key], $value);
            }
        }
        
        // Directives in the parent that have not been defined should be added.
        return array_replace($schema, array_diff_key($parent, $schema));
    }
1147496
private function getCreateQueryFromSchema(GetSchema\Schema $schema)
    {
        $definition = $schema->getTableDefinition($this->fromExpr);
        $defSchema = $definition->getSchema();
        $parser = new PHPSQLParser(false, false, [Options::CONSISTENT_SUB_TREES => true]);
        $query = new CreateQuery(new Query($defSchema, $parser->parse($defSchema)));

        return $query->getObjectExpression();
    }
523632
public static function typeFromAST(Schema $schema, $inputType)
    {
        if ($inputType instanceof ListType) {
            $innerType = self::typeFromAST($schema, $inputType->get('type'));
            return $innerType ? new ListModifier($innerType) : NULL;
        }

        if ($inputType instanceof NonNullType) {
            $innerType = self::typeFromAST($schema, $inputType->get('type'));
            return $innerType ? new NonNullModifier($innerType) : NULL;
        }

        if (!($inputType instanceof NamedType)) {
            throw new \LogicException('Must be a type name.');
        }

        return $schema->getType($inputType->get('name')->get('value'));
    }
1004254
private function autowireCalls(\ReflectionClass $reflectionClass, bool $isRoot): array
    {
        $this->decoratedId = null;
        $this->decoratedClass = null;
        $this->getPreviousValue = null;

        if ($isRoot && ($definition = $this->container->getDefinition($this->currentId)) && $this->container->has($this->decoratedId = $definition->innerServiceId)) {
            $this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass();
        }

        foreach ($this->methodCalls as $i => $call) {
            $this->decoratedMethodIndex = $i;
            list($method, $arguments) = $call;

            if ($method instanceof \ReflectionFunctionAbstract) {
                $reflectionMethod = $method;
            } else {
                $definition = new Definition($reflectionClass->name);
                try {
                    $reflectionMethod = $this->getReflectionMethod($definition, $method);
                } catch (RuntimeException $e) {
                    if ($definition->getFactory()) {
                        continue;
                    }
                    throw $e;
                }
            }

            $arguments = $this->autowireMethod($reflectionMethod, $arguments);

            if ($arguments !== $call[1]) {
                $this->methodCalls[$i][1] = $arguments;
            }
        }

        return $this->methodCalls;
    }
1311815
public function create($schema, $ifNotExists = true, $options = [])
    {
        $defaultOptions = [
            'auto_increment' => 1,
            'sequences' => [],
        ];

        $options = array_merge($defaultOptions, $options);
        $schema = $this->callSchema($schema);
        $columns = [];
        $comments = [];
        $primary = [];

        foreach ($schema->getColumns() as $column) {
            $column = $this->prepareColumn($column);

            $columns[$column->getName()] = PostgresqlGrammar::build(
                $column->getType() . $column->getLength(),
                $column->getAllowNull() ? null : 'NOT NULL',
                $column->isPrimary()
                    ? null
                    : 'DEFAULT ' . $this->db->getQuery(true)->validValue($column->getDefault())
            );

            // Comment
            if ($column->getComment()) {
                $comments[$column->getName()] = $column->getComment();
            }

            // Primary
            if ($column->isPrimary()) {
                $primary[] = $column->getName();
            }
        }

        $keys = [];
        $keyComments = [];

        foreach ($schema->getIndexes() as $index) {
            if ($index->getType() === Key::TYPE_PRIMARY) {
                $primary = array_merge($primary, $index->getColumns());
            } else {
                $keys[$index->getName()] = [
                    'type' => strtoupper($index->getType()),
                    'name' => $index->getName(),
                    'columns' => $index->getColumns(),
                ];

                if ($index->getComment()) {
                    $keyComments[$index->getName()] = $index->getComment();
                }
            }
        }

        $options['comments'] = $comments;
        $options['key_comments'] = $keyComments;

        $inherits = isset($options['inherits']) ? $options['inherits'] : null;
        $tablespace = isset($options['tablespace']) ? $options['tablespace'] : null;

        $query = PostgresqlGrammar::createTable(
            $this->getName(),
            $columns,
            $primary,
            $keys,
            $inherits,
            $ifNotExists,
            $tablespace
        );

        $comments = isset($options['comments']) ? $options['comments'] : [];
        $keyComments = isset($options['key_comments']) ? $options['key_comments'] : [];

        // Comments
        foreach ($comments as $name => $comment) {
            $query .= ";\n" . PostgresqlGrammar::comment('COLUMN', $this->getName(), $name, $comment);
        }

        foreach ($keyComments as $name => $comment) {
            $query .= ";\n" . PostgresqlGrammar::comment('INDEX', 'public', $name, $comment);
        }

        DatabaseHelper::batchQuery($this->db, $query);

        return $this->reset();
    }
636279
private function schemaApiTypeToPropertyInfoType($type)
    {
        switch ($type) {

          case 'serial':
          case 'int':
              return new Type(Type::BUILTIN_TYPE_INT, true);

          case 'float':
          case 'numeric':
            return new Type(Type::BUILTIN_TYPE_FLOAT, true);

          case 'varchar':
          case 'text':
          case 'blob':
              return new Type(Type::BUILTIN_TYPE_STRING, true);
        }
    }
77851
protected function mapType($schema, $column)
    {
        $baseType = $schema->baseColumnType($column);
        switch ($baseType) {
        case 'uuid':
            return ['type' => 'text', 'index' => false, 'null_value' => '_null_'];
        case 'integer':
            return ['type' => 'integer', 'null_value' => pow(-2,31)];
        case 'date':
            return ['type' => 'date', 'format' => 'dateOptionalTime||basic_date||yyy-MM-dd', 'null_value' => '0001-01-01'];
        case 'datetime':
        case 'timestamp':
            return ['type' => 'date', 'format' => 'basic_t_time_no_millis||dateOptionalTime||basic_date_time||ordinal_date_time_no_millis||yyyy-MM-dd HH:mm:ss||basic_date', 'null_value' => '0001-01-01 00:00:00'];
        case 'float':
        case 'decimal':
            return ['type' => 'float', 'null_value' => pow(-2,31)];
        case 'float':
        case 'decimal':
            return ['type' => 'float', 'null_value' => pow(-2,31)];
        case 'boolean':
            return ['type' => 'boolean'];
        default:
            return [
                'type' => 'text',
                'fields' => [
                    $column => ['type' => 'text'],
                    'raw' => ['type' => 'text', 'index' => false]
                ]
            ];
        }
    }
1029578
public function getPrimary($table, $schema = null)
    {
        //Argument 1 must be a string
        Argument::i()->test(1, 'string')->test(2, 'string', 'null');
        
        $select = array('columns.column_name');
        
        $where = array(
            "pg_attribute.attrelid = pg_class1.oid AND pg_class1.relname='".$table."'",
            'columns.column_name = pg_attribute.attname AND columns.table_name=pg_class1.relname',
            'pg_class1.oid = pg_index.indrelid AND pg_attribute.attnum = ANY(pg_index.indkey)',
            'pg_class2.oid = pg_index.indexrelid');
        
        if ($schema) {
            $where[1] .= ' AND columns.table_schema="'.$schema.'"';
        }
        
        $query = Select::i()
            ->select($select)
            ->from('pg_attribute')
            ->innerJoin('pg_class AS pg_class1', $where[0], false)
            ->innerJoin('information_schema.COLUMNS	AS columns', $where[1], false)
            ->innerJoin('pg_index', $where[2], false)
            ->innerJoin('pg_class AS pg_class2', $where[3], false)
            ->where('pg_class2.relname LIKE \'%_pkey\'')
            ->getQuery();
        
        return $this->query($query);
    }
869835
public function canExtract($source, $type, ExtractionContextInterface $extractionContext)
    {
        if (!$type instanceof Schema) {
            return false;
        }

        if (!$source instanceof ReflectionClass) {
            return false;
        }

        $constraints = $this->getPropertiesConstraints(
            $source,
            $type,
            $this->getValidationGroups($extractionContext)
        );

        return count($constraints);
    }
439656
protected function getSchemaByType(string $type): SchemaInterface
    {
        if ($this->hasCreatedProvider($type) === true) {
            return $this->getCreatedProvider($type);
        }

        $classNameOrCallable = $this->getProviderMapping($type);
        if (\is_string($classNameOrCallable) === true) {
            $schema = $this->createSchemaFromClassName($classNameOrCallable);
        } else {
            \assert(\is_callable($classNameOrCallable) === true);
            $schema = $this->createSchemaFromCallable($classNameOrCallable);
        }
        $this->setCreatedProvider($type, $schema);

        /** @var SchemaInterface $schema */

        $this->setResourceToJsonTypeMapping($schema->getType(), $type);

        return $schema;
    }
844378
function schemaType(schema) {
    let type;
    if (schema.hasOwnProperty('type')) {
        type = schema.type;
    } else if (schema.hasOwnProperty('properties') || schema.hasOwnProperty('allOf') || schema.hasOwnProperty('additionalProperties')) {
        type = 'object';
    } else if (schema.hasOwnProperty('items')) {
        type = 'array';
    }

    switch (type) {
        case 'array':
        case 'boolean':
        case 'file':
        case 'integer':
        case 'number':
        case 'object':
        case 'string':
            return type;
    }
}