public function read($query, array $options = []) {
		$defaults = [
			'return' => is_string($query) ? 'array' : 'item',
			'schema' => null,
			'quotes' => $this->_quotes
		];
		$options += $defaults;

		$params = compact('query', 'options');

		return Filters::run($this, __FUNCTION__, $params, function($params) {
			$query = $params['query'];
			$args = $params['options'];
			$return = $args['return'];
			unset($args['return']);

			$model = is_object($query) ? $query->model() : null;

			if (is_string($query)) {
				$sql = Text::insert($query, $this->value($args));
			} else {
				if (!$data = $this->_queryExport($query)) {
					return false;
				}
				$sql = $this->renderCommand($data['type'], $data);
			}
			$result = $this->_execute($sql);

			if ($return === 'resource') {
				return $result;
			}
			if ($return === 'item') {
				return $model::create([], compact('query', 'result') + [
					'class' => 'set', 'defaults' => false
				]);
			}
			$columns = $args['schema'] ?: $this->schema($query, $result);

			if (!is_array(reset($columns))) {
				$columns = ['' => $columns];
			}

			$i = 0;
			$records = [];

			foreach ($result as $data) {
				$offset = 0;
				$records[$i] = [];

				foreach ($columns as $path => $cols) {
					$len = count($cols);
					$values = array_combine($cols, array_slice($data, $offset, $len));
					($path) ? $records[$i][$path] = $values : $records[$i] += $values;
					$offset += $len;
				}
				$i++;
			}
			return Set::expand($records);
		});
	}