mirror of
https://github.com/SimpleMobileTools/Simple-Calendar.git
synced 2025-06-05 21:59:17 +02:00
convert DBHelper to kotlin
This commit is contained in:
@@ -30,7 +30,7 @@ public class CalendarImpl implements DBHelper.DBOperationsListener {
|
|||||||
mTargetDate = targetDate;
|
mTargetDate = targetDate;
|
||||||
final int startTS = Formatter.getDayStartTS(Formatter.getDayCodeFromDateTime(mTargetDate.minusMonths(1)));
|
final int startTS = Formatter.getDayStartTS(Formatter.getDayCodeFromDateTime(mTargetDate.minusMonths(1)));
|
||||||
final int endTS = Formatter.getDayEndTS(Formatter.getDayCodeFromDateTime(mTargetDate.plusMonths(1)));
|
final int endTS = Formatter.getDayEndTS(Formatter.getDayCodeFromDateTime(mTargetDate.plusMonths(1)));
|
||||||
DBHelper.newInstance(mContext, this).getEvents(startTS, endTS);
|
DBHelper.Companion.newInstance(mContext, this).getEvents(startTS, endTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getPrevMonth() {
|
public void getPrevMonth() {
|
||||||
|
@@ -1,297 +0,0 @@
|
|||||||
package com.simplemobiletools.calendar;
|
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.database.sqlite.SQLiteQueryBuilder;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import com.simplemobiletools.calendar.models.Event;
|
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DBHelper extends SQLiteOpenHelper {
|
|
||||||
private static SQLiteDatabase mDb;
|
|
||||||
private static DBOperationsListener mCallback;
|
|
||||||
|
|
||||||
private static final String DB_NAME = "events.db";
|
|
||||||
private static final int DB_VERSION = 3;
|
|
||||||
|
|
||||||
private static final String MAIN_TABLE_NAME = "events";
|
|
||||||
private static final String COL_ID = "id";
|
|
||||||
private static final String COL_START_TS = "start_ts";
|
|
||||||
private static final String COL_END_TS = "end_ts";
|
|
||||||
private static final String COL_TITLE = "title";
|
|
||||||
private static final String COL_DESCRIPTION = "description";
|
|
||||||
private static final String COL_REMINDER_MINUTES = "reminder_minutes";
|
|
||||||
|
|
||||||
private static final String META_TABLE_NAME = "events_meta";
|
|
||||||
private static final String COL_EVENT_ID = "event_id";
|
|
||||||
private static final String COL_REPEAT_START = "repeat_start";
|
|
||||||
private static final String COL_REPEAT_INTERVAL = "repeat_interval";
|
|
||||||
private static final String COL_REPEAT_MONTH = "repeat_month";
|
|
||||||
private static final String COL_REPEAT_DAY = "repeat_day";
|
|
||||||
|
|
||||||
public static DBHelper newInstance(Context context, DBOperationsListener callback) {
|
|
||||||
mCallback = callback;
|
|
||||||
return new DBHelper(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DBHelper(Context context) {
|
|
||||||
super(context, DB_NAME, null, DB_VERSION);
|
|
||||||
mDb = getWritableDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db) {
|
|
||||||
db.execSQL("CREATE TABLE " + MAIN_TABLE_NAME + " (" +
|
|
||||||
COL_ID + " INTEGER PRIMARY KEY, " +
|
|
||||||
COL_START_TS + " INTEGER," +
|
|
||||||
COL_END_TS + " INTEGER," +
|
|
||||||
COL_TITLE + " TEXT," +
|
|
||||||
COL_DESCRIPTION + " TEXT," +
|
|
||||||
COL_REMINDER_MINUTES + " INTEGER" +
|
|
||||||
")");
|
|
||||||
|
|
||||||
createMetaTable(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
|
||||||
if (oldVersion == 1) {
|
|
||||||
db.execSQL("ALTER TABLE " + MAIN_TABLE_NAME + " ADD COLUMN " + COL_REMINDER_MINUTES + " INTEGER DEFAULT -1");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newVersion == 3) {
|
|
||||||
createMetaTable(db);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createMetaTable(SQLiteDatabase db) {
|
|
||||||
db.execSQL("CREATE TABLE " + META_TABLE_NAME + " (" +
|
|
||||||
COL_ID + " INTEGER PRIMARY KEY, " +
|
|
||||||
COL_EVENT_ID + " INTEGER UNIQUE, " +
|
|
||||||
COL_REPEAT_START + " INTEGER, " +
|
|
||||||
COL_REPEAT_INTERVAL + " INTEGER, " +
|
|
||||||
COL_REPEAT_MONTH + " INTEGER, " +
|
|
||||||
COL_REPEAT_DAY + " INTEGER" +
|
|
||||||
")");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert(Event event) {
|
|
||||||
final ContentValues eventValues = fillContentValues(event);
|
|
||||||
long id = mDb.insert(MAIN_TABLE_NAME, null, eventValues);
|
|
||||||
event.setId((int) id);
|
|
||||||
if (event.getRepeatInterval() != 0) {
|
|
||||||
final ContentValues metaValues = fillMetaValues(event);
|
|
||||||
mDb.insert(META_TABLE_NAME, null, metaValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCallback != null)
|
|
||||||
mCallback.eventInserted(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(Event event) {
|
|
||||||
final String[] selectionArgs = {String.valueOf(event.getId())};
|
|
||||||
final ContentValues values = fillContentValues(event);
|
|
||||||
final String selection = COL_ID + " = ?";
|
|
||||||
mDb.update(MAIN_TABLE_NAME, values, selection, selectionArgs);
|
|
||||||
|
|
||||||
if (event.getRepeatInterval() == 0) {
|
|
||||||
final String metaSelection = COL_EVENT_ID + " = ?";
|
|
||||||
mDb.delete(META_TABLE_NAME, metaSelection, selectionArgs);
|
|
||||||
} else {
|
|
||||||
final ContentValues metaValues = fillMetaValues(event);
|
|
||||||
mDb.insertWithOnConflict(META_TABLE_NAME, null, metaValues, SQLiteDatabase.CONFLICT_REPLACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCallback != null)
|
|
||||||
mCallback.eventUpdated(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContentValues fillContentValues(Event event) {
|
|
||||||
final ContentValues values = new ContentValues();
|
|
||||||
values.put(COL_START_TS, event.getStartTS());
|
|
||||||
values.put(COL_END_TS, event.getEndTS());
|
|
||||||
values.put(COL_TITLE, event.getTitle());
|
|
||||||
values.put(COL_DESCRIPTION, event.getDescription());
|
|
||||||
values.put(COL_REMINDER_MINUTES, event.getReminderMinutes());
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContentValues fillMetaValues(Event event) {
|
|
||||||
final int repeatInterval = event.getRepeatInterval();
|
|
||||||
final ContentValues values = new ContentValues();
|
|
||||||
values.put(COL_EVENT_ID, event.getId());
|
|
||||||
values.put(COL_REPEAT_START, event.getStartTS());
|
|
||||||
values.put(COL_REPEAT_INTERVAL, repeatInterval);
|
|
||||||
final DateTime dateTime = Formatter.getDateTimeFromTS(event.getStartTS());
|
|
||||||
|
|
||||||
if (repeatInterval == Constants.MONTH || repeatInterval == Constants.YEAR) {
|
|
||||||
values.put(COL_REPEAT_DAY, dateTime.getDayOfMonth());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (repeatInterval == Constants.YEAR) {
|
|
||||||
values.put(COL_REPEAT_MONTH, dateTime.getMonthOfYear());
|
|
||||||
}
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteEvents(String[] ids) {
|
|
||||||
final String args = TextUtils.join(", ", ids);
|
|
||||||
final String selection = COL_ID + " IN (" + args + ")";
|
|
||||||
mDb.delete(MAIN_TABLE_NAME, selection, null);
|
|
||||||
|
|
||||||
final String metaSelection = COL_EVENT_ID + " IN (" + args + ")";
|
|
||||||
mDb.delete(META_TABLE_NAME, metaSelection, null);
|
|
||||||
|
|
||||||
if (mCallback != null)
|
|
||||||
mCallback.eventsDeleted(ids.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Event getEvent(int id) {
|
|
||||||
final String selection = MAIN_TABLE_NAME + "." + COL_ID + " = ?";
|
|
||||||
final String[] selectionArgs = {String.valueOf(id)};
|
|
||||||
final Cursor cursor = getEventsCursor(selection, selectionArgs);
|
|
||||||
final List<Event> events = fillEvents(cursor);
|
|
||||||
if (!events.isEmpty())
|
|
||||||
return events.get(0);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getEvents(int fromTS, int toTS) {
|
|
||||||
final List<Event> events = new ArrayList<>();
|
|
||||||
for (int ts = fromTS; ts <= toTS; ts += Constants.DAY) {
|
|
||||||
events.addAll(getEventsFor(ts));
|
|
||||||
}
|
|
||||||
|
|
||||||
final String selection = COL_START_TS + " <= ? AND " + COL_END_TS + " >= ? AND " + COL_REPEAT_INTERVAL + " IS NULL";
|
|
||||||
final String[] selectionArgs = {String.valueOf(toTS), String.valueOf(fromTS)};
|
|
||||||
final Cursor cursor = getEventsCursor(selection, selectionArgs);
|
|
||||||
if (cursor != null) {
|
|
||||||
events.addAll(fillEvents(cursor));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCallback != null)
|
|
||||||
mCallback.gotEvents(events);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Event> getEventsFor(int ts) {
|
|
||||||
final List<Event> newEvents = new ArrayList<>();
|
|
||||||
final int dayExclusive = Constants.DAY - 1;
|
|
||||||
final int dayEnd = ts + dayExclusive;
|
|
||||||
final DateTime dateTime = Formatter.getDateTimeFromTS(ts);
|
|
||||||
|
|
||||||
// get daily and weekly events
|
|
||||||
String selection = "(" + COL_REPEAT_INTERVAL + " = " + Constants.DAY + " OR " + COL_REPEAT_INTERVAL + " = " + Constants.WEEK +
|
|
||||||
") AND (" + dayEnd + " - " + COL_REPEAT_START + ") % " + COL_REPEAT_INTERVAL + " BETWEEN 0 AND " + dayExclusive;
|
|
||||||
newEvents.addAll(getEvents(selection, ts));
|
|
||||||
|
|
||||||
// get monthly events
|
|
||||||
selection = COL_REPEAT_INTERVAL + " = " + Constants.MONTH + " AND " + COL_REPEAT_DAY + " = " + dateTime.getDayOfMonth() +
|
|
||||||
" AND " + COL_REPEAT_START + " <= " + dayEnd;
|
|
||||||
newEvents.addAll(getEvents(selection, ts));
|
|
||||||
|
|
||||||
// get yearly events
|
|
||||||
selection = COL_REPEAT_INTERVAL + " = " + Constants.YEAR + " AND " + COL_REPEAT_MONTH + " = " + dateTime.getMonthOfYear() +
|
|
||||||
" AND " + COL_REPEAT_DAY + " = " + dateTime.getDayOfMonth() + " AND " + COL_REPEAT_START + " <= " + dayEnd;
|
|
||||||
newEvents.addAll(getEvents(selection, ts));
|
|
||||||
|
|
||||||
return newEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Event> getEvents(String selection, int ts) {
|
|
||||||
final List<Event> events = new ArrayList<>();
|
|
||||||
final Cursor cursor = getEventsCursor(selection, null);
|
|
||||||
if (cursor != null) {
|
|
||||||
final List<Event> currEvents = fillEvents(cursor);
|
|
||||||
for (Event e : currEvents) {
|
|
||||||
updateEventTimes(e, ts);
|
|
||||||
}
|
|
||||||
events.addAll(currEvents);
|
|
||||||
}
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateEventTimes(Event e, int ts) {
|
|
||||||
final int periods = (ts - e.getStartTS() + Constants.DAY) / e.getRepeatInterval();
|
|
||||||
DateTime currStart = Formatter.getDateTimeFromTS(e.getStartTS());
|
|
||||||
DateTime newStart;
|
|
||||||
if (e.getRepeatInterval() == Constants.DAY) {
|
|
||||||
newStart = currStart.plusDays(periods);
|
|
||||||
} else if (e.getRepeatInterval() == Constants.WEEK) {
|
|
||||||
newStart = currStart.plusWeeks(periods);
|
|
||||||
} else if (e.getRepeatInterval() == Constants.MONTH) {
|
|
||||||
newStart = currStart.plusMonths(periods);
|
|
||||||
} else {
|
|
||||||
newStart = currStart.plusYears(periods);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int newStartTS = (int) (newStart.getMillis() / 1000);
|
|
||||||
final int newEndTS = newStartTS + (e.getEndTS() - e.getStartTS());
|
|
||||||
e.setStartTS(newStartTS);
|
|
||||||
e.setEndTS(newEndTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Event> getEventsAtReboot() {
|
|
||||||
List<Event> events = new ArrayList<>();
|
|
||||||
final String selection = COL_REMINDER_MINUTES + " != -1 AND (" + COL_START_TS + " > ? OR " + COL_REPEAT_INTERVAL + " != 0)";
|
|
||||||
final String[] selectionArgs = {String.valueOf(DateTime.now().getMillis() / 1000)};
|
|
||||||
final Cursor cursor = getEventsCursor(selection, selectionArgs);
|
|
||||||
|
|
||||||
if (cursor != null) {
|
|
||||||
events = fillEvents(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cursor getEventsCursor(String selection, String[] selectionArgs) {
|
|
||||||
final SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
|
|
||||||
builder.setTables(
|
|
||||||
MAIN_TABLE_NAME + " LEFT OUTER JOIN " + META_TABLE_NAME + " ON " + COL_EVENT_ID + " = " + MAIN_TABLE_NAME + "." + COL_ID);
|
|
||||||
final String[] projection = getAllColumns();
|
|
||||||
return builder.query(mDb, projection, selection, selectionArgs, MAIN_TABLE_NAME + "." + COL_ID, null, COL_START_TS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] getAllColumns() {
|
|
||||||
return new String[]{MAIN_TABLE_NAME + "." + COL_ID, COL_START_TS, COL_END_TS, COL_TITLE, COL_DESCRIPTION, COL_REMINDER_MINUTES,
|
|
||||||
COL_REPEAT_INTERVAL, COL_REPEAT_MONTH, COL_REPEAT_DAY};
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Event> fillEvents(Cursor cursor) {
|
|
||||||
final List<Event> events = new ArrayList<>();
|
|
||||||
if (cursor.moveToFirst()) {
|
|
||||||
do {
|
|
||||||
final int id = cursor.getInt(cursor.getColumnIndex(COL_ID));
|
|
||||||
final int startTS = cursor.getInt(cursor.getColumnIndex(COL_START_TS));
|
|
||||||
final int endTS = cursor.getInt(cursor.getColumnIndex(COL_END_TS));
|
|
||||||
final int reminderMinutes = cursor.getInt(cursor.getColumnIndex(COL_REMINDER_MINUTES));
|
|
||||||
final int repeatInterval = cursor.getInt(cursor.getColumnIndex(COL_REPEAT_INTERVAL));
|
|
||||||
final String title = cursor.getString(cursor.getColumnIndex(COL_TITLE));
|
|
||||||
final String description = cursor.getString(cursor.getColumnIndex(COL_DESCRIPTION));
|
|
||||||
events.add(new Event(id, startTS, endTS, title, description, reminderMinutes, repeatInterval));
|
|
||||||
} while (cursor.moveToNext());
|
|
||||||
}
|
|
||||||
cursor.close();
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface DBOperationsListener {
|
|
||||||
void eventInserted(Event event);
|
|
||||||
|
|
||||||
void eventUpdated(Event event);
|
|
||||||
|
|
||||||
void eventsDeleted(int cnt);
|
|
||||||
|
|
||||||
void gotEvents(List<Event> events);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -226,7 +226,7 @@ public class EventActivity extends SimpleActivity implements DBHelper.DBOperatio
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final DBHelper dbHelper = DBHelper.newInstance(getApplicationContext(), this);
|
final DBHelper dbHelper = DBHelper.Companion.newInstance(getApplicationContext(), this);
|
||||||
final String description = mDescriptionET.getText().toString().trim();
|
final String description = mDescriptionET.getText().toString().trim();
|
||||||
mEvent.setStartTS(startTS);
|
mEvent.setStartTS(startTS);
|
||||||
mEvent.setEndTS(mEndCheckbox.isChecked() ? endTS : startTS);
|
mEvent.setEndTS(mEndCheckbox.isChecked() ? endTS : startTS);
|
||||||
|
@@ -14,7 +14,7 @@ public class BootCompletedReceiver extends BroadcastReceiver {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent arg1) {
|
public void onReceive(Context context, Intent arg1) {
|
||||||
final List<Event> events = DBHelper.newInstance(context, null).getEventsAtReboot();
|
final List<Event> events = DBHelper.Companion.newInstance(context, null).getEventsAtReboot();
|
||||||
for (Event event : events) {
|
for (Event event : events) {
|
||||||
Utils.scheduleNextEvent(context, event);
|
Utils.scheduleNextEvent(context, event);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ public class NotificationReceiver extends BroadcastReceiver {
|
|||||||
if (id == -1)
|
if (id == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
final Event event = DBHelper.newInstance(context, null).getEvent(id);
|
final Event event = DBHelper.Companion.newInstance(context, null).getEvent(id);
|
||||||
if (event == null || event.getReminderMinutes() == -1)
|
if (event == null || event.getReminderMinutes() == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
287
app/src/main/kotlin/com/simplemobiletools/calendar/DBHelper.kt
Normal file
287
app/src/main/kotlin/com/simplemobiletools/calendar/DBHelper.kt
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
package com.simplemobiletools.calendar
|
||||||
|
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Context
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.database.sqlite.SQLiteDatabase
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
|
import android.database.sqlite.SQLiteQueryBuilder
|
||||||
|
import android.text.TextUtils
|
||||||
|
import com.simplemobiletools.calendar.models.Event
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class DBHelper(context: Context) : SQLiteOpenHelper(context, DBHelper.DB_NAME, null, DBHelper.DB_VERSION) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
mDb = writableDatabase
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
|
db.execSQL("CREATE TABLE " + MAIN_TABLE_NAME + " (" +
|
||||||
|
COL_ID + " INTEGER PRIMARY KEY, " +
|
||||||
|
COL_START_TS + " INTEGER," +
|
||||||
|
COL_END_TS + " INTEGER," +
|
||||||
|
COL_TITLE + " TEXT," +
|
||||||
|
COL_DESCRIPTION + " TEXT," +
|
||||||
|
COL_REMINDER_MINUTES + " INTEGER" +
|
||||||
|
")")
|
||||||
|
|
||||||
|
createMetaTable(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||||
|
if (oldVersion == 1) {
|
||||||
|
db.execSQL("ALTER TABLE $MAIN_TABLE_NAME ADD COLUMN $COL_REMINDER_MINUTES INTEGER DEFAULT -1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newVersion == 3) {
|
||||||
|
createMetaTable(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createMetaTable(db: SQLiteDatabase) {
|
||||||
|
db.execSQL("CREATE TABLE " + META_TABLE_NAME + " (" +
|
||||||
|
COL_ID + " INTEGER PRIMARY KEY, " +
|
||||||
|
COL_EVENT_ID + " INTEGER UNIQUE, " +
|
||||||
|
COL_REPEAT_START + " INTEGER, " +
|
||||||
|
COL_REPEAT_INTERVAL + " INTEGER, " +
|
||||||
|
COL_REPEAT_MONTH + " INTEGER, " +
|
||||||
|
COL_REPEAT_DAY + " INTEGER" +
|
||||||
|
")")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun insert(event: Event) {
|
||||||
|
val eventValues = fillContentValues(event)
|
||||||
|
val id = mDb.insert(MAIN_TABLE_NAME, null, eventValues)
|
||||||
|
event.id = id.toInt()
|
||||||
|
if (event.repeatInterval != 0) {
|
||||||
|
val metaValues = fillMetaValues(event)
|
||||||
|
mDb.insert(META_TABLE_NAME, null, metaValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCallback != null)
|
||||||
|
mCallback!!.eventInserted(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(event: Event) {
|
||||||
|
val selectionArgs = arrayOf(event.id.toString())
|
||||||
|
val values = fillContentValues(event)
|
||||||
|
val selection = COL_ID + " = ?"
|
||||||
|
mDb.update(MAIN_TABLE_NAME, values, selection, selectionArgs)
|
||||||
|
|
||||||
|
if (event.repeatInterval == 0) {
|
||||||
|
val metaSelection = COL_EVENT_ID + " = ?"
|
||||||
|
mDb.delete(META_TABLE_NAME, metaSelection, selectionArgs)
|
||||||
|
} else {
|
||||||
|
val metaValues = fillMetaValues(event)
|
||||||
|
mDb.insertWithOnConflict(META_TABLE_NAME, null, metaValues, SQLiteDatabase.CONFLICT_REPLACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCallback != null)
|
||||||
|
mCallback!!.eventUpdated(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fillContentValues(event: Event): ContentValues {
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(COL_START_TS, event.startTS)
|
||||||
|
values.put(COL_END_TS, event.endTS)
|
||||||
|
values.put(COL_TITLE, event.title)
|
||||||
|
values.put(COL_DESCRIPTION, event.description)
|
||||||
|
values.put(COL_REMINDER_MINUTES, event.reminderMinutes)
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fillMetaValues(event: Event): ContentValues {
|
||||||
|
val repeatInterval = event.repeatInterval
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(COL_EVENT_ID, event.id)
|
||||||
|
values.put(COL_REPEAT_START, event.startTS)
|
||||||
|
values.put(COL_REPEAT_INTERVAL, repeatInterval)
|
||||||
|
val dateTime = Formatter.getDateTimeFromTS(event.startTS)
|
||||||
|
|
||||||
|
if (repeatInterval == Constants.MONTH || repeatInterval == Constants.YEAR) {
|
||||||
|
values.put(COL_REPEAT_DAY, dateTime.dayOfMonth)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (repeatInterval == Constants.YEAR) {
|
||||||
|
values.put(COL_REPEAT_MONTH, dateTime.monthOfYear)
|
||||||
|
}
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteEvents(ids: Array<String>) {
|
||||||
|
val args = TextUtils.join(", ", ids)
|
||||||
|
val selection = "$COL_ID IN ($args)"
|
||||||
|
mDb.delete(MAIN_TABLE_NAME, selection, null)
|
||||||
|
|
||||||
|
val metaSelection = "$COL_EVENT_ID IN ($args)"
|
||||||
|
mDb.delete(META_TABLE_NAME, metaSelection, null)
|
||||||
|
|
||||||
|
if (mCallback != null)
|
||||||
|
mCallback!!.eventsDeleted(ids.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getEvent(id: Int): Event? {
|
||||||
|
val selection = "$MAIN_TABLE_NAME.$COL_ID = ?"
|
||||||
|
val selectionArgs = arrayOf(id.toString())
|
||||||
|
val cursor = getEventsCursor(selection, selectionArgs)
|
||||||
|
val events = fillEvents(cursor)
|
||||||
|
if (!events.isEmpty())
|
||||||
|
return events[0]
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getEvents(fromTS: Int, toTS: Int) {
|
||||||
|
val events = ArrayList<Event>()
|
||||||
|
var ts = fromTS
|
||||||
|
while (ts <= toTS) {
|
||||||
|
events.addAll(getEventsFor(ts))
|
||||||
|
ts += Constants.DAY
|
||||||
|
}
|
||||||
|
|
||||||
|
val selection = "$COL_START_TS <= ? AND $COL_END_TS >= ? AND $COL_REPEAT_INTERVAL IS NULL"
|
||||||
|
val selectionArgs = arrayOf(toTS.toString(), fromTS.toString())
|
||||||
|
val cursor = getEventsCursor(selection, selectionArgs)
|
||||||
|
events.addAll(fillEvents(cursor))
|
||||||
|
|
||||||
|
if (mCallback != null)
|
||||||
|
mCallback!!.gotEvents(events)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getEventsFor(ts: Int): List<Event> {
|
||||||
|
val newEvents = ArrayList<Event>()
|
||||||
|
val dayExclusive = Constants.DAY - 1
|
||||||
|
val dayEnd = ts + dayExclusive
|
||||||
|
val dateTime = Formatter.getDateTimeFromTS(ts)
|
||||||
|
|
||||||
|
// get daily and weekly events
|
||||||
|
var selection = "(" + COL_REPEAT_INTERVAL + " = " + Constants.DAY + " OR " + COL_REPEAT_INTERVAL + " = " + Constants.WEEK +
|
||||||
|
") AND (" + dayEnd + " - " + COL_REPEAT_START + ") % " + COL_REPEAT_INTERVAL + " BETWEEN 0 AND " + dayExclusive
|
||||||
|
newEvents.addAll(getEvents(selection, ts))
|
||||||
|
|
||||||
|
// get monthly events
|
||||||
|
selection = COL_REPEAT_INTERVAL + " = " + Constants.MONTH + " AND " + COL_REPEAT_DAY + " = " + dateTime.dayOfMonth +
|
||||||
|
" AND " + COL_REPEAT_START + " <= " + dayEnd
|
||||||
|
newEvents.addAll(getEvents(selection, ts))
|
||||||
|
|
||||||
|
// get yearly events
|
||||||
|
selection = COL_REPEAT_INTERVAL + " = " + Constants.YEAR + " AND " + COL_REPEAT_MONTH + " = " + dateTime.monthOfYear +
|
||||||
|
" AND " + COL_REPEAT_DAY + " = " + dateTime.dayOfMonth + " AND " + COL_REPEAT_START + " <= " + dayEnd
|
||||||
|
newEvents.addAll(getEvents(selection, ts))
|
||||||
|
|
||||||
|
return newEvents
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getEvents(selection: String, ts: Int): List<Event> {
|
||||||
|
val events = ArrayList<Event>()
|
||||||
|
val cursor = getEventsCursor(selection, null)
|
||||||
|
if (cursor != null) {
|
||||||
|
val currEvents = fillEvents(cursor)
|
||||||
|
for (e in currEvents) {
|
||||||
|
updateEventTimes(e, ts)
|
||||||
|
}
|
||||||
|
events.addAll(currEvents)
|
||||||
|
}
|
||||||
|
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateEventTimes(e: Event, ts: Int) {
|
||||||
|
val periods = (ts - e.startTS + Constants.DAY) / e.repeatInterval
|
||||||
|
val currStart = Formatter.getDateTimeFromTS(e.startTS)
|
||||||
|
val newStart: DateTime
|
||||||
|
if (e.repeatInterval == Constants.DAY) {
|
||||||
|
newStart = currStart.plusDays(periods)
|
||||||
|
} else if (e.repeatInterval == Constants.WEEK) {
|
||||||
|
newStart = currStart.plusWeeks(periods)
|
||||||
|
} else if (e.repeatInterval == Constants.MONTH) {
|
||||||
|
newStart = currStart.plusMonths(periods)
|
||||||
|
} else {
|
||||||
|
newStart = currStart.plusYears(periods)
|
||||||
|
}
|
||||||
|
|
||||||
|
val newStartTS = (newStart.millis / 1000).toInt()
|
||||||
|
val newEndTS = newStartTS + (e.endTS - e.startTS)
|
||||||
|
e.startTS = newStartTS
|
||||||
|
e.endTS = newEndTS
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getEventsAtReboot(): List<Event> {
|
||||||
|
val selection = "$COL_REMINDER_MINUTES != -1 AND ($COL_START_TS > ? OR $COL_REPEAT_INTERVAL != 0)"
|
||||||
|
val selectionArgs = arrayOf((DateTime.now().millis / 1000).toString())
|
||||||
|
val cursor = getEventsCursor(selection, selectionArgs)
|
||||||
|
return fillEvents(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getEventsCursor(selection: String, selectionArgs: Array<String>?): Cursor? {
|
||||||
|
val builder = SQLiteQueryBuilder()
|
||||||
|
builder.tables = "$MAIN_TABLE_NAME LEFT OUTER JOIN $META_TABLE_NAME ON $COL_EVENT_ID = $MAIN_TABLE_NAME.$COL_ID"
|
||||||
|
val projection = allColumns
|
||||||
|
return builder.query(mDb, projection, selection, selectionArgs, MAIN_TABLE_NAME + "." + COL_ID, null, COL_START_TS)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val allColumns: Array<String>
|
||||||
|
get() = arrayOf(MAIN_TABLE_NAME + "." + COL_ID, COL_START_TS, COL_END_TS, COL_TITLE, COL_DESCRIPTION, COL_REMINDER_MINUTES, COL_REPEAT_INTERVAL, COL_REPEAT_MONTH, COL_REPEAT_DAY)
|
||||||
|
|
||||||
|
private fun fillEvents(cursor: Cursor?): List<Event> {
|
||||||
|
val events = ArrayList<Event>()
|
||||||
|
if (cursor == null)
|
||||||
|
return events
|
||||||
|
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
do {
|
||||||
|
val id = cursor.getInt(cursor.getColumnIndex(COL_ID))
|
||||||
|
val startTS = cursor.getInt(cursor.getColumnIndex(COL_START_TS))
|
||||||
|
val endTS = cursor.getInt(cursor.getColumnIndex(COL_END_TS))
|
||||||
|
val reminderMinutes = cursor.getInt(cursor.getColumnIndex(COL_REMINDER_MINUTES))
|
||||||
|
val repeatInterval = cursor.getInt(cursor.getColumnIndex(COL_REPEAT_INTERVAL))
|
||||||
|
val title = cursor.getString(cursor.getColumnIndex(COL_TITLE))
|
||||||
|
val description = cursor.getString(cursor.getColumnIndex(COL_DESCRIPTION))
|
||||||
|
events.add(Event(id, startTS, endTS, title, description, reminderMinutes, repeatInterval))
|
||||||
|
} while (cursor.moveToNext())
|
||||||
|
}
|
||||||
|
cursor.close()
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DBOperationsListener {
|
||||||
|
fun eventInserted(event: Event)
|
||||||
|
|
||||||
|
fun eventUpdated(event: Event)
|
||||||
|
|
||||||
|
fun eventsDeleted(cnt: Int)
|
||||||
|
|
||||||
|
fun gotEvents(events: MutableList<Event>)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
lateinit private var mDb: SQLiteDatabase
|
||||||
|
private var mCallback: DBOperationsListener? = null
|
||||||
|
|
||||||
|
private val DB_NAME = "events.db"
|
||||||
|
private val DB_VERSION = 3
|
||||||
|
|
||||||
|
private val MAIN_TABLE_NAME = "events"
|
||||||
|
private val COL_ID = "id"
|
||||||
|
private val COL_START_TS = "start_ts"
|
||||||
|
private val COL_END_TS = "end_ts"
|
||||||
|
private val COL_TITLE = "title"
|
||||||
|
private val COL_DESCRIPTION = "description"
|
||||||
|
private val COL_REMINDER_MINUTES = "reminder_minutes"
|
||||||
|
|
||||||
|
private val META_TABLE_NAME = "events_meta"
|
||||||
|
private val COL_EVENT_ID = "event_id"
|
||||||
|
private val COL_REPEAT_START = "repeat_start"
|
||||||
|
private val COL_REPEAT_INTERVAL = "repeat_interval"
|
||||||
|
private val COL_REPEAT_MONTH = "repeat_month"
|
||||||
|
private val COL_REPEAT_DAY = "repeat_day"
|
||||||
|
|
||||||
|
fun newInstance(context: Context, callback: DBOperationsListener): DBHelper {
|
||||||
|
mCallback = callback
|
||||||
|
return DBHelper(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -23,6 +23,7 @@ import kotlinx.android.synthetic.main.top_navigation.view.*
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class DayFragment : Fragment(), DBHelper.DBOperationsListener, AdapterView.OnItemClickListener, AbsListView.MultiChoiceModeListener {
|
class DayFragment : Fragment(), DBHelper.DBOperationsListener, AdapterView.OnItemClickListener, AbsListView.MultiChoiceModeListener {
|
||||||
|
|
||||||
private val EDIT_EVENT = 1
|
private val EDIT_EVENT = 1
|
||||||
|
|
||||||
private var mTextColor: Int = 0
|
private var mTextColor: Int = 0
|
||||||
@@ -171,7 +172,7 @@ class DayFragment : Fragment(), DBHelper.DBOperationsListener, AdapterView.OnIte
|
|||||||
|
|
||||||
fun deleteEvents() {
|
fun deleteEvents() {
|
||||||
val cnt = mToBeDeleted.size
|
val cnt = mToBeDeleted.size
|
||||||
val eventIDs = arrayOfNulls<String>(cnt)
|
val eventIDs = arrayOf<String>()
|
||||||
for (i in 0..cnt - 1) {
|
for (i in 0..cnt - 1) {
|
||||||
eventIDs[i] = mToBeDeleted[i].toString()
|
eventIDs[i] = mToBeDeleted[i].toString()
|
||||||
}
|
}
|
||||||
@@ -225,11 +226,10 @@ class DayFragment : Fragment(), DBHelper.DBOperationsListener, AdapterView.OnIte
|
|||||||
editEvent(getEventsToShow(mEvents!!)[position])
|
editEvent(getEventsToShow(mEvents!!)[position])
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun eventInserted(event: Event?) {
|
override fun eventInserted(event: Event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun eventUpdated(event: Event?) {
|
override fun eventUpdated(event: Event) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user