public function getOrPrepareStatement($sql)
    {
        // Return cached statements
        if (isset($this->cachedStatements[$sql])) {
            return $this->cachedStatements[$sql];
        }

        // Generate new statement
        $statement = $this->pdoConnection->prepare(
            $sql,
            array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)
        );

        // Wrap in a PDOStatementHandle, to cache column metadata
        $statementHandle = ($statement === false) ? false : new PDOStatementHandle($statement);

        // Only cache select statements
        if (preg_match('/^(\s*)select\b/i', $sql)) {
            $this->cachedStatements[$sql] = $statementHandle;
        }
        return $statementHandle;
    }