Query with Contract and Projection

Contract

Contract is useful for defining interface between database (data model) and UI (view)!


Functionality Overview diagram shows Contract WeatherContract along with surrounding component modules.


WeatherContract.java "Contract class" defines names of tables and their fields, without any type information:

public class WeatherContract {
    public static final String CONTENT_AUTHORITY = "com.example.shreekant.sunshine.app";
    public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
    // Possible paths (appended to base content URI for possible URI's)


    /* Inner class that defines the table contents of the weather table */
    public static final class WeatherEntry implements BaseColumns {


        public static final Uri CONTENT_URI =
                BASE_CONTENT_URI.buildUpon().appendPath(PATH_WEATHER).build(); /// content://com.example.shreekant.sunshine.app/weather/


        public static final String CONTENT_TYPE =
                ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER;
        public static final String CONTENT_ITEM_TYPE =
                ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_WEATHER;


        public static final String TABLE_NAME = "weather";
        public static final String COLUMN_WEATHER_ID = "weather_id";
        public static final String COLUMN_SHORT_DESC = "short_desc";
        public static final String COLUMN_MIN_TEMP = "min";
        public static final String COLUMN_MAX_TEMP = "max";


        /* content://com.example.shreekant.sunshine.app/weather/<Pune> */
        public static Uri buildWeatherLocation(String locationSetting) {
            return CONTENT_URI.buildUpon().appendPath(locationSetting).build();
        }


        /* content://com.example.shreekant.sunshine.app/weather/<Pune>?date=<normalizedDate> */
        public static Uri buildWeatherLocationWithStartDate(
                String locationSetting, long startDate) {
            long normalizedDate = normalizeDate(startDate);
            return CONTENT_URI.buildUpon().appendPath(locationSetting)
                    .appendQueryParameter(COLUMN_DATE, Long.toString(normalizedDate)).build();
        }



        /* content://com.example.shreekant.sunshine.app/weather/<Pune>/<normalizedDate> */
        public static Uri buildWeatherLocationWithDate(String locationSetting, long date) {
            return CONTENT_URI.buildUpon().appendPath(locationSetting)
                    .appendPath(Long.toString(normalizeDate(date))).build();
        }

        :

        public static long getDateFromUri(Uri uri) {
            return Long.parseLong(uri.getPathSegments().get(2));
        }


        public static long getStartDateFromUri(Uri uri) {
            String dateString = uri.getQueryParameter(COLUMN_DATE);
            if (null != dateString && dateString.length() > 0)
                return Long.parseLong(dateString);
            else
                return 0;
        }

        :
    }
} // WeatherContract





Projection

Projection is the set of columns that the query should return:

    private static final String[] NOTIFY_WEATHER_PROJECTION = new String[] {
            WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
            WeatherContract.WeatherEntry.COLUMN_MAX_TEMP,
            WeatherContract.WeatherEntry.COLUMN_MIN_TEMP,
            WeatherContract.WeatherEntry.COLUMN_SHORT_DESC
    };



Define indices to exactly match the projection:

    private static final int INDEX_WEATHER_ID = 0;
    private static final int INDEX_MAX_TEMP = 1;
    private static final int INDEX_MIN_TEMP = 2;
    private static final int INDEX_SHORT_DESC = 3;



Fire a query with the projection:

    Uri weatherUri = WeatherContract.WeatherEntry.buildWeatherLocationWithDate(locationQuery,
                       System.currentTimeMillis());
    Cursor cursor = context.getContentResolver().query(
                        weatherUri,                     // query URI path content://com.example.shreekant.sunshine.app/weather/<Pune>/<normalizedDate>
                        NOTIFY_WEATHER_PROJECTION,      // "projection" columns to return for each row
                        null,                           // Selection WHERE Clause: null or WeatherEntry.COLUMN_MAX_TEMP + " = ?"
                        null,                           // SelectionArgs: null or substitute values for ?s in Selection Clause
                        null);                          // The sort order for the returned rows: null or WeatherEntry.COLUMN_SHORT_DESC + " ASC"



Extract the column values from cursor:

    if (cursor.moveToFirst()) {
        int weatherId = cursor.getInt(INDEX_WEATHER_ID);
        double high = cursor.getDouble(INDEX_MAX_TEMP);
        double low = cursor.getDouble(INDEX_MIN_TEMP);
        String desc = cursor.getString(INDEX_SHORT_DESC);

    // projection is the set of columns that the query should return
    private static final String[] NOTIFY_LOCATION_PROJECTION = new String[] {
            WeatherContract.WeatherEntry.COLUMN_COORD_LAT,
            WeatherContract.WeatherEntry.COLUMN_COORD_LONG,
    };




No comments:

Post a Comment