package tech.salroid.filmy.providers;
import android.annotation.TargetApi;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.Nullable;
import tech.salroid.filmy.database.FilmContract;
import tech.salroid.filmy.database.FilmDbHelper;
/*
* Filmy Application for Android
* Copyright (c) 2016 Ramankit Singh (http://github.com/webianks).
*
* 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.
*/
public class FilmProvider extends ContentProvider {
static final int TRENDING_MOVIE = 100;
static final int INTHEATERS_MOVIE = 400;
static final int UPCOMING_MOVIE = 500;
static final int TRENDING_MOVIE_DETAILS_WITH_MOVIE_ID = 101;
static final int INTHEATERS_MOVIE_DETAILS_WITH_MOVIE_ID = 401;
static final int UPCOMING_MOVIE_DETAILS_WITH_MOVIE_ID = 501;
static final int CAST_WITH_MOVIE_ID = 102;
static final int CAST = 300;
static final int SAVE = 200;
static final int SAVE_DETAILS_WITH_MOVIE_ID = 201;
// The URI Matcher used by this content provider.
private static final UriMatcher sUriMatcher = buildUriMatcher();
private static final String sTrendingMovieIdSelection =
FilmContract.MoviesEntry.TABLE_NAME +
"." + FilmContract.MoviesEntry.MOVIE_ID + " = ? ";
private static final String sInTheatersMovieIdSelection =
FilmContract.InTheatersMoviesEntry.TABLE_NAME +
"." + FilmContract.MoviesEntry.MOVIE_ID + " = ? ";
private static final String sUpcomingMovieIdSelection =
FilmContract.UpComingMoviesEntry.TABLE_NAME +
"." + FilmContract.MoviesEntry.MOVIE_ID + " = ? ";
private static final String sMovieIdSelectionForCast =
FilmContract.CastEntry.TABLE_NAME +
"." + FilmContract.CastEntry.CAST_MOVIE_ID + " = ? ";
private FilmDbHelper mOpenHelper;
static UriMatcher buildUriMatcher() {
// 1) The code passed into the constructor represents the code to return for the root
// URI. It'FilmyAuthenticator common to use NO_MATCH as the code for this case. Add the constructor below.
final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = FilmContract.CONTENT_AUTHORITY;
// 2) Use the addURI function to match each of the types. Use the constants from
// WeatherContract to help define the types to the UriMatcher.
uriMatcher.addURI(authority, FilmContract.TRENDING_PATH_MOVIE, TRENDING_MOVIE);
uriMatcher.addURI(authority, FilmContract.TRENDING_PATH_MOVIE + "/*", TRENDING_MOVIE_DETAILS_WITH_MOVIE_ID);
uriMatcher.addURI(authority, FilmContract.INTHEATERS_PATH_MOVIE, INTHEATERS_MOVIE);
uriMatcher.addURI(authority, FilmContract.INTHEATERS_PATH_MOVIE + "/*", INTHEATERS_MOVIE_DETAILS_WITH_MOVIE_ID);
uriMatcher.addURI(authority, FilmContract.UPCOMING_PATH_MOVIE, UPCOMING_MOVIE);
uriMatcher.addURI(authority, FilmContract.UPCOMING_PATH_MOVIE + "/*", UPCOMING_MOVIE_DETAILS_WITH_MOVIE_ID);
uriMatcher.addURI(authority, FilmContract.PATH_CAST + "/*", CAST_WITH_MOVIE_ID);
uriMatcher.addURI(authority, FilmContract.PATH_CAST, CAST);
uriMatcher.addURI(authority, FilmContract.PATH_SAVE, SAVE);
uriMatcher.addURI(authority, FilmContract.PATH_SAVE + "/*", SAVE_DETAILS_WITH_MOVIE_ID);
// 3) Return the new matcher!
return uriMatcher;
}
@Override
public boolean onCreate() {
mOpenHelper = new FilmDbHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor retCursor;
switch (sUriMatcher.match(uri)) {
case TRENDING_MOVIE_DETAILS_WITH_MOVIE_ID: {
retCursor = getTrendingMovieDetailsByMovieId(uri, projection, sortOrder);
break;
}
case INTHEATERS_MOVIE_DETAILS_WITH_MOVIE_ID: {
retCursor = getInTheatersMovieDetailsByMovieId(uri, projection, sortOrder);
break;
}
case UPCOMING_MOVIE_DETAILS_WITH_MOVIE_ID: {
retCursor = getUpcomingMovieDetailsByMovieId(uri, projection, sortOrder);
break;
}
case CAST_WITH_MOVIE_ID: {
retCursor = getCastByMovieID(uri, projection, sortOrder);
break;
}
case TRENDING_MOVIE: {
retCursor = mOpenHelper.getReadableDatabase().query(
FilmContract.MoviesEntry.TABLE_NAME,
projection, selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
case INTHEATERS_MOVIE: {
retCursor = mOpenHelper.getReadableDatabase().query(
FilmContract.InTheatersMoviesEntry.TABLE_NAME,
projection, selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
case UPCOMING_MOVIE: {
retCursor = mOpenHelper.getReadableDatabase().query(
FilmContract.UpComingMoviesEntry.TABLE_NAME,
projection, selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
case CAST: {
retCursor = mOpenHelper.getReadableDatabase().query(
FilmContract.CastEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
case SAVE: {
retCursor = mOpenHelper.getReadableDatabase().query(
FilmContract.SaveEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
}
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
private Cursor getTrendingMovieDetailsByMovieId(Uri uri, String[] projection, String sortOrder) {
String movieId = FilmContract.MoviesEntry.getMovieIdFromUri(uri);
String selection = sTrendingMovieIdSelection;
String[] selectionArgs = new String[]{movieId};
return mOpenHelper.getReadableDatabase().query(
FilmContract.MoviesEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
}
private Cursor getInTheatersMovieDetailsByMovieId(Uri uri, String[] projection, String sortOrder) {
String movieId = FilmContract.InTheatersMoviesEntry.getMovieIdFromUri(uri);
String selection = sInTheatersMovieIdSelection;
String[] selectionArgs = new String[]{movieId};
return mOpenHelper.getReadableDatabase().query(
FilmContract.InTheatersMoviesEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
}
private Cursor getUpcomingMovieDetailsByMovieId(Uri uri, String[] projection, String sortOrder) {
String movieId = FilmContract.UpComingMoviesEntry.getMovieIdFromUri(uri);
String selection = sUpcomingMovieIdSelection;
String[] selectionArgs = new String[]{movieId};
return mOpenHelper.getReadableDatabase().query(
FilmContract.UpComingMoviesEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
}
private Cursor getCastByMovieID(Uri uri, String[] projection, String sortOrder) {
String movieId = FilmContract.CastEntry.getMovieIdFromUri(uri);
String selection = sTrendingMovieIdSelection;
String[] selectionArgs = new String[]{movieId};
return mOpenHelper.getReadableDatabase().query(
FilmContract.CastEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
}
private Cursor getSaveByMovieID(Uri uri, String[] projection, String sortOrder) {
String movieId = FilmContract.SaveEntry.getMovieIdFromUri(uri);
String selection = sTrendingMovieIdSelection;
String[] selectionArgs = new String[]{movieId};
return mOpenHelper.getReadableDatabase().query(
FilmContract.SaveEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
}
@Nullable
@Override
public String getType(Uri uri) {
// Use the Uri Matcher to determine what kind of URI this is.
final int match = sUriMatcher.match(uri);
switch (match) {
case TRENDING_MOVIE_DETAILS_WITH_MOVIE_ID:
return FilmContract.MoviesEntry.CONTENT_ITEM_TYPE;
case INTHEATERS_MOVIE_DETAILS_WITH_MOVIE_ID:
return FilmContract.MoviesEntry.CONTENT_ITEM_TYPE;
case UPCOMING_MOVIE_DETAILS_WITH_MOVIE_ID:
return FilmContract.MoviesEntry.CONTENT_ITEM_TYPE;
case CAST_WITH_MOVIE_ID:
return FilmContract.CastEntry.CONTENT_TYPE;
case TRENDING_MOVIE:
return FilmContract.MoviesEntry.CONTENT_TYPE;
case INTHEATERS_MOVIE:
return FilmContract.MoviesEntry.CONTENT_TYPE;
case UPCOMING_MOVIE:
return FilmContract.MoviesEntry.CONTENT_TYPE;
case CAST:
return FilmContract.CastEntry.CONTENT_TYPE;
case SAVE:
return FilmContract.SaveEntry.CONTENT_TYPE;
case SAVE_DETAILS_WITH_MOVIE_ID:
return FilmContract.SaveEntry.CONTENT_ITEM_TYPE;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
Uri returnUri;
switch (match) {
case TRENDING_MOVIE: {
long _id = db.insert(FilmContract.MoviesEntry.TABLE_NAME, null, contentValues);
if (_id > 0)
returnUri = FilmContract.MoviesEntry.buildMovieUri(_id);
else
throw new android.database.SQLException("Failed to insert row into " + uri);
break;
}
case INTHEATERS_MOVIE: {
long _id = db.insert(FilmContract.InTheatersMoviesEntry.TABLE_NAME, null, contentValues);
if (_id > 0)
returnUri = FilmContract.InTheatersMoviesEntry.buildMovieUri(_id);
else
throw new android.database.SQLException("Failed to insert row into " + uri);
break;
}
case UPCOMING_MOVIE: {
long _id = db.insert(FilmContract.UpComingMoviesEntry.TABLE_NAME, null, contentValues);
if (_id > 0)
returnUri = FilmContract.UpComingMoviesEntry.buildMovieUri(_id);
else
throw new android.database.SQLException("Failed to insert row into " + uri);
break;
}
case CAST: {
long _id = db.insert(FilmContract.CastEntry.TABLE_NAME, null, contentValues);
if (_id > 0)
returnUri = FilmContract.CastEntry.buildCastUri(_id);
else
throw new android.database.SQLException("Failed to insert row into " + uri);
break;
}
case SAVE: {
long _id = db.insert(FilmContract.SaveEntry.TABLE_NAME, null, contentValues);
if (_id > 0)
returnUri = FilmContract.SaveEntry.buildMovieUri(_id);
else
throw new android.database.SQLException("Failed to insert row into " + uri);
break;
}
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
int rowsDeleted;
if (selection == null) selection = "1";
switch (match) {
case TRENDING_MOVIE:
rowsDeleted = db.delete(FilmContract.MoviesEntry.TABLE_NAME, selection, selectionArgs);
break;
case INTHEATERS_MOVIE:
rowsDeleted = db.delete(FilmContract.InTheatersMoviesEntry.TABLE_NAME, selection, selectionArgs);
break;
case UPCOMING_MOVIE:
rowsDeleted = db.delete(FilmContract.UpComingMoviesEntry.TABLE_NAME, selection, selectionArgs);
break;
case CAST:
rowsDeleted = db.delete(FilmContract.CastEntry.TABLE_NAME, selection, selectionArgs);
break;
case SAVE:
rowsDeleted = db.delete(FilmContract.SaveEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri = " + uri);
}
if (rowsDeleted != 0)
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
@Override
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
int rowsUpdated;
switch (match) {
case TRENDING_MOVIE_DETAILS_WITH_MOVIE_ID:
rowsUpdated = db.update(FilmContract.MoviesEntry.TABLE_NAME, contentValues, selection, selectionArgs);
break;
case INTHEATERS_MOVIE_DETAILS_WITH_MOVIE_ID:
rowsUpdated = db.update(FilmContract.InTheatersMoviesEntry.TABLE_NAME, contentValues, selection, selectionArgs);
break;
case UPCOMING_MOVIE_DETAILS_WITH_MOVIE_ID:
rowsUpdated = db.update(FilmContract.UpComingMoviesEntry.TABLE_NAME, contentValues, selection, selectionArgs);
break;
case SAVE_DETAILS_WITH_MOVIE_ID:
rowsUpdated = db.update(FilmContract.SaveEntry.TABLE_NAME, contentValues, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri = " + uri);
}
if (rowsUpdated != 0)
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
switch (match) {
case TRENDING_MOVIE:
db.beginTransaction();
int returnCount = 0;
try {
for (ContentValues value : values) {
long _id = db.insert(FilmContract.MoviesEntry.TABLE_NAME, null, value);
if (_id != -1) {
returnCount++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
getContext().getContentResolver().notifyChange(uri, null);
return returnCount;
case INTHEATERS_MOVIE:
db.beginTransaction();
int returnCount1 = 0;
try {
for (ContentValues value : values) {
long _id = db.insert(FilmContract.InTheatersMoviesEntry.TABLE_NAME, null, value);
if (_id != -1) {
returnCount1++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
getContext().getContentResolver().notifyChange(uri, null);
return returnCount1;
case UPCOMING_MOVIE:
db.beginTransaction();
int returnCount2 = 0;
try {
for (ContentValues value : values) {
long _id = db.insert(FilmContract.UpComingMoviesEntry.TABLE_NAME, null, value);
if (_id != -1) {
returnCount2++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
getContext().getContentResolver().notifyChange(uri, null);
return returnCount2;
case SAVE:
db.beginTransaction();
int SaveReturnCount = 0;
try {
for (ContentValues value : values) {
long _id = db.insert(FilmContract.SaveEntry.TABLE_NAME, null, value);
if (_id != -1) {
SaveReturnCount++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
getContext().getContentResolver().notifyChange(uri, null);
return SaveReturnCount;
default:
return super.bulkInsert(uri, values);
}
}
// You do not need to call this method. This is a method specifically to assist the testing
// framework in running smoothly. You can read more at:
// http://developer.android.com/reference/android/content/ContentProvider.html#shutdown()
@Override
@TargetApi(11)
public void shutdown() {
mOpenHelper.close();
super.shutdown();
}
}