NotePadProvider.java revision 2b6482773eb251df1f205bf239b94aa0a563a82e
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
17package com.example.android.notepad;
18
19import com.example.android.notepad.NotePad.Notes;
20
21import android.content.ContentProvider;
22import android.content.ContentUris;
23import android.content.ContentValues;
24import android.content.Context;
25import android.content.UriMatcher;
26import android.content.res.Resources;
27import android.database.Cursor;
28import android.database.SQLException;
29import android.database.sqlite.SQLiteDatabase;
30import android.database.sqlite.SQLiteOpenHelper;
31import android.database.sqlite.SQLiteQueryBuilder;
32import android.net.Uri;
33import android.provider.LiveFolders;
34import android.text.TextUtils;
35import android.util.Log;
36
37import 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 */
43public class NotePadProvider extends ContentProvider {
44
45    private static final String TAG = "NotePadProvider";
46
47    private static final String DATABASE_NAME = "note_pad.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
65        DatabaseHelper(Context context) {
66            super(context, DATABASE_NAME, null, DATABASE_VERSION);
67        }
68
69        @Override
70        public void onCreate(SQLiteDatabase db) {
71            db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
72                    + Notes._ID + " INTEGER PRIMARY KEY,"
73                    + Notes.TITLE + " TEXT,"
74                    + Notes.NOTE + " TEXT,"
75                    + Notes.CREATED_DATE + " INTEGER,"
76                    + Notes.MODIFIED_DATE + " INTEGER"
77                    + ");");
78        }
79
80        @Override
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
92    public boolean onCreate() {
93        mOpenHelper = new DatabaseHelper(getContext());
94        return true;
95    }
96
97    @Override
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(Notes._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 = NotePad.Notes.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
139    public String getType(Uri uri) {
140        switch (sUriMatcher.match(uri)) {
141        case NOTES:
142        case LIVE_FOLDER_NOTES:
143            return Notes.CONTENT_TYPE;
144
145        case NOTE_ID:
146            return Notes.CONTENT_ITEM_TYPE;
147
148        default:
149            throw new IllegalArgumentException("Unknown URI " + uri);
150        }
151    }
152
153    @Override
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(NotePad.Notes.CREATED_DATE) == false) {
171            values.put(NotePad.Notes.CREATED_DATE, now);
172        }
173
174        if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
175            values.put(NotePad.Notes.MODIFIED_DATE, now);
176        }
177
178        if (values.containsKey(NotePad.Notes.TITLE) == false) {
179            Resources r = Resources.getSystem();
180            values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
181        }
182
183        if (values.containsKey(NotePad.Notes.NOTE) == false) {
184            values.put(NotePad.Notes.NOTE, "");
185        }
186
187        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
188        long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
189        if (rowId > 0) {
190            Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.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
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, Notes._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
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, Notes._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);
246        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
247        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
248        sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
249
250        sNotesProjectionMap = new HashMap<String, String>();
251        sNotesProjectionMap.put(Notes._ID, Notes._ID);
252        sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
253        sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
254        sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);
255        sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);
256
257        // Support for Live Folders.
258        sLiveFolderProjectionMap = new HashMap<String, String>();
259        sLiveFolderProjectionMap.put(LiveFolders._ID, Notes._ID + " AS " +
260                LiveFolders._ID);
261        sLiveFolderProjectionMap.put(LiveFolders.NAME, Notes.TITLE + " AS " +
262                LiveFolders.NAME);
263        // Add more columns here for more robust Live Folders.
264    }
265}
266