Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store trackpoint,waypoint count fields in track table for inactive tracks #28

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
<classpathentry kind="lib" path="libs/httpclient-4.2.1.jar"/>
<classpathentry kind="lib" path="libs/httpcore-4.2.1.jar"/>
<classpathentry kind="lib" path="libs/httpmime-4.2.1.jar"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protected void onResume() {
return; // <--- Early return ---
}

bindTrack(Track.build(trackId, cursor, getContentResolver(), false));
bindTrack(Track.build(trackId, cursor, getContentResolver(), false, false));

Uri uri = getIntent().getData();
Log.d(TAG, "URI: " + uri);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ protected void onResume() {

// Bind WP count, TP count, start date, etc.
// Fill name-field only if empty (in case changed by user/restored by onRestoreInstanceState)
Track t = Track.build(trackId, cursor, cr, true);
Track t = Track.build(trackId, cursor, cr, true, true);

bindTrack(t);

Expand Down
5 changes: 5 additions & 0 deletions src/me/guillaumin/android/osmtracker/db/DataHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ public void stopTracking(long trackId) {
ContentValues values = new ContentValues();
values.put(Schema.COL_ACTIVE, Schema.VAL_TRACK_INACTIVE);
contentResolver.update(trackUri, values, null, null);

// The next time TrackManager displays this track in the list,
// Track.build will count the trackpoints and waypoints and
// save them to the track's tp_count and wp_count columns.
// We don't need to do that here.
}

/**
Expand Down
12 changes: 10 additions & 2 deletions src/me/guillaumin/android/osmtracker/db/DatabaseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
+ Schema.COL_DIR + " text," // unused since DB_VERSION 13, since SQLite doesn't support to remove a column it will stay for now
+ Schema.COL_ACTIVE + " integer not null default 0,"
+ Schema.COL_EXPORT_DATE + " long," // null indicates not yet exported
+ Schema.COL_OSM_UPLOAD_DATE + " long" // null indicates not yet uploaded
+ Schema.COL_OSM_UPLOAD_DATE + " long," // null indicates not yet uploaded
+ Schema.COL_TRACKPOINT_COUNT + " integer," // null indicates active track or not yet calculated
+ Schema.COL_WAYPOINT_COUNT + " integer" // null indicates active track or not yet calculated
+ ")";

/**
Expand All @@ -112,9 +114,10 @@ public class DatabaseHelper extends SQLiteOpenHelper {
* v13: TBL_TRACK.COL_DIR is now deprecated (rxxx) v0.5.3 TODO: fill in correct revision and version
* v14: add TBL_TRACK.COL_OSM_UPLOAD_DATE, TBL_TRACK.COL_DESCRIPTION,
* TBL_TRACK.COL_TAGS and TBL_TRACK.COL_OSM_VISIBILITY for OSM upload - v0.6.0
* v15: add TBL_TRACK.COL_TRACKPOINT_COUNT, COL_WAYPOINT_COUNT
*</pre>
*/
private static final int DB_VERSION = 14;
private static final int DB_VERSION = 15;

public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
Expand All @@ -132,6 +135,7 @@ public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_TABLE_TRACK);
}

/** Upgrade an existing db to the latest {@link #DB_VERSION}. */
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion){
Expand All @@ -157,6 +161,10 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("alter table " + Schema.TBL_TRACK + " add column " + Schema.COL_TAGS + " text");
db.execSQL("alter table " + Schema.TBL_TRACK + " add column " + Schema.COL_OSM_VISIBILITY
+ " text default '"+OSMVisibility.Private+"'");
case 14:
// Create 'tp_count', 'wp_count'
db.execSQL("alter table " + Schema.TBL_TRACK + " add column " + Schema.COL_TRACKPOINT_COUNT + " integer");
db.execSQL("alter table " + Schema.TBL_TRACK + " add column " + Schema.COL_WAYPOINT_COUNT + " integer");
}

}
Expand Down
76 changes: 72 additions & 4 deletions src/me/guillaumin/android/osmtracker/db/TrackContentProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class TrackContentProvider extends ContentProvider {
/**
* tables and joins to be used within a query to get the important informations of a track
*/
private static final String TRACK_TABLES = Schema.TBL_TRACK + " left join " + Schema.TBL_TRACKPOINT + " on " + Schema.TBL_TRACK + "." + Schema.COL_ID + " = " + Schema.TBL_TRACKPOINT + "." + Schema.COL_TRACK_ID;
private static final String TRACK_TABLES = Schema.TBL_TRACK;

/**
* the projection to be used to get the important informations of a track
Expand All @@ -64,10 +64,15 @@ public class TrackContentProvider extends ContentProvider {
Schema.COL_TAGS,
Schema.COL_OSM_VISIBILITY,
Schema.COL_START_DATE,
"count(" + Schema.TBL_TRACKPOINT + "." + Schema.COL_ID + ") as " + Schema.COL_TRACKPOINT_COUNT,
"(SELECT count("+Schema.TBL_WAYPOINT+"."+Schema.COL_TRACK_ID+") FROM "+Schema.TBL_WAYPOINT+" WHERE "+Schema.TBL_WAYPOINT+"."+Schema.COL_TRACK_ID+" = " + Schema.TBL_TRACK + "." + Schema.COL_ID + ") as " + Schema.COL_WAYPOINT_COUNT
Schema.COL_TRACKPOINT_COUNT,
Schema.COL_WAYPOINT_COUNT
};

/**
* Projection with one column: count(*).
*/
private static final String[] ROWCOUNT_PROJECTION = { "count(*)" };

/**
* the group by statement that is used for the track statements
*/
Expand All @@ -88,6 +93,8 @@ public class TrackContentProvider extends ContentProvider {
uriMatcher.addURI(AUTHORITY, Schema.TBL_TRACK + "/#/" + Schema.TBL_WAYPOINT + "s", Schema.URI_CODE_TRACK_WAYPOINTS);
uriMatcher.addURI(AUTHORITY, Schema.TBL_TRACK + "/#/" + Schema.TBL_TRACKPOINT + "s", Schema.URI_CODE_TRACK_TRACKPOINTS);
uriMatcher.addURI(AUTHORITY, Schema.TBL_WAYPOINT + "/uuid/*", Schema.URI_CODE_WAYPOINT_UUID);
uriMatcher.addURI(AUTHORITY, Schema.TBL_TRACK + "/#/tpcount", Schema.URI_CODE_TRACK_TP_COUNT);
uriMatcher.addURI(AUTHORITY, Schema.TBL_TRACK + "/#/wpcount", Schema.URI_CODE_TRACK_WP_COUNT);

}

Expand Down Expand Up @@ -131,6 +138,34 @@ public static final Uri trackEndUri(long trackId) {
"end" );
}

/**
* Get a URI for the track's trackpoint count in the {@link Schema#TBL_TRACKPOINT} table.
* This queries and calculates using SQL COUNT(*), it does not use the track table's
* {@link Schema#COL_TRACKPOINT_COUNT} field.
* @param trackId target track id
* @return Uri for the trackpoint count of the track
* @since schema 15
*/
public static final Uri trackTrackpointCountUri(long trackId) {
return Uri.withAppendedPath(
ContentUris.withAppendedId(CONTENT_URI_TRACK, trackId),
"tpcount" ); // URI_CODE_TRACK_TP_COUNT
}

/**
* Get a URI for the track's waypoint count in the {@link Schema#TBL_WAYPOINT} table.
* This queries and calculates using SQL COUNT(*), it does not use the track table's
* {@link Schema#COL_WAYPOINT_COUNT} field.
* @param trackId target track id
* @return Uri for the waypoint count of the track
* @since schema 15
*/
public static final Uri trackWaypointCountUri(long trackId) {
return Uri.withAppendedPath(
ContentUris.withAppendedId(CONTENT_URI_TRACK, trackId),
"wpcount" ); // URI_CODE_TRACK_WP_COUNT
}

/**
* Database Helper
*/
Expand Down Expand Up @@ -356,6 +391,29 @@ public Cursor query(Uri uri, String[] projection, String selectionIn, String[] s
selection = Schema.COL_ACTIVE + " = ?";
selectionArgs = new String[] {Integer.toString(Schema.VAL_TRACK_ACTIVE)};
break;
case Schema.URI_CODE_TRACK_TP_COUNT:
if (selectionIn != null || selectionArgsIn != null) {
// Any selection/selectionArgs will be rejected
throw new UnsupportedOperationException();
}
trackId = uri.getPathSegments().get(1);
qb.setTables(Schema.TBL_TRACKPOINT);
projection = ROWCOUNT_PROJECTION;
selection = Schema.COL_TRACK_ID + " = ?";
selectionArgs = new String[] {trackId};
break;
case Schema.URI_CODE_TRACK_WP_COUNT:
if (selectionIn != null || selectionArgsIn != null) {
// Any selection/selectionArgs will be rejected
throw new UnsupportedOperationException();
}
trackId = uri.getPathSegments().get(1);
qb.setTables(Schema.TBL_WAYPOINT);
projection = ROWCOUNT_PROJECTION;
selection = Schema.COL_TRACK_ID + " = ?";
selectionArgs = new String[] {trackId};
break;

default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
Expand Down Expand Up @@ -444,8 +502,16 @@ public static final class Schema {
public static final String COL_EXPORT_DATE = "export_date";
public static final String COL_OSM_UPLOAD_DATE = "osm_upload_date";

// virtual colums that are used in some sqls but dont exist in database
/**
* A track's calculated trackpoint count, or null if active. Before schema 15,
* this was a virtual column used in some SQLs that didn't exist in the database.
* @since 15
*/
public static final String COL_TRACKPOINT_COUNT = "tp_count";
/**
* A track's calculated waypoint count, or null if active.
* @since 15
*/
public static final String COL_WAYPOINT_COUNT = "wp_count";

// Codes for UriMatcher
Expand All @@ -457,6 +523,8 @@ public static final class Schema {
public static final int URI_CODE_WAYPOINT_UUID = 8;
public static final int URI_CODE_TRACK_START = 9;
public static final int URI_CODE_TRACK_END = 10;
private static final int URI_CODE_TRACK_TP_COUNT = 11; // query only
private static final int URI_CODE_TRACK_WP_COUNT = 12; // query only


public static final int VAL_TRACK_ACTIVE = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private View bind(Cursor cursor, View v, Context context) {
vId.setText("#" + strTrackId);

// Bind WP count, TP count, name
Track t = Track.build(trackId, cursor, context.getContentResolver(), false);
Track t = Track.build(trackId, cursor, context.getContentResolver(), true, false);
vTps.setText(Integer.toString(t.getTpCount()));
vWps.setText(Integer.toString(t.getWpCount()));
vNameOrStartDate.setText(t.getName());
Expand Down
52 changes: 48 additions & 4 deletions src/me/guillaumin/android/osmtracker/db/model/Track.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
import me.guillaumin.android.osmtracker.db.TrackContentProvider;
import me.guillaumin.android.osmtracker.db.TrackContentProvider.Schema;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

/**
* Represents a Track
Expand Down Expand Up @@ -68,10 +71,14 @@ public static OSMVisibility fromPosition(int position) {
* @param trackId id of the track that will be built
* @param tc cursor that is used to build the track
* @param cr the content resolver to use
* @param readPointCounts if trackpoint/waypoint counts will be needed; may be more work for the database.
* If the track table's tp_count and wp_count fields are null, or the track is active,
* the points are counted with SQL COUNT(*) select statements. The counts will then be
* saved to tp_count and wp_count unless the track is active.
* @param withExtraInformation if additional informations (startDate, endDate, first and last track point will be loaded from the database
* @return Track
*/
public static Track build(final long trackId, Cursor tc, ContentResolver cr, boolean withExtraInformation) {
public static Track build(final long trackId, Cursor tc, ContentResolver cr, final boolean readPointCounts, boolean withExtraInformation) {
Track out = new Track();

out.trackId = trackId;
Expand All @@ -88,9 +95,46 @@ public static Track build(final long trackId, Cursor tc, ContentResolver cr, boo

out.visibility = OSMVisibility.valueOf(tc.getString(tc.getColumnIndex(Schema.COL_OSM_VISIBILITY)));

out.tpCount = tc.getInt(tc.getColumnIndex(Schema.COL_TRACKPOINT_COUNT));

out.wpCount = tc.getInt(tc.getColumnIndex(Schema.COL_WAYPOINT_COUNT));
if (readPointCounts) {
final boolean trackInactive = (tc.getInt(tc.getColumnIndex(Schema.COL_ACTIVE)) == Schema.VAL_TRACK_INACTIVE);
boolean countedAlready = trackInactive;
if (countedAlready) {
// try to retrieve from tp_count, wp_count columns
final int idx_tp = tc.getColumnIndex(Schema.COL_TRACKPOINT_COUNT),
idx_wp = tc.getColumnIndex(Schema.COL_WAYPOINT_COUNT);
if (tc.isNull(idx_tp) || tc.isNull(idx_wp)) {
countedAlready = false;
} else {
out.tpCount = tc.getInt(idx_tp);
out.wpCount = tc.getInt(idx_wp);
}
}

if (! countedAlready) {
Cursor pcc = cr.query(TrackContentProvider.trackTrackpointCountUri(trackId), null, null, null, null);
if (pcc.moveToFirst())
out.tpCount = pcc.getInt(0);
else
out.tpCount = -1;
pcc.close();

pcc = cr.query(TrackContentProvider.trackWaypointCountUri(trackId), null, null, null, null);
if (pcc.moveToFirst())
out.wpCount = pcc.getInt(0);
else
out.wpCount = -1;
pcc.close();

if (trackInactive && (out.tpCount != -1) && (out.wpCount != -1)) {
// remember those counts in track table
Uri trackUri = ContentUris.withAppendedId(TrackContentProvider.CONTENT_URI_TRACK, trackId);
ContentValues values = new ContentValues();
values.put(Schema.COL_TRACKPOINT_COUNT, out.tpCount);
values.put(Schema.COL_WAYPOINT_COUNT, out.wpCount);
cr.update(trackUri, values, null, null);
}
}
}

if(withExtraInformation){
out.readExtraInformation();
Expand Down