12eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski/* 22eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * Copyright (C) 2013 The Android Open Source Project 32eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 42eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * Licensed under the Apache License, Version 2.0 (the "License"); 52eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * you may not use this file except in compliance with the License. 62eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * You may obtain a copy of the License at 72eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 82eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * http://www.apache.org/licenses/LICENSE-2.0 92eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 102eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * Unless required by applicable law or agreed to in writing, software 112eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * distributed under the License is distributed on an "AS IS" BASIS, 122eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * See the License for the specific language governing permissions and 142eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * limitations under the License. 152eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski */ 162eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 172eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskipackage com.android.deskclock.provider; 182eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 192eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport android.content.ContentResolver; 202eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport android.content.ContentUris; 212eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport android.content.ContentValues; 222eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport android.database.Cursor; 232eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport android.net.Uri; 242eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 252eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport java.util.Calendar; 262eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport java.util.LinkedList; 272eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskiimport java.util.List; 282eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 292eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowskipublic final class City implements ClockContract.CitiesColumns { 302eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski private static final String[] QUERY_COLUMNS = { 312eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski CITY_ID, 322eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski CITY_NAME, 332eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski TIMEZONE_NAME, 342eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski TIMEZONE_OFFSET 352eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski }; 362eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 372eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski /** 382eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * These save calls to cursor.getColumnIndexOrThrow() 392eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS 402eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski */ 412eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski private static final int CITY_ID_INDEX = 0; 422eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski private static final int CITY_NAME_INDEX = 1; 432eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski private static final int TIMEZONE_NAME_INDEX = 2; 442eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski private static final int TIMEZONE_OFFSET_INDEX = 3; 452eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 462eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski private static final int COLUMN_COUNT = TIMEZONE_OFFSET_INDEX + 1; 472eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 482eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public static ContentValues createContentValues(City city) { 492eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski ContentValues values = new ContentValues(COLUMN_COUNT); 502eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski values.put(CITY_ID, city.mCityId); 512eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski values.put(CITY_NAME, city.mCityName); 522eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski values.put(TIMEZONE_NAME, city.mTimezoneName); 532eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski values.put(TIMEZONE_OFFSET, city.mTimezoneOffset); 542eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return values; 552eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 562eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 571c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski public static String getCityId(Uri contentUri) { 581c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski return contentUri.getLastPathSegment(); 592eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 602eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 612eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski /** 622eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * Return content uri for specific city id. 632eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 642eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @param cityId to append to content uri 652eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 662eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @return a new city content uri with the given ID appended to the end of the path 672eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski */ 682eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public static Uri getContentUriForId(String cityId) { 692eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return CONTENT_URI.buildUpon().appendEncodedPath(cityId).build(); 702eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 712eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 722eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 732eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski /** 742eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * Get city from cityId. 752eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 762eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @param contentResolver to perform the query on. 772eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @param cityId for the desired city. 782eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @return city if found, null otherwise 792eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski */ 802eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public static City getCity(ContentResolver contentResolver, String cityId) { 812eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski Cursor cursor = contentResolver.query(getContentUriForId(cityId), 822eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski QUERY_COLUMNS, null, null, null); 832eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski City result = null; 842eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski if (cursor == null) { 852eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return result; 862eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 872eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 882eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski try { 892eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski if (cursor.moveToFirst()) { 902eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski result = new City(cursor); 912eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 922eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } finally { 932eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski cursor.close(); 942eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 952eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 962eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return result; 972eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 982eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 992eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski /** 1002eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * Get a list of cities given selection. 1012eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * 1022eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @param contentResolver to perform the query on. 1032eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @param selection A filter declaring which rows to return, formatted as an 1042eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * SQL WHERE clause (excluding the WHERE itself). Passing null will 1052eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * return all rows for the given URI. 1062eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @param selectionArgs You may include ?s in selection, which will be 1072eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * replaced by the values from selectionArgs, in the order that they 1082eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * appear in the selection. The values will be bound as Strings. 1092eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski * @return list of alarms matching where clause or empty list if none found. 1102eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski */ 1112eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public static List<City> getCities(ContentResolver contentResolver, 1122eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski String selection, String... selectionArgs) { 1132eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski Cursor cursor = contentResolver.query(CONTENT_URI, QUERY_COLUMNS, 1142eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski selection, selectionArgs, null); 1152eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski List<City> result = new LinkedList<City>(); 1162eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski if (cursor == null) { 1172eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return result; 1182eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1192eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1202eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski try { 1212eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski if (cursor.moveToFirst()) { 1222eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski do { 1232eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski result.add(new City(cursor)); 1242eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } while (cursor.moveToNext()); 1252eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1262eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } finally { 1272eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski cursor.close(); 1282eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1292eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1302eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return result; 1312eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1322eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1331c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski public static City addCity(ContentResolver contentResolver, City city) { 1341c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski ContentValues values = createContentValues(city); 1351c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski Uri uri = contentResolver.insert(CONTENT_URI, values); 1361c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski city.mCityId = getCityId(uri); 1371c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski return city; 1381c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski } 1391c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski 1401c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski public static boolean updateCity(ContentResolver contentResolver, City city) { 1411c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski ContentValues values = createContentValues(city); 1421c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski Uri updateUri = getContentUriForId(city.mCityId); 1431c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski long rowsUpdated = contentResolver.update(updateUri, values, null, null); 1441c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski return rowsUpdated == 1; 1451c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski } 1461c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski 1471c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski public static boolean deleteCity(ContentResolver contentResolver, String cityId) { 1481c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski Uri uri = getContentUriForId(cityId); 1491c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski int deletedRows = contentResolver.delete(uri, "", null); 1501c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski return deletedRows == 1; 1511c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski } 1521c7788b33dd4516dae81e6bcab043addc45fc1a1Paul Sliwowski 1532eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski // Public fields 1542eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public String mCityId; 1552eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public String mCityName; 1562eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public String mTimezoneName; 1572eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public int mTimezoneOffset; 1582eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1592eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public City(String cityId, String cityName, String timezoneName, int timezoneOffset) { 1602eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mCityId = cityId; 1612eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mCityName = cityName; 1622eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mTimezoneName = timezoneName; 1632eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mTimezoneOffset = timezoneOffset; 1642eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1652eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1662eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public City(Cursor c) { 1672eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mCityId = c.getString(CITY_ID_INDEX); 1682eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mCityName = c.getString(CITY_NAME_INDEX); 1692eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mTimezoneName = c.getString(TIMEZONE_NAME_INDEX); 1702eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski mTimezoneOffset = c.getInt(TIMEZONE_OFFSET_INDEX); 1712eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1722eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1732eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski @Override 1742eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public boolean equals(Object o) { 1752eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski if (!(o instanceof City)) return false; 1762eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski final City other = (City) o; 1772eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return mCityId.equals(other.mCityId); 1782eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1792eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1802eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski @Override 1812eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public int hashCode() { 1822eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return mCityId.hashCode(); 1832eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1842eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski 1852eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski @Override 1862eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski public String toString() { 1872eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski return "Instance{" + 1882eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski "mCityId=" + mCityId + 1892eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski ", mCityName=" + mCityName + 1902eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski ", mTimezoneName=" + mTimezoneName + 1912eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski ", mTimezoneOffset=" + mTimezoneOffset + 1922eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski '}'; 1932eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski } 1942eb3e5467cb76617fd6da3ea4a3f222d537a6bd9Paul Sliwowski} 195