def _setup_connection(self):
        """Ensure database is ready to fly."""
        self.conn = sqlite3.connect(self.db_path, check_same_thread=False)
        self.conn.row_factory = sqlite3.Row

        # Make sure the database is closed whenever Python exits
        # without the STOP event being fired.
        atexit.register(self._close_connection)

        # Have datetime objects be saved as integers.
        sqlite3.register_adapter(date, _adapt_datetime)
        sqlite3.register_adapter(datetime, _adapt_datetime)

        # Validate we are on the correct schema or that we have to migrate.
        cur = self.conn.cursor()

        def save_migration(migration_id):
            """Save and commit a migration to the database."""
            cur.execute('INSERT INTO schema_version VALUES (?, ?)',
                        (migration_id, dt_util.utcnow()))
            self.conn.commit()
            _LOGGER.info("Database migrated to version %d", migration_id)

        try:
            cur.execute('SELECT max(migration_id) FROM schema_version;')
            migration_id = cur.fetchone()[0] or 0

        except sqlite3.OperationalError:
            # The table does not exist.
            cur.execute('CREATE TABLE schema_version ('
                        'migration_id integer primary key, performed integer)')
            migration_id = 0

        if migration_id < 1:
            cur.execute("""
                CREATE TABLE recorder_runs (
                    run_id integer primary key,
                    start integer,
                    end integer,
                    closed_incorrect integer default 0,
                    created integer)
            """)

            cur.execute("""
                CREATE TABLE events (
                    event_id integer primary key,
                    event_type text,
                    event_data text,
                    origin text,
                    created integer)
            """)
            cur.execute(
                'CREATE INDEX events__event_type ON events(event_type)')

            cur.execute("""
                CREATE TABLE states (
                    state_id integer primary key,
                    entity_id text,
                    state text,
                    attributes text,
                    last_changed integer,
                    last_updated integer,
                    created integer)
            """)
            cur.execute('CREATE INDEX states__entity_id ON states(entity_id)')

            save_migration(1)

        if migration_id < 2:
            cur.execute("""
                ALTER TABLE events
                ADD COLUMN time_fired integer
            """)

            cur.execute('UPDATE events SET time_fired=created')

            save_migration(2)

        if migration_id < 3:
            utc_offset = self.utc_offset

            cur.execute("""
                ALTER TABLE recorder_runs
                ADD COLUMN utc_offset integer
            """)

            cur.execute("""
                ALTER TABLE events
                ADD COLUMN utc_offset integer
            """)

            cur.execute("""
                ALTER TABLE states
                ADD COLUMN utc_offset integer
            """)

            cur.execute("UPDATE recorder_runs SET utc_offset=?", [utc_offset])
            cur.execute("UPDATE events SET utc_offset=?", [utc_offset])
            cur.execute("UPDATE states SET utc_offset=?", [utc_offset])

            save_migration(3)

        if migration_id < 4:
            # We had a bug where we did not save utc offset for recorder runs.
            cur.execute(
                """UPDATE recorder_runs SET utc_offset=?
                   WHERE utc_offset IS NULL""", [self.utc_offset])

            cur.execute("""
                ALTER TABLE states
                ADD COLUMN event_id integer
            """)

            save_migration(4)

        if migration_id < 5:
            # Add domain so that thermostat graphs look right.
            try:
                cur.execute("""
                    ALTER TABLE states
                    ADD COLUMN domain text
                """)
            except sqlite3.OperationalError:
                # We had a bug in this migration for a while on dev.
                # Without this, dev-users will have to throw away their db.
                pass

            # TravisCI has Python compiled against an old version of SQLite3
            # which misses the instr method.
            self.conn.create_function(
                "instr", 2,
                lambda string, substring: string.find(substring) + 1)

            # Populate domain with defaults.
            cur.execute("""
                UPDATE states
                set domain=substr(entity_id, 0, instr(entity_id, '.'))
            """)

            # Add indexes we are going to use a lot on selects.
            cur.execute("""
                CREATE INDEX states__state_changes ON
                states (last_changed, last_updated, entity_id)""")
            cur.execute("""
                CREATE INDEX states__significant_changes ON
                states (domain, last_updated, entity_id)""")
            save_migration(5)
dataset/ETHPy150Open home-assistant/home-assistant/homeassistant/components/recorder.py/Recorder._setup_connection/original