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