1c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount/* 2c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Copyright (C) 2013 The Android Open Source Project 3c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * 4c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 5c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * you may not use this file except in compliance with the License. 6c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * You may obtain a copy of the License at 7c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * 8c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * http://www.apache.org/licenses/LICENSE-2.0 9c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * 10c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Unless required by applicable law or agreed to in writing, software 11c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * distributed under the License is distributed on an "AS IS" BASIS, 12c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * See the License for the specific language governing permissions and 14c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * limitations under the License. 15c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 16c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountpackage com.android.photos.data; 17c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 185139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mountimport android.content.ContentResolver; 19aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mountimport android.content.ContentUris; 20c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.content.ContentValues; 215139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mountimport android.content.Context; 22c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.content.UriMatcher; 23c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.database.Cursor; 24c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.database.DatabaseUtils; 25c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.database.sqlite.SQLiteDatabase; 26c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.database.sqlite.SQLiteOpenHelper; 27135c2e576f3dfea954ba628942c55adcb35a7cf6George Mountimport android.database.sqlite.SQLiteQueryBuilder; 282f5a064980ad79e88616ba124268e4d7298c68a5George Mountimport android.media.ExifInterface; 29c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.net.Uri; 30c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.os.CancellationSignal; 31c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport android.provider.BaseColumns; 32c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 33091314b7ea73e774ce96c981bd7007c94ad80e30George Mountimport com.android.gallery3d.common.ApiHelper; 34091314b7ea73e774ce96c981bd7007c94ad80e30George Mount 35c8419b4e5e3302f2efc7ea629891041a14219aa7George Mountimport java.util.List; 36c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 37c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount/** 38c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * A provider that gives access to photo and video information for media stored 39c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * on the server. Only media that is or will be put on the server will be 40c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * accessed by this provider. Use Photos.CONTENT_URI to query all photos and 41c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * videos. Use Albums.CONTENT_URI to query all albums. Use Metadata.CONTENT_URI 42c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * to query metadata about a photo or video, based on the ID of the media. Use 43c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * ImageCache.THUMBNAIL_CONTENT_URI, ImageCache.PREVIEW_CONTENT_URI, or 44c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * ImageCache.ORIGINAL_CONTENT_URI to query the path of the thumbnail, preview, 45c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * or original-sized image respectfully. <br/> 46c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * To add or update metadata, use the update function rather than insert. All 47c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * values for the metadata must be in the ContentValues, even if they are also 48c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * in the selection. The selection and selectionArgs are not used when updating 49c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * metadata. If the metadata values are null, the row will be deleted. 50c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 515139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mountpublic class PhotoProvider extends SQLiteContentProvider { 52c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @SuppressWarnings("unused") 53c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount private static final String TAG = PhotoProvider.class.getSimpleName(); 54135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount 55135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount protected static final String DB_NAME = "photo.db"; 56135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount public static final String AUTHORITY = PhotoProviderAuthority.AUTHORITY; 57c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount static final Uri BASE_CONTENT_URI = new Uri.Builder().scheme("content").authority(AUTHORITY) 58c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount .build(); 59c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 60135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount // Used to allow mocking out the change notification because 61135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount // MockContextResolver disallows system-wide notification. 62135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount public static interface ChangeNotification { 635139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount void notifyChange(Uri uri, boolean syncToNetwork); 64135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount } 65135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount 66c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 672f5a064980ad79e88616ba124268e4d7298c68a5George Mount * Contains columns that can be accessed via Accounts.CONTENT_URI 68c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 692f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static interface Accounts extends BaseColumns { 70c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 712f5a064980ad79e88616ba124268e4d7298c68a5George Mount * Internal database table used for account information 72c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 732f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String TABLE = "accounts"; 74c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 752f5a064980ad79e88616ba124268e4d7298c68a5George Mount * Content URI for account information 76c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 77c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE); 78c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 792f5a064980ad79e88616ba124268e4d7298c68a5George Mount * User name for this account. 80c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 812f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String ACCOUNT_NAME = "name"; 822f5a064980ad79e88616ba124268e4d7298c68a5George Mount } 832f5a064980ad79e88616ba124268e4d7298c68a5George Mount 842f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** 852f5a064980ad79e88616ba124268e4d7298c68a5George Mount * Contains columns that can be accessed via Photos.CONTENT_URI. 862f5a064980ad79e88616ba124268e4d7298c68a5George Mount */ 872f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static interface Photos extends BaseColumns { 88d4681a3c9d417970a9602112bd83f921ac16af96George Mount /** 89d4681a3c9d417970a9602112bd83f921ac16af96George Mount * The image_type query parameter required for requesting a specific 90d4681a3c9d417970a9602112bd83f921ac16af96George Mount * size of image. 91d4681a3c9d417970a9602112bd83f921ac16af96George Mount */ 92d4681a3c9d417970a9602112bd83f921ac16af96George Mount public static final String MEDIA_SIZE_QUERY_PARAMETER = "media_size"; 93d4681a3c9d417970a9602112bd83f921ac16af96George Mount 942f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Internal database table used for basic photo information. */ 95693a5b7a18066d4757d49a44214356a3dd9f61a0Mangesh Ghiware public static final String TABLE = "photos"; 962f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Content URI for basic photo and video information. */ 972f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE); 982f5a064980ad79e88616ba124268e4d7298c68a5George Mount 992f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Long foreign key to Accounts._ID */ 1002f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String ACCOUNT_ID = "account_id"; 1012f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Column name for the width of the original image. Integer value. */ 102c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String WIDTH = "width"; 1032f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Column name for the height of the original image. Integer value. */ 104c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String HEIGHT = "height"; 105c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 106c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Column name for the date that the original image was taken. Long 107c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * value indicating the milliseconds since epoch in the GMT time zone. 108c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 109c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String DATE_TAKEN = "date_taken"; 110c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 111c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Column name indicating the long value of the album id that this image 112c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * resides in. Will be NULL if it it has not been uploaded to the 113c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * server. 114c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 115c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String ALBUM_ID = "album_id"; 1162f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The column name for the mime-type String. */ 1172f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String MIME_TYPE = "mime_type"; 1182f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The title of the photo. String value. */ 1192f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String TITLE = "title"; 1202f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The date the photo entry was last updated. Long value. */ 1212f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String DATE_MODIFIED = "date_modified"; 122c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 1232f5a064980ad79e88616ba124268e4d7298c68a5George Mount * The rotation of the photo in degrees, if rotation has not already 1242f5a064980ad79e88616ba124268e4d7298c68a5George Mount * been applied. Integer value. 125c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 1262f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String ROTATION = "rotation"; 127c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 128c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 129c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 130c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Contains columns and Uri for accessing album information. 131c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 132c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static interface Albums extends BaseColumns { 1332f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Internal database table used album information. */ 134693a5b7a18066d4757d49a44214356a3dd9f61a0Mangesh Ghiware public static final String TABLE = "albums"; 1352f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Content URI for album information. */ 136c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE); 1372f5a064980ad79e88616ba124268e4d7298c68a5George Mount 1382f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Long foreign key to Accounts._ID */ 1392f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String ACCOUNT_ID = "account_id"; 1402f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Parent directory or null if this is in the root. */ 1412f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String PARENT_ID = "parent_id"; 142b2a646658c87378b681d85a130db705a39d07171Mangesh Ghiware /** The type of album. Non-null, if album is auto-generated. String value. */ 143b2a646658c87378b681d85a130db705a39d07171Mangesh Ghiware public static final String ALBUM_TYPE = "album_type"; 144c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 145c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Column name for the visibility level of the album. Can be any of the 146c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * VISIBILITY_* values. 147c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 148c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String VISIBILITY = "visibility"; 1492f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The user-specified location associated with the album. String value. */ 1502f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String LOCATION_STRING = "location_string"; 1512f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The title of the album. String value. */ 1522f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String TITLE = "title"; 1532f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** A short summary of the contents of the album. String value. */ 1542f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String SUMMARY = "summary"; 1552f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The date the album was created. Long value */ 1562f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String DATE_PUBLISHED = "date_published"; 1572f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The date the album entry was last updated. Long value. */ 1582f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String DATE_MODIFIED = "date_modified"; 159c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 160c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount // Privacy values for Albums.VISIBILITY 161c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final int VISIBILITY_PRIVATE = 1; 162c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final int VISIBILITY_SHARED = 2; 163c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final int VISIBILITY_PUBLIC = 3; 164c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 165c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 166c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 167c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Contains columns and Uri for accessing photo and video metadata 168c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 169c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static interface Metadata extends BaseColumns { 1702f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Internal database table used metadata information. */ 171c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String TABLE = "metadata"; 1722f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Content URI for photo and video metadata. */ 173c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE); 1742f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Foreign key to photo_id. Long value. */ 175c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String PHOTO_ID = "photo_id"; 1762f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Metadata key. String value */ 177c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String KEY = "key"; 178c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 179c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * Metadata value. Type is based on key. 180c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 181c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public static final String VALUE = "value"; 1822f5a064980ad79e88616ba124268e4d7298c68a5George Mount 1832f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** A short summary of the photo. String value. */ 1842f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_SUMMARY = "summary"; 1852f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The date the photo was added. Long value. */ 1862f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_PUBLISHED = "date_published"; 1872f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The date the photo was last updated. Long value. */ 1882f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_DATE_UPDATED = "date_updated"; 1892f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The size of the photo is bytes. Integer value. */ 1902f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_SIZE_IN_BTYES = "size"; 1912f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The latitude associated with the photo. Double value. */ 1922f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_LATITUDE = "latitude"; 1932f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The longitude associated with the photo. Double value. */ 1942f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_LONGITUDE = "longitude"; 1952f5a064980ad79e88616ba124268e4d7298c68a5George Mount 1962f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The make of the camera used. String value. */ 1972f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_MAKE = ExifInterface.TAG_MAKE; 1982f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The model of the camera used. String value. */ 1992f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_MODEL = ExifInterface.TAG_MODEL;; 2002f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The exposure time used. Float value. */ 2012f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_EXPOSURE = ExifInterface.TAG_EXPOSURE_TIME; 2022f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** Whether the flash was used. Boolean value. */ 2032f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_FLASH = ExifInterface.TAG_FLASH; 2042f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The focal length used. Float value. */ 2052f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_FOCAL_LENGTH = ExifInterface.TAG_FOCAL_LENGTH; 2062f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The fstop value used. Float value. */ 2072f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_FSTOP = ExifInterface.TAG_APERTURE; 2082f5a064980ad79e88616ba124268e4d7298c68a5George Mount /** The ISO equivalent value used. Integer value. */ 2092f5a064980ad79e88616ba124268e4d7298c68a5George Mount public static final String KEY_EXIF_ISO = ExifInterface.TAG_ISO; 210c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 211c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 212c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount // SQL used within this class. 213c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String WHERE_ID = BaseColumns._ID + " = ?"; 214c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String WHERE_METADATA_ID = Metadata.PHOTO_ID + " = ? AND " 215c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount + Metadata.KEY + " = ?"; 216c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 217c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String SELECT_ALBUM_ID = "SELECT " + Albums._ID + " FROM " 218c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount + Albums.TABLE; 219c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String SELECT_PHOTO_ID = "SELECT " + Photos._ID + " FROM " 220c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount + Photos.TABLE; 221c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String SELECT_PHOTO_COUNT = "SELECT COUNT(*) FROM " + Photos.TABLE; 222c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String DELETE_PHOTOS = "DELETE FROM " + Photos.TABLE; 223c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String DELETE_METADATA = "DELETE FROM " + Metadata.TABLE; 224c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String SELECT_METADATA_COUNT = "SELECT COUNT(*) FROM " + Metadata.TABLE; 225c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String WHERE = " WHERE "; 226c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String IN = " IN "; 227c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String NESTED_SELECT_START = "("; 228c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final String NESTED_SELECT_END = ")"; 229ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount protected static final String[] PROJECTION_COUNT = { 230ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount "COUNT(*)" 231ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount }; 232c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 233c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount /** 234c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount * For selecting the mime-type for an image. 235c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount */ 236c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount private static final String[] PROJECTION_MIME_TYPE = { 237c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount Photos.MIME_TYPE, 238c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount }; 239c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 24009bfc1d566621498d08903559ae707161a701571George Mount protected static final String[] BASE_COLUMNS_ID = { 241135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount BaseColumns._ID, 242135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount }; 243135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount 244135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount protected ChangeNotification mNotifier = null; 245c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 246c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 247c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final int MATCH_PHOTO = 1; 248c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final int MATCH_PHOTO_ID = 2; 249c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final int MATCH_ALBUM = 3; 250c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final int MATCH_ALBUM_ID = 4; 251c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final int MATCH_METADATA = 5; 252c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static final int MATCH_METADATA_ID = 6; 253d4681a3c9d417970a9602112bd83f921ac16af96George Mount protected static final int MATCH_ACCOUNT = 7; 254d4681a3c9d417970a9602112bd83f921ac16af96George Mount protected static final int MATCH_ACCOUNT_ID = 8; 255c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 256c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount static { 257c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount sUriMatcher.addURI(AUTHORITY, Photos.TABLE, MATCH_PHOTO); 258c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount // match against Photos._ID 259c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount sUriMatcher.addURI(AUTHORITY, Photos.TABLE + "/#", MATCH_PHOTO_ID); 260c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount sUriMatcher.addURI(AUTHORITY, Albums.TABLE, MATCH_ALBUM); 261c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount // match against Albums._ID 262c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount sUriMatcher.addURI(AUTHORITY, Albums.TABLE + "/#", MATCH_ALBUM_ID); 263c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount sUriMatcher.addURI(AUTHORITY, Metadata.TABLE, MATCH_METADATA); 264c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount // match against metadata/<Metadata._ID> 265c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount sUriMatcher.addURI(AUTHORITY, Metadata.TABLE + "/#", MATCH_METADATA_ID); 266dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware sUriMatcher.addURI(AUTHORITY, Accounts.TABLE, MATCH_ACCOUNT); 267dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware // match against Accounts._ID 268dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware sUriMatcher.addURI(AUTHORITY, Accounts.TABLE + "/#", MATCH_ACCOUNT_ID); 269c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 270c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 271c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @Override 2725139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount public int deleteInTransaction(Uri uri, String selection, String[] selectionArgs, 2735139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount boolean callerIsSyncAdapter) { 274c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount int match = matchUri(uri); 275c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount selection = addIdToSelection(match, selection); 276c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount selectionArgs = addIdToSelectionArgs(match, uri, selectionArgs); 2778324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount return deleteCascade(uri, match, selection, selectionArgs); 278c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 279c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 280c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @Override 281c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public String getType(Uri uri) { 282c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount Cursor cursor = query(uri, PROJECTION_MIME_TYPE, null, null, null); 283c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String mimeType = null; 284c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount if (cursor.moveToNext()) { 285c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount mimeType = cursor.getString(0); 286c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 287c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount cursor.close(); 288c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return mimeType; 289c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 290c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 291c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @Override 2925139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount public Uri insertInTransaction(Uri uri, ContentValues values, boolean callerIsSyncAdapter) { 293aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount int match = matchUri(uri); 294aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount validateMatchTable(match); 295aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount String table = getTableFromMatch(match, uri); 2965139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); 297aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount Uri insertedUri = null; 2985139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount long id = db.insert(table, null, values); 2995139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount if (id != -1) { 3005139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount // uri already matches the table. 3015139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount insertedUri = ContentUris.withAppendedId(uri, id); 3025139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount postNotifyUri(insertedUri); 303aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount } 304aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount return insertedUri; 305c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 306c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 307c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @Override 308c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 309c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String sortOrder) { 310c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return query(uri, projection, selection, selectionArgs, sortOrder, null); 311c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 312c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 313c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @Override 314c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 315c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String sortOrder, CancellationSignal cancellationSignal) { 316ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount projection = replaceCount(projection); 317c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount int match = matchUri(uri); 318c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount selection = addIdToSelection(match, selection); 319c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount selectionArgs = addIdToSelectionArgs(match, uri, selectionArgs); 320c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String table = getTableFromMatch(match, uri); 321835a0d50318e9cd61bbbd834e36ddda4cff9c59dJohn Reck Cursor c = query(table, projection, selection, selectionArgs, sortOrder, cancellationSignal); 322835a0d50318e9cd61bbbd834e36ddda4cff9c59dJohn Reck if (c != null) { 323835a0d50318e9cd61bbbd834e36ddda4cff9c59dJohn Reck c.setNotificationUri(getContext().getContentResolver(), uri); 324835a0d50318e9cd61bbbd834e36ddda4cff9c59dJohn Reck } 325835a0d50318e9cd61bbbd834e36ddda4cff9c59dJohn Reck return c; 326c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 327c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 328c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount @Override 3295139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount public int updateInTransaction(Uri uri, ContentValues values, String selection, 3305139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount String[] selectionArgs, boolean callerIsSyncAdapter) { 331c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount int match = matchUri(uri); 332c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount int rowsUpdated = 0; 3335139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); 3345139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount if (match == MATCH_METADATA) { 3355139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount rowsUpdated = modifyMetadata(db, values); 3365139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount } else { 3375139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount selection = addIdToSelection(match, selection); 3385139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount selectionArgs = addIdToSelectionArgs(match, uri, selectionArgs); 3395139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount String table = getTableFromMatch(match, uri); 3405139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount rowsUpdated = db.update(table, values, selection, selectionArgs); 341c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 3425139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount postNotifyUri(uri); 343c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return rowsUpdated; 344c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 345c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 346135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount public void setMockNotification(ChangeNotification notification) { 347135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount mNotifier = notification; 348135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount } 349135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount 350c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static String addIdToSelection(int match, String selection) { 351c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String where; 352c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount switch (match) { 353c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_PHOTO_ID: 354c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_ALBUM_ID: 355c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_METADATA_ID: 356c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount where = WHERE_ID; 357c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 358c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount default: 359c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return selection; 360c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 361c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return DatabaseUtils.concatenateWhere(selection, where); 362c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 363c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 364c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static String[] addIdToSelectionArgs(int match, Uri uri, String[] selectionArgs) { 365c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String[] whereArgs; 366c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount switch (match) { 367c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_PHOTO_ID: 368c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_ALBUM_ID: 369c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_METADATA_ID: 370c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount whereArgs = new String[] { 371c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount uri.getPathSegments().get(1), 372c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount }; 373c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 374c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount default: 375c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return selectionArgs; 376c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 377c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return DatabaseUtils.appendSelectionArgs(selectionArgs, whereArgs); 378c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 379c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 380c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static String[] addMetadataKeysToSelectionArgs(String[] selectionArgs, Uri uri) { 381c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount List<String> segments = uri.getPathSegments(); 382c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String[] additionalArgs = { 383c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount segments.get(1), 384c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount segments.get(2), 385c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount }; 386c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 387c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return DatabaseUtils.appendSelectionArgs(selectionArgs, additionalArgs); 388c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 389c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 390c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static String getTableFromMatch(int match, Uri uri) { 391c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String table; 392c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount switch (match) { 393c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_PHOTO: 394c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_PHOTO_ID: 395c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount table = Photos.TABLE; 396c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 397c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_ALBUM: 398c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_ALBUM_ID: 399c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount table = Albums.TABLE; 400c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 401c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_METADATA: 402c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_METADATA_ID: 403c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount table = Metadata.TABLE; 404c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 405dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware case MATCH_ACCOUNT: 406dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware case MATCH_ACCOUNT_ID: 407dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware table = Accounts.TABLE; 408dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware break; 409c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount default: 410c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount throw unknownUri(uri); 411c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 412c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return table; 413c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 414c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 4155139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount @Override 4165139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount public SQLiteOpenHelper getDatabaseHelper(Context context) { 4175139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount return new PhotoDatabase(context, DB_NAME); 418c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 419c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 420c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount private int modifyMetadata(SQLiteDatabase db, ContentValues values) { 421c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount int rowCount; 422c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount if (values.get(Metadata.VALUE) == null) { 423aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount String[] selectionArgs = { 424aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount values.getAsString(Metadata.PHOTO_ID), values.getAsString(Metadata.KEY), 425aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount }; 426c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount rowCount = db.delete(Metadata.TABLE, WHERE_METADATA_ID, selectionArgs); 427c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } else { 428aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount long rowId = db.replace(Metadata.TABLE, null, values); 429aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount rowCount = (rowId == -1) ? 0 : 1; 430c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 431c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return rowCount; 432c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 433c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 434c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount private int matchUri(Uri uri) { 435c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount int match = sUriMatcher.match(uri); 436c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount if (match == UriMatcher.NO_MATCH) { 437c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount throw unknownUri(uri); 438c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 439c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return match; 440c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 441c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 4425139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount @Override 4435139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount protected void notifyChange(ContentResolver resolver, Uri uri, boolean syncToNetwork) { 444135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount if (mNotifier != null) { 4455139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount mNotifier.notifyChange(uri, syncToNetwork); 446135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount } else { 447835a0d50318e9cd61bbbd834e36ddda4cff9c59dJohn Reck super.notifyChange(resolver, uri, syncToNetwork); 448135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount } 449c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 450c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 451c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount protected static IllegalArgumentException unknownUri(Uri uri) { 452c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount return new IllegalArgumentException("Unknown Uri format: " + uri); 453c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 454c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 455135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount protected static String nestWhere(String matchColumn, String table, String nestedWhere) { 456135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount String query = SQLiteQueryBuilder.buildQueryString(false, table, BASE_COLUMNS_ID, 457135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount nestedWhere, null, null, null, null); 458135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount return matchColumn + IN + NESTED_SELECT_START + query + NESTED_SELECT_END; 459c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 460c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 4618324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount protected static String metadataSelectionFromPhotos(String where) { 4628324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount return nestWhere(Metadata.PHOTO_ID, Photos.TABLE, where); 4638324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount } 4648324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount 4658324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount protected static String photoSelectionFromAlbums(String where) { 4668324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount return nestWhere(Photos.ALBUM_ID, Albums.TABLE, where); 4678324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount } 4688324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount 4698324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount protected static String photoSelectionFromAccounts(String where) { 4708324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount return nestWhere(Photos.ACCOUNT_ID, Accounts.TABLE, where); 4718324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount } 4728324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount 4738324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount protected static String albumSelectionFromAccounts(String where) { 4748324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount return nestWhere(Albums.ACCOUNT_ID, Accounts.TABLE, where); 4758324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount } 4768324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount 4778324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount protected int deleteCascade(Uri uri, int match, String selection, String[] selectionArgs) { 478c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount switch (match) { 479c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_PHOTO: 48056c42ad3265ceac0674e6a4c00800336101a230cGeorge Mount case MATCH_PHOTO_ID: 4818324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount deleteCascade(Metadata.CONTENT_URI, MATCH_METADATA, 4828324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount metadataSelectionFromPhotos(selection), selectionArgs); 483c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 484c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount case MATCH_ALBUM: 48556c42ad3265ceac0674e6a4c00800336101a230cGeorge Mount case MATCH_ALBUM_ID: 4868324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount deleteCascade(Photos.CONTENT_URI, MATCH_PHOTO, 4878324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount photoSelectionFromAlbums(selection), selectionArgs); 488c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount break; 48956c42ad3265ceac0674e6a4c00800336101a230cGeorge Mount case MATCH_ACCOUNT: 49056c42ad3265ceac0674e6a4c00800336101a230cGeorge Mount case MATCH_ACCOUNT_ID: 4918324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount deleteCascade(Photos.CONTENT_URI, MATCH_PHOTO, 4928324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount photoSelectionFromAccounts(selection), selectionArgs); 4938324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount deleteCascade(Albums.CONTENT_URI, MATCH_ALBUM, 4948324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount albumSelectionFromAccounts(selection), selectionArgs); 49556c42ad3265ceac0674e6a4c00800336101a230cGeorge Mount break; 496c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 4978324b3355817e8f6d08ac0b1f7349926df8a9bc7George Mount SQLiteDatabase db = getDatabaseHelper().getWritableDatabase(); 498c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount String table = getTableFromMatch(match, uri); 499135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount int deleted = db.delete(table, selection, selectionArgs); 500135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount if (deleted > 0) { 5015139ee00d28c3f694df74f0ccf13cec402707aeaGeorge Mount postNotifyUri(uri); 502c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 503135c2e576f3dfea954ba628942c55adcb35a7cf6George Mount return deleted; 504c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount } 505c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount 506aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount private static void validateMatchTable(int match) { 507aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount switch (match) { 508aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount case MATCH_PHOTO: 509aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount case MATCH_ALBUM: 510aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount case MATCH_METADATA: 511dc32aaf95fd6925796474688c24704b3265a1ae7Mangesh Ghiware case MATCH_ACCOUNT: 512aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount break; 513aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount default: 514aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount throw new IllegalArgumentException("Operation not allowed on an existing row."); 515aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount } 516aebb3b012aef838001c5f9e6adfa4bbcc7bb6569George Mount } 517091314b7ea73e774ce96c981bd7007c94ad80e30George Mount 518091314b7ea73e774ce96c981bd7007c94ad80e30George Mount protected Cursor query(String table, String[] columns, String selection, 519091314b7ea73e774ce96c981bd7007c94ad80e30George Mount String[] selectionArgs, String orderBy, CancellationSignal cancellationSignal) { 520091314b7ea73e774ce96c981bd7007c94ad80e30George Mount SQLiteDatabase db = getDatabaseHelper().getReadableDatabase(); 521091314b7ea73e774ce96c981bd7007c94ad80e30George Mount if (ApiHelper.HAS_CANCELLATION_SIGNAL) { 522091314b7ea73e774ce96c981bd7007c94ad80e30George Mount return db.query(false, table, columns, selection, selectionArgs, null, null, 523091314b7ea73e774ce96c981bd7007c94ad80e30George Mount orderBy, null, cancellationSignal); 524091314b7ea73e774ce96c981bd7007c94ad80e30George Mount } else { 525091314b7ea73e774ce96c981bd7007c94ad80e30George Mount return db.query(table, columns, selection, selectionArgs, null, null, orderBy); 526091314b7ea73e774ce96c981bd7007c94ad80e30George Mount } 527091314b7ea73e774ce96c981bd7007c94ad80e30George Mount } 528ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount 529ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount protected static String[] replaceCount(String[] projection) { 530ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount if (projection != null && projection.length == 1 531ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount && BaseColumns._COUNT.equals(projection[0])) { 532ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount return PROJECTION_COUNT; 533ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount } 534ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount return projection; 535ba1d7caf633631e3195e3938a39b86efd820869aGeorge Mount } 536c8419b4e5e3302f2efc7ea629891041a14219aa7George Mount} 537