package com.battlelancer.seriesguide.provider;

import android.arch.persistence.db.SupportSQLiteDatabase;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.migration.Migration;
import android.content.Context;
import android.support.annotation.NonNull;
import com.battlelancer.seriesguide.model.Episode;
import com.battlelancer.seriesguide.model.List;
import com.battlelancer.seriesguide.model.Season;
import com.battlelancer.seriesguide.model.Show;
import com.uwetrottmann.androidutils.AndroidUtils;

@Database(
        entities = {
                Show.class,
                Season.class,
                Episode.class,
                List.class
        },
        version = SgRoomDatabase.VERSION
)
public abstract class SgRoomDatabase extends RoomDatabase {

    private static final int VERSION_43_ROOM = 43;
    public static final int VERSION = VERSION_43_ROOM;

    private static SgRoomDatabase INSTANCE;

    public abstract ShowHelper showHelper();

    private static final Object sLock = new Object();

    static final Callback CALLBACK = new Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            // manually create FTS table not supported by Room
            if (AndroidUtils.isJellyBeanOrHigher()) {
                db.execSQL(SeriesGuideDatabase.CREATE_SEARCH_TABLE);
            } else {
                db.execSQL(SeriesGuideDatabase.CREATE_SEARCH_TABLE_API_ICS);
            }
        }
    };

    static final Migration MIGRATION_42_43 = new Migration(
            SeriesGuideDatabase.DBVER_42_JOBS, VERSION_43_ROOM) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            // Room uses an own database hash to uniquely identify the database
            // Since version 42 does not use Room, it doesn't have the database hash associated.
            // By implementing a Migration class, we're telling Room that it should use the data
            // from version 42 to version 43.
            // If no migration is provided, then the tables will be dropped and recreated.
            // Since we didn't alter the tables, there's not much to do here.

            // Room does not support UNIQUE constraints, so use unique indexes instead (probably
            // faster anyhow)
            database.execSQL("CREATE UNIQUE INDEX `index_lists_list_id` ON `lists` (`list_id`)");
        }
    };

    public static SgRoomDatabase getInstance(Context context) {
        synchronized (sLock) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        SgRoomDatabase.class, SeriesGuideDatabase.DATABASE_NAME)
                        .addMigrations(MIGRATION_42_43)
                        .addCallback(CALLBACK)
                        .build();
            }
            return INSTANCE;
        }
    }
}

@@ -1003,32 +1003,41 @@
  private static 
+volatile 
 SgRoomDatabase I
@@ -1035,24 +1035,24 @@
 atabase 
-INSTANCE
+instance
 ;%0A%0A    p
@@ -1061,93 +1061,756 @@
 lic 
-abstract ShowHelper showHelper();%0A%0A    private static final Object sLock = new Object
+static SgRoomDatabase getInstance(Context context) %7B%0A        SgRoomDatabase result = instance;%0A        if (result == null) %7B // First check (no locking)%0A            synchronized (SgRoomDatabase.class) %7B%0A                result = instance;%0A                if (result == null) %7B // Second check (with locking)%0A                    result = instance = Room.databaseBuilder(context.getApplicationContext(),%0A                            SgRoomDatabase.class, SeriesGuideDatabase.DATABASE_NAME)%0A                            .addMigrations(MIGRATION_42_43)%0A                            .addCallback(CALLBACK)%0A                            .build();%0A                %7D%0A            %7D%0A        %7D%0A        return result;%0A    %7D%0A%0A    public abstract ShowHelper showHelper
 ();%0A
@@ -3214,497 +3214,7 @@
   %7D;
-%0A%0A    public static SgRoomDatabase getInstance(Context context) %7B%0A        synchronized (sLock) %7B%0A            if (INSTANCE == null) %7B%0A                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),%0A                        SgRoomDatabase.class, SeriesGuideDatabase.DATABASE_NAME)%0A                        .addMigrations(MIGRATION_42_43)%0A                        .addCallback(CALLBACK)%0A                        .build();%0A            %7D%0A            return INSTANCE;%0A        %7D%0A    %7D
 %0A%7D%0A

Access instance faster with double-checked locking.