CRUD operations implemented
This commit is contained in:
@@ -2,11 +2,20 @@ package com.philliphsu.clock2.model;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import com.philliphsu.clock2.Alarm;
|
||||
import com.philliphsu.clock2.DaysOfWeek;
|
||||
|
||||
import static com.philliphsu.clock2.DaysOfWeek.FRIDAY;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.MONDAY;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.SATURDAY;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.THURSDAY;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.TUESDAY;
|
||||
import static com.philliphsu.clock2.DaysOfWeek.WEDNESDAY;
|
||||
|
||||
/**
|
||||
* Created by Phillip Hsu on 6/24/2016.
|
||||
@@ -19,6 +28,8 @@ public class AlarmDatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
// TODO: Consider creating an inner class that implements BaseColumns
|
||||
// and defines all the columns.
|
||||
// TODO: Consider statically defining index constants for each column,
|
||||
// and then removing all cursor getColumnIndex() calls.
|
||||
private static final String TABLE_ALARMS = "alarms";
|
||||
private static final String COLUMN_ID = "_id";
|
||||
private static final String COLUMN_HOUR = "hour";
|
||||
@@ -41,6 +52,17 @@ public class AlarmDatabaseHelper extends SQLiteOpenHelper {
|
||||
private static final String COLUMN_FRIDAY = "friday";
|
||||
private static final String COLUMN_SATURDAY = "saturday";
|
||||
|
||||
// Statically define column indices for the days so we don't have
|
||||
// to call cursor.getColumnIndex(COLUMN_[DAY]). We offset the value
|
||||
// by one because COLUMN_ALARM_ID is actually first.
|
||||
private static final int INDEX_SUNDAY = SUNDAY + 1;
|
||||
private static final int INDEX_MONDAY = MONDAY + 1;
|
||||
private static final int INDEX_TUESDAY = TUESDAY + 1;
|
||||
private static final int INDEX_WEDNESDAY = WEDNESDAY + 1;
|
||||
private static final int INDEX_THURSDAY = THURSDAY + 1;
|
||||
private static final int INDEX_FRIDAY = FRIDAY + 1;
|
||||
private static final int INDEX_SATURDAY = SATURDAY + 1;
|
||||
|
||||
private static void createAlarmsTable(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TABLE_ALARMS + " ("
|
||||
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
@@ -89,6 +111,75 @@ public class AlarmDatabaseHelper extends SQLiteOpenHelper {
|
||||
// TODO: Consider changing param to Alarm.Builder so the Alarm that will be
|
||||
// built can have its ID set.
|
||||
public long insertAlarm(Alarm alarm) {
|
||||
long id = getWritableDatabase().insert(TABLE_ALARMS, null, toContentValues(alarm));
|
||||
alarm.setId(id);
|
||||
getWritableDatabase().insert(TABLE_ALARM_RECURRING_DAYS, null, toRecurrenceContentValues(id, alarm));
|
||||
return id;
|
||||
}
|
||||
|
||||
public int updateAlarm(Alarm oldAlarm, Alarm newAlarm) {
|
||||
newAlarm.setId(oldAlarm.getId());
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
int rowsUpdatedInAlarmsTable = db.update(TABLE_ALARMS,
|
||||
toContentValues(newAlarm),
|
||||
COLUMN_ID + " = " + newAlarm.getId(),
|
||||
null);
|
||||
int rowsUpdatedInRecurrencesTable = db.update(TABLE_ALARM_RECURRING_DAYS,
|
||||
toRecurrenceContentValues(newAlarm.getId(), newAlarm),
|
||||
COLUMN_ALARM_ID + " = " + newAlarm.getId(),
|
||||
null);
|
||||
if (rowsUpdatedInAlarmsTable == rowsUpdatedInRecurrencesTable && rowsUpdatedInAlarmsTable == 1) {
|
||||
return 1;
|
||||
}
|
||||
throw new IllegalStateException("rows updated in TABLE_ALARMS = " + rowsUpdatedInAlarmsTable +
|
||||
", rows updated in TABLE_ALARM_RECURRING_DAYS = " + rowsUpdatedInRecurrencesTable);
|
||||
}
|
||||
|
||||
public int deleteAlarm(Alarm alarm) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
int rowsDeletedInAlarmsTable = db.delete(TABLE_ALARMS,
|
||||
COLUMN_ID + " = " + alarm.getId(),
|
||||
null);
|
||||
int rowsDeletedInRecurrencesTable = db.delete(TABLE_ALARM_RECURRING_DAYS,
|
||||
COLUMN_ALARM_ID + " = " + alarm.getId(),
|
||||
null);
|
||||
if (rowsDeletedInAlarmsTable == rowsDeletedInRecurrencesTable && rowsDeletedInAlarmsTable == 1) {
|
||||
return 1;
|
||||
}
|
||||
throw new IllegalStateException("rows deleted in TABLE_ALARMS = " + rowsDeletedInAlarmsTable +
|
||||
", rows deleted in TABLE_ALARM_RECURRING_DAYS = " + rowsDeletedInRecurrencesTable);
|
||||
}
|
||||
|
||||
public AlarmCursor queryAlarm(long id) {
|
||||
Cursor alarmCursor = getReadableDatabase().query(TABLE_ALARMS,
|
||||
null, // All columns
|
||||
COLUMN_ID + " = " + id, // Selection for this alarm id
|
||||
null, // selection args, none b/c id already specified in selection
|
||||
null, // group by
|
||||
null, // order/sort by
|
||||
null, // having
|
||||
"1"); // limit 1 row
|
||||
Cursor recurrenceCursor = getReadableDatabase().query(TABLE_ALARM_RECURRING_DAYS,
|
||||
null, // All columns
|
||||
COLUMN_ID + " = " + id, // selection
|
||||
null, // selection args
|
||||
null, // group by
|
||||
null, // order by
|
||||
null, // having
|
||||
"1");
|
||||
return new AlarmCursor(alarmCursor, recurrenceCursor);
|
||||
}
|
||||
|
||||
public AlarmCursor queryAlarms() {
|
||||
// Select all rows and columns from both tables
|
||||
Cursor alarmCursor = getReadableDatabase().query(TABLE_ALARMS,
|
||||
null, null, null, null, null, null);
|
||||
Cursor recurrenceCursor = getReadableDatabase().query(TABLE_ALARM_RECURRING_DAYS,
|
||||
null, null, null, null, null, null);
|
||||
return new AlarmCursor(alarmCursor, recurrenceCursor);
|
||||
}
|
||||
|
||||
private ContentValues toContentValues(Alarm alarm) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_HOUR, alarm.hour());
|
||||
values.put(COLUMN_MINUTES, alarm.minutes());
|
||||
@@ -97,19 +188,62 @@ public class AlarmDatabaseHelper extends SQLiteOpenHelper {
|
||||
values.put(COLUMN_VIBRATES, alarm.vibrates());
|
||||
values.put(COLUMN_ENABLED, alarm.isEnabled());
|
||||
values.put(COLUMN_SNOOZING_UNTIL_MILLIS, alarm.snoozingUntil());
|
||||
long id = getWritableDatabase().insert(TABLE_ALARMS, null, values);
|
||||
alarm.setId(id);
|
||||
return values;
|
||||
}
|
||||
|
||||
values = new ContentValues();
|
||||
values.put(COLUMN_ALARM_ID, id);
|
||||
values.put(COLUMN_SUNDAY, alarm.isRecurring(DaysOfWeek.SUNDAY));
|
||||
values.put(COLUMN_MONDAY, alarm.isRecurring(DaysOfWeek.MONDAY));
|
||||
values.put(COLUMN_TUESDAY, alarm.isRecurring(DaysOfWeek.TUESDAY));
|
||||
values.put(COLUMN_WEDNESDAY, alarm.isRecurring(DaysOfWeek.WEDNESDAY));
|
||||
values.put(COLUMN_THURSDAY, alarm.isRecurring(DaysOfWeek.THURSDAY));
|
||||
values.put(COLUMN_FRIDAY, alarm.isRecurring(DaysOfWeek.FRIDAY));
|
||||
values.put(COLUMN_SATURDAY, alarm.isRecurring(DaysOfWeek.SATURDAY));
|
||||
getWritableDatabase().insert(TABLE_ALARM_RECURRING_DAYS, null, values);
|
||||
return id;
|
||||
// Even though the current impl of insertAlarm() sets the given id on the alarm, we require it
|
||||
// as a param just as an extra measure, in case you happen to not set it.
|
||||
private ContentValues toRecurrenceContentValues(long id, Alarm alarm) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(COLUMN_ALARM_ID, id); // *could* have used alarm.id() instead
|
||||
values.put(COLUMN_SUNDAY, alarm.isRecurring(SUNDAY));
|
||||
values.put(COLUMN_MONDAY, alarm.isRecurring(MONDAY));
|
||||
values.put(COLUMN_TUESDAY, alarm.isRecurring(TUESDAY));
|
||||
values.put(COLUMN_WEDNESDAY, alarm.isRecurring(WEDNESDAY));
|
||||
values.put(COLUMN_THURSDAY, alarm.isRecurring(THURSDAY));
|
||||
values.put(COLUMN_FRIDAY, alarm.isRecurring(FRIDAY));
|
||||
values.put(COLUMN_SATURDAY, alarm.isRecurring(SATURDAY));
|
||||
return values;
|
||||
}
|
||||
|
||||
public static class AlarmCursor extends CursorWrapper {
|
||||
|
||||
private final Cursor mRecurrenceCursor;
|
||||
|
||||
public AlarmCursor(Cursor alarmCursor, Cursor recurrenceCursor) {
|
||||
super(alarmCursor);
|
||||
mRecurrenceCursor = recurrenceCursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an Alarm instance configured for the current row,
|
||||
* or null if the current row is invalid
|
||||
*/
|
||||
public Alarm getAlarm() {
|
||||
if (isBeforeFirst() || isAfterLast())
|
||||
return null;
|
||||
Alarm alarm = Alarm.builder()
|
||||
.hour(getInt(getColumnIndex(COLUMN_HOUR)))
|
||||
.minutes(getInt(getColumnIndex(COLUMN_MINUTES)))
|
||||
.vibrates(getInt(getColumnIndex(COLUMN_VIBRATES)) == 1)
|
||||
.ringtone(getString(getColumnIndex(COLUMN_RINGTONE)))
|
||||
.label(getString(getColumnIndex(COLUMN_LABEL)))
|
||||
.build();
|
||||
alarm.setId(getLong(getColumnIndex(COLUMN_ID)));
|
||||
alarm.setEnabled(getInt(getColumnIndex(COLUMN_ENABLED)) == 1);
|
||||
alarm.setSnoozing(getLong(getColumnIndex(COLUMN_SNOOZING_UNTIL_MILLIS)));
|
||||
alarm.setRecurring(SUNDAY, isRecurring(INDEX_SUNDAY));
|
||||
alarm.setRecurring(MONDAY, isRecurring(INDEX_MONDAY));
|
||||
alarm.setRecurring(TUESDAY, isRecurring(INDEX_TUESDAY));
|
||||
alarm.setRecurring(WEDNESDAY, isRecurring(INDEX_WEDNESDAY));
|
||||
alarm.setRecurring(THURSDAY, isRecurring(INDEX_THURSDAY));
|
||||
alarm.setRecurring(FRIDAY, isRecurring(INDEX_FRIDAY));
|
||||
alarm.setRecurring(SATURDAY, isRecurring(INDEX_SATURDAY));
|
||||
return alarm;
|
||||
}
|
||||
|
||||
private boolean isRecurring(int dayColumnIndex) {
|
||||
return mRecurrenceCursor.getInt(dayColumnIndex) == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ import android.content.Context;
|
||||
|
||||
import com.philliphsu.clock2.Alarm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by Phillip Hsu on 6/25/2016.
|
||||
*
|
||||
* TODO: Not sure this class is all that useful? We could make the DbHelper singleton instance in its own class.
|
||||
*/
|
||||
public class DatabaseManager {
|
||||
|
||||
@@ -27,8 +27,40 @@ public class DatabaseManager {
|
||||
return sDatabaseManager;
|
||||
}
|
||||
|
||||
// TODO: why return an Alarm?
|
||||
public Alarm insertAlarm(Alarm alarm) {
|
||||
mHelper.insertAlarm(alarm);
|
||||
return alarm;
|
||||
}
|
||||
|
||||
public int updateAlarm(Alarm oldAlarm, Alarm newAlarm) {
|
||||
return mHelper.updateAlarm(oldAlarm, newAlarm);
|
||||
}
|
||||
|
||||
public int deleteAlarm(Alarm alarm) {
|
||||
return mHelper.deleteAlarm(alarm);
|
||||
}
|
||||
|
||||
// Since the query returns at most one row, just return the Alarm the row represents.
|
||||
public Alarm getAlarm(long id) {
|
||||
Alarm alarm = null;
|
||||
AlarmDatabaseHelper.AlarmCursor cursor = mHelper.queryAlarm(id);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
alarm = cursor.getAlarm();
|
||||
cursor.close();
|
||||
}
|
||||
return alarm;
|
||||
}
|
||||
|
||||
public ArrayList<Alarm> getAlarms() {
|
||||
ArrayList<Alarm> alarms = new ArrayList<>();
|
||||
AlarmDatabaseHelper.AlarmCursor cursor = mHelper.queryAlarms();
|
||||
if (cursor != null) {
|
||||
while (cursor.moveToNext()) {
|
||||
alarms.add(cursor.getAlarm());
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return alarms;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user