Parse a Foreign Key constraint to its SQL representation

@param Constraint\ForeignKey $cons
@return string
196044
protected function _getFKConstraint(Constraint\ForeignKey $cons)
    {
        $onDelete = '';
        if ($cons->getOnDelete()) {
            $onDelete = " ON DELETE {$cons->getOnDelete()}";
        }
        $onUpdated = '';
        if ($cons->getOnUpdate()) {
            $onUpdated = " ON UPDATE {$cons->getOnUpdate()}";
        }
        return sprintf(
            'CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s(%s)%s%s',
            $cons->getName(),
            $cons->getColumn(),
            $cons->getReferenceTable(),
            $cons->getReferenceColumn(),
            $onDelete,
            $onUpdated
        );
    }
1344634
private function parseFrom()
    {
        if (!empty($this->parts['from'])) {
            $parts = [];

            foreach ($this->parts['from'] as $key => $item) {
                if (is_array($item)) {
                    $table = isset($item[0]) ? $item[0] : false;
                    $alias = isset($item[1]) ? $item[1] : false;

                    if (is_object($table)) {
                        if (!$alias) {
                            trigger_error('Select statements in for need aliases defined', E_USER_ERROR);
                        }
                        $parts[$key] = '('.$table.') AS '.$this->protect($alias).$this->parseJoin($alias);
                    } else {
                        $parts[$key] = $this->protect($table).' AS '.$this->protect((!empty($alias) ? $alias : $table)).$this->parseJoin($alias);
                    }
                } elseif (!strpos($item, ' ')) {
                    $parts[] = $this->protect($item).$this->parseJoin($item);
                } else {
                    $parts[] = $item;
                }
            }

            return implode(", ", array_unique($parts));
        }

        return null;
    }
154619
protected function compileOneJoin(Join $join, array &$bindings): string
    {
        $sql = $join->type.' JOIN '.$this->compileIdentifierWithAlias($join->table, $join->tableAlias, $bindings);

        if ($join->criteria) {
            $sql .= ' ON '.$this->compileCriteria($join->criteria, $bindings);
        }

        return $sql;
    }
889306
protected function compileJoinPart(Query $query, array &$bindings): string
    {
        $joinsSQL = [];

        foreach ($query->join as $join) {
            $joinsSQL[] = $this->compileOneJoin($join, $bindings);
        }

        return $this->implodeSQL($joinsSQL);
    }
778295
protected function getConstraints()
    {
        if (is_null($this->constrains)) {
            $this->constrains = DB::select(
                'SELECT
                    r.referenced_table_name AS `references`
                   ,r.CONSTRAINT_NAME AS `name`
                   ,r.UPDATE_RULE AS `onUpdate`
                   ,r.DELETE_RULE AS `onDelete`
                   ,u.referenced_column_name AS `on`
                   ,u.column_name AS `foreign`
                   ,CASE WHEN u.TABLE_NAME = r.referenced_table_name THEN 1 ELSE 0 END selfReferences
                   FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS r
                   INNER JOIN information_schema.key_column_usage AS u ON u.CONSTRAINT_NAME = r.CONSTRAINT_NAME
                                                                       AND u.table_schema = r.constraint_schema
                                                                       AND u.table_name = r.table_name
                   WHERE u.table_name = ? AND u.constraint_schema = ?;',
                [$this->tableName, $this->databaseName]
            );
        }

        return $this->constrains;
    }
274141
private function parseDsn(string $dsn, array $config = null): array
    {
        if (false === strpos($dsn, ':')) {
            throw new \LogicException(sprintf('The DSN is invalid. It does not have scheme separator ":".'));
        }

        if (false === parse_url($dsn)) {
            throw new \LogicException(sprintf('Failed to parse DSN "%s"', $dsn));
        }

        list($scheme) = explode(':', $dsn, 2);

        $scheme = strtolower($scheme);
        if (false == preg_match('/^[a-z\d+-.]*$/', $scheme)) {
            throw new \LogicException('The DSN is invalid. Scheme contains illegal symbols.');
        }

        $supported = [
            'db2' => 'db2',
            'ibm-db2' => 'ibm-db2',
            'mssql' => 'mssql',
            'sqlsrv+pdo' => 'pdo_sqlsrv',
            'mysql' => 'mysql',
            'mysql2' => 'mysql2',
            'mysql+pdo' => 'pdo_mysql',
            'pgsql' => 'pgsql',
            'postgres' => 'postgres',
            'pgsql+pdo' => 'pdo_pgsql',
            'sqlite' => 'sqlite',
            'sqlite3' => 'sqlite3',
            'sqlite+pdo' => 'pdo_sqlite',
        ];

        if (false == isset($supported[$scheme])) {
            throw new \LogicException(sprintf(
                'The given DSN schema "%s" is not supported. There are supported schemes: "%s".',
                $scheme,
                implode('", "', array_keys($supported))
            ));
        }

        $doctrineScheme = $supported[$scheme];

        if ($scheme.':' === $dsn && is_array($config) && array_key_exists('connection', $config)) {
            $default = [
                'driver' => $doctrineScheme,
                'host' => 'localhost',
                'port' => '3306',
                'user' => 'root',
                'password' => '',
            ];

            return [
                'lazy' => true,
                'connection' => array_replace_recursive($default, $config['connection']),
            ];
        }

        return [
            'lazy' => true,
            'connection' => [
                'url' => $scheme.':' === $dsn ?
                    $doctrineScheme.'://root@localhost' :
                    str_replace($scheme, $doctrineScheme, $dsn),
            ],
        ];
    }
1017818
protected function concatColReferences($tokens) {

        $cnt = count($tokens);
        $i = 0;
        while ($i < $cnt) {

            if (!isset($tokens[$i])) {
                $i++;
                continue;
            }

            if ($tokens[$i][0] === ".") {

                // concat the previous tokens, till the token has been changed
                $k = $i - 1;
                $len = strlen($tokens[$i]);
                while (($k >= 0) && ($len == strlen($tokens[$i]))) {
                    if (!isset($tokens[$k])) { // FIXME: this can be wrong if we have schema . table . column
                        $k--;
                        continue;
                    }
                    $tokens[$i] = $tokens[$k] . $tokens[$i];
                    unset($tokens[$k]);
                    $k--;
                }
            }

            if ($this->endsWith($tokens[$i], '.') && !is_numeric($tokens[$i])) {

                // concat the next tokens, till the token has been changed
                $k = $i + 1;
                $len = strlen($tokens[$i]);
                while (($k < $cnt) && ($len == strlen($tokens[$i]))) {
                    if (!isset($tokens[$k])) {
                        $k++;
                        continue;
                    }
                    $tokens[$i] .= $tokens[$k];
                    unset($tokens[$k]);
                    $k++;
                }
            }

            $i++;
        }

        return array_values($tokens);
    }
983242
private function extractConstraints($vars): array
    {
        $form = $this->getFormInterface($this->form, $vars['id']);
        $result = [];
        $required = false;
        $constraints = $form->getConfig()->getOption('constraints');
        foreach($constraints as $q=>$constraint)
        {
            $result[$q] = (array) $constraint;
            $name = explode('\\',get_class($constraint));
            $result[$q]['class'] = end($name);

            switch($result[$q]['class']) {
                case 'NotBlank':
                    $result[$q]['message'] = $this->getTranslator()->trans($result[$q]['message'], [], 'validators');
                    $required = true;
                    break;
                case 'Colour':
                    $result[$q]['message'] = $this->getTranslator()->trans($result[$q]['message'], [], 'validators');
                    break;
                case 'Length':
                    $result[$q]['maxMessage'] = $this->getTranslator()->transChoice($result[$q]['maxMessage'], $result[$q]['max'], ['{{ limit }}' => $result[$q]['max']], 'validators');
                    $result[$q]['minMessage'] = $this->getTranslator()->transChoice($result[$q]['minMessage'], $result[$q]['min'], ['{{ limit }}' => $result[$q]['min']], 'validators');
                    $result[$q]['exactMessage'] = $this->getTranslator()->transChoice($result[$q]['exactMessage'], $result[$q]['min'], ['{{ limit }}' => $result[$q]['max']], 'validators');
                    break;
                case 'Choice':
                    $result[$q]['message'] = $this->getTranslator()->trans($result[$q]['message'], [], 'validators');
                    $result[$q]['multipleMessage'] = $this->getTranslator()->trans($result[$q]['multipleMessage'], [], 'validators');
                    $result[$q]['maxMessage'] = $this->getTranslator()->transChoice($result[$q]['maxMessage'], $result[$q]['max'], ['{{ limit }}' => $result[$q]['max']], 'validators');
                    $result[$q]['minMessage'] = $this->getTranslator()->transChoice($result[$q]['minMessage'], $result[$q]['min'], ['{{ limit }}' => $result[$q]['min']], 'validators');
                    break;
                default:
                    dump($result[$q]);
                    trigger_error(sprintf('The constraint (%s) has no handler in the React Form Manager', $result[$q]['class']), E_USER_ERROR);
            }

        }
        if (! empty($vars['required']) && ! $required)
        {
            $notBlank['message'] = $this->getTranslator()->trans('The value should not be empty!', [], 'validators');
            $notBlank['class'] = 'NotBlank';
            $result[] = $notBlank;
        }
        return $result;
    }
623504
protected function findRelatedGroupSkillCounts($con)
    {
        $criteria = clone $this;
        if ($this->useAliasInSQL) {
            $alias = $this->getModelAlias();
            $criteria->removeAlias($alias);
        } else {
            $alias = '';
        }
        $this->groupSkillCounts = \gossi\trixionary\model\GroupQuery::create()
            ->joinSkillGroup($alias)
            ->mergeWith($criteria)
            ->find($con);
    }
1055056
protected function fixJoinCondition($cond)
    {
        if (!$cond) {
            return '';
        }

        $cond = $this->quoteNamesIn($cond);

        if (strtoupper(substr(ltrim($cond), 0, 3)) == 'ON ') {
            return $cond;
        }

        if (strtoupper(substr(ltrim($cond), 0, 6)) == 'USING ') {
            return $cond;
        }

        return 'ON ' . $cond;
    }
1258041
protected function parseJoin($join, $options = [])
    {
        $joinStr = '';
        if (!empty($join)) {
            foreach ($join as $item) {
                list($table, $type, $on) = $item;
                $condition = [];
                foreach ((array)$on as $val) {
                    if (strpos($val, '=')) {
                        list($val1, $val2) = explode('=', $val, 2);
                        $condition[] = $this->parseKey($val1, $options) . '=' . $this->parseKey($val2, $options);
                    } else {
                        $condition[] = $val;
                    }
                }

                $table   = $this->parseTable($table, $options);
                $joinStr .= ' ' . $type . ' JOIN ' . $table . ' ON ' . implode(' AND ', $condition);
            }
        }
        return $joinStr;
    }
610342
public function parse($schema)
    {
        $fields = $this->splitIntoFields($schema);

        foreach ($fields as $field) {
            $segments = $this->parseSegments($field);

            if ($this->fieldNeedsForeignConstraint($segments)) {
                unset($segments['options']['foreign']);

                // If the user wants a foreign constraint, then
                // we'll first add the regular field.
                $this->addField($segments);

                // And then add another field for the constraint.
                $this->addForeignConstraint($segments);

                continue;
            }

            $this->addField($segments);
        }

        return $this->schema;
    }
886779
public function getForeignKeyDDL(ForeignKey $fk)
    {
        if ($this->supportsForeignKeys($fk->getTable())) {
            return parent::getForeignKeyDDL($fk);
        }

        return '';
    }
725376
protected function _droppedConstraintsStatement()
    {
        $columns = $this->_sql->getDroppedConstraints();
        if (empty($columns)) {
            return null;
        }

        $commands = [];
        foreach ($columns as $constraint) {
            if ($constraint instanceof Primary) {
                $commands[] = 'DROP PRIMARY KEY';
            }
            if ($constraint instanceof ForeignKey) {
                $commands[] = 'DROP FOREIGN KEY '. $constraint->getName();
            }
            if ($constraint instanceof Unique) {
                $commands[] = 'DROP INDEX '. $constraint->getName();
            }
        }

        return implode(', ', $commands);
    }
450427
public function getSchemaUniqueConstraints($conn = null)
    {
        $command = $this->invoke('neo.get_constraints_command', $conn);
        $httpResponse = $command->execute();

        $responseO = $this->handleHttpResponse($httpResponse);
        $response = $responseO->getBody();
        $constraints = [];
        foreach ($response as $constraint) {
            foreach ($constraint['property_keys'] as $key) {
                $constraints[] = new UniqueConstraint($constraint['label'], $key);
            }
        }

        return $constraints;
    }
800121
public function incr_field($table, $field, $incr = 1, $cond=null)
    {
    	$incr = (int)$incr;
        if ($incr == 0) return false;
        
        $ds = $this->ds();
        $field = SqlHelper::qfield($field, $table);
        $cond = SqlHelper::parse_cond($ds,$cond);
        $sql = "UPDATE {$table} SET {$field} = {$field} + {$incr} " . (empty($cond) ? '' : "WHERE {$cond}");

        $result = Sql::write($ds, Sql::MODE_WRITE_UPDATE, [
				$sql
			]);
		return $result;
    }
210408
public function in($item, array $list, $cond = null, $not = false)
    {
        $inClause = '';

        if (null == $this->oosql_where && null == $this->oosql_in && null == $this->oosql_between) {
            $inClause .= ' WHERE ';
        } else {
            $cnd = ' AND ';

            if (null != $cond) {

                if (strtolower($cond) == 'or') {
                    $cnd = ' OR ';
                }

            }
            $inClause .= $cnd;
        }
        if ($not) {
            $item = $item . ' NOT ';
        }
        $inClause .= $item . ' IN ';

        $obj = $this;

        $list = array_map(function ($data) use ($obj) {
            return (!$obj->validInt($data)) ? $obj->quote($data) : $data;
        }, $list);

        $inClause .= '(' . implode(',', $list) . ')';

        $this->oosql_in = $inClause;

        return $this;
    }