18188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski/*
28188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Copyright (C) 2013 The Android Open Source Project
38188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski *
48188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Licensed under the Apache License, Version 2.0 (the "License");
58188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * you may not use this file except in compliance with the License.
68188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * You may obtain a copy of the License at
78188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski *
88188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski *      http://www.apache.org/licenses/LICENSE-2.0
98188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski *
108188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Unless required by applicable law or agreed to in writing, software
118188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * distributed under the License is distributed on an "AS IS" BASIS,
128188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * See the License for the specific language governing permissions and
148188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * limitations under the License.
158188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */
168188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
178188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskipackage com.android.deskclock.provider;
188188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
198188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.ContentResolver;
208188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.ContentUris;
218188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.ContentValues;
228188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.database.Cursor;
238188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.net.Uri;
248188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
258188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport java.util.Calendar;
268188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport java.util.LinkedList;
278188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport java.util.List;
288188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
298188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskipublic final class City implements ClockContract.CitiesColumns {
308188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    private static final String[] QUERY_COLUMNS = {
318188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            CITY_ID,
328188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            CITY_NAME,
338188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            TIMEZONE_NAME,
348188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            TIMEZONE_OFFSET
358188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    };
368188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
378188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    /**
388188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * These save calls to cursor.getColumnIndexOrThrow()
398188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS
408188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     */
418188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    private static final int CITY_ID_INDEX = 0;
428188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    private static final int CITY_NAME_INDEX = 1;
438188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    private static final int TIMEZONE_NAME_INDEX = 2;
448188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    private static final int TIMEZONE_OFFSET_INDEX = 3;
458188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
468188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    private static final int COLUMN_COUNT = TIMEZONE_OFFSET_INDEX + 1;
478188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
488188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public static ContentValues createContentValues(City city) {
498188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        ContentValues values = new ContentValues(COLUMN_COUNT);
508188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        values.put(CITY_ID, city.mCityId);
518188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        values.put(CITY_NAME, city.mCityName);
528188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        values.put(TIMEZONE_NAME, city.mTimezoneName);
538188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        values.put(TIMEZONE_OFFSET, city.mTimezoneOffset);
548188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return values;
558188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
568188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
57ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    public static String getCityId(Uri contentUri) {
58ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        return contentUri.getLastPathSegment();
598188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
608188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
618188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    /**
628188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * Return content uri for specific city id.
638188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *
648188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @param cityId to append to content uri
658188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *
668188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @return a new city content uri with the given ID appended to the end of the path
678188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     */
688188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public static Uri getContentUriForId(String cityId) {
698188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return CONTENT_URI.buildUpon().appendEncodedPath(cityId).build();
708188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
718188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
728188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
738188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    /**
748188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * Get city from cityId.
758188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *
768188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @param contentResolver to perform the query on.
778188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @param cityId for the desired city.
788188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @return city if found, null otherwise
798188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     */
808188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public static City getCity(ContentResolver contentResolver, String cityId) {
818188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        Cursor cursor = contentResolver.query(getContentUriForId(cityId),
828188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                QUERY_COLUMNS, null, null, null);
838188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        City result = null;
848188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        if (cursor == null) {
858188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            return result;
868188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        }
878188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
888188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        try {
898188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            if (cursor.moveToFirst()) {
908188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                result = new City(cursor);
918188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            }
928188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        } finally {
938188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            cursor.close();
948188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        }
958188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
968188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return result;
978188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
988188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
998188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    /**
1008188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * Get a list of cities given selection.
1018188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *
1028188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @param contentResolver to perform the query on.
1038188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @param selection A filter declaring which rows to return, formatted as an
1048188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *         SQL WHERE clause (excluding the WHERE itself). Passing null will
1058188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *         return all rows for the given URI.
1068188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @param selectionArgs You may include ?s in selection, which will be
1078188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *         replaced by the values from selectionArgs, in the order that they
1088188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     *         appear in the selection. The values will be bound as Strings.
1098188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     * @return list of alarms matching where clause or empty list if none found.
1108188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski     */
1118188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public static List<City> getCities(ContentResolver contentResolver,
1128188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            String selection, String... selectionArgs) {
1138188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        Cursor cursor  = contentResolver.query(CONTENT_URI, QUERY_COLUMNS,
1148188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                selection, selectionArgs, null);
1158188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        List<City> result = new LinkedList<City>();
1168188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        if (cursor == null) {
1178188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            return result;
1188188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        }
1198188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1208188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        try {
1218188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            if (cursor.moveToFirst()) {
1228188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                do {
1238188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                    result.add(new City(cursor));
1248188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                } while (cursor.moveToNext());
1258188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            }
1268188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        } finally {
1278188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski            cursor.close();
1288188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        }
1298188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1308188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return result;
1318188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
1328188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
133ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    public static City addCity(ContentResolver contentResolver, City city) {
134ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        ContentValues values = createContentValues(city);
135ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        Uri uri = contentResolver.insert(CONTENT_URI, values);
136ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        city.mCityId = getCityId(uri);
137ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        return city;
138ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    }
139ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski
140ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    public static boolean updateCity(ContentResolver contentResolver, City city) {
141ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        ContentValues values = createContentValues(city);
142ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        Uri updateUri = getContentUriForId(city.mCityId);
143ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        long rowsUpdated = contentResolver.update(updateUri, values, null, null);
144ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        return rowsUpdated == 1;
145ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    }
146ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski
147ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    public static boolean deleteCity(ContentResolver contentResolver, String cityId) {
148ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        Uri uri = getContentUriForId(cityId);
149ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        int deletedRows = contentResolver.delete(uri, "", null);
150ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski        return deletedRows == 1;
151ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski    }
152ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski
1538188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    // Public fields
1548188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public String mCityId;
1558188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public String mCityName;
1568188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public String mTimezoneName;
1578188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public int mTimezoneOffset;
1588188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1598188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public City(String cityId, String cityName, String timezoneName, int timezoneOffset) {
1608188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mCityId = cityId;
1618188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mCityName = cityName;
1628188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mTimezoneName = timezoneName;
1638188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mTimezoneOffset = timezoneOffset;
1648188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
1658188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1668188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public City(Cursor c) {
1678188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mCityId = c.getString(CITY_ID_INDEX);
1688188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mCityName = c.getString(CITY_NAME_INDEX);
1698188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mTimezoneName = c.getString(TIMEZONE_NAME_INDEX);
1708188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        mTimezoneOffset = c.getInt(TIMEZONE_OFFSET_INDEX);
1718188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
1728188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1738188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    @Override
1748188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public boolean equals(Object o) {
1758188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        if (!(o instanceof City)) return false;
1768188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        final City other = (City) o;
1778188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return mCityId.equals(other.mCityId);
1788188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
1798188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1808188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    @Override
1818188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public int hashCode() {
1828188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return mCityId.hashCode();
1838188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
1848188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski
1858188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    @Override
1868188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    public String toString() {
1878188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski        return "Instance{" +
1888188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                "mCityId=" + mCityId +
1898188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                ", mCityName=" + mCityName +
1908188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                ", mTimezoneName=" + mTimezoneName +
1918188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                ", mTimezoneOffset=" + mTimezoneOffset +
1928188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski                '}';
1938188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski    }
1948188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski}
195