1 /* 2 * Copyright (C) 2007 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.example.android.notepad; 18 19 import com.example.android.notepad.NotePad.Notes; 20 21 import android.content.ContentProvider; 22 import android.content.ContentUris; 23 import android.content.ContentValues; 24 import android.content.Context; 25 import android.content.UriMatcher; 26 import android.content.res.Resources; 27 import android.database.Cursor; 28 import android.database.SQLException; 29 import android.database.sqlite.SQLiteDatabase; 30 import android.database.sqlite.SQLiteOpenHelper; 31 import android.database.sqlite.SQLiteQueryBuilder; 32 import android.net.Uri; 33 import android.text.TextUtils; 34 import android.util.Log; 35 36 import java.util.HashMap; 37 38 /** 39 * Provides access to a database of notes. Each note has a title, the note 40 * itself, a creation date and a modified data. 41 */ 42 public class NotePadProvider extends ContentProvider { 43 44 private static final String TAG = "NotePadProvider"; 45 46 private static final String DATABASE_NAME = "note_pad.db"; 47 private static final int DATABASE_VERSION = 2; 48 private static final String NOTES_TABLE_NAME = "notes"; 49 50 private static HashMap<String, String> sNotesProjectionMap; 51 52 private static final int NOTES = 1; 53 private static final int NOTE_ID = 2; 54 55 private static final UriMatcher sUriMatcher; 56 57 /** 58 * This class helps open, create, and upgrade the database file. 59 */ 60 private static class DatabaseHelper extends SQLiteOpenHelper { 61 DatabaseHelper(Context context)62 DatabaseHelper(Context context) { 63 super(context, DATABASE_NAME, null, DATABASE_VERSION); 64 } 65 66 @Override onCreate(SQLiteDatabase db)67 public void onCreate(SQLiteDatabase db) { 68 db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " (" 69 + Notes._ID + " INTEGER PRIMARY KEY," 70 + Notes.TITLE + " TEXT," 71 + Notes.NOTE + " TEXT," 72 + Notes.CREATED_DATE + " INTEGER," 73 + Notes.MODIFIED_DATE + " INTEGER" 74 + ");"); 75 } 76 77 @Override onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)78 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 79 Log.w(TAG, "Upgrading database from version " + oldVersion + " to " 80 + newVersion + ", which will destroy all old data"); 81 db.execSQL("DROP TABLE IF EXISTS notes"); 82 onCreate(db); 83 } 84 } 85 86 private DatabaseHelper mOpenHelper; 87 88 @Override onCreate()89 public boolean onCreate() { 90 mOpenHelper = new DatabaseHelper(getContext()); 91 return true; 92 } 93 94 @Override query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)95 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 96 String sortOrder) { 97 SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 98 99 switch (sUriMatcher.match(uri)) { 100 case NOTES: 101 qb.setTables(NOTES_TABLE_NAME); 102 qb.setProjectionMap(sNotesProjectionMap); 103 break; 104 105 case NOTE_ID: 106 qb.setTables(NOTES_TABLE_NAME); 107 qb.setProjectionMap(sNotesProjectionMap); 108 qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1)); 109 break; 110 111 default: 112 throw new IllegalArgumentException("Unknown URI " + uri); 113 } 114 115 // If no sort order is specified use the default 116 String orderBy; 117 if (TextUtils.isEmpty(sortOrder)) { 118 orderBy = NotePad.Notes.DEFAULT_SORT_ORDER; 119 } else { 120 orderBy = sortOrder; 121 } 122 123 // Get the database and run the query 124 SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 125 Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); 126 127 // Tell the cursor what uri to watch, so it knows when its source data changes 128 c.setNotificationUri(getContext().getContentResolver(), uri); 129 return c; 130 } 131 132 @Override getType(Uri uri)133 public String getType(Uri uri) { 134 switch (sUriMatcher.match(uri)) { 135 case NOTES: 136 return Notes.CONTENT_TYPE; 137 138 case NOTE_ID: 139 return Notes.CONTENT_ITEM_TYPE; 140 141 default: 142 throw new IllegalArgumentException("Unknown URI " + uri); 143 } 144 } 145 146 @Override insert(Uri uri, ContentValues initialValues)147 public Uri insert(Uri uri, ContentValues initialValues) { 148 // Validate the requested uri 149 if (sUriMatcher.match(uri) != NOTES) { 150 throw new IllegalArgumentException("Unknown URI " + uri); 151 } 152 153 ContentValues values; 154 if (initialValues != null) { 155 values = new ContentValues(initialValues); 156 } else { 157 values = new ContentValues(); 158 } 159 160 Long now = Long.valueOf(System.currentTimeMillis()); 161 162 // Make sure that the fields are all set 163 if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) { 164 values.put(NotePad.Notes.CREATED_DATE, now); 165 } 166 167 if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) { 168 values.put(NotePad.Notes.MODIFIED_DATE, now); 169 } 170 171 if (values.containsKey(NotePad.Notes.TITLE) == false) { 172 Resources r = Resources.getSystem(); 173 values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled)); 174 } 175 176 if (values.containsKey(NotePad.Notes.NOTE) == false) { 177 values.put(NotePad.Notes.NOTE, ""); 178 } 179 180 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 181 long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values); 182 if (rowId > 0) { 183 Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId); 184 getContext().getContentResolver().notifyChange(noteUri, null); 185 return noteUri; 186 } 187 188 throw new SQLException("Failed to insert row into " + uri); 189 } 190 191 @Override delete(Uri uri, String where, String[] whereArgs)192 public int delete(Uri uri, String where, String[] whereArgs) { 193 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 194 int count; 195 switch (sUriMatcher.match(uri)) { 196 case NOTES: 197 count = db.delete(NOTES_TABLE_NAME, where, whereArgs); 198 break; 199 200 case NOTE_ID: 201 String noteId = uri.getPathSegments().get(1); 202 count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId 203 + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); 204 break; 205 206 default: 207 throw new IllegalArgumentException("Unknown URI " + uri); 208 } 209 210 getContext().getContentResolver().notifyChange(uri, null); 211 return count; 212 } 213 214 @Override update(Uri uri, ContentValues values, String where, String[] whereArgs)215 public int update(Uri uri, ContentValues values, String where, String[] whereArgs) { 216 SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 217 int count; 218 switch (sUriMatcher.match(uri)) { 219 case NOTES: 220 count = db.update(NOTES_TABLE_NAME, values, where, whereArgs); 221 break; 222 223 case NOTE_ID: 224 String noteId = uri.getPathSegments().get(1); 225 count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId 226 + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); 227 break; 228 229 default: 230 throw new IllegalArgumentException("Unknown URI " + uri); 231 } 232 233 getContext().getContentResolver().notifyChange(uri, null); 234 return count; 235 } 236 237 static { 238 sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES)239 sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID)240 sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID); 241 242 sNotesProjectionMap = new HashMap<String, String>(); sNotesProjectionMap.put(Notes._ID, Notes._ID)243 sNotesProjectionMap.put(Notes._ID, Notes._ID); sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE)244 sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE); sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE)245 sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE); sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE)246 sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE); sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE)247 sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE); 248 } 249 } 250