Select json.
@param  string|array $field
@param  string       $as
@param  string       $type
@param  bool         $reset
@return self
@throws Oppa\Query\BuilderException
777013
public function selectJson($field, string $as, string $type = 'object', bool $reset = true): self
    {
        if (!in_array($type, ['object', 'array'])) {
            throw new BuilderException("Given JSON type '{$type}' is not implemented!");
        }

        $reset && $this->reset();

        static $server, $serverVersion, $serverVersionMin, $fnJsonObject, $fnJsonArray, $toField, $toJson;

        if ($server == null) {
            if ($this->agent->isMysql()) {
                $server = 'MySQL'; $serverVersionMin = '5.7.8';
                $fnJsonObject = 'json_object'; $fnJsonArray = 'json_array';
            } elseif ($this->agent->isPgsql()) {
                $server = 'PostgreSQL'; $serverVersionMin = '9.4';
                $fnJsonObject = 'json_build_object'; $fnJsonArray = 'json_build_array';
            }

            $serverVersion = $this->link->getDatabase()->getInfo('serverVersion');
            if (version_compare($serverVersion, $serverVersionMin) == -1) {
                throw new BuilderException(sprintf('JSON not supported by %s/v%s, minimum v%s required',
                    $server, $serverVersion, $serverVersionMin));
            }

            $toField = function ($field) {
                switch ($field) {
                    case 'null':
                        return null;
                    case 'true':
                    case 'false':
                        return ($field == 'true') ? true : false;
                    default:
                        if (is_numeric($field)) {
                            $field = strpos($field, '.') === false ? intval($field) : floatval($field);
                        } elseif ($field && $field[0] == '@') {
                            $field = $this->agent->escapeIdentifier($field);
                        } else {
                            $field = $this->agent->escape($field);
                        }
                }
                return $field;
            };

            $toJson = function ($values) use (&$toJson, &$toField, $fnJsonArray, $fnJsonObject) {
                $json = [];
                foreach ($values as $key => $value) {
                    $keyType = gettype($key);
                    $valueType = gettype($value);
                    if ($valueType == 'array') {
                        // eg: 'bar' => ['baz' => ['a', ['b' => ['c:d'], ...]]]
                        $json[] = is_string($key) ? $this->agent->quote(trim($key)) .', '. $toJson($value)
                            : $toJson($value);
                    } elseif ($keyType == 'integer') {
                        // eg: ['uid: @u.id' or 'uid' => '@u.id', 'user' => ['id: @u.id' or 'id' => '@u.id', ...], ...]
                        if ($valueType == 'string' && strpbrk($value, ',:')) {
                            if (strpos($value, ',')) {
                                $json[] = $toJson(Util::split(',', $value));
                            } elseif (strpos($value, ':')) {
                                [$key, $value] = Util::split(':', $value, 2);
                                if (!isset($key, $value)) {
                                    throw new BuilderException('Field name and value must be given fo JSON objects!');
                                }

                                if (!isset($json[0])) {
                                    $json[0] = $fnJsonObject; // tick
                                }

                                $json[] = $this->agent->quote(trim($key)) .', '. $toField($value);
                            }
                        } else {
                            // eg: ['u.id', '@u.name', 1, 2, 3, true, ...]
                            if ($valueType == 'integer') {
                                $value = $toField($value);
                            }

                            if (!isset($json[0])) {
                                $json[0] = $fnJsonArray; // tick
                            }

                            $json[] = $value;
                        }
                    } elseif ($keyType == 'string') {
                        // eg: ['uid' => '@u.id']
                        if (!isset($json[0])) {
                            $json[0] = $fnJsonObject; // tick
                        }

                        $json[] = $this->agent->quote(trim($key)) .', '. $toField($value);
                    }
                }

                if ($json) {
                    $fn = array_shift($json);
                    $json = $fn ? $fn .'('. join(', ', $json) .')' : '';
                    if (substr($json, -2) == '()') { // .. :(
                        $json = substr($json, 0, -2);
                    }
                    return $json;
                }

                return null;
            };
        }

        $json = [];
        $jsonJoins = false;
        if (is_string($field)) {
            foreach (Util::split(',', $field) as $field) {
                if ($type == 'object') {
                    // eg: 'id: @id, ...'
                    [$key, $value] = Util::split(':', $field, 2);
                    if (!isset($key, $value)) {
                        throw new BuilderException('Field name and value must be given fo JSON objects!');
                    }
                    $json[] = $this->agent->quote(trim($key));
                    $json[] = $toField($value);
                } elseif ($type == 'array') {
                    // eg: 'id, ...'
                    $json[] = $toField($field);
                }
            }
        } elseif (is_array($field)) {
            $keyIndex = 0;
            foreach ($field as $key => $value) {
                $keyType = gettype($key);
                if ($type == 'object') {
                    // eg: ['id' => '@id', ... or 0 => 'id: @id, ...', ...]
                    if ($keyType == 'integer') {
                        $value = Util::split(',', $value);
                    } elseif ($keyType != 'string') {
                        throw new BuilderException("Field name must be string, {$keyType} given!");
                    }

                    if (is_array($value)) {
                        if ($keyType == 'string') {
                            // eg: ['id' => '@id', ...]
                            $key = $this->agent->quote(trim($key));
                            $json[$keyIndex][$key] = $toJson($value);
                        } else {
                            // eg: [0 => 'id: @id, ...', ...]
                            $value = $toJson($value);
                            $value = preg_replace('~json(?:_build)?_(?:object|array)\((.+)\)$~', '\1', $value); // :(
                            $json[$keyIndex][] = [$value];
                        }
                        $jsonJoins = true;
                        continue;
                    } elseif (is_string($value)) {
                        $key = $this->agent->quote(trim($key));
                        $json[$keyIndex][$key] = $toJson(Util::split(',', $value));
                        $jsonJoins = true;
                        continue;
                    }

                    $json[] = $key .', '. $toField($value);
                } elseif ($type == 'array') {
                    // eg: ['@id', '@name', ...]
                    if ($keyType != 'integer') {
                        throw new BuilderException("Field name must be int, {$keyType} given!");
                    }
                    $json[] = $toField($value);
                }
                $keyIndex++;
            }
        } else {
            throw new BuilderException(sprintf('String and array fields accepted only, %s given!',
                gettype($field)));
        }

        $as = $this->agent->quoteField($as);
        $fn = ($type == 'object') ? $fnJsonObject : $fnJsonArray;

        if ($jsonJoins) {
            $jsonJoins = [];
            foreach ($json[0] as $key => $value) {
                $jsonJoins[] = is_array($value) ? join(', ', $value) : $key .', '. $value;
            }
            $json = $jsonJoins;
        }

        return $this->push('select', sprintf('%s(%s) AS %s', $fn, join(', ', $json), $as));
    }
262579
public List<String> updateType(String typeAsJson) throws AtlasServiceException {
        LOG.debug("Updating type definition: {}", typeAsJson);
        JSONObject response = callAPIWithBody(API.UPDATE_TYPE, typeAsJson);
        List<String> results = extractResults(response, AtlasClient.TYPES, new ExtractOperation<String, JSONObject>() {
            @Override
            String extractElement(JSONObject element) throws JSONException {
                return element.getString(AtlasClient.NAME);
            }
        });
        LOG.debug("Update type definition returned results: {}", results);
        return results;
    }
586334
public function setFilterSelect(
        string $field,
        array $array,
        string $class = '',
        string $style = '',
        string $placeholder = ''
    ): ColumnInterface {
        return $this->setFilter($field, $array, self::FILTER_TYPE_SELECT, [], $class, $style, $placeholder);
    }
986411
public function asType(Type $type)
    {
        if ($this->nullable) {
            $type = $type->nullable();
        }

        $this->invokeCallback($type);

        if ($this->indexName) {
            if ($this->isUnique) {
                $this->definition->unique($this->indexName)->on($this->name);
            } else {
                $this->definition->index($this->indexName)->on($this->name);
            }
        }
    }
332102
protected function buildFilter($field, $type, $filter, $value)
    {
        if ((is_array($value) && count($value) != 2)
                || (!is_array($value) && ($value !== false && strlen($value) == 0))) {
            return false;
        }
        if (strlen($field) == 0)
            throw new \Exception("Empty 'field'");
        if (strlen($type) == 0)
            throw new \Exception("Empty 'type'");

        if ($type == Table::TYPE_DATETIME) {
            if ($filter == Table::FILTER_BETWEEN
                    && is_array($value) && count($value) == 2) {
                $value = [
                    $value[0] ? new MongoDate($value[0]) : null,
                    $value[1] ? new MongoDate($value[1]) : null,
                ];
            } else if ($filter != Table::FILTER_BETWEEN
                    && is_scalar($value)) {
                $value = new MongoDate($value);
            } else {
                return false;
            }
        } else {
            if ($filter == Table::FILTER_BETWEEN) {
                if (!is_array($value) || count($value) != 2)
                    return false;
            } else if (!is_scalar($value)) {
                return false;
            }
        }

        switch ($filter) {
            case Table::FILTER_LIKE:
                if (!(isset($this->andOps[$field])))
                    $this->andOps[$field] = [];
                $this->andOps[$field][] = [
                    'operator'  => 'equals',
                    'value'     => new MongoRegex('/.*' . preg_quote($value) . '.*/i'),
                ];
                break;
            case Table::FILTER_EQUAL:
                if (!(isset($this->andOps[$field])))
                    $this->andOps[$field] = [];
                $this->andOps[$field][] = [
                    'operator'  => 'equals',
                    'value'     => $value,
                ];
                break;
            case Table::FILTER_BETWEEN:
                if (!(isset($this->andOps[$field])))
                    $this->andOps[$field] = [];
                $this->andOps[$field][] = [
                    'operator'  => 'range',
                    'value1'    => $value[0],
                    'value2'    => $value[1],
                ];
                break;
            case Table::FILTER_NULL:
                if (!(isset($this->andOps[$field])))
                    $this->andOps[$field] = [];
                $this->andOps[$field][] = [
                    'operator'  => 'exists',
                    'value'     => false,
                ];
                break;
            default:
                throw new \Exception("Unknown filter: $filter");
        }

        return true;
    }
375927
public function format_json($field)
    {
        if (!is_scalar($this->current_row[$field])) {
            $this->current_row[$field] = json_encode($this->current_row[$field]);
        }
    }
619176
public function joinUsing(string $to, string $as, string $using, $usingParams = null, string $type = ''): self
    {
        return $this->push('join', sprintf('%sJOIN %s AS %s USING (%s)',
            $type ? strtoupper($type) .' ' : '',
            $this->prepareField($to),
            $this->agent->quoteField($as),
            $this->agent->prepareIdentifier($using, $usingParams))
        );
    }
1229705
protected function setDataType(Field & $field, $type)
    {
        $map = $this->dataTypeMap();

        if (array_key_exists($type, $map)) {
            $field->dataType = $map[$type];
        }

        return $this;
    }
473606
public function getField($field)
    {
        $result = array_filter($this->getFields(), function($input) use ($field) {
            return $field === $input->getName();
        });

        return reset($result);
    }
452623
public function loadElement($type, $key)
    {
        $json = $this->load();
        $fields = array();
        $columns = $json[$type]["elements"][$key]["columns"];

        //Check if it is an array before trying to count it
        if (is_array($columns) && count($columns) > 0) {
            foreach ($columns as $fieldName) {
                $fields[$fieldName] = $json[$type]["tca"][$fieldName];
            }
        }
        if (count($fields) > 0) {
            $json[$type]["elements"][$key]["tca"] = $fields;
        }
        return $json[$type]["elements"][$key];
    }
1214857
public function serializeSchemaTypeToJson(
        JsonSerializationVisitor $visitor,
        SchemaType $schemaType,
        array $type,
        Context $context
    ) {
        $types = $schemaType->getTypes();

        if (count($types) === 1) {
            return array_pop($types);
        }

        return $types;
    }
1298979
public function selectMax(string $field, $as=FALSE): QueryBuilderInterface
	{
		// Create the select string
		$this->state->appendSelectString(' MAX'.$this->_select($field, $as));
		return $this;
	}
570121
public function setJSON($json)
    {
        global $CFG;
        $PDOX = $this->launch->pdox;

        $stmt = $PDOX->queryDie(
            "UPDATE {$CFG->dbprefix}lti_result SET json = :json, updated_at = NOW()
                WHERE result_id = :RID",
            array(
                ':json' => $json,
                ':RID' => $this->id)
        );
    }
222229
public function level($field = 'level', $type = 'integer', callable $callback = null)
    {
        $this->validateNumericField($type, $field);

        $this->mapField($type, $field, $callback);

        $this->level = $field;

        return $this;
    }
1619
protected function buildFilter($field, $type, $filter, $value)
    {
        if (strlen($field) == 0)
            throw new \Exception("Empty 'field'");
        if (strlen($type) == 0)
            throw new \Exception("Empty 'type'");

        if ($type == Table::TYPE_DATETIME) {
            if ($filter == Table::FILTER_BETWEEN
                    && is_array($value) && count($value) == 2) {
                $value = [
                    $value[0] ? new \DateTime('@' . $value[0]) : null,
                    $value[1] ? new \DateTime('@' . $value[1]) : null,
                ];
                if ($value[0] && $this->getDbTimezone())
                    $value[0]->setTimezone(new \DateTimeZone($this->getDbTimezone()));
                if ($value[1] && $this->getDbTimezone())
                    $value[1]->setTimezone(new \DateTimeZone($this->getDbTimezone()));
            } else if ($filter != Table::FILTER_BETWEEN
                    && !is_array($value)) {
                $value = new \DateTime('@' . $value);
                if ($this->getDbTimezone())
                    $value->setTimezone(new \DateTimeZone($this->getDbTimezone()));
            } else {
                return false;
            }
        } else {
            if ($filter == Table::FILTER_BETWEEN) {
                if (!is_array($value) || count($value) != 2)
                    return false;
            } else if (is_array($value)) {
                return false;
            }
        }

        if (!isset($this->sqlAnds[$field]))
            $this->sqlAnds[$field] = [];

        $paramBaseName = 'dt_' . str_replace('.', '_', $field);
        switch ($filter) {
            case Table::FILTER_LIKE:
                $param = ':' . $paramBaseName . '_like';
                $this->sqlAnds[$field][] = "$field LIKE $param";
                $this->sqlParams[$param] = '%' . $value . '%';
                break;
            case Table::FILTER_EQUAL:
                $param = ':' . $paramBaseName . '_equal';
                $this->sqlAnds[$field][] = "$field = $param";
                $this->sqlParams[$param] = $value;
                break;
            case Table::FILTER_BETWEEN:
                $ands = [];
                if ($value[0] !== null) {
                    $param = ':' . $paramBaseName . '_begin';
                    $ands[] = "$field >= $param";
                    $this->sqlParams[$param] = $value[0];
                }
                if ($value[1] !== null) {
                    $param = ':' . $paramBaseName . '_end';
                    $ands[] = "$field <= $param";
                    $this->sqlParams[$param] = $value[1];
                }
                $this->sqlAnds[$field][] = join(' AND ', $ands);
                break;
            case Table::FILTER_NULL:
                $this->sqlAnds[$field][] = "$field IS NULL";
                break;
            default:
                throw new \Exception("Unknown filter: $filter");
        }

        return true;
    }
705577
public function select($fields = null, $where = null, $orderBy = null, $limit = null): Statement
    {
        $this->operation = 'select';
        return $this->setSelectArgument($fields, $where, $orderBy, $limit);
    }
340108
public function select($fields=null)
    {
        if (func_num_args() > 1) {
            $fields = func_get_args();
        }
        $this->getQuery()->type('select')->fields($fields);
        return $this;
    }