/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.DatabaseDao;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.ABTestEvent;
public class ABTestEventDao extends DatabaseDao<ABTestEvent> {
@Autowired
private Database database;
public ABTestEventDao() {
super(ABTestEvent.class);
DependencyInjectionService.getInstance().inject(this);
setDatabase(database);
}
/**
* Creates the baseline +0 days event (i.e. the first time the user
* launches the app containing this test)
* @param testName - the name of the test
* @param testVariant - which option was chosen for this user
* @param newUser - are they a new user?
* @param activeUser - are they an activated user?
*/
public void createInitialTestEvent(String testName, String testVariant,
boolean newUser, boolean activeUser) {
ABTestEvent event = new ABTestEvent();
event.setValue(ABTestEvent.TEST_NAME, testName);
event.setValue(ABTestEvent.TEST_VARIANT, testVariant);
event.setValue(ABTestEvent.NEW_USER, newUser ? 1 : 0);
event.setValue(ABTestEvent.ACTIVATED_USER, activeUser ? 1 : 0);
event.setValue(ABTestEvent.TIME_INTERVAL, 0);
event.setValue(ABTestEvent.DATE_RECORDED, DateUtilities.now());
createNew(event);
}
/**
* Only public for unit testing--don't use unless you really mean it!
*
* Creates data points for the specified test name, creating one data point
* for each time interval that hasn't yet been recorded up to the specified one
* @param testName
* @param timeInterval
*/
public void createTestEventWithTimeInterval(String testName, int timeInterval) {
TodorooCursor<ABTestEvent> existing = query(Query.select(ABTestEvent.PROPERTIES)
.where(ABTestEvent.TEST_NAME.eq(testName)).orderBy(Order.asc(ABTestEvent.TIME_INTERVAL)));
try {
if (existing.getCount() == 0)
return;
existing.moveToLast();
ABTestEvent item = new ABTestEvent(existing);
int lastRecordedTimeIntervalIndex = AndroidUtilities.indexOf(
ABTestEvent.TIME_INTERVALS, item.getValue(ABTestEvent.TIME_INTERVAL));
int currentTimeIntervalIndex = AndroidUtilities.indexOf(
ABTestEvent.TIME_INTERVALS, timeInterval);
if (lastRecordedTimeIntervalIndex < 0 || currentTimeIntervalIndex < 0)
return;
long now = DateUtilities.now();
for (int i = lastRecordedTimeIntervalIndex + 1; i <= currentTimeIntervalIndex; i++) {
item.clearValue(ABTestEvent.ID);
item.setValue(ABTestEvent.REPORTED, 0);
item.setValue(ABTestEvent.TIME_INTERVAL, ABTestEvent.TIME_INTERVALS[i]);
item.setValue(ABTestEvent.DATE_RECORDED, now);
createNew(item);
}
} finally {
existing.close();
}
return;
}
/**
* For each baseline data point that exists in the database, check the current
* time against the time that baseline was recorded and report the appropriate
* +n days events. Called on startup.
*/
public void createRelativeDateEvents() {
TodorooCursor<ABTestEvent> allEvents = query(Query.select(ABTestEvent.TEST_NAME, ABTestEvent.DATE_RECORDED)
.where(ABTestEvent.TIME_INTERVAL.eq(0)));
try {
long now = DateUtilities.now();
ABTestEvent event = new ABTestEvent();
for (allEvents.moveToFirst(); !allEvents.isAfterLast(); allEvents.moveToNext()) {
event.readFromCursor(allEvents);
long baseTime = event.getValue(ABTestEvent.DATE_RECORDED);
long timeSinceBase = now - baseTime;
String testName = event.getValue(ABTestEvent.TEST_NAME);
int timeInterval = -1;
long days = timeSinceBase / DateUtilities.ONE_DAY;
for(int i = 0; i < ABTestEvent.TIME_INTERVALS.length; i++)
if(days >= ABTestEvent.TIME_INTERVALS[i])
timeInterval = ABTestEvent.TIME_INTERVALS[i];
if (timeInterval > 0)
createTestEventWithTimeInterval(testName, timeInterval);
}
} finally {
allEvents.close();
}
}
}