Made metadata have five value columns. Still to do: transition RTM to use metadata table

pull/14/head
Tim Su 16 years ago
parent cf75d057c1
commit 60d2157d06

@ -4,7 +4,7 @@
<booleanAttribute key="ch.zork.quicklaunch" value="true"/> <booleanAttribute key="ch.zork.quicklaunch" value="true"/>
<stringAttribute key="ch.zork.quicklaunch.icon" value="14.gif"/> <stringAttribute key="ch.zork.quicklaunch.icon" value="14.gif"/>
<intAttribute key="ch.zork.quicklaunch.index" value="0"/> <intAttribute key="ch.zork.quicklaunch.index" value="0"/>
<stringAttribute key="ch.zork.quicklaunch.mode" value="debug"/> <stringAttribute key="ch.zork.quicklaunch.mode" value="run"/>
<intAttribute key="com.android.ide.eclipse.adt.action" value="0"/> <intAttribute key="com.android.ide.eclipse.adt.action" value="0"/>
<stringAttribute key="com.android.ide.eclipse.adt.avd" value="android-22"/> <stringAttribute key="com.android.ide.eclipse.adt.avd" value="android-22"/>
<stringAttribute key="com.android.ide.eclipse.adt.commandline" value="-scale 0.7"/> <stringAttribute key="com.android.ide.eclipse.adt.commandline" value="-scale 0.7"/>

@ -111,7 +111,6 @@ public final class CoreFilterExposer extends BroadcastReceiver {
* Build inbox filter * Build inbox filter
* @return * @return
*/ */
@SuppressWarnings("nls")
public static Filter buildInboxFilter(Resources r) { public static Filter buildInboxFilter(Resources r) {
Filter inbox = new Filter(CorePlugin.IDENTIFIER, r.getString(R.string.BFE_Active), Filter inbox = new Filter(CorePlugin.IDENTIFIER, r.getString(R.string.BFE_Active),
r.getString(R.string.BFE_Active_title), r.getString(R.string.BFE_Active_title),

@ -9,7 +9,7 @@ import com.todoroo.astrid.api.AstridApiConstants;
public class CorePlugin extends BroadcastReceiver { public class CorePlugin extends BroadcastReceiver {
static final String IDENTIFIER = "core"; static final String IDENTIFIER = "core"; //$NON-NLS-1$
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {

@ -9,7 +9,7 @@ import com.todoroo.astrid.api.AstridApiConstants;
public class NotesPlugin extends BroadcastReceiver { public class NotesPlugin extends BroadcastReceiver {
static final String IDENTIFIER = "notes"; static final String IDENTIFIER = "notes"; //$NON-NLS-1$
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {

@ -17,6 +17,7 @@ import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterCategory; import com.todoroo.astrid.api.FilterCategory;
import com.todoroo.astrid.api.FilterListHeader; import com.todoroo.astrid.api.FilterListHeader;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.tags.TagService.Tag; import com.todoroo.astrid.tags.TagService.Tag;
/** /**
@ -36,7 +37,8 @@ public class TagFilterExposer extends BroadcastReceiver {
String title = context.getString(R.string.tag_FEx_name, tag.tag); String title = context.getString(R.string.tag_FEx_name, tag.tag);
QueryTemplate tagTemplate = tag.queryTemplate(); QueryTemplate tagTemplate = tag.queryTemplate();
ContentValues contentValues = new ContentValues(); ContentValues contentValues = new ContentValues();
contentValues.put(TagService.KEY, tag.tag); contentValues.put(Metadata.KEY.name, TagService.KEY);
contentValues.put(TagService.TAG.name, tag.tag);
Filter filter = new Filter(TagsPlugin.IDENTIFIER, Filter filter = new Filter(TagsPlugin.IDENTIFIER,
listTitle, title, listTitle, title,

@ -4,6 +4,7 @@ import java.util.ArrayList;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.data.Property.CountProperty; import com.todoroo.andlib.data.Property.CountProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
@ -17,7 +18,6 @@ import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.Task; import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.MetadataService;
/** /**
* Provides operations for working with tags * Provides operations for working with tags
@ -28,27 +28,28 @@ import com.todoroo.astrid.service.MetadataService;
@SuppressWarnings("nls") @SuppressWarnings("nls")
public class TagService { public class TagService {
/** // --- public constants
* Metadata key for tag data
*/
public static final String KEY = "tags-tag";
@Autowired /** Metadata key for tag data */
private MetadataDao metadataDao; public static final String KEY = "tags";
/** Property for reading tag values */
public static final StringProperty TAG = Metadata.VALUE1;
// --- implementation details
@Autowired @Autowired
private MetadataService metadataService; private MetadataDao metadataDao;
public TagService() { public TagService() {
DependencyInjectionService.getInstance().inject(this); DependencyInjectionService.getInstance().inject(this);
} }
/** /**
* Property for retrieving count of aggregated rows * Property for retrieving count of aggregated rows
*/ */
private static final CountProperty COUNT = new CountProperty(); private static final CountProperty COUNT = new CountProperty();
public static final Order GROUPED_TAGS_BY_ALPHA = Order.asc(Metadata.VALUE); public static final Order GROUPED_TAGS_BY_ALPHA = Order.asc(TAG);
public static final Order GROUPED_TAGS_BY_SIZE = Order.desc(COUNT); public static final Order GROUPED_TAGS_BY_SIZE = Order.desc(COUNT);
/** /**
@ -75,7 +76,7 @@ public class TagService {
public QueryTemplate queryTemplate() { public QueryTemplate queryTemplate() {
return new QueryTemplate().join(Join.inner(Metadata.TABLE, return new QueryTemplate().join(Join.inner(Metadata.TABLE,
Task.ID.eq(Metadata.TASK))).where(Criterion.and( Task.ID.eq(Metadata.TASK))).where(Criterion.and(
MetadataCriteria.withKey(KEY), Metadata.VALUE.eq(tag), MetadataCriteria.withKey(KEY), TAG.eq(tag),
TaskCriteria.isActive())); TaskCriteria.isActive()));
} }
} }
@ -94,14 +95,17 @@ public class TagService {
* @return empty array if no tags, otherwise array * @return empty array if no tags, otherwise array
*/ */
public Tag[] getGroupedTags(Order order) { public Tag[] getGroupedTags(Order order) {
TodorooCursor<Metadata> cursor = metadataService.fetchWithCount( Query query = Query.select(TAG, COUNT).
COUNT, Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(KEY)), order); join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(KEY))).
orderBy(order).groupBy(TAG);
TodorooCursor<Metadata> cursor = metadataDao.query(query);
try { try {
Tag[] array = new Tag[cursor.getCount()]; Tag[] array = new Tag[cursor.getCount()];
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
cursor.moveToNext(); cursor.moveToNext();
array[i] = new Tag(); array[i] = new Tag();
array[i].tag = cursor.get(Metadata.VALUE); array[i].tag = cursor.get(TAG);
array[i].count = cursor.get(COUNT); array[i].count = cursor.get(COUNT);
} }
return array; return array;
@ -117,7 +121,7 @@ public class TagService {
* @return cursor. PLEASE CLOSE THE CURSOR! * @return cursor. PLEASE CLOSE THE CURSOR!
*/ */
public TodorooCursor<Metadata> getTags(long taskId) { public TodorooCursor<Metadata> getTags(long taskId) {
Query query = Query.select(Metadata.VALUE).where(Criterion.and(MetadataCriteria.withKey(KEY), Query query = Query.select(TAG).where(Criterion.and(MetadataCriteria.withKey(KEY),
MetadataCriteria.byTask(taskId))); MetadataCriteria.byTask(taskId)));
return metadataDao.query(query); return metadataDao.query(query);
} }
@ -137,7 +141,7 @@ public class TagService {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
tags.moveToNext(); tags.moveToNext();
metadata.readFromCursor(tags); metadata.readFromCursor(tags);
tagBuilder.append(metadata.getValue(Metadata.VALUE)); tagBuilder.append(metadata.getValue(TAG));
if (i < length - 1) if (i < length - 1)
tagBuilder.append(", "); tagBuilder.append(", ");
} }
@ -160,7 +164,7 @@ public class TagService {
metadata.setValue(Metadata.KEY, KEY); metadata.setValue(Metadata.KEY, KEY);
metadata.setValue(Metadata.TASK, taskId); metadata.setValue(Metadata.TASK, taskId);
for(String tag : tags) { for(String tag : tags) {
metadata.setValue(Metadata.VALUE, tag.trim()); metadata.setValue(TAG, tag.trim());
metadataDao.createNew(metadata); metadataDao.createNew(metadata);
} }
} }

@ -54,7 +54,7 @@ public final class TagsControlSet implements TaskEditControlSet {
TodorooCursor<Metadata> cursor = tagService.getTags(task.getId()); TodorooCursor<Metadata> cursor = tagService.getTags(task.getId());
try { try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
addTag(cursor.get(Metadata.VALUE)); addTag(cursor.get(TagService.TAG));
} finally { } finally {
cursor.close(); cursor.close();
} }

@ -345,13 +345,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener {
taskService.save(task, false); taskService.save(task, false);
if(forMetadata != null && forMetadata.size() > 0) { if(forMetadata != null && forMetadata.size() > 0) {
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
for(Entry<String, Object> item : forMetadata.valueSet()) {
metadata.setValue(Metadata.TASK, task.getId()); metadata.setValue(Metadata.TASK, task.getId());
metadata.setValue(Metadata.KEY, item.getKey()); metadata.mergeWith(forMetadata);
metadata.setValue(Metadata.VALUE, item.getValue().toString());
metadataService.save(metadata); metadataService.save(metadata);
metadata.clear();
}
} }
TextView quickAdd = (TextView)findViewById(R.id.quickAddText); TextView quickAdd = (TextView)findViewById(R.id.quickAddText);

@ -125,6 +125,7 @@ public class FilterAdapter extends BaseExpandableListAdapter {
FrameLayout.LayoutParams expansionImageLayout = new FrameLayout.LayoutParams( FrameLayout.LayoutParams expansionImageLayout = new FrameLayout.LayoutParams(
32, 32); 32, 32);
expansionImageLayout.gravity = Gravity.CENTER_VERTICAL; expansionImageLayout.gravity = Gravity.CENTER_VERTICAL;
image.setPadding(5, 0, 5, 0);
image.setLayoutParams(expansionImageLayout); image.setLayoutParams(expansionImageLayout);
image.setScaleType(ScaleType.FIT_CENTER); image.setScaleType(ScaleType.FIT_CENTER);
layout.addView(image); layout.addView(image);

@ -6,6 +6,7 @@
package com.todoroo.astrid.dao; package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.AbstractDatabase; import com.todoroo.andlib.data.AbstractDatabase;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.Table; import com.todoroo.andlib.data.Table;
import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.Task; import com.todoroo.astrid.model.Task;
@ -25,7 +26,7 @@ public class Database extends AbstractDatabase {
* Database version number. This variable must be updated when database * Database version number. This variable must be updated when database
* tables are updated, as it determines whether a database needs updating. * tables are updated, as it determines whether a database needs updating.
*/ */
public static final int VERSION = 2; public static final int VERSION = 3;
/** /**
* Database name (must be unique) * Database name (must be unique)
@ -76,13 +77,19 @@ public class Database extends AbstractDatabase {
switch(oldVersion) { switch(oldVersion) {
case 1: { case 1: {
SqlConstructorVisitor visitor = new SqlConstructorVisitor(); SqlConstructorVisitor visitor = new SqlConstructorVisitor();
String sql = "ALTER TABLE " + Task.TABLE.name + " ADD " + database.execSQL("ALTER TABLE " + Task.TABLE.name + " ADD " +
Task.RECURRENCE.accept(visitor, null); Task.RECURRENCE.accept(visitor, null));
database.execSQL(sql);
return true;
} }
case 2: {
SqlConstructorVisitor visitor = new SqlConstructorVisitor();
for(Property<?> property : new Property<?>[] { Metadata.VALUE2,
Metadata.VALUE3, Metadata.VALUE4, Metadata.VALUE5 })
database.execSQL("ALTER TABLE " + Metadata.TABLE.name + " ADD " +
property.accept(visitor, null));
} }
return true;
}
return false; return false;
} }

@ -1,22 +0,0 @@
package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.Property.IntegerProperty;
import com.todoroo.astrid.model.Metadata;
/**
* Helper class for representing string columns from joined metadata
*/
public class IntegerJoinProperty extends IntegerProperty implements JoinProperty {
public IntegerJoinProperty(String name) {
super(null, name);
}
@SuppressWarnings("nls")
public String joinTable() {
return String.format("SELECT %s,%s AS %s FROM %s WHERE %s='%s'",
Metadata.TASK, Metadata.VALUE, name,
Metadata.TABLE, Metadata.KEY, name);
}
}

@ -1,14 +0,0 @@
/**
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.dao;
public interface JoinProperty {
/**
* @return SQL select statement describing how to load this property
* in a join statement
*/
public String joinTable();
}

@ -62,7 +62,7 @@ public class MetadataDao extends GenericDao<Metadata> {
* @param properties * @param properties
* @return * @return
*/ */
public TodorooCursor<Metadata> fetchDangling(Property<?>[] properties) { public TodorooCursor<Metadata> fetchDangling(Property<?>... properties) {
Query sql = Query.select(properties).from(Metadata.TABLE).join(Join.left(Task.TABLE, Query sql = Query.select(properties).from(Metadata.TABLE).join(Join.left(Task.TABLE,
Metadata.TASK.eq(Task.ID))).where(Task.TITLE.isNull()); Metadata.TASK.eq(Task.ID))).where(Task.TITLE.isNull());
Cursor cursor = database.rawQuery(sql.toString(), null); Cursor cursor = database.rawQuery(sql.toString(), null);

@ -1,21 +0,0 @@
package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.astrid.model.Metadata;
/**
* Helper class for representing string columns from another table
*/
public class StringJoinProperty extends StringProperty implements JoinProperty {
public StringJoinProperty(String name) {
super(null, name);
}
@SuppressWarnings("nls")
public String joinTable() {
return String.format("SELECT %s,%s AS %s FROM %s WHERE %s='%s'",
Metadata.TASK, Metadata.VALUE, name,
Metadata.TABLE, Metadata.KEY, name);
}
}

@ -8,10 +8,10 @@ import android.content.ContentValues;
import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.Table; import com.todoroo.andlib.data.Table;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty;
/** /**
* Data Model which represents a piece of metadata associated with a task * Data Model which represents a piece of metadata associated with a task
@ -40,10 +40,26 @@ public class Metadata extends AbstractModel {
public static final StringProperty KEY = new StringProperty( public static final StringProperty KEY = new StringProperty(
TABLE, "key"); TABLE, "key");
/** Metadata Text Value */ /** Metadata Text Value Column 1 */
public static final StringProperty VALUE = new StringProperty( public static final StringProperty VALUE1 = new StringProperty(
TABLE, "value"); TABLE, "value");
/** Metadata Text Value Column 2 */
public static final StringProperty VALUE2 = new StringProperty(
TABLE, "value2");
/** Metadata Text Value Column 1 */
public static final StringProperty VALUE3 = new StringProperty(
TABLE, "value3");
/** Metadata Text Value Column 1 */
public static final StringProperty VALUE4 = new StringProperty(
TABLE, "value4");
/** Metadata Text Value Column 1 */
public static final StringProperty VALUE5 = new StringProperty(
TABLE, "value5");
/** List of all properties for this model */ /** List of all properties for this model */
public static final Property<?>[] PROPERTIES = generateProperties(Metadata.class); public static final Property<?>[] PROPERTIES = generateProperties(Metadata.class);

@ -12,8 +12,8 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log; import android.util.Log;
import com.google.ical.values.Frequency; import com.google.ical.values.Frequency;
@ -414,7 +414,7 @@ public class Astrid2To3UpgradeHelper {
long task = mapCursor.getLong(1); long task = mapCursor.getLong(1);
metadata.setValue(Metadata.TASK, task); metadata.setValue(Metadata.TASK, task);
metadata.setValue(Metadata.KEY, TagService.KEY); metadata.setValue(Metadata.KEY, TagService.KEY);
metadata.setValue(Metadata.VALUE, tag); metadata.setValue(TagService.TAG, tag);
metadataDao.createNew(metadata); metadataDao.createNew(metadata);
metadata.clearValue(Metadata.ID); metadata.clearValue(Metadata.ID);
} }

@ -1,17 +1,12 @@
package com.todoroo.astrid.service; package com.todoroo.astrid.service;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.Property.CountProperty;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.Task;
/** /**
* Service layer for {@link Metadata}-centered activities. * Service layer for {@link Metadata}-centered activities.
@ -28,29 +23,13 @@ public class MetadataService {
DependencyInjectionService.getInstance().inject(this); DependencyInjectionService.getInstance().inject(this);
} }
// --- property list
/**
* @return property list containing just task id's
*/
public static Property<?>[] idProperty() {
return new Property<?>[] { Metadata.ID };
}
/**
* @return property list containing just task id's
*/
public static Property<?>[] valueProperty() {
return new Property<?>[] { Metadata.VALUE };
}
// --- service layer // --- service layer
/** /**
* Clean up metadata. Typically called on startup * Clean up metadata. Typically called on startup
*/ */
public void cleanup() { public void cleanup() {
TodorooCursor<Metadata> cursor = metadataDao.fetchDangling(idProperty()); TodorooCursor<Metadata> cursor = metadataDao.fetchDangling(Metadata.ID);
try { try {
if(cursor.getCount() == 0) if(cursor.getCount() == 0)
return; return;
@ -65,17 +44,12 @@ public class MetadataService {
} }
/** /**
* Retrieve count of all metadata grouped by value * Query underlying database
* @param where SQL where clause * @param query
* @param onlyCountsGreaterThanZero only include items where count > 0 * @return
*/ */
public TodorooCursor<Metadata> fetchWithCount(CountProperty count, public TodorooCursor<Metadata> query(Query query) {
Criterion where, Order order) { return metadataDao.query(query);
Query query = Query.select(Metadata.VALUE.as(Metadata.VALUE.name), count).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(where).orderBy(order).groupBy(Metadata.VALUE);
TodorooCursor<Metadata> cursor = metadataDao.query(query);
return cursor;
} }
/** /**

@ -10,8 +10,8 @@ import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Metadata;
import com.todoroo.astrid.model.Task; import com.todoroo.astrid.model.Task;
@ -36,6 +36,15 @@ public class TaskService {
// --- service layer // --- service layer
/**
* Query underlying database
* @param query
* @return
*/
public TodorooCursor<Task> query(Query query) {
return taskDao.query(query);
}
/** /**
* *
* @param properties * @param properties

Loading…
Cancel
Save