public function query($query, $return_set = false, $buffered = true){

		$query = trim($query);

		$Result = @$this->_Connection->query($query);

		// Formatting takes some time, so explicitly check FireLogger's state

		if(!($Result instanceof \SQLite3Result)){

			$message = sprintf(
				'Invalid query, SQLite returned "%s" (code: %s)',
				$this->_Connection->lastErrorMsg(),
				$this->_Connection->lastErrorCode()
			);

			throw new QueryException($message);
		}

		$matches = [];

		/** @noinspection PhpUnusedLocalVariableInspection */
		$match_count = preg_match('/^([\w]+)(?:[\W]+|$)/i', $query, $matches);
		assert('$match_count === 1');

		$query_type = strtoupper($matches[1]);

		switch($query_type){

			case 'SELECT':
			case 'SHOW':

				/*
				 * Figure out how many rows are in the result-set.
				 *
				 * This is "a bit" brute-force, but there still (as of May 2014)
				 * doesn't appear to be a better way to do this. This wrapper is
				 * intended for convenience, not for optimal performance, so
				 * let's not worry too much about this...
				 */

				$row1 = $Result->fetchArray(SQLITE3_NUM);

				$num_rows = 0;

				if(!empty($row1) && is_array($row1)){

					$num_rows = 1;
					$row2 = $Result->fetchArray(SQLITE3_NUM);

					if(!empty($row2) && is_array($row2)){

						$num_rows = 2;
					}
				}

				$Result->reset();

				if($return_set && $num_rows >= 1){

					return new SQLiteResultSet($Result, $buffered);
				}
				elseif($num_rows == 1){

					return new SQLiteResultRow($Result);
				}
				elseif($num_rows > 1){

					return new SQLiteResultSet($Result, $buffered);
				}
				else{

					return false;
				}

			break;

			case 'DELETE':
			case 'INSERT':
			case 'REPLACE':
			case 'UPDATE':

				return $this->getAffectedRows();

			break;

			default:

				return false;
		}
	}