@param string $schema
@param string $typeName
@param array  $criteria

@return array
1243
public function findBy(string $schema, string $typeName, array $criteria = []) : array
    {
        if (!$this->typeExists($schema, $typeName)) {
            return [];
        }

        foreach ($this->storage[$schema][$typeName] as $id => $data) {
            if ($this->matchesCriteria($criteria, $data)) {
                return $data;
            }
        }

        return [];
    }
396413
public function getSchemaTables(Schema $schema, Config $config)
    {
        if ($this->tableSchemas !== null) {
            return $this->tableSchemas;
        }

        /** @var $fieldManager FieldManager */
        $fieldManager = $config->getFields();
        $contentTypes = $this->getNormalisedContentTypes($config);
        $tables = [];

        foreach ($this->tables->keys() as $name) {
            $contentType = $contentTypes[$name];
            /** @var ContentType $table */
            $table = $this->tables[$name];
            $tables[$name] = $table->buildTable($schema, $name, $this->charset, $this->collate);
            if (isset($contentType['fields']) && is_array($contentType['fields'])) {
                $this->addContentTypeTableColumns($this->tables[$name], $tables[$name], $contentType['fields'], $fieldManager);
            }
        }

        return $this->tableSchemas = $tables;
    }
537017
protected function checkTypeObject($entity, $schema, $entityName)
    {
        $this->validateProperties($entity, $schema, $entityName);

        return $this;
    }
718058
public function create(Schema $schema)
    {
        $currentDbSchema = $this->connection->getSchemaManager()->createSchema();

        $dbSchema = new DBALSchema(
            $currentDbSchema->getTables(),
            $currentDbSchema->getSequences(),
            $this->connection->getSchemaManager()->createSchemaConfig()
        );

        foreach ($schema->types() as $type) {
            $tableName = $this->tableName($schema->name(), $type->name());

            if ($dbSchema->hasTable($tableName)) {
                throw DoctrineStorageException::tableAlreadyExists($tableName);
            }

            $this->createTable($dbSchema, $schema->name(), $type);
        }

        $queries = $dbSchema->toSql($this->connection->getDatabasePlatform());

        $this->executeQueries($queries);
    }
563575
protected function parseGroupBy($schema, $fields = null)
    {
        $outArray = [];
        if (!empty($fields)) {
            foreach ($fields as $field) {
                if ($fieldInfo = $schema->getColumn($field, true)) {
                    $outArray[] = $fieldInfo->name;
                } else {
                    if (false !== strpos($field, ';')) {
                        throw new BadRequestException('Invalid group by clause in request.');
                    }
                    $outArray[] = DB::raw($field); // todo better checks on group by clause
                }
            }
        }

        return $outArray;
    }
818706
public function apply($schema, $columns = null, $notation = null)
    {
        //
        if (is_string($schema)) {
            $schema = [
                $schema => is_string($columns)
                    ? [$columns => $notation]
                    : $columns,
            ];
        }

        //
        if (!$schema || count($schema) == 0 || !is_array($schema)) {
            $this->error('generic', 'empty schema not allowed');
        }

        //
        foreach ($schema as $model => $attributes) {
            if (!$attributes || count($attributes) == 0 || !is_array($attributes)) {
                $this->error('generic', "empty model '{$model}' not allowed");
            }
        }

        // retrive queries
        $queries = $this->diff($schema);

        // send all queries to align database
        if (count($queries) > 0) {
            foreach ($queries as $sql) {
                $this->execute($sql);
            }
        }

        return $queries;
    }
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();
    }
30757
private function addSchema($collectionName, $schemaName, $schema)
    {
        if (!\is_string($schema) && !$schema instanceof SchemaDefinitionInterface) {
            throw new InvalidSchemaDefinitionException();
        }

        $this->schemaCollections[$collectionName][$schemaName] = $schema;
    }
23830
public function getAttributes($column, $schema)
    {
        $fields = str_replace($column . ':', '', $schema);

        return $this->hasCustomAttribute($column) ? $this->getCustomAttribute($column) : explode(':', $fields);
    }
1223417
protected function checkTypeArray($entity, $schema, $entityName)
    {
        $this->checkMinItems($entity, $schema, $entityName);
        $this->checkMaxItems($entity, $schema, $entityName);
        $this->checkUniqueItems($entity, $schema, $entityName);
        $this->checkEnum($entity, $schema, $entityName);
        $this->checkItems($entity, $schema, $entityName);
        $this->checkDisallow($entity, $schema, $entityName);

        return $this;
    }
184905
public function register(string $type, $schema): void
    {
        if (empty($type) === true || \class_exists($type) === false) {
            throw new InvalidArgumentException(_(static::MSG_INVALID_MODEL_TYPE));
        }

        $isOk = (
            (
                \is_string($schema) === true &&
                empty($schema) === false &&
                \class_exists($schema) === true &&
                \in_array(SchemaInterface::class, \class_implements($schema)) === true
            ) ||
            \is_callable($schema) ||
            $schema instanceof SchemaInterface
        );
        if ($isOk === false) {
            throw new InvalidArgumentException(_(static::MSG_INVALID_SCHEME, $type));
        }

        if ($this->hasProviderMapping($type) === true) {
            throw new InvalidArgumentException(_(static::MSG_TYPE_REUSE_FORBIDDEN, $type));
        }

        if ($schema instanceof SchemaInterface) {
            $this->setProviderMapping($type, \get_class($schema));
            $this->setResourceToJsonTypeMapping($schema->getType(), $type);
            $this->setCreatedProvider($type, $schema);
        } else {
            $this->setProviderMapping($type, $schema);
        }
    }
1038327
protected function getColumnCreate(array $schema, string $tableName, string $columnName): array
    {
        $columns = $schema['tables'][$tableName]['columns'];
        $columnData = $columns[$columnName];
        $phinxType = $this->getPhinxColumnType($columnData);
        $columnAttributes = $this->getPhinxColumnOptions($phinxType, $columnData, $columns);

        return [$tableName, $columnName, $phinxType, $columnAttributes];
    }
829896
protected function generateType($typeName, array $data, $directory, array $schema)
    {
        $type = $this->getTypeClassName($typeName);

        $class = new PhpClass();
        $class
            ->setQualifiedName('SecIT\\SchemaOrg\\Mapping\\Type\\'.$type)
            ->setDescription('Class '.$type.'.')
            ->setMethod(PhpMethod::create('getSchemaUrl')
                ->setDescription('Get schema URL.')
                ->setType('string')
                ->setBody('return \''.$data['url'].'\';')
            )
        ;

        if ($this->backwardCompatibility && !$this->php7ClassNames) {
            $this->php7ClassNames = true;
            $deprecatedMessage = 'This class is deprecated and will be removed in release 3.4. Use SecIT\\SchemaOrg\\Mapping\\Type\\'.$this->getTypeClassName($typeName).' instead.';
            $this->php7ClassNames = false;
            $class->setDescription($class->getDescription()."\n\n".'@deprecated '.$deprecatedMessage);
        }

        if ($data['ancestors']) {
            $class->setParentClassName($this->getTypeClassName(end($data['ancestors'])));

            $phpdocMethods = '';
            try {
                $inheritedProperties = $this->getInheritedProperties($typeName, $schema);
            } catch (\Exception $e) {
                printf("\n > Type %s declaration not found. Is it defined in extension?", $typeName);
                return;
            }

            foreach ($inheritedProperties as $inheritedProperty) {
                if ($inheritedProperty == 'itemListElement') {
                    $phpdocMethods .= '@method '.$type.' setItemListElements(array|Property\\'.$this->getPropertyClassName($inheritedProperty).'[] $itemListElements)'."\n";
                    $phpdocMethods .= '@method '.$type.' addItemListElement(Property\\'.$this->getPropertyClassName($inheritedProperty).' $itemListElement)'."\n";
                } else {
                    $phpdocMethods .= '@method '.$type.' set'.ucfirst($inheritedProperty).'(Property\\'.$this->getPropertyClassName($inheritedProperty).' $'.$inheritedProperty.')'."\n";
                }
            }

            $class->setDescription($class->getDescription()."\n\n".$phpdocMethods);
            if ($phpdocMethods) {
                $class->addUseStatement('SecIT\\SchemaOrg\\Mapping\\Property');
            }
        } else {
            $class
                ->addInterface($this->typeInterfaceName)
                ->setProperty(PhpProperty::create('id')
                    ->setVisibility('private')
                    ->setType(null)
                )
                ->setMethod(PhpMethod::create('__construct')
                    ->setDescription($type.' constructor.')
                    ->addParameter(PhpParameter::create('id')
                        ->setType('string')
                        ->setValue(null)
                    )
                    ->setBody('$this->id = $id;')
                )
                ->setMethod(PhpMethod::create('getId')
                    ->setDescription('Get id.')
                    ->setType('string')
                    ->setBody('return $this->id;')
                )
            ;
        }

        foreach ($data['specific_properties'] as $property) {
            if (!isset($schema['properties'][$property])) {
                continue;
            }

            if ($property == 'itemListElement') {
                $setterBody = 'if (!is_array($itemListElements)) {'."\n";
                $setterBody .= '    throw new \\Exception(\'The value is expected to be an array\');'."\n";
                $setterBody .= '}'."\n";
                $setterBody .= 'foreach ($itemListElements as $itemListElement) {'."\n";
                $setterBody .= '    if (!$itemListElement instanceof Property\\'.$this->getPropertyClassName($property).') {'."\n";
                $setterBody .= '        throw new \\Exception(\'Unexpected value type\');'."\n";
                $setterBody .= '    }'."\n";
                $setterBody .= '}'."\n";
                $setterBody .= '$this->itemListElement = $itemListElements;'."\n";
                $setterBody .= "\n";
                $setterBody .= 'return $this;';

                $adderBody = 'if (!$itemListElement instanceof Property\\'.$this->getPropertyClassName($property).') {'."\n";
                $adderBody .= '     throw new \\Exception(\'Unexpected value type\');'."\n";
                $adderBody .= '}'."\n";
                $adderBody .= '$this->itemListElement[] = $itemListElement;'."\n";
                $adderBody .= "\n";
                $adderBody .= 'return $this;';

                $class
                    ->addUseStatement('SecIT\\SchemaOrg\\Mapping\\Property')
                    ->setProperty(PhpProperty::create('itemListElement')
                        ->setVisibility('private')
                        ->setType('array|Property\\'.$this->getPropertyClassName($property).'[]')
                    )
                    ->setMethod(PhpMethod::create('__construct')
                        ->setDescription($type.' constructor.')
                        ->addParameter(PhpParameter::create('id')
                            ->setType('string')
                            ->setValue(null)
                        )
                        ->setBody('parent::__construct($id);'."\n".'$this->'.$property.' = [];')
                    )
                    ->setMethod(PhpMethod::create('setItemListElements')
                        ->setDescription('Set item list elements.')
                        ->addParameter(PhpParameter::create('itemListElements')
                            ->setType('array|Property\\'.$this->getPropertyClassName($property).'[]')
                        )
                        ->setType($type)
                        ->setBody($setterBody)
                    )
                    ->setMethod(PhpMethod::create('addItemListElement')
                        ->setDescription('Add an item list element.')
                        ->addParameter(PhpParameter::create('itemListElement')
                            ->setType('Property\\'.$this->getPropertyClassName($property))
                        )
                        ->setType($type)
                        ->setBody($adderBody)
                    )
                    ->setMethod(PhpMethod::create('getItemListElements')
                        ->setDescription('Get item list elements.')
                        ->setType('array|Property\\'.$this->getPropertyClassName($property).'[]')
                        ->setBody('return $this->'.$property.';')
                    )
                ;
            } else {
                $class
                    ->addUseStatement('SecIT\\SchemaOrg\\Mapping\\Property')
                    ->setProperty(PhpProperty::create($property)
                        ->setVisibility('private')
                        ->setType('Property\\'.$this->getPropertyClassName($property))
                    )
                    ->setMethod(PhpMethod::create('set'.ucfirst($property))
                        ->setDescription('Set '.mb_strtolower(preg_replace('/(?!^)[A-Z]{2,}(?=[A-Z][a-z])|[A-Z][a-z]/', ' $0', $property)).'.')
                        ->addParameter(PhpParameter::create($property)
                            ->setType('Property\\'.$this->getPropertyClassName($property))
                        )
                        ->setType($type)
                        ->setBody('$this->'.$property.' = $'.$property.';'."\n\n".'return $this;')
                    )
                    ->setMethod(PhpMethod::create('get'.ucfirst($property))
                        ->setDescription('Get '.mb_strtolower(preg_replace('/(?!^)[A-Z]{2,}(?=[A-Z][a-z])|[A-Z][a-z]/', ' $0', $property)).'.')
                        ->setType('Property\\'.$this->getPropertyClassName($property))
                        ->setBody('return $this->'.$property.';')
                    )
                ;
            }
        }

        $generator = new CodeGenerator();
        $code = $generator->generate($class);

        file_put_contents($directory.$type.'.php', "<?php\n\n".$code);
    }
453869
public function ApplyRulesBySchema($Schema) {
      $this->_Schema = $Schema->Fetch();
      foreach($this->_Schema as $Field => $Properties) {
         // Create an array to hold rules for this field
         $RuleNames = array();

         if ($Properties->AutoIncrement === TRUE) {
            // Skip all rules for auto-incrementing integer columns - they will
         // not be inserted or updated.
         } else {
            // Force non-null fields without defaults to be required.
            if ($Properties->AllowNull === FALSE && $Properties->Default == '') {
               $RuleNames[] = 'Required';
               $this->_RequiredSchemaFields[] = $Field;
            }

            // Force other constraints based on field type.
            switch($Properties->Type) {
               case 'bit':
               case 'bool':
               case 'boolean':
                  $RuleNames[] = 'Boolean';
                  break;

               case 'tinyint':
               case 'smallint':
               case 'mediumint':
               case 'int':
               case 'integer':
               case 'bigint':
                  $RuleNames[] = 'Integer';
                  break;

               case 'double':
               case 'float':
               case 'real':
               case 'decimal':
               case 'dec':
               case 'numeric':
               case 'fixed':
                  $RuleNames[] = 'Decimal';
                  break;

               case 'date':
               case 'datetime':
                  $RuleNames[] = 'Date';
                  break;
               case 'time':
                  $RuleNames[] = 'Time';
                  break;
               case 'year':
                  $RuleNames[] = 'Year';
                  break;
               case 'timestamp':
                  $RuleNames[] = 'Timestamp';
                  break;

               case 'char':
               case 'varchar':
               case 'tinyblob':
               case 'blob':
               case 'mediumblob':
               case 'longblob':
               case 'tinytext':
               case 'mediumtext':
               case 'text':
               case 'longtext':
               case 'binary':
               case 'varbinary':
                  if ($Properties->Length != '')
                     $RuleNames[] = 'Length';
                  break;

               case 'enum':
               case 'set':
                  $RuleNames[] = 'Enum';
                  break;
            }
            
            if ($Field == 'Format') {
               $RuleNames[] = 'Format';
            }
         }
         // Assign the rules to the field.
         // echo '<div>Field: '.$Field.'</div>';
         // print_r($RuleNames);
         $this->_ApplyRule($Field, $RuleNames);
      }
   }
1171733
private function getMixinSchemas(SchemaDescriptor $schema)
    {
        $schemaIds = [];

        foreach ($schema->getMixins() as $mixin) {
            $schemaIds[] = $mixin->getId()->getCurieWithMajorRev();

            $schemaIds = array_merge(
                $schemaIds,
                $this->getExtendsSchemas($mixin),
                $this->getMixinSchemas($mixin)
            );
        }

        return $schemaIds;
    }
187388
public function generate(Schema $schema, string $className, Context $context)
    {
        foreach ($schema->getClasses() as $class) {
            $properties = [];
            $methods = [];

            foreach ($class->getProperties() as $property) {
                $properties[] = $this->createProperty($property, $schema->getNamespace() . '\\Model');
                $methods[] = $this->createGetter($property, $schema->getNamespace() . '\\Model');
                $methods[] = $this->createSetter($property, $schema->getNamespace() . '\\Model');
            }

            $model = $this->createModel(
                $class->getName(),
                $properties,
                $methods,
                \count($class->getExtensionsType()) > 0
            );

            $namespace = new Stmt\Namespace_(new Name($schema->getNamespace() . '\\Model'), [$model]);

            $schema->addFile(new File($schema->getDirectory() . '/Model/' . $class->getName() . '.php', $namespace, self::FILE_TYPE_MODEL));
        }
    }
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'));
    }