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