@param null|array|bool|float|int|\stdClass|string $data
@param \stdClass                                  $schema

@throws \InvalidArgumentException

@return null|array|bool|float|int|\stdClass|string
176404
private function normalizeData($data, \stdClass $schema)
    {
        if (\is_array($data)) {
            return $this->normalizeArray(
                $data,
                $schema
            );
        }

        if ($data instanceof \stdClass) {
            return $this->normalizeObject(
                $data,
                $schema
            );
        }

        return $data;
    }
1244986
public function build(Schema &$schema, $alias = null) {
		if ($this->clause instanceof SQLPredicate) {
			if (!is_null($alias))
				$this->clause->setAlias($alias);
			return $this->clause->evaluate($this->driver, $schema);
		}
	
		return $this->clause;
	}
1357637
private static function cast(array $cfg, $schema=null){
    if ( \is_null($schema) && \is_object(static::$schema) ){
      $schema = static::$schema;
    }
    if ( \is_object($schema) && \is_array($cfg) && isset($schema->properties) ){
      foreach ( $schema->properties as $k => $p ){
        if ( empty($cfg[$k]) ){
          unset($cfg[$k]);
        }
        else if ( \is_object($p) ){
          if ( \is_string($cfg[$k]) && $p->type === 'integer' ){
            $cfg[$k] = (int)$cfg[$k];
          }
          else if ( \is_int($cfg[$k]) && $p->type === 'boolean' ){
            $cfg[$k] = (bool)$cfg[$k];
          }
          else if ( \is_array($cfg[$k]) ){
            $cfg[$k] = self::cast($cfg[$k], $p);
          }
        }
      }
    }
    return $cfg;
  }
126366
protected function validateProperties(&$document_data, &$data, array $data_pointer, array $parent_data_pointer, ISchema $document, $schema, ValidationResult $bag, array $defaults = null): bool
    {
        $type = $this->helper->type($data, true);
        if ($type === 'null' || $type === 'boolean') {
            return true;
        }

        $valid = false;

        switch ($type) {
            case 'string':
                $valid = $this->validateString($document_data, $data, $data_pointer, $parent_data_pointer, $document, $schema, $bag);
                break;
            case 'number':
            case 'integer':
                $valid = $this->validateNumber($document_data, $data, $data_pointer, $parent_data_pointer, $document, $schema, $bag);
                break;
            case 'array':
                $valid = $this->validateArray($document_data, $data, $data_pointer, $parent_data_pointer, $document, $schema, $bag);
                break;
            case 'object':
                $valid = $this->validateObject($document_data, $data, $data_pointer, $parent_data_pointer, $document, $schema, $bag, $defaults);
                // Setup unused defaults
                if (!$valid && $defaults) {
                    $this->setObjectDefaults($data, $defaults);
                }
                break;
        }

        if (!$valid && $bag->isFull()) {
            return false;
        }

        if (property_exists($schema, 'format') && $this->formats) {
            if (!is_string($schema->format)) {
                throw new SchemaKeywordException(
                    $schema,
                    'format',
                    $schema->format,
                    "'format' keyword must be a string, " . gettype($schema->format) . ", given"
                );
            }
            $formatObj = $this->formats->get($type, $schema->format);
            if ($formatObj === null && $type === 'integer') {
                $formatObj = $this->formats->get('number', $schema->format);
            }
            if ($formatObj !== null) {
                if (!$formatObj->validate($data)) {
                    $valid = false;
                    $bag->addError(new ValidationError($data, $data_pointer, $parent_data_pointer, $schema, 'format', [
                        'type' => $type,
                        'format' => $schema->format,
                    ]));
                    if ($bag->isFull()) {
                        return false;
                    }
                }
            }
            unset($formatObj);
        }

        return $valid;
    }
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;
    }
452522
public function visitSchema(Schema $schema)
    {
        return new Schema(
            $this->transformConstraintArray($schema->constraints()),
            $schema->defaultValue(),
            $schema->title(),
            $schema->description()
        );
    }
828875
protected function validateArray(&$document_data, &$data, array $data_pointer, array $parent_data_pointer, ISchema $document, $schema, ValidationResult $bag): bool
    {
        $ok = true;

        // minItems
        if (property_exists($schema, 'minItems')) {
            if (!is_int($schema->minItems)) {
                throw new SchemaKeywordException(
                    $schema,
                    'minItems',
                    $schema->minItems,
                    "'minItems' keyword must be an integer, " . gettype($schema->minItems) . " given"
                );
            }
            if ($schema->minItems < 0) {
                throw new SchemaKeywordException(
                    $schema,
                    'minItems',
                    $schema->minItems,
                    "'minItems' keyword must be positive, " . $schema->minItems . " given"
                );
            }
            if (($count = count($data)) < $schema->minItems) {
                $ok = false;
                $bag->addError(new ValidationError($data, $data_pointer, $parent_data_pointer, $schema, 'minItems', [
                    'min' => $schema->minItems,
                    'count' => $count,
                ]));
                if ($bag->isFull()) {
                    return false;
                }
            }
            unset($count);
        }

        // maxItems
        if (property_exists($schema, 'maxItems')) {
            if (!is_int($schema->maxItems)) {
                throw new SchemaKeywordException(
                    $schema,
                    'maxItems',
                    $schema->maxItems,
                    "'maxItems' keyword must be an integer, " . gettype($schema->maxItems) . " given"
                );
            }
            if ($schema->maxItems < 0) {
                throw new SchemaKeywordException(
                    $schema,
                    'maxItems',
                    $schema->maxItems,
                    "'maxItems' keyword must be positive, " . $schema->maxItems . " given"
                );
            }
            if (($count = count($data)) > $schema->maxItems) {
                $ok = false;
                $bag->addError(new ValidationError($data, $data_pointer, $parent_data_pointer, $schema, 'maxItems', [
                    'max' => $schema->maxItems,
                    'count' => $count,
                ]));
                if ($bag->isFull()) {
                    return false;
                }
            }
            unset($count);
        }

        // uniqueItems
        if (property_exists($schema, 'uniqueItems')) {
            if (!is_bool($schema->uniqueItems)) {
                throw new SchemaKeywordException(
                    $schema,
                    'uniqueItems',
                    $schema->uniqueItems,
                    "'uniqueItems' keyword must be a boolean, " . gettype($schema->uniqueItems) . " given"
                );
            }
            if ($schema->uniqueItems) {
                $valid = true;
                $count = count($data);
                $dup = null;
                for ($i = 0; $i < $count - 1; $i++) {
                    for ($j = $i + 1; $j < $count; $j++) {
                        if ($this->helper->equals($data[$i], $data[$j])) {
                            $valid = false;
                            $dup = $data[$i];
                            break 2;
                        }
                    }
                }
                if (!$valid) {
                    $ok = false;
                    $bag->addError(new ValidationError($data, $data_pointer, $parent_data_pointer, $schema, 'uniqueItems', [
                        'duplicate' => $dup,
                    ]));
                    if ($bag->isFull()) {
                        return false;
                    }
                }
                unset($valid, $count, $dup);
            }
        }

        // contains
        if (property_exists($schema, 'contains')) {
            $valid = false;
            $newbag = new ValidationResult(1);
            $errors = [];
            foreach ($data as $i => &$value) {
                $data_pointer[] = $i;
                $valid = $this->validateSchema($document_data, $value, $data_pointer, $parent_data_pointer, $document, $schema->contains, $newbag);
                array_pop($data_pointer);
                if ($valid) {
                    break;
                }
                $errors = array_merge($errors, $newbag->getErrors());
                $newbag->clear();
            }
            unset($value, $newbag);
            if (!$valid) {
                $ok = false;
                $bag->addError(new ValidationError($data, $data_pointer, $parent_data_pointer, $schema, 'contains', [], $errors));
                if ($bag->isFull()) {
                    return false;
                }
            }
            unset($valid, $errors);
        }

        // items, additionalItems
        if (property_exists($schema, 'items')) {
            if (is_array($schema->items)) {
                $count = count($schema->items);
                $data_count = count($data);
                $max = min($count, $data_count);
                for ($i = 0; $i < $max; $i++) {
                    $data_pointer[] = $i;
                    $valid = $this->validateSchema($document_data, $data[$i], $data_pointer, $parent_data_pointer, $document, $schema->items[$i], $bag);
                    array_pop($data_pointer);
                    if (!$valid) {
                        $ok = false;
                        if ($bag->isFull()) {
                            return false;
                        }
                    }
                }
                if ($max < $data_count && property_exists($schema, 'additionalItems')) {
                    if (!is_bool($schema->additionalItems) && !is_object($schema->additionalItems)) {
                        throw new SchemaKeywordException(
                            $schema,
                            'additionalItems',
                            $schema->additionalItems,
                            "'additionalItems' keyword must be a boolean or an object, " . gettype($schema->additionalItems) . " given"
                        );
                    }
                    for ($i = $max; $i < $data_count; $i++) {
                        $data_pointer[] = $i;
                        $valid = $this->validateSchema($document_data, $data[$i], $data_pointer, $parent_data_pointer, $document, $schema->additionalItems, $bag);
                        array_pop($data_pointer);
                        if (!$valid) {
                            $ok = false;
                            if ($bag->isFull()) {
                                return false;
                            }
                        }
                    }
                }
                unset($max, $count, $data_count);
            } else {
                $count = count($data);
                for ($i = 0; $i < $count; $i++) {
                    $data_pointer[] = $i;
                    $valid = $this->validateSchema($document_data, $data[$i], $data_pointer, $parent_data_pointer, $document, $schema->items, $bag);
                    array_pop($data_pointer);
                    if (!$valid) {
                        $ok = false;
                        if ($bag->isFull()) {
                            return false;
                        }
                    }
                }
            }
        }

        return $ok;
    }
552518
public function make($schema)
    {
        if (array_key_exists($schema, $this->schemas)) {
            return $this->schemas[$schema];
        }

        return $this->schemas[$schema] = $this->makeMapper($schema);
    }
567749
public function validateSchema($schema = self::STRICT_SCHEMA)
    {
        $content = file_get_contents($this->path);
        $data = json_decode($content);

        if (null === $data && 'null' !== $content) {
            self::validateSyntax($content, $this->path);
        }

        $schemaFile = __DIR__ . '/../../../res/composer-schema.json';
        $schemaData = json_decode(file_get_contents($schemaFile));

        if ($schema === self::LAX_SCHEMA) {
            $schemaData->additionalProperties = true;
            $schemaData->required = array();
        }

        $validator = new Validator();
        $validator->check($data, $schemaData);

        // TODO add more validation like check version constraints and such, perhaps build that into the arrayloader?

        if (!$validator->isValid()) {
            $errors = array();
            foreach ((array) $validator->getErrors() as $error) {
                $errors[] = ($error['property'] ? $error['property'].' : ' : '').$error['message'];
            }
            throw new JsonValidationException('"'.$this->path.'" does not match the expected JSON schema', $errors);
        }

        return true;
    }
824811
public function getSchemaOid($schema, Where $where = null)
    {
        $condition =
            Where::create("s.nspname = $*", [$schema])
            ->andWhere($where)
            ;
        $sql = <<<SQL
select
    s.oid as oid
from
    pg_catalog.pg_namespace s
where
    {condition}
SQL;

        $iterator = $this->executeSql($sql, $condition);

        return $iterator->isEmpty() ? null : $iterator->current()['oid'];
    }
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);
    }
259878
protected function result(Schema $schema)
    {
        $key = $this->generateVisitKey($schema);
        if (array_key_exists($key, $this->results)) {
            return $this->results[$key];
        }

        return null;
    }
747293
public function formatColumns(Schema $schema) {
        $columns = [];

        foreach ($schema->getColumns() as $column => $options) {
            $dataType = $this->getDriver()->getType($options['type']);

            $options = $options + $dataType->getDefaultOptions();
            $type = $options['type'];

            if (!empty($options['length'])) {
                $type .= '(' . $options['length'] . ')';
            }

            $output = [$this->quote($column), strtoupper($type)];

            // Integers
            if (!empty($options['unsigned'])) {
                $output[] = $this->getKeyword(self::UNSIGNED);
            }

            if (!empty($options['zerofill'])) {
                $output[] = $this->getKeyword(self::ZEROFILL);
            }

            // Strings
            if (!empty($options['charset'])) {
                $output[] = sprintf($this->getClause(self::CHARACTER_SET), $options['charset']);
            }

            if (!empty($options['collate'])) {
                $output[] = sprintf($this->getClause(self::COLLATE), $options['collate']);
            }

            // Primary and uniques can't be null
            if (!empty($options['primary']) || !empty($options['unique'])) {
                $output[] = $this->getKeyword(self::NOT_NULL);
            } else {
                $output[] = $this->getKeyword(empty($options['null']) ? self::NOT_NULL : self::NULL);
            }

            if (array_key_exists('default', $options)) {
                $output[] = $this->formatDefault($options['default']);
            }

            if (!empty($options['ai'])) {
                $output[] = $this->getKeyword(self::AUTO_INCREMENT);
            }

            if (!empty($options['comment'])) {
                $output[] = sprintf($this->getClause(self::COMMENT), $this->getDriver()->escape(substr($options['comment'], 0, 255)));
            }

            $columns[] = trim(implode(' ', $output));
        }

        return implode(",\n", $columns);
    }
104735
protected function writeSchemaHelp($schema) {
        // Write the command description.
        $meta = Cli::val(Cli::META, $schema, []);
        $description = Cli::val('description', $meta);

        if ($description) {
            echo implode("\n", Cli::breakLines($description, 80, false)).PHP_EOL.PHP_EOL;
        }

        unset($schema[Cli::META]);

        // Add the help.
        $schema['help'] = [
            'description' => 'Display this help.',
            'type' => 'boolean',
            'short' => '?'
        ];

        echo Cli::bold('OPTIONS').PHP_EOL;

        ksort($schema);

        $table = new Table();
        $table->setFormatOutput($this->formatOutput);

        foreach ($schema as $key => $definition) {
            $table->row();

            // Write the keys.
            $keys = "--{$key}";
            if ($shortKey = Cli::val('short', $definition, false)) {
                $keys .= ", -$shortKey";
            }
            if (Cli::val('required', $definition)) {
                $table->bold($keys);
            } else {
                $table->cell($keys);
            }

            // Write the description.
            $table->cell(Cli::val('description', $definition, ''));
        }

        $table->write();
        echo PHP_EOL;

        $args = Cli::val(Cli::ARGS, $meta, []);
        if (!empty($args)) {
            echo Cli::bold('ARGUMENTS').PHP_EOL;

            $table = new Table();
            $table->setFormatOutput($this->formatOutput);

            foreach ($args as $argName => $arg) {
                $table->row();

                if (Cli::val('required', $arg)) {
                    $table->bold($argName);
                } else {
                    $table->cell($argName);
                }

                $table->cell(Cli::val('description', $arg, ''));
            }
            $table->write();
            echo PHP_EOL;
        }
    }
45891
public function parse($schema)
    {
        $this->schema = $schema;
        $parsed = [];
        foreach ($this->getSchemas() as $schemaArray) {
            $column = $this->getColumn($schemaArray);
            $attributes = $this->getAttributes($column, $schemaArray);
            $parsed[$column] = $attributes;
        }

        return $parsed;
    }
1015491
public static function make($schema)
    {
        return new self(
            $schema,
            StringValidator::make($schema->getMeta()),
            FloatValidator::make($schema->getMeta()),
            IntValidator::make($schema->getMeta()),
            JsonValidator::make($schema->getMeta())
        );
    }
1122598
public function setSchema($schema)
    {
        $oldSchema = $this->schema;
        if ($this->schema !== $schema && $this->getPlatform()) {
            $schemaDelimiter = $this->getPlatform()->getSchemaDelimiter();
            $fixHash = function (&$array) use ($schema, $oldSchema, $schemaDelimiter) {
                foreach ($array as $k => $v) {
                    if ($schema && $this->getPlatform()->supportsSchemas()) {
                        if (false === strpos($k, $schemaDelimiter)) {
                            $array[$schema . $schemaDelimiter . $k] = $v;
                            unset($array[$k]);
                        }
                    } elseif ($oldSchema) {
                        if (false !== strpos($k, $schemaDelimiter)) {
                            $array[explode($schemaDelimiter, $k)[1]] = $v;
                            unset($array[$k]);
                        }
                    }
                }
            };

            $fixHash($this->tablesByName);
            $fixHash($this->tablesByLowercaseName);
        }
        parent::setSchema($schema);
    }