1 package uk
.me
.njae
.sunshine
.data
;
3 import android
.content
.ContentProvider
;
4 import android
.content
.ContentUris
;
5 import android
.content
.ContentValues
;
6 import android
.content
.UriMatcher
;
7 import android
.database
.Cursor
;
8 import android
.database
.sqlite
.SQLiteDatabase
;
9 import android
.database
.sqlite
.SQLiteQueryBuilder
;
10 import android
.net
.Uri
;
13 * Created by neil on 09/11/14.
15 public class WeatherProvider
extends ContentProvider
{
17 // The URI Matcher used by this content provider.
18 private static final UriMatcher sUriMatcher
= buildUriMatcher();
20 private static final int WEATHER
= 100;
21 private static final int WEATHER_WITH_LOCATION
= 101;
22 private static final int WEATHER_WITH_LOCATION_AND_DATE
= 102;
23 private static final int LOCATION
= 300;
24 private static final int LOCATION_ID
= 301;
26 private WeatherDbHelper mOpenHelper
;
28 private static UriMatcher
buildUriMatcher() {
29 // I know what you're thinking. Why create a UriMatcher when you can use regular
30 // expressions instead? Because you're not crazy, that's why.
32 // All paths added to the UriMatcher have a corresponding code to return when a match is
33 // found. The code passed into the constructor represents the code to return for the root
34 // URI. It's common to use NO_MATCH as the code for this case.
35 final UriMatcher matcher
= new UriMatcher(UriMatcher
.NO_MATCH
);
36 final String authority
= WeatherContract
.CONTENT_AUTHORITY
;
38 // For each type of URI you want to add, create a corresponding code.
39 matcher
.addURI(authority
, WeatherContract
.PATH_WEATHER
, WEATHER
);
40 matcher
.addURI(authority
, WeatherContract
.PATH_WEATHER
+ "/*", WEATHER_WITH_LOCATION
);
41 matcher
.addURI(authority
, WeatherContract
.PATH_WEATHER
+ "/*/*", WEATHER_WITH_LOCATION_AND_DATE
);
43 matcher
.addURI(authority
, WeatherContract
.PATH_LOCATION
, LOCATION
);
44 matcher
.addURI(authority
, WeatherContract
.PATH_LOCATION
+ "/#", LOCATION_ID
);
50 private static final SQLiteQueryBuilder sWeatherByLocationSettingQueryBuilder
;
53 sWeatherByLocationSettingQueryBuilder
= new SQLiteQueryBuilder();
54 sWeatherByLocationSettingQueryBuilder
.setTables(
55 WeatherContract
.WeatherEntry
.TABLE_NAME
+ " INNER JOIN " +
56 WeatherContract
.LocationEntry
.TABLE_NAME
+
57 " ON " + WeatherContract
.WeatherEntry
.TABLE_NAME
+
58 "." + WeatherContract
.WeatherEntry
.COLUMN_LOC_KEY
+
59 " = " + WeatherContract
.LocationEntry
.TABLE_NAME
+
60 "." + WeatherContract
.LocationEntry
._ID
);
63 private static final String sLocationSettingSelection
=
64 WeatherContract
.LocationEntry
.TABLE_NAME
+
65 "." + WeatherContract
.LocationEntry
.COLUMN_LOCATION_SETTING
+ " = ? ";
66 private static final String sLocationSettingWithStartDateSelection
=
67 WeatherContract
.LocationEntry
.TABLE_NAME
+
68 "." + WeatherContract
.LocationEntry
.COLUMN_LOCATION_SETTING
+ " = ? AND " +
69 WeatherContract
.WeatherEntry
.COLUMN_DATETEXT
+ " >= ? ";
70 private static final String sLocationSettingAndDaySelection
=
71 WeatherContract
.LocationEntry
.TABLE_NAME
+
72 "." + WeatherContract
.LocationEntry
.COLUMN_LOCATION_SETTING
+ " = ? AND " +
73 WeatherContract
.WeatherEntry
.COLUMN_DATETEXT
+ " = ? ";
75 private Cursor
getWeatherByLocationSetting(Uri uri
, String
[] projection
, String sortOrder
) {
76 String locationSetting
= WeatherContract
.WeatherEntry
.getLocationSettingFromUri(uri
);
77 String startDate
= WeatherContract
.WeatherEntry
.getStartDateFromUri(uri
);
79 String
[] selectionArgs
;
82 if (startDate
== null) {
83 selection
= sLocationSettingSelection
;
84 selectionArgs
= new String
[]{locationSetting
};
86 selectionArgs
= new String
[]{locationSetting
, startDate
};
87 selection
= sLocationSettingWithStartDateSelection
;
90 return sWeatherByLocationSettingQueryBuilder
.query(mOpenHelper
.getReadableDatabase(),
100 private Cursor
getWeatherByLocationSettingAndDate(
101 Uri uri
, String
[] projection
, String sortOrder
) {
102 String locationSetting
= WeatherContract
.WeatherEntry
.getLocationSettingFromUri(uri
);
103 String date
= WeatherContract
.WeatherEntry
.getDateFromUri(uri
);
105 return sWeatherByLocationSettingQueryBuilder
.query(mOpenHelper
.getReadableDatabase(),
107 sLocationSettingAndDaySelection
,
108 new String
[]{locationSetting
, date
},
116 public boolean onCreate() {
117 mOpenHelper
= new WeatherDbHelper(getContext());
122 public Cursor
query(Uri uri
, String
[] projection
, String selection
, String
[] selectionArgs
,
124 // Here's the switch statement that, given a URI, will determine what kind of request it is,
125 // and query the database accordingly.
127 switch (sUriMatcher
.match(uri
)) {
129 case WEATHER_WITH_LOCATION_AND_DATE
:
131 retCursor
= getWeatherByLocationSettingAndDate(uri
, projection
, sortOrder
);
135 case WEATHER_WITH_LOCATION
: {
136 retCursor
= getWeatherByLocationSetting(uri
, projection
, sortOrder
);
141 retCursor
= mOpenHelper
.getReadableDatabase().query(
142 WeatherContract
.WeatherEntry
.TABLE_NAME
,
154 retCursor
= mOpenHelper
.getReadableDatabase().query(
155 WeatherContract
.LocationEntry
.TABLE_NAME
,
157 WeatherContract
.LocationEntry
._ID
+ " = '" + ContentUris
.parseId(uri
) + "'",
167 retCursor
= mOpenHelper
.getReadableDatabase().query(
168 WeatherContract
.LocationEntry
.TABLE_NAME
,
179 throw new UnsupportedOperationException("Unknown uri: " + uri
);
181 retCursor
.setNotificationUri(getContext().getContentResolver(), uri
);
186 public String
getType(Uri uri
) {
187 // Use the Uri Matcher to determine what kind of URI this is.
188 final int match
= sUriMatcher
.match(uri
);
191 case WEATHER_WITH_LOCATION_AND_DATE
:
192 return WeatherContract
.WeatherEntry
.CONTENT_ITEM_TYPE
;
193 case WEATHER_WITH_LOCATION
:
194 return WeatherContract
.WeatherEntry
.CONTENT_TYPE
;
196 return WeatherContract
.WeatherEntry
.CONTENT_TYPE
;
198 return WeatherContract
.LocationEntry
.CONTENT_TYPE
;
200 return WeatherContract
.LocationEntry
.CONTENT_ITEM_TYPE
;
202 throw new UnsupportedOperationException("Unknown uri: " + uri
);
207 public Uri
insert(Uri uri
, ContentValues contentValues
) {
208 final SQLiteDatabase db
= mOpenHelper
.getWritableDatabase();
209 final int match
= sUriMatcher
.match(uri
);
214 long _id
= db
.insert(WeatherContract
.WeatherEntry
.TABLE_NAME
, null, contentValues
);
216 returnUri
= WeatherContract
.WeatherEntry
.buildWeatherUri(_id
);
218 throw new android
.database
.SQLException("Failed to insert row into " + uri
);
222 long _id
= db
.insert(WeatherContract
.LocationEntry
.TABLE_NAME
, null, contentValues
);
224 returnUri
= WeatherContract
.LocationEntry
.buildLocationUri(_id
);
226 throw new android
.database
.SQLException("Failed to insert row into " + uri
);
230 throw new UnsupportedOperationException("Unknown uri: " + uri
);
232 getContext().getContentResolver().notifyChange(returnUri
, null);
237 public int delete(Uri uri
, String selection
, String
[] selectionArgs
) {
238 final SQLiteDatabase db
= mOpenHelper
.getWritableDatabase();
239 final int match
= sUriMatcher
.match(uri
);
244 rowsDeleted
= db
.delete(WeatherContract
.WeatherEntry
.TABLE_NAME
, selection
, selectionArgs
);
248 rowsDeleted
= db
.delete(WeatherContract
.LocationEntry
.TABLE_NAME
, selection
, selectionArgs
);
252 throw new UnsupportedOperationException("Unknown uri: " + uri
);
254 if (selection
== null || rowsDeleted
!= 0) {
255 getContext().getContentResolver().notifyChange(uri
, null);
261 public int update(Uri uri
, ContentValues contentValues
, String selection
, String
[] selectionArgs
) {
262 final SQLiteDatabase db
= mOpenHelper
.getWritableDatabase();
263 final int match
= sUriMatcher
.match(uri
);
268 rowsUpdated
= db
.update(WeatherContract
.WeatherEntry
.TABLE_NAME
, contentValues
, selection
,
272 rowsUpdated
= db
.update(WeatherContract
.LocationEntry
.TABLE_NAME
, contentValues
, selection
,
276 throw new UnsupportedOperationException("Unknown uri: " + uri
);
278 if (rowsUpdated
!= 0) {
279 getContext().getContentResolver().notifyChange(uri
, null);
285 public int bulkInsert(Uri uri
, ContentValues
[] values
) {
286 final SQLiteDatabase db
= mOpenHelper
.getWritableDatabase();
287 final int match
= sUriMatcher
.match(uri
);
290 db
.beginTransaction();
293 for (ContentValues value
: values
) {
294 long _id
= db
.insert(WeatherContract
.WeatherEntry
.TABLE_NAME
, null, value
);
299 db
.setTransactionSuccessful();
303 getContext().getContentResolver().notifyChange(uri
, null);
306 return super.bulkInsert(uri
, values
);