package co.touchlab.droidconandroid.data; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import org.jetbrains.annotations.NotNull; import java.sql.SQLException; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import co.touchlab.droidconandroid.data.staff.EventAttendee; import co.touchlab.droidconandroid.presenter.AppManager; import co.touchlab.droidconandroid.tasks.persisted.RefreshScheduleData; import co.touchlab.squeaky.dao.Dao; import co.touchlab.squeaky.db.sqlite.SQLiteDatabaseImpl; import co.touchlab.squeaky.db.sqlite.SqueakyOpenHelper; import co.touchlab.squeaky.table.TableUtils; /** * Created by kgalligan on 6/28/14. */ public class DatabaseHelper extends SqueakyOpenHelper { private static final String DATABASE_FILE_NAME = "droidcon"; public static final int BASELINE = 3; private static final int VOTE = 4; private static final int STREAM = 5; private static final int VERSION = STREAM; private static DatabaseHelper instance; // @reminder Ordering matters, create foreign key dependant classes later private final Class[] tableClasses = new Class[] {Venue.class, Event.class, Block.class, Invite.class, UserAccount.class, EventAttendee.class, EventSpeaker.class, TalkSubmission.class}; private Context context; private DatabaseHelper(Context context) { super(context, DATABASE_FILE_NAME, null, VERSION); this.context = context; } @NotNull public static synchronized DatabaseHelper getInstance(Context context) { if(instance == null) { instance = new DatabaseHelper(context); } return instance; } @Override public void onCreate(SQLiteDatabase db) { try { TableUtils.createTables(new SQLiteDatabaseImpl(db), tableClasses); } catch(SQLException e) { throw new RuntimeException(e); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if(oldVersion < VOTE) { try { TableUtils.createTables(new SQLiteDatabaseImpl(db), TalkSubmission.class); } catch(SQLException e) { throw new RuntimeException(e); } } if(oldVersion < STREAM) { try { TableUtils.dropTables(new SQLiteDatabaseImpl(db), false, Event.class); TableUtils.createTables(new SQLiteDatabaseImpl(db), Event.class); } catch(SQLException e) { throw new RuntimeException(e); } } RefreshScheduleData.callMe(context); } @Override public void onOpen(SQLiteDatabase db) { super.onOpen(db); db.execSQL("PRAGMA foreign_keys=ON;"); } @NotNull public Dao<Venue> getVenueDao() { return (Dao<Venue>) getDao(Venue.class); } @NotNull public Dao<Event> getEventDao() { return (Dao<Event>) getDao(Event.class); } @NotNull public Dao<UserAccount> getUserAccountDao() { return (Dao<UserAccount>) getDao(UserAccount.class); } @NotNull public Dao<EventSpeaker> getEventSpeakerDao() { return (Dao<EventSpeaker>) getDao(EventSpeaker.class); } @NotNull public Dao<Block> getBlockDao() { return (Dao<Block>) getDao(Block.class); } @NotNull public Dao<TalkSubmission> getTalkSubDao() { return (Dao<TalkSubmission>) getDao(TalkSubmission.class); } public void deleteEventsNotIn(Set<Long> goodStuff) throws SQLException { final Dao<Event> eventDao = getEventDao(); final List<Event> allEvents = eventDao.queryForAll().list(); final Iterator<Event> iterator = allEvents.iterator(); while(iterator.hasNext()) { Event event = iterator.next(); if(goodStuff.contains(event.id)) iterator.remove(); } if(allEvents.size() > 0) eventDao.delete(allEvents); } /** * @param transaction . * @throws RuntimeException on {@link SQLException} */ public void performTransactionOrThrowRuntime(Callable<Void> transaction) { SQLiteDatabase db = getWritableDatabase(); try { db.beginTransaction(); transaction.call(); db.setTransactionSuccessful(); } catch(Exception e) { AppManager.getPlatformClient().logException(e); throw new RuntimeException(e); } finally { db.endTransaction(); } } public void inTransaction(final Runnable r) { performTransactionOrThrowRuntime(new Callable<Void>() { @Override public Void call() throws Exception { r.run(); return null; } }); } }