1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.deskclock.provider;
18 
19 import android.content.ContentProvider;
20 import android.content.ContentUris;
21 import android.content.ContentValues;
22 import android.content.UriMatcher;
23 import android.database.Cursor;
24 import android.database.sqlite.SQLiteDatabase;
25 import android.database.sqlite.SQLiteQueryBuilder;
26 import android.net.Uri;
27 import android.text.TextUtils;
28 
29 import com.android.deskclock.LogUtils;
30 
31 public class ClockProvider extends ContentProvider {
32     private ClockDatabaseHelper mOpenHelper;
33 
34     private static final int ALARMS = 1;
35     private static final int ALARMS_ID = 2;
36     private static final int INSTANCES = 3;
37     private static final int INSTANCES_ID = 4;
38     private static final int CITIES = 5;
39     private static final int CITIES_ID = 6;
40 
41     private static final UriMatcher sURLMatcher = new UriMatcher(UriMatcher.NO_MATCH);
42     static {
sURLMatcher.addURI(ClockContract.AUTHORITY, "alarms", ALARMS)43         sURLMatcher.addURI(ClockContract.AUTHORITY, "alarms", ALARMS);
sURLMatcher.addURI(ClockContract.AUTHORITY, "alarms/#", ALARMS_ID)44         sURLMatcher.addURI(ClockContract.AUTHORITY, "alarms/#", ALARMS_ID);
sURLMatcher.addURI(ClockContract.AUTHORITY, "instances", INSTANCES)45         sURLMatcher.addURI(ClockContract.AUTHORITY, "instances", INSTANCES);
sURLMatcher.addURI(ClockContract.AUTHORITY, "instances/#", INSTANCES_ID)46         sURLMatcher.addURI(ClockContract.AUTHORITY, "instances/#", INSTANCES_ID);
sURLMatcher.addURI(ClockContract.AUTHORITY, "cities", CITIES)47         sURLMatcher.addURI(ClockContract.AUTHORITY, "cities", CITIES);
sURLMatcher.addURI(ClockContract.AUTHORITY, "cities/*", CITIES_ID)48         sURLMatcher.addURI(ClockContract.AUTHORITY, "cities/*", CITIES_ID);
49     }
50 
ClockProvider()51     public ClockProvider() {
52     }
53 
54     @Override
onCreate()55     public boolean onCreate() {
56         mOpenHelper = new ClockDatabaseHelper(getContext());
57         return true;
58     }
59 
60     @Override
query(Uri uri, String[] projectionIn, String selection, String[] selectionArgs, String sort)61     public Cursor query(Uri uri, String[] projectionIn, String selection, String[] selectionArgs,
62             String sort) {
63         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
64 
65         // Generate the body of the query
66         int match = sURLMatcher.match(uri);
67         switch (match) {
68             case ALARMS:
69                 qb.setTables(ClockDatabaseHelper.ALARMS_TABLE_NAME);
70                 break;
71             case ALARMS_ID:
72                 qb.setTables(ClockDatabaseHelper.ALARMS_TABLE_NAME);
73                 qb.appendWhere(ClockContract.AlarmsColumns._ID + "=");
74                 qb.appendWhere(uri.getLastPathSegment());
75                 break;
76             case INSTANCES:
77                 qb.setTables(ClockDatabaseHelper.INSTANCES_TABLE_NAME);
78                 break;
79             case INSTANCES_ID:
80                 qb.setTables(ClockDatabaseHelper.INSTANCES_TABLE_NAME);
81                 qb.appendWhere(ClockContract.InstancesColumns._ID + "=");
82                 qb.appendWhere(uri.getLastPathSegment());
83                 break;
84             case CITIES:
85                 qb.setTables(ClockDatabaseHelper.CITIES_TABLE_NAME);
86                 break;
87             case CITIES_ID:
88                 qb.setTables(ClockDatabaseHelper.CITIES_TABLE_NAME);
89                 qb.appendWhere(ClockContract.CitiesColumns.CITY_ID + "=");
90                 qb.appendWhere(uri.getLastPathSegment());
91                 break;
92             default:
93                 throw new IllegalArgumentException("Unknown URL " + uri);
94         }
95 
96         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
97         Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,
98                               null, null, sort);
99 
100         if (ret == null) {
101             LogUtils.e("Alarms.query: failed");
102         } else {
103             ret.setNotificationUri(getContext().getContentResolver(), uri);
104         }
105 
106         return ret;
107     }
108 
109     @Override
getType(Uri uri)110     public String getType(Uri uri) {
111         int match = sURLMatcher.match(uri);
112         switch (match) {
113             case ALARMS:
114                 return "vnd.android.cursor.dir/alarms";
115             case ALARMS_ID:
116                 return "vnd.android.cursor.item/alarms";
117             case INSTANCES:
118                 return "vnd.android.cursor.dir/instances";
119             case INSTANCES_ID:
120                 return "vnd.android.cursor.item/instances";
121             case CITIES:
122                 return "vnd.android.cursor.dir/cities";
123             case CITIES_ID:
124                 return "vnd.android.cursor.item/cities";
125             default:
126                 throw new IllegalArgumentException("Unknown URL");
127         }
128     }
129 
130     @Override
update(Uri uri, ContentValues values, String where, String[] whereArgs)131     public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
132         int count;
133         String alarmId;
134         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
135         switch (sURLMatcher.match(uri)) {
136             case ALARMS_ID:
137                 alarmId = uri.getLastPathSegment();
138                 count = db.update(ClockDatabaseHelper.ALARMS_TABLE_NAME, values,
139                         ClockContract.AlarmsColumns._ID + "=" + alarmId,
140                         null);
141                 break;
142             case INSTANCES_ID:
143                 alarmId = uri.getLastPathSegment();
144                 count = db.update(ClockDatabaseHelper.INSTANCES_TABLE_NAME, values,
145                         ClockContract.InstancesColumns._ID + "=" + alarmId,
146                         null);
147                 break;
148             case CITIES_ID:
149                 alarmId = uri.getLastPathSegment();
150                 count = db.update(ClockDatabaseHelper.CITIES_TABLE_NAME, values,
151                         ClockContract.CitiesColumns.CITY_ID + "=" + alarmId,
152                         null);
153                 break;
154             default: {
155                 throw new UnsupportedOperationException(
156                         "Cannot update URL: " + uri);
157             }
158         }
159         LogUtils.v("*** notifyChange() id: " + alarmId + " url " + uri);
160         getContext().getContentResolver().notifyChange(uri, null);
161         return count;
162     }
163 
164     @Override
insert(Uri uri, ContentValues initialValues)165     public Uri insert(Uri uri, ContentValues initialValues) {
166         long rowId;
167         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
168         switch (sURLMatcher.match(uri)) {
169             case ALARMS:
170                 rowId = mOpenHelper.fixAlarmInsert(initialValues);
171                 break;
172             case INSTANCES:
173                 rowId = db.insert(ClockDatabaseHelper.INSTANCES_TABLE_NAME, null, initialValues);
174                 break;
175             case CITIES:
176                 rowId = db.insert(ClockDatabaseHelper.CITIES_TABLE_NAME, null, initialValues);
177                 break;
178             default:
179                 throw new IllegalArgumentException("Cannot insert from URL: " + uri);
180         }
181 
182         Uri uriResult = ContentUris.withAppendedId(ClockContract.AlarmsColumns.CONTENT_URI, rowId);
183         getContext().getContentResolver().notifyChange(uriResult, null);
184         return uriResult;
185     }
186 
187     @Override
delete(Uri uri, String where, String[] whereArgs)188     public int delete(Uri uri, String where, String[] whereArgs) {
189         int count;
190         String primaryKey;
191         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
192         switch (sURLMatcher.match(uri)) {
193             case ALARMS:
194                 count = db.delete(ClockDatabaseHelper.ALARMS_TABLE_NAME, where, whereArgs);
195                 break;
196             case ALARMS_ID:
197                 primaryKey = uri.getLastPathSegment();
198                 if (TextUtils.isEmpty(where)) {
199                     where = ClockContract.AlarmsColumns._ID + "=" + primaryKey;
200                 } else {
201                     where = ClockContract.AlarmsColumns._ID + "=" + primaryKey +
202                             " AND (" + where + ")";
203                 }
204                 count = db.delete(ClockDatabaseHelper.ALARMS_TABLE_NAME, where, whereArgs);
205                 break;
206             case INSTANCES:
207                 count = db.delete(ClockDatabaseHelper.INSTANCES_TABLE_NAME, where, whereArgs);
208                 break;
209             case INSTANCES_ID:
210                 primaryKey = uri.getLastPathSegment();
211                 if (TextUtils.isEmpty(where)) {
212                     where = ClockContract.InstancesColumns._ID + "=" + primaryKey;
213                 } else {
214                     where = ClockContract.InstancesColumns._ID + "=" + primaryKey +
215                             " AND (" + where + ")";
216                 }
217                 count = db.delete(ClockDatabaseHelper.INSTANCES_TABLE_NAME, where, whereArgs);
218                 break;
219             case CITIES:
220                 count = db.delete(ClockDatabaseHelper.CITIES_TABLE_NAME, where, whereArgs);
221                 break;
222             case CITIES_ID:
223                 primaryKey = uri.getLastPathSegment();
224                 if (TextUtils.isEmpty(where)) {
225                     where = ClockContract.CitiesColumns.CITY_ID + "=" + primaryKey;
226                 } else {
227                     where = ClockContract.CitiesColumns.CITY_ID +"=" + primaryKey +
228                             " AND (" + where + ")";
229                 }
230                 count = db.delete(ClockDatabaseHelper.CITIES_TABLE_NAME, where, whereArgs);
231                 break;
232             default:
233                 throw new IllegalArgumentException("Cannot delete from URL: " + uri);
234         }
235 
236         getContext().getContentResolver().notifyChange(uri, null);
237         return count;
238     }
239 }
240