Kore/app/src/main/java/org/xbmc/kore/provider/MediaProvider.java

831 lines
40 KiB
Java

/*
* Copyright 2015 Synced Synapse. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xbmc.kore.provider;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.provider.BaseColumns;
import android.support.annotation.Nullable;
import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.SelectionBuilder;
import java.util.Arrays;
/**
* Provider for {@link MediaContract} data.
*/
public class MediaProvider extends ContentProvider {
private static final String TAG = LogUtils.makeLogTag(MediaProvider.class);
private MediaDatabase mOpenHelper;
private Context context;
private static final UriMatcher sUriMatcher = buildUriMatcher();
private static final int HOSTS_LIST = 100;
private static final int HOSTS_ID = 101;
private static final int MOVIES_ALL = 200;
private static final int MOVIES_LIST = 201;
private static final int MOVIES_ID = 202;
private static final int MOVIE_CAST_ALL = 210;
private static final int MOVIE_CAST_LIST = 211;
private static final int TVSHOWS_ALL = 300;
private static final int TVSHOWS_LIST = 302;
private static final int TVSHOWS_ID = 303;
private static final int TVSHOWS_CAST_ALL = 310;
private static final int TVSHOWS_CAST_LIST = 311;
private static final int SEASONS_ALL = 400;
private static final int TVSHOW_SEASONS_LIST = 401;
private static final int TVSHOW_SEASONS_ID = 402;
private static final int EPISODES_ALL = 500;
private static final int TVSHOW_EPISODES_LIST = 501;
private static final int TVSHOW_EPISODES_ID = 502;
private static final int TVSHOW_SEASON_EPISODES_LIST = 503;
private static final int TVSHOW_SEASON_EPISODES_ID = 504;
private static final int ARTISTS_ALL = 600;
private static final int ARTISTS_LIST = 601;
private static final int ARTISTS_ID = 602;
private static final int ARTIST_ALBUMS_LIST = 610;
private static final int ARTIST_SONGS_LIST = 611;
private static final int ALBUMS_ALL = 700;
private static final int ALBUMS_LIST = 701;
private static final int ALBUMS_ID = 702;
private static final int ALBUM_ARTISTS_LIST = 710;
private static final int ALBUM_GENRES_LIST = 711;
private static final int SONGS_ALL = 800;
private static final int SONGS_ALBUM = 802;
private static final int SONGS_ID = 803;
private static final int SONGS_LIST = 804;
private static final int AUDIO_GENRES_ALL = 900;
private static final int AUDIO_GENRES_LIST = 901;
private static final int AUDIO_GENRES_ID = 902;
private static final int AUDIO_GENRE_ALBUMS_LIST = 910;
private static final int ALBUM_ARTISTS_ALL = 1000;
private static final int ALBUM_GENRES_ALL = 1001;
private static final int SONG_ARTISTS_ALL = 1002;
private static final int MUSIC_VIDEOS_ALL = 1100;
private static final int MUSIC_VIDEOS_LIST = 1101;
private static final int MUSIC_VIDEOS_ID = 1102;
/**
* Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by
* this {@link ContentProvider}.
*/
private static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = MediaContract.CONTENT_AUTHORITY;
// Hosts
matcher.addURI(authority, MediaContract.PATH_HOSTS, HOSTS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*", HOSTS_ID);
// Movies and cast
matcher.addURI(authority, MediaContract.PATH_MOVIES, MOVIES_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_MOVIES, MOVIES_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_MOVIES + "/*", MOVIES_ID);
matcher.addURI(authority, MediaContract.PATH_MOVIE_CAST, MOVIE_CAST_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_MOVIES + "/*/" +
MediaContract.PATH_MOVIE_CAST, MOVIE_CAST_LIST);
// TV Shows and cast
matcher.addURI(authority, MediaContract.PATH_TVSHOWS, TVSHOWS_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS, TVSHOWS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*", TVSHOWS_ID);
matcher.addURI(authority, MediaContract.PATH_TVSHOW_CAST, TVSHOWS_CAST_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_TVSHOW_CAST, TVSHOWS_CAST_LIST);
// Seasons
matcher.addURI(authority, MediaContract.PATH_SEASONS, SEASONS_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_SEASONS, TVSHOW_SEASONS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_SEASONS + "/*", TVSHOW_SEASONS_ID);
// Episodes
matcher.addURI(authority, MediaContract.PATH_EPISODES, EPISODES_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_EPISODES, TVSHOW_EPISODES_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_EPISODES + "/*", TVSHOW_EPISODES_ID);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_SEASONS + "/*/" +
MediaContract.PATH_EPISODES, TVSHOW_SEASON_EPISODES_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_TVSHOWS + "/*/" +
MediaContract.PATH_SEASONS + "/*/" +
MediaContract.PATH_EPISODES + "/*", TVSHOW_SEASON_EPISODES_ID);
// Artists
matcher.addURI(authority, MediaContract.PATH_ARTISTS, ARTISTS_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ARTISTS, ARTISTS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ARTISTS + "/*", ARTISTS_ID);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ARTISTS + "/*/" +
MediaContract.PATH_ALBUMS, ARTIST_ALBUMS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ARTISTS + "/*/" +
MediaContract.PATH_SONGS, ARTIST_SONGS_LIST);
// Albums
matcher.addURI(authority, MediaContract.PATH_ALBUMS, ALBUMS_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ALBUMS, ALBUMS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ALBUMS + "/*", ALBUMS_ID);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ALBUMS + "/*/" +
MediaContract.PATH_ARTISTS, ALBUM_ARTISTS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ALBUMS + "/*/" +
MediaContract.PATH_AUDIO_GENRES, ALBUM_GENRES_LIST);
// Songs
matcher.addURI(authority, MediaContract.PATH_SONGS, SONGS_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_SONGS, SONGS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ALBUMS + "/*/" +
MediaContract.PATH_SONGS, SONGS_ALBUM);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_ALBUMS + "/*/" +
MediaContract.PATH_SONGS + "/*", SONGS_ID);
// Genres
matcher.addURI(authority, MediaContract.PATH_AUDIO_GENRES, AUDIO_GENRES_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_AUDIO_GENRES, AUDIO_GENRES_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_AUDIO_GENRES + "/*", AUDIO_GENRES_ID);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_AUDIO_GENRES + "/*/" +
MediaContract.PATH_ALBUMS, AUDIO_GENRE_ALBUMS_LIST);
// AlbumArtists
matcher.addURI(authority, MediaContract.PATH_ALBUM_ARTISTS, ALBUM_ARTISTS_ALL);
// AlbumGenres
matcher.addURI(authority, MediaContract.PATH_ALBUM_GENRES, ALBUM_GENRES_ALL);
// SongArtists
matcher.addURI(authority, MediaContract.PATH_SONG_ARTISTS, SONG_ARTISTS_ALL);
// Music Videos
matcher.addURI(authority, MediaContract.PATH_MUSIC_VIDEOS, MUSIC_VIDEOS_ALL);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_MUSIC_VIDEOS, MUSIC_VIDEOS_LIST);
matcher.addURI(authority, MediaContract.PATH_HOSTS + "/*/" +
MediaContract.PATH_MUSIC_VIDEOS + "/*", MUSIC_VIDEOS_ID);
return matcher;
}
public void setContext(Context context) {
this.context = context;
}
@Override
public boolean onCreate() {
if (context == null) {
context = getContext();
}
mOpenHelper = new MediaDatabase(context);
return true;
}
/** {@inheritDoc} */
@Override
public String getType(Uri uri) {
final int match = sUriMatcher.match(uri);
switch (match) {
case HOSTS_LIST:
return MediaContract.Hosts.CONTENT_TYPE;
case HOSTS_ID:
return MediaContract.Hosts.CONTENT_ITEM_TYPE;
case MOVIES_ALL:
case MOVIES_LIST:
return MediaContract.Movies.CONTENT_TYPE;
case MOVIES_ID:
return MediaContract.Movies.CONTENT_ITEM_TYPE;
case MOVIE_CAST_ALL:
case MOVIE_CAST_LIST:
return MediaContract.MovieCast.CONTENT_TYPE;
case TVSHOWS_ALL:
case TVSHOWS_LIST:
return MediaContract.TVShows.CONTENT_TYPE;
case TVSHOWS_ID:
return MediaContract.TVShows.CONTENT_ITEM_TYPE;
case TVSHOWS_CAST_ALL:
case TVSHOWS_CAST_LIST:
return MediaContract.TVShowCast.CONTENT_TYPE;
case SEASONS_ALL:
case TVSHOW_SEASONS_LIST:
return MediaContract.Seasons.CONTENT_TYPE;
case TVSHOW_SEASONS_ID:
return MediaContract.Seasons.CONTENT_ITEM_TYPE;
case EPISODES_ALL:
case TVSHOW_EPISODES_LIST:
case TVSHOW_SEASON_EPISODES_LIST:
return MediaContract.Episodes.CONTENT_TYPE;
case TVSHOW_EPISODES_ID:
case TVSHOW_SEASON_EPISODES_ID:
return MediaContract.Episodes.CONTENT_ITEM_TYPE;
case ARTISTS_ALL:
case ARTISTS_LIST:
case ALBUM_ARTISTS_LIST:
return MediaContract.Artists.CONTENT_TYPE;
case ARTISTS_ID:
return MediaContract.Artists.CONTENT_ITEM_TYPE;
case ALBUMS_ALL:
case ALBUMS_LIST:
case ARTIST_ALBUMS_LIST:
case AUDIO_GENRE_ALBUMS_LIST:
return MediaContract.Albums.CONTENT_TYPE;
case ALBUMS_ID:
return MediaContract.Albums.CONTENT_ITEM_TYPE;
case SONGS_ALL:
case SONGS_LIST:
case ARTIST_SONGS_LIST:
case SONGS_ALBUM:
return MediaContract.Songs.CONTENT_TYPE;
case SONGS_ID:
return MediaContract.Songs.CONTENT_ITEM_TYPE;
case AUDIO_GENRES_ALL:
case AUDIO_GENRES_LIST:
case ALBUM_GENRES_LIST:
return MediaContract.AudioGenres.CONTENT_TYPE;
case AUDIO_GENRES_ID:
return MediaContract.AudioGenres.CONTENT_ITEM_TYPE;
case ALBUM_ARTISTS_ALL:
return MediaContract.AlbumArtists.CONTENT_TYPE;
case ALBUM_GENRES_ALL:
return MediaContract.AlbumGenres.CONTENT_TYPE;
case SONG_ARTISTS_ALL:
return MediaContract.SongArtists.CONTENT_TYPE;
case MUSIC_VIDEOS_ALL:
case MUSIC_VIDEOS_LIST:
return MediaContract.MusicVideos.CONTENT_TYPE;
case MUSIC_VIDEOS_ID:
return MediaContract.MusicVideos.CONTENT_ITEM_TYPE;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
/** {@inheritDoc} */
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
LogUtils.LOGV(TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
final int match = sUriMatcher.match(uri);
Cursor cursor;
switch (match) {
default: {
// Most cases are handled with simple SelectionBuilder
final SelectionBuilder builder = buildQuerySelection(uri, match);
cursor = builder.where(selection, selectionArgs)
.query(db, projection, sortOrder);
}
}
return cursor;
}
/** {@inheritDoc} */
@Override
public Uri insert(Uri uri, ContentValues values) {
LogUtils.LOGV(TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
Uri insertedUri;
switch (match) {
case HOSTS_LIST: {
values.put(MediaContract.SyncColumns.UPDATED, System.currentTimeMillis());
long hostId = db.insertOrThrow(MediaDatabase.Tables.HOSTS, null, values);
insertedUri = MediaContract.Hosts.buildHostUri(hostId);
break;
}
default: {
throw new UnsupportedOperationException("Unsuported uri: " + uri);
}
}
context.getContentResolver().notifyChange(uri, null);
return insertedUri;
}
/** {@inheritDoc} */
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
long startTime = System.currentTimeMillis();
final int match = sUriMatcher.match(uri);
String table;
switch (match) {
case MOVIES_ALL: {
table = MediaDatabase.Tables.MOVIES;
break;
}
case MOVIE_CAST_ALL: {
table = MediaDatabase.Tables.MOVIE_CAST;
break;
}
case TVSHOWS_ALL: {
table = MediaDatabase.Tables.TVSHOWS;
break;
}
case TVSHOWS_CAST_ALL: {
table = MediaDatabase.Tables.TVSHOWS_CAST;
break;
}
case SEASONS_ALL: {
table = MediaDatabase.Tables.SEASONS;
break;
}
case EPISODES_ALL: {
table = MediaDatabase.Tables.EPISODES;
break;
}
case ARTISTS_ALL: {
table = MediaDatabase.Tables.ARTISTS;
break;
}
case ALBUMS_ALL: {
table = MediaDatabase.Tables.ALBUMS;
break;
}
case SONGS_ALL: {
table = MediaDatabase.Tables.SONGS;
break;
}
case AUDIO_GENRES_ALL: {
table = MediaDatabase.Tables.AUDIO_GENRES;
break;
}
case ALBUM_GENRES_ALL: {
table = MediaDatabase.Tables.ALBUM_GENRES;
break;
}
case ALBUM_ARTISTS_ALL: {
table = MediaDatabase.Tables.ALBUM_ARTISTS;
break;
}
case SONG_ARTISTS_ALL: {
table = MediaDatabase.Tables.SONG_ARTISTS;
break;
}
case MUSIC_VIDEOS_ALL: {
table = MediaDatabase.Tables.MUSIC_VIDEOS;
break;
}
default: {
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
long updateTime = System.currentTimeMillis();
try {
for (ContentValues value : values) {
switch (match) {
case ALBUM_GENRES_ALL:
case ALBUM_ARTISTS_ALL:
case SONG_ARTISTS_ALL:
// Nothing to add to these tables
break;
default:
value.put(MediaContract.SyncColumns.UPDATED, updateTime);
break;
}
db.insertOrThrow(table, null, value);
}
db.setTransactionSuccessful();
} catch (Exception e) {
LogUtils.LOGD(TAG, "Couldn't bulk insert records. Exception: " + e.getMessage());
} finally {
db.endTransaction();
}
context.getContentResolver().notifyChange(uri, null);
LogUtils.LOGD(TAG, "Bulk insert finished for uri (" + uri +
") in (ms): " + (System.currentTimeMillis() - startTime));
return values.length;
}
/** {@inheritDoc} */
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
LogUtils.LOGD(TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
final int match = sUriMatcher.match(uri);
switch (match) {
case HOSTS_ID:
case MOVIES_ID:
case TVSHOWS_ID:
case TVSHOW_SEASONS_ID:
case TVSHOW_EPISODES_ID:
case ARTISTS_ID:
case ALBUMS_ID:
case SONGS_ID:
case AUDIO_GENRES_ID:
case MUSIC_VIDEOS_ID: {
// Add updated field
values.put(MediaContract.SyncColumns.UPDATED, System.currentTimeMillis());
break;
}
default: {
throw new UnsupportedOperationException("Unknown uri for update: " + uri);
}
}
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final SelectionBuilder builder = buildQuerySelection(uri, match);
int result = builder.where(selection, selectionArgs)
.update(db, values);
context.getContentResolver().notifyChange(uri, null);
return result;
}
/** {@inheritDoc} */
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
final int match = sUriMatcher.match(uri);
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final SelectionBuilder builder = buildQuerySelection(uri, match);
int result = builder.where(selection, selectionArgs)
.delete(db);
LogUtils.LOGD(TAG, "delete(uri=" + uri + "). Rows affected: " + result);
context.getContentResolver().notifyChange(uri, null);
return result;
}
/**
* Build an advanced {@link SelectionBuilder} to match the requested
* {@link Uri}. This is usually only used by {@link #query}, since it
* performs table joins useful for {@link Cursor} data.
*/
private SelectionBuilder buildQuerySelection(Uri uri, int match) {
final SelectionBuilder builder = new SelectionBuilder();
switch (match) {
case HOSTS_LIST: {
return builder.table(MediaDatabase.Tables.HOSTS);
}
case HOSTS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.HOSTS)
.where(BaseColumns._ID + "=?", hostId);
}
case MOVIES_ALL: {
return builder.table(MediaDatabase.Tables.MOVIES);
}
case MOVIES_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.MOVIES)
.where(MediaContract.Movies.HOST_ID + "=?", hostId);
}
case MOVIES_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String movieId = MediaContract.Movies.getMovieId(uri);
return builder.table(MediaDatabase.Tables.MOVIES)
.where(MediaContract.Movies.HOST_ID + "=?", hostId)
.where(MediaContract.Movies.MOVIEID + "=?", movieId);
}
case MOVIE_CAST_ALL: {
return builder.table(MediaDatabase.Tables.MOVIE_CAST);
}
case MOVIE_CAST_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String movieId = MediaContract.Movies.getMovieId(uri);
return builder.table(MediaDatabase.Tables.MOVIE_CAST)
.where(MediaContract.MovieCast.HOST_ID + "=?", hostId)
.where(MediaContract.MovieCast.MOVIEID + "=?", movieId);
}
case TVSHOWS_ALL: {
return builder.table(MediaDatabase.Tables.TVSHOWS);
}
case TVSHOWS_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.TVSHOWS)
.where(MediaContract.TVShows.HOST_ID + "=?", hostId);
}
case TVSHOWS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
return builder.table(MediaDatabase.Tables.TVSHOWS)
.where(MediaContract.TVShows.HOST_ID + "=?", hostId)
.where(MediaContract.TVShows.TVSHOWID + "=?", tvshowId);
}
case TVSHOWS_CAST_ALL: {
return builder.table(MediaDatabase.Tables.TVSHOWS_CAST);
}
case TVSHOWS_CAST_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
return builder.table(MediaDatabase.Tables.TVSHOWS_CAST)
.where(MediaContract.TVShowCast.HOST_ID + "=?", hostId)
.where(MediaContract.TVShowCast.TVSHOWID + "=?", tvshowId);
}
case SEASONS_ALL: {
return builder.table(MediaDatabase.Tables.SEASONS);
}
case TVSHOW_SEASONS_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
return builder.table(MediaDatabase.Tables.SEASONS)
.where(MediaContract.Seasons.HOST_ID + "=?", hostId)
.where(MediaContract.Seasons.TVSHOWID + "=?", tvshowId);
}
case TVSHOW_SEASONS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
final String season = MediaContract.Seasons.getTVShowSeasonId(uri);
return builder.table(MediaDatabase.Tables.SEASONS)
.where(MediaContract.Seasons.HOST_ID + "=?", hostId)
.where(MediaContract.Seasons.TVSHOWID + "=?", tvshowId)
.where(MediaContract.Seasons.SEASON + "=?", season);
}
case EPISODES_ALL: {
return builder.table(MediaDatabase.Tables.EPISODES);
}
case TVSHOW_EPISODES_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
return builder.table(MediaDatabase.Tables.EPISODES)
.where(MediaContract.Episodes.HOST_ID + "=?", hostId)
.where(MediaContract.Episodes.TVSHOWID + "=?", tvshowId);
}
case TVSHOW_EPISODES_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
final String episodeId = MediaContract.Episodes.getTVShowEpisodeId(uri);
return builder.table(MediaDatabase.Tables.EPISODES)
.where(MediaContract.Episodes.HOST_ID + "=?", hostId)
.where(MediaContract.Episodes.TVSHOWID + "=?", tvshowId)
.where(MediaContract.Episodes.EPISODEID + "=?", episodeId);
}
case TVSHOW_SEASON_EPISODES_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
final String season = MediaContract.Seasons.getTVShowSeasonId(uri);
return builder.table(MediaDatabase.Tables.EPISODES)
.where(MediaContract.Episodes.HOST_ID + "=?", hostId)
.where(MediaContract.Episodes.TVSHOWID + "=?", tvshowId)
.where(MediaContract.Episodes.SEASON + "=?", season);
}
case TVSHOW_SEASON_EPISODES_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String tvshowId = MediaContract.TVShows.getTVShowId(uri);
final String season = MediaContract.Seasons.getTVShowSeasonId(uri);
final String episodeId = MediaContract.Episodes.getTVShowSeasonEpisodeId(uri);
return builder.table(MediaDatabase.Tables.EPISODES)
.where(MediaContract.Episodes.HOST_ID + "=?", hostId)
.where(MediaContract.Episodes.TVSHOWID + "=?", tvshowId)
.where(MediaContract.Episodes.SEASON + "=?", season)
.where(MediaContract.Episodes.EPISODEID + "=?", episodeId);
}
case ARTISTS_ALL: {
return builder.table(MediaDatabase.Tables.ARTISTS);
}
case ARTISTS_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.ARTISTS)
.where(MediaContract.Artists.HOST_ID + "=?", hostId);
}
case ARTISTS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String artistId = MediaContract.Artists.getArtistId(uri);
return builder.table(MediaDatabase.Tables.ARTISTS)
.where(MediaContract.Artists.HOST_ID + "=?", hostId)
.where(MediaContract.Artists.ARTISTID + "=?", artistId);
}
case ALBUMS_ALL: {
return builder.table(MediaDatabase.Tables.ALBUMS);
}
case ALBUMS_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.ALBUMS)
.where(MediaContract.Albums.HOST_ID + "=?", hostId);
}
case ALBUMS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String albumId = MediaContract.Albums.getAlbumId(uri);
return builder.table(MediaDatabase.Tables.ALBUMS)
.where(MediaContract.Albums.HOST_ID + "=?", hostId)
.where(MediaContract.Albums.ALBUMID + "=?", albumId);
}
case SONGS_ALL: {
return builder.table(MediaDatabase.Tables.SONGS);
}
case SONGS_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.SONGS_FOR_ARTIST_AND_OR_ALBUM_JOIN)
.mapToTable(MediaContract.Songs.SONGID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.TITLE, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.ALBUMID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.UPDATED, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.THUMBNAIL, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.SongArtists.ARTISTID, MediaDatabase.Tables.SONG_ARTISTS)
.where(Qualified.SONGS_HOST_ID + "=?", hostId)
.groupBy(Qualified.SONGS_SONGID);
}
case SONGS_ALBUM: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String albumId = MediaContract.Albums.getAlbumId(uri);
return builder.table(MediaDatabase.Tables.SONGS)
.where(MediaContract.Songs.HOST_ID + "=?", hostId)
.where(MediaContract.Songs.ALBUMID + "=?", albumId);
}
case SONGS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String albumId = MediaContract.Albums.getAlbumId(uri);
final String songId = MediaContract.Songs.getSongId(uri);
return builder.table(MediaDatabase.Tables.SONGS)
.where(MediaContract.Songs.HOST_ID + "=?", hostId)
.where(MediaContract.Songs.ALBUMID + "=?", albumId)
.where(MediaContract.Songs.SONGID + "=?", songId);
}
case AUDIO_GENRES_ALL: {
return builder.table(MediaDatabase.Tables.AUDIO_GENRES);
}
case AUDIO_GENRES_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.AUDIO_GENRES)
.where(MediaContract.AudioGenres.HOST_ID + "=?", hostId);
}
case AUDIO_GENRES_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String audioGenreId = MediaContract.AudioGenres.getAudioGenreId(uri);
return builder.table(MediaDatabase.Tables.AUDIO_GENRES)
.where(MediaContract.AudioGenres.HOST_ID + "=?", hostId)
.where(MediaContract.AudioGenres.GENREID + "=?", audioGenreId);
}
case ALBUM_ARTISTS_ALL: {
return builder.table(MediaDatabase.Tables.ALBUM_ARTISTS);
}
case SONG_ARTISTS_ALL: {
return builder.table(MediaDatabase.Tables.SONG_ARTISTS);
}
case ALBUM_GENRES_ALL: {
return builder.table(MediaDatabase.Tables.ALBUM_GENRES);
}
case ARTIST_ALBUMS_LIST: {
// Albums for Artists
final String hostId = MediaContract.Hosts.getHostId(uri);
final String artistId = MediaContract.Artists.getArtistId(uri);
return builder.table(MediaDatabase.Tables.ALBUMS_FOR_ARTIST_JOIN)
.mapToTable(MediaContract.Albums._ID, MediaDatabase.Tables.ALBUMS)
.mapToTable(MediaContract.Albums.HOST_ID, MediaDatabase.Tables.ALBUMS)
.mapToTable(MediaContract.Albums.ALBUMID, MediaDatabase.Tables.ALBUMS)
.mapToTable(MediaContract.AlbumArtists.ARTISTID, MediaDatabase.Tables.ALBUM_ARTISTS)
.where(Qualified.ALBUM_ARTISTS_HOST_ID + "=?", hostId)
.where(Qualified.ALBUM_ARTISTS_ARTISTID + "=?", artistId);
}
case ARTIST_SONGS_LIST: {
// Songs for Artists
final String hostId = MediaContract.Hosts.getHostId(uri);
final String artistId = MediaContract.Artists.getArtistId(uri);
return builder.table(MediaDatabase.Tables.SONGS_FOR_ARTIST_AND_OR_ALBUM_JOIN)
.mapToTable(MediaContract.Songs.SONGID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.TITLE, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.ALBUMID, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.UPDATED, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.Songs.THUMBNAIL, MediaDatabase.Tables.SONGS)
.mapToTable(MediaContract.SongArtists.ARTISTID, MediaDatabase.Tables.SONG_ARTISTS)
.where(Qualified.SONG_ARTISTS_HOST_ID + "=?", hostId)
.where(Qualified.SONG_ARTISTS_ARTISTID + "=?", artistId);
}
case ALBUM_ARTISTS_LIST: {
// Artists for Album
final String hostId = MediaContract.Hosts.getHostId(uri);
final String albumId = MediaContract.Albums.getAlbumId(uri);
return builder.table(MediaDatabase.Tables.ARTISTS_FOR_ALBUM_JOIN)
.mapToTable(MediaContract.Artists._ID, MediaDatabase.Tables.ARTISTS)
.mapToTable(MediaContract.Artists.HOST_ID, MediaDatabase.Tables.ARTISTS)
.mapToTable(MediaContract.Artists.ARTISTID, MediaDatabase.Tables.ARTISTS)
.mapToTable(MediaContract.AlbumArtists.ALBUMID, MediaDatabase.Tables.ALBUM_ARTISTS)
.where(Qualified.ALBUM_ARTISTS_HOST_ID + "=?", hostId)
.where(Qualified.ALBUM_ARTISTS_ALBUMID + "=?", albumId);
}
case ALBUM_GENRES_LIST: {
// Genres for Album
final String hostId = MediaContract.Hosts.getHostId(uri);
final String albumId = MediaContract.Albums.getAlbumId(uri);
return builder.table(MediaDatabase.Tables.GENRES_FOR_ALBUM_JOIN)
.mapToTable(MediaContract.AudioGenres._ID, MediaDatabase.Tables.AUDIO_GENRES)
.mapToTable(MediaContract.AudioGenres.HOST_ID, MediaDatabase.Tables.AUDIO_GENRES)
.mapToTable(MediaContract.AudioGenres.GENREID, MediaDatabase.Tables.AUDIO_GENRES)
.mapToTable(MediaContract.AlbumGenres.ALBUMID, MediaDatabase.Tables.ALBUM_GENRES)
.where(Qualified.ALBUM_GENRES_HOST_ID + "=?", hostId)
.where(Qualified.ALBUM_GENRES_ALBUMID + "=?", albumId);
}
case AUDIO_GENRE_ALBUMS_LIST: {
// Album for a Genre
final String hostId = MediaContract.Hosts.getHostId(uri);
final String genreId = MediaContract.AudioGenres.getAudioGenreId(uri);
return builder.table(MediaDatabase.Tables.ALBUMS_FOR_GENRE_JOIN)
.mapToTable(MediaContract.Albums._ID, MediaDatabase.Tables.ALBUMS)
.mapToTable(MediaContract.Albums.HOST_ID, MediaDatabase.Tables.ALBUMS)
.mapToTable(MediaContract.Albums.ALBUMID, MediaDatabase.Tables.ALBUMS)
.mapToTable(MediaContract.AlbumGenres.GENREID, MediaDatabase.Tables.ALBUM_GENRES)
.where(Qualified.ALBUM_GENRES_HOST_ID + "=?", hostId)
.where(Qualified.ALBUM_GENRES_GENREID + "=?", genreId);
}
case MUSIC_VIDEOS_ALL: {
return builder.table(MediaDatabase.Tables.MUSIC_VIDEOS);
}
case MUSIC_VIDEOS_LIST: {
final String hostId = MediaContract.Hosts.getHostId(uri);
return builder.table(MediaDatabase.Tables.MUSIC_VIDEOS)
.where(MediaContract.MusicVideos.HOST_ID + "=?", hostId);
}
case MUSIC_VIDEOS_ID: {
final String hostId = MediaContract.Hosts.getHostId(uri);
final String musicVideoId = MediaContract.MusicVideos.getMusicVideoId(uri);
return builder.table(MediaDatabase.Tables.MUSIC_VIDEOS)
.where(MediaContract.MusicVideos.HOST_ID + "=?", hostId)
.where(MediaContract.MusicVideos.MUSICVIDEOID + "=?", musicVideoId);
}
default: {
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
}
/**
* {@link MediaContract} fields that are fully qualified with a specific
* parent {@link MediaDatabase.Tables}. Used when needed to work around SQL ambiguity.
*/
public interface Qualified {
String ALBUM_ARTISTS_HOST_ID =
MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.HOST_ID;
String ALBUM_ARTISTS_ARTISTID =
MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.ARTISTID;
String ALBUM_ARTISTS_ALBUMID =
MediaDatabase.Tables.ALBUM_ARTISTS + "." + MediaContract.AlbumArtists.ALBUMID;
String ALBUM_GENRES_HOST_ID =
MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.HOST_ID;
String ALBUM_GENRES_GENREID =
MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.GENREID;
String ALBUM_GENRES_ALBUMID =
MediaDatabase.Tables.ALBUM_GENRES + "." + MediaContract.AlbumGenres.ALBUMID;
String SONGS_HOST_ID =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.HOST_ID;
String SONGS_SONGID =
MediaDatabase.Tables.SONGS + "." + MediaContract.Songs.SONGID;
String SONG_ARTISTS_HOST_ID =
MediaDatabase.Tables.SONG_ARTISTS + "." + MediaContract.SongArtists.HOST_ID;
String SONG_ARTISTS_ARTISTID =
MediaDatabase.Tables.SONG_ARTISTS + "." + MediaContract.SongArtists.ARTISTID;
}
}