Skip to content

Instantly share code, notes, and snippets.

@jdkoren
Last active August 29, 2015 14:19
Show Gist options
  • Save jdkoren/32bc35c03df34d809145 to your computer and use it in GitHub Desktop.
Save jdkoren/32bc35c03df34d809145 to your computer and use it in GitHub Desktop.
UniversityProvider.java
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
import com.example.squidbuni.UniversityDatabase;
import com.example.squidbuni.models.Course;
import com.example.squidbuni.models.FacultyMember;
import com.example.squidbuni.models.Student;
import com.example.squidbuni.provider.UniversityContract.Courses;
import com.example.squidbuni.provider.UniversityContract.Faculty;
import com.example.squidbuni.provider.UniversityContract.Students;
import com.example.squidbuni.provider.models.ContractStudent;
import com.example.squidbuni.provider.models.CoursesByStudent;
import com.example.squidbuni.provider.models.StudentsByCourse;
import com.yahoo.squidb.data.AbstractModel;
import com.yahoo.squidb.data.DatabaseDao;
import com.yahoo.squidb.data.SquidCursor;
import com.yahoo.squidb.data.TableModel;
import com.yahoo.squidb.sql.Criterion;
import com.yahoo.squidb.sql.Function;
import com.yahoo.squidb.sql.Query;
import com.yahoo.squidb.utility.ContentProviderQueryBuilder;
import com.yahoo.squidb.utility.ProjectionMap;
import java.util.List;
public class UniversityProvider extends ContentProvider {
// match codes
private static final int FACULTY = 100;
private static final int FACULTY_ID = 101;
private static final int FACULTY_ID_COURSES = 102;
private static final int STUDENTS = 200;
private static final int STUDENTS_ID = 201;
private static final int STUDENTS_ID_COURSES = 202;
private static final int COURSES = 300;
private static final int COURSES_ID = 301;
private static final int COURSES_ID_FACULTY = 302;
private static final int COURSES_ID_STUDENTS = 303;
private static final UriMatcher URI_MATCHER = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
final String authority = UniversityContract.AUTHORITY;
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(authority, "faculty", FACULTY);
matcher.addURI(authority, "faculty/#", FACULTY_ID);
matcher.addURI(authority, "faculty/#/courses", FACULTY_ID_COURSES);
matcher.addURI(authority, "students", STUDENTS);
matcher.addURI(authority, "students/#", STUDENTS_ID);
matcher.addURI(authority, "students/#/courses", STUDENTS_ID_COURSES);
matcher.addURI(authority, "courses", COURSES);
matcher.addURI(authority, "courses/#", COURSES_ID);
matcher.addURI(authority, "courses/#/faculty", COURSES_ID_FACULTY);
matcher.addURI(authority, "courses/#/students", COURSES_ID_STUDENTS);
return matcher;
}
private DatabaseDao databaseDao;
private static final ProjectionMap FACULTY_PROJECTION_MAP = new ProjectionMap();
private static final ProjectionMap COUNT_PROJECTION_MAP = new ProjectionMap();
static {
FACULTY_PROJECTION_MAP.put(Faculty._ID, FacultyMember.ID);
FACULTY_PROJECTION_MAP.put(Faculty.NAME, FacultyMember.NAME);
FACULTY_PROJECTION_MAP.put(Faculty.DEPARTMENT, FacultyMember.DEPARTMENT);
COUNT_PROJECTION_MAP.put(BaseColumns._COUNT, Function.count());
}
@Override
public boolean onCreate() {
databaseDao = new DatabaseDao(new UniversityDatabase(getContext()));
return true;
}
@Override
public String getType(Uri uri) {
switch (URI_MATCHER.match(uri)) {
case FACULTY:
return Faculty.CONTENT_TYPE;
case FACULTY_ID:
return Faculty.CONTENT_ITEM_TYPE;
case FACULTY_ID_COURSES:
return Courses.CONTENT_TYPE;
case STUDENTS:
return Students.CONTENT_TYPE;
case STUDENTS_ID:
return Students.CONTENT_ITEM_TYPE;
case STUDENTS_ID_COURSES:
return Courses.CONTENT_TYPE;
case COURSES:
return Courses.CONTENT_TYPE;
case COURSES_ID:
return Courses.CONTENT_ITEM_TYPE;
case COURSES_ID_FACULTY:
return Faculty.CONTENT_TYPE;
case COURSES_ID_STUDENTS:
return Students.CONTENT_TYPE;
}
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Query query;
switch (URI_MATCHER.match(uri)) {
case FACULTY:
query = buildFacultyQuery(projection, selection, selectionArgs, sortOrder);
break;
case FACULTY_ID:
query = buildFacultyQuery(projection, selection, selectionArgs, sortOrder);
query.where(FacultyMember.ID.eq(ContentUris.parseId(uri)));
break;
case FACULTY_ID_COURSES:
query = buildCoursesQuery(projection, selection, selectionArgs, sortOrder);
query.where(Course.INSTRUCTOR_ID.eq(getIdPathSegment(uri, 1)));
break;
case STUDENTS:
query = buildStudentsQuery(projection, selection, selectionArgs, sortOrder);
break;
case STUDENTS_ID:
query = buildStudentsQuery(projection, selection, selectionArgs, sortOrder);
query.where(ContractStudent.ID.eq(ContentUris.parseId(uri)));
break;
case STUDENTS_ID_COURSES:
query = buildCoursesByStudentQuery(projection, selection, selectionArgs, sortOrder);
query.where(CoursesByStudent.STUDENT_ID.eq(getIdPathSegment(uri, 1)));
break;
case COURSES:
query = buildCoursesQuery(projection, selection, selectionArgs, sortOrder);
break;
case COURSES_ID:
query = buildCoursesQuery(projection, selection, selectionArgs, sortOrder);
query.where(Course.ID.eq(ContentUris.parseId(uri)));
break;
case COURSES_ID_FACULTY:
query = buildFacultyQuery(projection, selection, selectionArgs, sortOrder);
query.where(FacultyMember.ID.eq(getIdPathSegment(uri, 1)));
break;
case COURSES_ID_STUDENTS:
query = buildStudentsByCourseQuery(projection, selection, selectionArgs, sortOrder);
query.where(StudentsByCourse.COURSE_ID.eq(getIdPathSegment(uri, 1)));
break;
default:
throw new UnsupportedOperationException("Unsupported uri: " + uri);
}
query.limit(getLimit(uri));
SquidCursor<AbstractModel> cursor = databaseDao.query(AbstractModel.class, query);
return cursor;
}
private long getIdPathSegment(Uri uri, int pathIndex) {
if (pathIndex < 0) {
throw new IllegalArgumentException("pathIndex can't be less than zero");
}
List<String> pathSegments = uri.getPathSegments();
if (pathSegments.size() <= pathIndex) {
throw new IllegalArgumentException("Uri has too few path segments");
}
return Long.parseLong(pathSegments.get(pathIndex));
}
private int getLimit(Uri uri) {
int limit = Query.NO_LIMIT;
String paramString = uri.getQueryParameter(UniversityContract.QUERY_PARAM_LIMIT);
if (!TextUtils.isEmpty(paramString)) {
try {
limit = Integer.parseInt(paramString);
} catch (NumberFormatException e) {
// ignore and return default
}
}
return limit;
}
private boolean isCountProjection(String[] projection) {
return projection != null && projection.length == 1 && BaseColumns._COUNT.equals(projection[0]);
}
private Query buildFacultyQuery(String[] projection, String selection, String[] selectionArgs, String sortOrder) {
ProjectionMap map = isCountProjection(projection) ? COUNT_PROJECTION_MAP : FACULTY_PROJECTION_MAP;
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder()
.setStrict(true)
.setProjectionMap(map)
.setDataSource(FacultyMember.TABLE)
.setDefaultOrder(FacultyMember.NAME.asc());
return builder.build(projection, selection, selectionArgs, sortOrder);
}
private Query buildStudentsQuery(String[] projection, String selection, String[] selectionArgs, String sortOrder) {
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(ContractStudent.class)
.setStrict(true)
.setDefaultOrder(ContractStudent.NAME.asc());
if (isCountProjection(projection)) {
builder.setProjectionMap(COUNT_PROJECTION_MAP);
}
return builder.build(projection, selection, selectionArgs, sortOrder);
}
private Query buildCoursesQuery(String[] projection, String selection, String[] selectionArgs, String sortOrder) {
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(Course.class)
.setStrict(true);
if (isCountProjection(projection)) {
builder.setProjectionMap(COUNT_PROJECTION_MAP);
}
return builder.build(projection, selection, selectionArgs, sortOrder);
}
private Query buildStudentsByCourseQuery(String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(StudentsByCourse.class)
.setStrict(true);
if (isCountProjection(projection)) {
builder.setProjectionMap(COUNT_PROJECTION_MAP);
}
return builder.build(projection, selection, selectionArgs, sortOrder);
}
private Query buildCoursesByStudentQuery(String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
ContentProviderQueryBuilder builder = new ContentProviderQueryBuilder(CoursesByStudent.class)
.setStrict(true);
if (isCountProjection(projection)) {
builder.setProjectionMap(COUNT_PROJECTION_MAP);
}
return builder.build(projection, selection, selectionArgs, sortOrder);
}
@Override
public Uri insert(Uri uri, ContentValues values) {
TableModel model;
switch (URI_MATCHER.match(uri)) {
case FACULTY:
model = facultyMemberFromValues(values);
break;
case STUDENTS:
ContractStudent contractStudent = new ContractStudent(values);
model = contractStudent.mapToModel(new Student());
break;
case COURSES:
model = courseFromValues(values);
break;
default:
throw new UnsupportedOperationException("Unsupported uri: " + uri);
}
if (databaseDao.createNew(model)) {
Uri newUri = ContentUris.withAppendedId(uri, model.getId());
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
return null;
}
private FacultyMember facultyMemberFromValues(ContentValues values) {
FacultyMember faculty = new FacultyMember();
faculty.setName(values.getAsString(Faculty.NAME));
faculty.setDepartment(values.getAsString(Faculty.DEPARTMENT));
return faculty;
}
private Course courseFromValues(ContentValues values) {
Course course = new Course();
course.setCode(values.getAsString(Courses.CODE));
course.setCredits(values.getAsInteger(Courses.CREDITS));
course.setInstructorId(values.getAsLong(Courses.INSTRUCTOR_ID));
course.setStartDate(values.getAsLong(Courses.START_DATE));
course.setEndDate(values.getAsLong(Courses.END_DATE));
return course;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
values.remove(BaseColumns._ID);
int numUpdated;
switch (URI_MATCHER.match(uri)) {
case FACULTY: {
FacultyMember template = facultyMemberFromValues(values);
numUpdated = databaseDao.update(Criterion.fromRawSelection(selection, selectionArgs), template);
break;
}
case FACULTY_ID: {
FacultyMember faculty = facultyMemberFromValues(values);
faculty.setId(ContentUris.parseId(uri));
numUpdated = databaseDao.saveExisting(faculty) ? 1 : 0;
break;
}
case STUDENTS: {
ContractStudent contractStudent = new ContractStudent(values);
Student template = contractStudent.mapToModel(new Student());
Query query = Query.select(ContractStudent.ID)
.from(ContractStudent.VIEW)
.where(Criterion.fromRawSelection(selection, selectionArgs));
numUpdated = databaseDao.update(Student.ID.in(query), template);
break;
}
case STUDENTS_ID: {
ContractStudent contractStudent = new ContractStudent(values);
Student student = contractStudent.mapToModel(new Student());
student.setId(ContentUris.parseId(uri));
numUpdated = databaseDao.saveExisting(student) ? 1 : 0;
break;
}
case COURSES: {
Course template = courseFromValues(values);
numUpdated = databaseDao.update(Criterion.fromRawSelection(selection, selectionArgs), template);
break;
}
case COURSES_ID: {
Course course = courseFromValues(values);
course.setId(ContentUris.parseId(uri));
numUpdated = databaseDao.saveExisting(course) ? 1 : 0;
break;
}
default:
throw new UnsupportedOperationException("Unsupported uri: " + uri);
}
if (numUpdated > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return numUpdated;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int numDeleted;
switch (URI_MATCHER.match(uri)) {
case FACULTY: {
numDeleted = databaseDao.deleteWhere(FacultyMember.class,
Criterion.fromRawSelection(selection, selectionArgs));
break;
}
case FACULTY_ID: {
long id = ContentUris.parseId(uri);
numDeleted = databaseDao.delete(FacultyMember.class, id) ? 1 : 0;
break;
}
case STUDENTS: {
Query query = Query.select(ContractStudent.ID)
.from(ContractStudent.VIEW)
.where(Criterion.fromRawSelection(selection, selectionArgs));
numDeleted = databaseDao.deleteWhere(Student.class, Student.ID.in(query));
break;
}
case STUDENTS_ID: {
long id = ContentUris.parseId(uri);
numDeleted = databaseDao.delete(Student.class, id) ? 1 : 0;
break;
}
case COURSES: {
numDeleted = databaseDao.deleteWhere(Course.class,
Criterion.fromRawSelection(selection, selectionArgs));
break;
}
case COURSES_ID: {
long id = ContentUris.parseId(uri);
numDeleted = databaseDao.delete(Course.class, id) ? 1 : 0;
break;
}
default:
throw new UnsupportedOperationException("Unsupported uri: " + uri);
}
if (numDeleted > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return numDeleted;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment