protected function openDatabase()
    {
        $this->pdo_conn = false;

        if ($this->use_database) {
            $pdo_extension = 'PDO_' . strtoupper($this->database_driver);

            if (!extension_loaded($pdo_extension)) {
                trigger_error("Database support is turned on in Securimage, but the chosen extension $pdo_extension is not loaded in PHP.", E_USER_WARNING);
                return false;
            }
        }

        if ($this->database_driver == self::SI_DRIVER_SQLITE3) {
            if (!file_exists($this->database_file)) {
                $fp = fopen($this->database_file, 'w+');
                if (!$fp) {
                    $err = error_get_last();
                    trigger_error("Securimage failed to create SQLite3 database file '{$this->database_file}'. Reason: {$err['message']}", E_USER_WARNING);
                    return false;
                }
                fclose($fp);
                chmod($this->database_file, 0666);
            } else if (!is_writeable($this->database_file)) {
                trigger_error("Securimage does not have read/write access to database file '{$this->database_file}. Make sure permissions are 0666 and writeable by user '" . get_current_user() . "'", E_USER_WARNING);
                return false;
            }
        }

        try {
            $dsn = $this->getDsn();

            $options = array();
            $this->pdo_conn = new PDO($dsn, $this->database_user, $this->database_pass, $options);
        } catch (PDOException $pdoex) {
            trigger_error("Database connection failed: " . $pdoex->getMessage(), E_USER_WARNING);
            return false;
        } catch (Exception $ex) {
            trigger_error($ex->getMessage(), E_USER_WARNING);
            return false;
        }

        try {
            if (!$this->skip_table_check && !$this->checkTablesExist()) {
                // create tables...
                $this->createDatabaseTables();
            }
        } catch (Exception $ex) {
            trigger_error($ex->getMessage(), E_USER_WARNING);
            $this->pdo_conn = false;
            return false;
        }

        if (mt_rand(0, 100) / 100.0 == 1.0) {
            $this->purgeOldCodesFromDatabase();
        }

        return $this->pdo_conn;
    }