package com.kuxhausen.huemore.persistence.migrations;
import com.google.gson.Gson;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.support.v4.util.ArrayMap;
import android.util.Pair;
import com.kuxhausen.huemore.R;
import com.kuxhausen.huemore.alarm.AlarmData;
import com.kuxhausen.huemore.alarm.DaysOfWeek;
import com.kuxhausen.huemore.net.hue.HueBulbData;
import com.kuxhausen.huemore.persistence.Definitions;
import com.kuxhausen.huemore.persistence.Definitions.AlarmColumns;
import com.kuxhausen.huemore.persistence.Definitions.GroupBulbColumns;
import com.kuxhausen.huemore.persistence.Definitions.GroupColumns;
import com.kuxhausen.huemore.persistence.Definitions.MoodColumns;
import com.kuxhausen.huemore.persistence.Definitions.NetBulbColumns;
import com.kuxhausen.huemore.persistence.Definitions.NetConnectionColumns;
import com.kuxhausen.huemore.persistence.Definitions.PlayingMood;
import com.kuxhausen.huemore.persistence.HueUrlEncoder;
import com.kuxhausen.huemore.persistence.migrations.DeprecatedDefinitions.DeprecatedAlarmColumns;
import com.kuxhausen.huemore.persistence.migrations.DeprecatedDefinitions.DeprecatedGroupColumns;
import com.kuxhausen.huemore.state.BulbState;
import com.kuxhausen.huemore.state.Event;
import com.kuxhausen.huemore.state.Mood;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "huemore.db";
private static final int DATABASE_VERSION = 12;
Gson gson = new Gson();
private Context mContext;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
if (!db.isReadOnly()) {
// Enable foreign key constraints
db.execSQL("PRAGMA foreign_keys=ON;");
}
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + MoodColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + MoodColumns.COL_MOOD_NAME + " TEXT,"
+ MoodColumns.COL_MOOD_VALUE
+ " TEXT"
+ ");");
db.execSQL("CREATE TABLE " + DeprecatedGroupColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + DeprecatedGroupColumns.GROUP + " TEXT,"
+ DeprecatedGroupColumns.PRECEDENCE
+ " INTEGER," + "Dbulb" + " INTEGER" + ");");
this.onUpgrade(db, 1, DATABASE_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1: {
ContentValues cv = new ContentValues();
/** update 2.4/2.5/switch to serialized b64 **/
String[] moodColumns = {MoodColumns.COL_MOOD_NAME, MoodColumns.COL_MOOD_VALUE};
Cursor cursor =
db.query(Definitions.MoodColumns.TABLE_NAME, moodColumns, null, null, null,
null, null);
HashMap<String, ArrayList<String>> moodStateMap = new HashMap<String, ArrayList<String>>();
while (cursor.moveToNext()) {
String mood = cursor.getString(0);
String state = cursor.getString(1);
if (mood != null && state != null && !mood.equals("") && !state.equals("")
&& !state.equals("{}")) {
ArrayList<String> states;
if (moodStateMap.containsKey(mood)) {
states = moodStateMap.get(mood);
} else {
states = new ArrayList<String>();
}
states.add(state);
moodStateMap.put(mood, states);
}
}
db.execSQL("DROP TABLE " + MoodColumns.TABLE_NAME);
db.execSQL("CREATE TABLE " + MoodColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + MoodColumns.COL_MOOD_NAME + " TEXT,"
+ MoodColumns.COL_MOOD_VALUE
+ " TEXT"
+ ");");
// remove standard moods that are no longer correct
String[] moodsToRemove =
{"OFF", "Reading", "Relax", "Concentrate", "Energize", "Red", "Orange", "Blue",
"Romantic", "Rainbow", ((char) 8) + "OFF", ((char) 8) + "ON", ((char) 8) + "RANDOM"};
for (String removeKey : moodsToRemove) {
moodStateMap.remove(removeKey);
}
for (String key : moodStateMap.keySet()) {
ArrayList<String> stateJson = moodStateMap.get(key);
// bug fix in case there are any empty bulbstates in the old system
for (int i = 0; i < stateJson.size(); i++) {
if (stateJson.get(i) == null
|| gson.fromJson(stateJson.get(i), BulbState.class) == null) {
stateJson.remove(i);
}
}
Event[] events = new Event[stateJson.size()];
for (int i = 0; i < stateJson.size(); i++) {
Event e = new Event(gson.fromJson(stateJson.get(i), BulbState.class), i, 0l);
events[i] = e;
}
Mood mood = new Mood.Builder()
.setNumChannels(stateJson.size())
.setEvents(events)
.build();
cv.put(MoodColumns.COL_MOOD_NAME, key);
cv.put(MoodColumns.COL_MOOD_VALUE, HueUrlEncoder.encode(mood));
db.insert(MoodColumns.TABLE_NAME, null, cv);
}
cursor.close();
}
case 2: {
db.execSQL("DROP TABLE IF EXISTS " + DeprecatedAlarmColumns.TABLE_NAME);
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + DeprecatedAlarmColumns.TABLE_NAME + " ("
+ BaseColumns._ID + " INTEGER PRIMARY KEY,"
+ DeprecatedAlarmColumns.STATE + " TEXT,"
+ DeprecatedAlarmColumns.INTENT_REQUEST_CODE + " INTEGER" + ");");
// remove the sunset mood
String[] moodArgs = {"Sunset"};
db.delete(MoodColumns.TABLE_NAME, MoodColumns.COL_MOOD_NAME + " =?", moodArgs);
}
case 3: {
//land and fall through to next case
}
case 4: {
ContentValues cv = new ContentValues();
String[] moodColumns = {MoodColumns.COL_MOOD_NAME, MoodColumns.COL_MOOD_VALUE};
Cursor moodCursor =
db.query(Definitions.MoodColumns.TABLE_NAME, moodColumns, null, null, null,
null, null);
HashMap<String, String> moodMap = new HashMap<String, String>();
while (moodCursor.moveToNext()) {
String name = moodCursor.getString(0);
String encodedMood = moodCursor.getString(1);
moodMap.put(name, encodedMood);
}
// remove any nameless moods
moodMap.remove("");
moodMap.remove(null);
//my own colors
moodMap.put("Blacklight", "AQwAAQAAACPl49NJ4s09ywYAxNIDAA==");
moodMap.put("Cyan", "AQQAAQAAACf_54NbqOJrvVAAABAABAAAAA==\uFEFF");
moodMap.put("Neon Green", "AQQAAQAAACf_570O5eFXdmkFABAABAAAAA==\uFEFF");
moodMap.put("Glow", "AQQAAQAAACf_56NDs-CHE6wDABAABAAAAA== ");
// add the stock moods (and write over old hsv versions)
moodMap.put("Reading", "BgQAAQAAjJTvChKYbxnjBwAQAAAA");
moodMap.put("Relax", "BgQAAQAAjJQfGPqQb0U5HgAQAAAA");
moodMap.put("Energize", "BgQAAQAAjJSvUGWKrywgFwAQAAAA");
moodMap.put("Concentrate", "BgQAAQAAjJSvx8qfr6eTBAAQAAAA");
moodMap.put("Deep Sea", "BgYAAQAAipSf6G-Ur9oDGCLl49NJ4s09ywYAhiICAAA=");
moodMap.put("Fruity",
"BvaHAQAAACYAwASOmB-hypSvUsQcgClifiBxUb4DwUgApoj5Fp58-EGyywCYABIUIsIqMTUBQBo=");
// add these stock moods but don't write over prior versions
if (!moodMap.containsKey("Gentle Sunrise")) {
moodMap.put("Gentle Sunrise",
"AQSAAQAAgDQApAGAJzfkJ8o85KtGLQMAk8j5riCB-ZYxfgDAZPIyfiB9bL5VtUAAMAFgwCSAQwA=");
}
if (!moodMap.containsKey("Gentle Sunset")) {
moodMap.put("Gentle Sunset",
"AQSAAQAAgDQApAGAI-cHhj7kW1GOBwCTyd34iaDH-GrSiQHAJDAAMAFgQBWAQwA=");
}
if (!moodMap.containsKey("Living Night")) {
moodMap.put("Living Night", "AfKHAAAAAEwAaGJWfu4rZb4IfDsAk4m_-TkqEvniQEQATAAEFBAVACYA");
}
if (!moodMap.containsKey("f.lux")) {
moodMap
.put("f.lux",
"AQxA5RmHN7_yNEQDWOqnAoAj5-ux8ufr6SQBAJDI-YGhD_lWlOMBACRyvitIYL5ljB8AAAFQFGIoEQAAAA==");
}
db.execSQL("DROP TABLE IF EXISTS " + MoodColumns.TABLE_NAME);
db.execSQL("CREATE TABLE " + MoodColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + MoodColumns.COL_MOOD_NAME + " TEXT,"
+ MoodColumns.COL_MOOD_VALUE
+ " TEXT"
+ ");");
for (String key : moodMap.keySet()) {
cv.put(MoodColumns.COL_MOOD_NAME, key);
cv.put(MoodColumns.COL_MOOD_VALUE, moodMap.get(key));
db.insert(MoodColumns.TABLE_NAME, null, cv);
}
moodCursor.close();
}
case 5: {
db.execSQL("CREATE TABLE " + NetConnectionColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + NetConnectionColumns.NAME_COLUMN + " TEXT,"
+ NetConnectionColumns.DEVICE_ID_COLUMN + " TEXT,"
+ NetConnectionColumns.TYPE_COLUMN
+ " INTEGER," + NetConnectionColumns.JSON_COLUMN + " TEXT" + ");");
db.execSQL("CREATE TABLE " + NetBulbColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + NetBulbColumns.NAME_COLUMN + " TEXT,"
+ NetBulbColumns.DEVICE_ID_COLUMN + " TEXT,"
+ NetBulbColumns.CONNECTION_DATABASE_ID
+ " INTEGER," + NetBulbColumns.TYPE_COLUMN + " INTEGER,"
+ NetBulbColumns.JSON_COLUMN
+ " TEXT," + NetBulbColumns.CURRENT_MAX_BRIGHTNESS + " INTEGER,"
+ " FOREIGN KEY ("
+ NetBulbColumns.CONNECTION_DATABASE_ID + ") REFERENCES "
+ NetConnectionColumns.TABLE_NAME + " (" + NetConnectionColumns._ID
+ " ) ON DELETE CASCADE " + ");");
/** Migrate the groups Database & add placeholder entries into the NetBulb table as needed */
String[] oldGroupColumns =
{DeprecatedGroupColumns._ID, DeprecatedGroupColumns.GROUP,
DeprecatedGroupColumns.PRECEDENCE, "Dbulb"};
Cursor oldGroupCursor =
db.query(DeprecatedGroupColumns.TABLE_NAME, oldGroupColumns, null, null,
null, null, null);
// load all the old group data into here <name, list of hue hub bulb <precedence, hub bulb
// number>>
HashMap<String, ArrayList<Pair<Integer, Integer>>> oldGroupMap =
new HashMap<String, ArrayList<Pair<Integer, Integer>>>();
while (oldGroupCursor.moveToNext()) {
String name = oldGroupCursor.getString(1);
int precedence = 0;
try {
precedence = oldGroupCursor.getInt(2);
} catch (Exception e) {
}
Integer bulbNumber = oldGroupCursor.getInt(3);
if (!oldGroupMap.containsKey(name)) {
oldGroupMap.put(name, new ArrayList<Pair<Integer, Integer>>());
}
oldGroupMap.get(name).add(new Pair<Integer, Integer>(precedence, bulbNumber));
}
/* remove any illegal group names */
{
oldGroupMap.remove("");
oldGroupMap.remove("ALL");
oldGroupMap.remove(((char) 8) + "ALL");
}
/* now add placeholder entries for every bulb referenced in the groups * */
// <hub bulb number, database id for corresponding NetBulb entry>
HashMap<Integer, Long> hubIdToBaseIdMapping = new HashMap<Integer, Long>();
for (String groupName : oldGroupMap.keySet()) {
for (Pair<Integer, Integer> oldPair : oldGroupMap.get(groupName)) {
int hubBulbNumber = oldPair.second;
if (!hubIdToBaseIdMapping.containsKey(hubBulbNumber)) {
ContentValues netBulbValues = new ContentValues();
netBulbValues.put(NetBulbColumns.NAME_COLUMN, "?");
netBulbValues.put(NetBulbColumns.TYPE_COLUMN, NetBulbColumns.NetBulbType.PHILIPS_HUE);
netBulbValues.putNull(NetBulbColumns.CONNECTION_DATABASE_ID);
netBulbValues.put(NetBulbColumns.DEVICE_ID_COLUMN, "" + hubBulbNumber);
netBulbValues.put(NetBulbColumns.JSON_COLUMN, gson.toJson(new HueBulbData()));
long baseId = db.insert(NetBulbColumns.TABLE_NAME, null, netBulbValues);
hubIdToBaseIdMapping.put(hubBulbNumber, baseId);
}
}
}
/* rebuild the sql tables */
db.execSQL("DROP TABLE IF EXISTS " + DeprecatedGroupColumns.TABLE_NAME);
db.execSQL("CREATE TABLE " + DeprecatedGroupColumns.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + DeprecatedGroupColumns.GROUP + " TEXT,"
+ DeprecatedGroupColumns.PRECEDENCE
+ " INTEGER," + DeprecatedGroupColumns.BULB_DATABASE_ID + " INTEGER,"
+ " FOREIGN KEY ("
+ DeprecatedGroupColumns.BULB_DATABASE_ID + ") REFERENCES "
+ NetBulbColumns.TABLE_NAME
+ " ("
+ NetBulbColumns._ID + " ) ON DELETE CASCADE " + ");");
/* now add the groups to the new table */
for (String groupName : oldGroupMap.keySet()) {
for (Pair<Integer, Integer> oldPair : oldGroupMap.get(groupName)) {
int bulbPrecidence = oldPair.first;
long bulbBaseId = hubIdToBaseIdMapping.get(oldPair.second);
ContentValues groupValues = new ContentValues();
groupValues.put(DeprecatedGroupColumns.GROUP, groupName);
groupValues.put(DeprecatedGroupColumns.PRECEDENCE, bulbPrecidence);
groupValues.put(DeprecatedGroupColumns.BULB_DATABASE_ID, bulbBaseId);
db.insert(DeprecatedGroupColumns.TABLE_NAME, null, groupValues);
}
}
oldGroupCursor.close();
}
case 6: {
//land and fall through to next case
}
case 7: {
//land and fall through to next case
}
case 8: {
//land and fall through to next case
}
case 9: {
//TODO clean previous migrations or create non-upgrade path for first run performance
ContentValues cv = new ContentValues();
String[] moodColumns = {MoodColumns.COL_MOOD_NAME, MoodColumns.COL_MOOD_VALUE};
Cursor moodCursor =
db.query(Definitions.MoodColumns.TABLE_NAME, moodColumns, null, null, null,
null, null);
HashMap<String, Pair<String, Pair<String, Integer>>>
moodMap =
new HashMap<String, Pair<String, Pair<String, Integer>>>();
while (moodCursor.moveToNext()) {
String visibleName = moodCursor.getString(0);
String encodedMood = moodCursor.getString(1);
String lowercaseName = visibleName.toLowerCase().trim();
Integer priority = 1;
while (moodMap.containsKey(lowercaseName)) {
visibleName += " 1";
lowercaseName += " 1";
}
moodMap.put(lowercaseName, new Pair<String, Pair<String, Integer>>(visibleName,
new Pair<String, Integer>(
encodedMood,
priority)
));
}
String onName = mContext.getString(R.string.cap_on);
moodMap.put(onName.toLowerCase(), new Pair<String, Pair<String, Integer>>(onName,
new Pair<String, Integer>(
getEncodedOn(),
2)
));
String offName = mContext.getString(R.string.cap_off);
moodMap.put(offName.toLowerCase(), new Pair<String, Pair<String, Integer>>(offName,
new Pair<String, Integer>(
getEncodedOff(),
2)
));
// remove any nameless moods
moodMap.remove("");
moodMap.remove(null);
db.execSQL("DROP TABLE IF EXISTS " + MoodColumns.TABLE_NAME);
db.execSQL("CREATE TABLE " + MoodColumns.TABLE_NAME + " (" +
BaseColumns._ID + " INTEGER PRIMARY KEY," +
MoodColumns.COL_MOOD_LOWERCASE_NAME + " TEXT," +
MoodColumns.COL_MOOD_NAME + " TEXT," +
MoodColumns.COL_MOOD_VALUE + " TEXT," +
MoodColumns.COL_MOOD_PRIORITY + " INTEGER," +
"UNIQUE (" + MoodColumns.COL_MOOD_LOWERCASE_NAME + ") ON CONFLICT REPLACE" +
");");
for (String key : moodMap.keySet()) {
Pair<String, Pair<String, Integer>> mapped = moodMap.get(key);
String visibleName = mapped.first;
String value = mapped.second.first;
Integer priority = mapped.second.second;
cv.put(MoodColumns.COL_MOOD_LOWERCASE_NAME, key.toLowerCase());
cv.put(MoodColumns.COL_MOOD_NAME, visibleName);
cv.put(MoodColumns.COL_MOOD_VALUE, value);
cv.put(MoodColumns.COL_MOOD_PRIORITY, priority);
db.insert(MoodColumns.TABLE_NAME, null, cv);
}
moodCursor.close();
}
case 10: {
db.execSQL("DROP TABLE IF EXISTS " + PlayingMood.TABLE_NAME);
db.execSQL("CREATE TABLE " + PlayingMood.TABLE_NAME + " (" + BaseColumns._ID
+ " INTEGER PRIMARY KEY," + PlayingMood.COL_GROUP_VALUE + " TEXT,"
+ PlayingMood.COL_MOOD_NAME + " TEXT," + PlayingMood.COL_MOOD_VALUE + " TEXT,"
+ PlayingMood.COL_MOOD_BRI + " INTEGER,"
+ PlayingMood.COL_MILI_TIME_STARTED + " INTEGER,"
+ PlayingMood.COL_INTERNAL_PROGRESS + " INTEGER"
+ ");");
}
case 11: {
/* query existing groups data */
String[] oldGroupColumns =
{DeprecatedGroupColumns.GROUP, DeprecatedGroupColumns.PRECEDENCE,
DeprecatedGroupColumns.BULB_DATABASE_ID};
Cursor oldGroupCursor =
db.query(DeprecatedGroupColumns.TABLE_NAME, oldGroupColumns, null, null, null, null,
null);
/* load all the old group data into here <name, <precedence,bulb_database_id>> */
ArrayMap<String, ArrayList<Pair<Long, Long>>>
oldGroupMapping =
new ArrayMap<String, ArrayList<Pair<Long, Long>>>();
oldGroupCursor.moveToPosition(-1);
while (oldGroupCursor.moveToNext()) {
String groupName = oldGroupCursor.getString(0);
long precedence = 0;
try {
precedence = oldGroupCursor.getLong(1);
} catch (Exception e) {
}
Long bulbDatabaseId = null;
try {
bulbDatabaseId = oldGroupCursor.getLong(2);
} catch (Exception e) {
}
Pair bulbData = new Pair<Long, Long>(precedence, bulbDatabaseId);
if (!oldGroupMapping.containsKey(groupName)) {
oldGroupMapping.put(groupName, new ArrayList<Pair<Long, Long>>());
}
oldGroupMapping.get(groupName).add(bulbData);
}
oldGroupCursor.close();
/* rebuild the sql tables */
db.execSQL("DROP TABLE IF EXISTS " + DeprecatedGroupColumns.TABLE_NAME);
db.execSQL("CREATE TABLE " + GroupColumns.TABLE_NAME + " ("
+ GroupColumns._ID + " INTEGER PRIMARY KEY,"
+ GroupColumns.COL_GROUP_NAME + " TEXT,"
+ GroupColumns.COL_GROUP_LOWERCASE_NAME + " TEXT,"
+ GroupColumns.COL_GROUP_PRIORITY + " INTEGER,"
+ GroupColumns.COL_GROUP_FLAGS + " INTEGER"
+ ");");
db.execSQL("CREATE TABLE " + GroupBulbColumns.TABLE_NAME + " ("
+ GroupBulbColumns._ID + " INTEGER PRIMARY KEY,"
+ GroupBulbColumns.COL_GROUP_ID + " INTEGER,"
+ GroupBulbColumns.COL_BULB_PRECEDENCE + " INTEGER,"
+ GroupBulbColumns.COL_NET_BULB_ID + " INTEGER,"
+ " FOREIGN KEY (" + GroupBulbColumns.COL_GROUP_ID + ") REFERENCES "
+ GroupColumns.TABLE_NAME + " (" + GroupColumns._ID + " ) ON DELETE CASCADE,"
+ " FOREIGN KEY (" + GroupBulbColumns.COL_NET_BULB_ID + ") REFERENCES "
+ NetBulbColumns.TABLE_NAME + " (" + NetBulbColumns._ID + " ) ON DELETE CASCADE"
+ ");");
/* now add existing groups to the new tables */
for (String groupName : oldGroupMapping.keySet()) {
ContentValues groupValues = new ContentValues();
groupValues.put(GroupColumns.COL_GROUP_NAME, groupName);
groupValues.put(GroupColumns.COL_GROUP_LOWERCASE_NAME, groupName.toLowerCase().trim());
groupValues.put(GroupColumns.COL_GROUP_PRIORITY, GroupColumns.PRIORITY_UNSTARRED);
groupValues.put(GroupColumns.COL_GROUP_FLAGS, GroupColumns.FLAG_NORMAL);
long groupId = db.insert(GroupColumns.TABLE_NAME, null, groupValues);
for (Pair<Long, Long> bulbData : oldGroupMapping.get(groupName)) {
Long bulbPrecedence = bulbData.first;
Long netBulbId = bulbData.second;
ContentValues groupBulbValues = new ContentValues();
groupBulbValues.put(GroupBulbColumns.COL_GROUP_ID, groupId);
groupBulbValues.put(GroupBulbColumns.COL_BULB_PRECEDENCE, bulbPrecedence);
groupBulbValues.put(GroupBulbColumns.COL_NET_BULB_ID, netBulbId);
db.insert(GroupBulbColumns.TABLE_NAME, null, groupBulbValues);
}
}
/* Now add the all group */
String allName = mContext.getString(R.string.cap_all);
ContentValues allValue = new ContentValues();
allValue.put(GroupColumns.COL_GROUP_NAME, allName);
allValue.put(GroupColumns.COL_GROUP_LOWERCASE_NAME, allName.toLowerCase().trim());
allValue.put(GroupColumns.COL_GROUP_PRIORITY, GroupColumns.PRIORITY_STARRED);
allValue.put(GroupColumns.COL_GROUP_FLAGS, GroupColumns.FLAG_ALL);
long allGroupId = db.insert(GroupColumns.TABLE_NAME, null, allValue);
String[] netBulbColumns = {NetBulbColumns._ID};
Cursor netBulbCursor =
db.query(NetBulbColumns.TABLE_NAME, netBulbColumns, null, null, null, null, null);
netBulbCursor.moveToFirst();
for (int i = 0; i < netBulbCursor.getCount(); i++) {
long netBulbId = netBulbCursor.getLong(0);
netBulbCursor.moveToNext();
ContentValues allBulbValues = new ContentValues();
allBulbValues.put(GroupBulbColumns.COL_GROUP_ID, allGroupId);
allBulbValues.put(GroupBulbColumns.COL_BULB_PRECEDENCE, i);
allBulbValues.put(GroupBulbColumns.COL_NET_BULB_ID, netBulbId);
db.insert(GroupBulbColumns.TABLE_NAME, null, allBulbValues);
}
netBulbCursor.close();
/* load everything from old alarms table */
ContentValues cv = new ContentValues();
String[]
oldAlarmColumns =
{DeprecatedAlarmColumns.STATE,
DeprecatedAlarmColumns.INTENT_REQUEST_CODE};
Cursor
oldAlarmsCursor =
db.query(DeprecatedAlarmColumns.TABLE_NAME, oldAlarmColumns, null, null,
null, null, null);
ArrayList<Pair<DeprecatedAlarmState, Long>>
oldList = new ArrayList<Pair<DeprecatedAlarmState, Long>>();
oldAlarmsCursor.moveToPosition(-1);
while (oldAlarmsCursor.moveToNext()) {
String jsonOldState = oldAlarmsCursor.getString(0);
long oldIntentRequestCode = oldAlarmsCursor.getLong(1);
DeprecatedAlarmState oldState = gson.fromJson(jsonOldState, DeprecatedAlarmState.class);
oldList.add(new Pair<DeprecatedAlarmState, Long>(oldState, oldIntentRequestCode));
}
oldAlarmsCursor.close();
/* restructure alarms table */
db.execSQL("DROP TABLE IF EXISTS " + DeprecatedAlarmColumns.TABLE_NAME);
db.execSQL("CREATE TABLE " + AlarmColumns.TABLE_NAME + " (" +
BaseColumns._ID + " INTEGER PRIMARY KEY," +
AlarmColumns.COL_GROUP_ID + " INTEGER," +
AlarmColumns.COL_MOOD_ID + " INTEGER," +
AlarmColumns.COL_BRIGHTNESS + " INTEGER," +
AlarmColumns.COL_IS_ENABLED + " INTEGER," +
AlarmColumns.COL_REPEAT_DAYS + " INTEGER," +
AlarmColumns.COL_YEAR + " INTEGER," +
AlarmColumns.COL_MONTH + " INTEGER," +
AlarmColumns.COL_DAY_OF_MONTH + " INTEGER," +
AlarmColumns.COL_HOUR_OF_DAY + " INTEGER," +
AlarmColumns.COL_MINUTE + " INTEGER," +
" FOREIGN KEY (" + AlarmColumns.COL_MOOD_ID + ") REFERENCES " +
MoodColumns.TABLE_NAME + " (" + MoodColumns._ID + " ) ON DELETE CASCADE " +
");");
/* now save all the migrated data to the new table */
for (Pair<DeprecatedAlarmState, Long> oldRow : oldList) {
DeprecatedAlarmState oldState = oldRow.first;
AlarmData alarm = new AlarmData();
String[] groupCols = {GroupColumns._ID};
String groupWhere = GroupColumns.COL_GROUP_NAME + " =?";
String[] groupWhereArgs = {oldState.group};
Cursor
groupCursor =
db.query(GroupColumns.TABLE_NAME, groupCols, groupWhere, groupWhereArgs, null, null,
null);
if (groupCursor.moveToFirst()) {
alarm.setGroup(groupCursor.getLong(0), oldState.group);
groupCursor.close();
} else {
groupCursor.close();
//this group doesn't actually exist, so this alarm must be discarded
continue;
}
String[] moodCols = {MoodColumns._ID};
String[] moodArgs = {oldState.mood};
Cursor
moodCursor =
db.query(MoodColumns.TABLE_NAME, moodCols, MoodColumns.COL_MOOD_NAME + " =?",
moodArgs, null, null, null);
if (moodCursor.moveToFirst()) {
alarm.setMood(moodCursor.getLong(0), oldState.mood);
} else {
//this mood doesn't actually exist, so this alarm must be discarded
continue;
}
alarm.setBrightness(oldState.brightness);
alarm.setEnabled(oldState.isScheduled());
if (oldState.isRepeating()) {
DaysOfWeek days = new DaysOfWeek();
for (int i = 0; i < 7; i++) {
days.setDay(i + 1, oldState.getRepeatingDays()[i]);
}
alarm.setRepeatDays(days);
}
Long timeInMillis = null;
if (oldState.isRepeating()) {
for (Long daysTime : oldState.getRepeatingTimes()) {
if (daysTime != null) {
timeInMillis = daysTime;
}
}
} else {
timeInMillis = oldState.getRepeatingTimes()[0];
}
if (timeInMillis != null) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(timeInMillis);
alarm.setAlarmTime(cal);
} else {
//this alarm time is invalid, so this alarm must be discarded
continue;
}
db.insert(AlarmColumns.TABLE_NAME, null, alarm.getValues());
moodCursor.close();
}
oldAlarmsCursor.close();
}
}
}
private static String getEncodedOn() {
BulbState resultState = new BulbState();
resultState.setOn(true);
resultState.setEffect(BulbState.Effect.NONE);
return HueUrlEncoder.encode(new Mood.Builder(resultState).build());
}
private static String getEncodedOff() {
BulbState resultState = new BulbState();
resultState.setOn(false);
resultState.setEffect(BulbState.Effect.NONE);
return HueUrlEncoder.encode(new Mood.Builder(resultState).build());
}
}