From a90fe8e947d1cf7cd0349906ef17e4eb982f6d56 Mon Sep 17 00:00:00 2001 From: weichunyi <2948523237@qq.com> Date: Thu, 12 Jun 2025 14:30:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...源软件维护方案及成果模板.docx | Bin 16779 -> 18307 bytes .../notes/data/NotesDatabaseHelper.java | 365 +++++++++++------- .../net/micode/notes/data/NotesProvider.java | 236 ++++++----- 3 files changed, 363 insertions(+), 238 deletions(-) diff --git a/doc/开源软件维护方案及成果模板.docx b/doc/开源软件维护方案及成果模板.docx index ef65cfccd1b362848a4416269a65163909afc486..d9db027e50b7bbc411e96e39b7b1f6381d9a33ad 100644 GIT binary patch delta 12425 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 delta 10925 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 Sfq2FPY0A*R5DNY)_0" + ";" + - " END"; + "CREATE TRIGGER decrease_folder_count_on_update " + + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" + + " END"; /** - * Increase folder's note count when insert new note to the folder + * 触发器:当插入新便签时,增加父文件夹的便签计数 */ private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER = - "CREATE TRIGGER increase_folder_count_on_insert " + - " AFTER INSERT ON " + TABLE.NOTE + - " BEGIN " + - " UPDATE " + TABLE.NOTE + - " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + - " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + - " END"; + "CREATE TRIGGER increase_folder_count_on_insert " + + " AFTER INSERT ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; /** - * Decrease folder's note count when delete note from the folder + * 触发器:当删除便签时,减少父文件夹的便签计数 */ private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER = - "CREATE TRIGGER decrease_folder_count_on_delete " + - " AFTER DELETE ON " + TABLE.NOTE + - " BEGIN " + - " UPDATE " + TABLE.NOTE + - " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + - " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + - " AND " + NoteColumns.NOTES_COUNT + ">0;" + - " END"; + "CREATE TRIGGER decrease_folder_count_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0;" + + " END"; /** - * Update note's content when insert data with type {@link DataConstants#NOTE} + * 触发器:当插入类型为NOTE的数据时,更新便签的内容摘要 */ private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER = - "CREATE TRIGGER update_note_content_on_insert " + - " AFTER INSERT ON " + TABLE.DATA + - " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + - " BEGIN" + - " UPDATE " + TABLE.NOTE + - " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + - " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + - " END"; + "CREATE TRIGGER update_note_content_on_insert " + + " AFTER INSERT ON " + TABLE.DATA + + " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; /** - * Update note's content when data with {@link DataConstants#NOTE} type has changed + * 触发器:当更新类型为NOTE的数据时,更新便签的内容摘要 */ private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER = - "CREATE TRIGGER update_note_content_on_update " + - " AFTER UPDATE ON " + TABLE.DATA + - " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + - " BEGIN" + - " UPDATE " + TABLE.NOTE + - " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + - " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + - " END"; + "CREATE TRIGGER update_note_content_on_update " + + " AFTER UPDATE ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; /** - * Update note's content when data with {@link DataConstants#NOTE} type has deleted + * 触发器:当删除类型为NOTE的数据时,清空便签的内容摘要 */ private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER = - "CREATE TRIGGER update_note_content_on_delete " + - " AFTER delete ON " + TABLE.DATA + - " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + - " BEGIN" + - " UPDATE " + TABLE.NOTE + - " SET " + NoteColumns.SNIPPET + "=''" + - " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" + - " END"; + "CREATE TRIGGER update_note_content_on_delete " + + " AFTER delete ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=''" + + " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" + + " END"; /** - * Delete datas belong to note which has been deleted + * 触发器:当删除便签时,自动删除关联的数据 */ private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER = - "CREATE TRIGGER delete_data_on_delete " + - " AFTER DELETE ON " + TABLE.NOTE + - " BEGIN" + - " DELETE FROM " + TABLE.DATA + - " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" + - " END"; + "CREATE TRIGGER delete_data_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.DATA + + " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" + + " END"; /** - * Delete notes belong to folder which has been deleted + * 触发器:当删除文件夹时,自动删除该文件夹下的所有便签 */ private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER = - "CREATE TRIGGER folder_delete_notes_on_delete " + - " AFTER DELETE ON " + TABLE.NOTE + - " BEGIN" + - " DELETE FROM " + TABLE.NOTE + - " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + - " END"; + "CREATE TRIGGER folder_delete_notes_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; /** - * Move notes belong to folder which has been moved to trash folder + * 触发器:当文件夹被移动到回收站时,将其下的便签也移动到回收站 */ private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER = - "CREATE TRIGGER folder_move_notes_on_trash " + - " AFTER UPDATE ON " + TABLE.NOTE + - " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + - " BEGIN" + - " UPDATE " + TABLE.NOTE + - " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + - " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + - " END"; - + "CREATE TRIGGER folder_move_notes_on_trash " + + " AFTER UPDATE ON " + TABLE.NOTE + + " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + // 构造函数 public NotesDatabaseHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } + /** + * 创建便签表 + * @param db SQLiteDatabase对象 + */ public void createNoteTable(SQLiteDatabase db) { - db.execSQL(CREATE_NOTE_TABLE_SQL); - reCreateNoteTableTriggers(db); - createSystemFolder(db); + db.execSQL(CREATE_NOTE_TABLE_SQL); // 执行创建表SQL + reCreateNoteTableTriggers(db); // 重建触发器 + createSystemFolder(db); // 创建系统文件夹 Log.d(TAG, "note table has been created"); } + /** + * 重建便签表相关的触发器 + * @param db SQLiteDatabase对象 + */ private void reCreateNoteTableTriggers(SQLiteDatabase db) { + // 删除所有现有的触发器 db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update"); db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update"); db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_delete"); @@ -226,6 +246,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL("DROP TRIGGER IF EXISTS folder_delete_notes_on_delete"); db.execSQL("DROP TRIGGER IF EXISTS folder_move_notes_on_trash"); + // 重新创建所有触发器 db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER); @@ -235,18 +256,22 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER); } + /** + * 创建系统文件夹 + * @param db SQLiteDatabase对象 + */ private void createSystemFolder(SQLiteDatabase db) { ContentValues values = new ContentValues(); /** - * call record foler for call notes + * 创建通话记录文件夹 */ values.put(NoteColumns.ID, Notes.ID_CALL_RECORD_FOLDER); values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); db.insert(TABLE.NOTE, null, values); /** - * root folder which is default folder + * 创建根文件夹 */ values.clear(); values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER); @@ -254,7 +279,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.insert(TABLE.NOTE, null, values); /** - * temporary folder which is used for moving note + * 创建临时文件夹(用于移动便签时临时存放) */ values.clear(); values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER); @@ -262,7 +287,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.insert(TABLE.NOTE, null, values); /** - * create trash folder + * 创建回收站文件夹 */ values.clear(); values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); @@ -270,23 +295,38 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.insert(TABLE.NOTE, null, values); } + /** + * 创建数据表 + * @param db SQLiteDatabase对象 + */ public void createDataTable(SQLiteDatabase db) { - db.execSQL(CREATE_DATA_TABLE_SQL); - reCreateDataTableTriggers(db); - db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL); + db.execSQL(CREATE_DATA_TABLE_SQL); // 执行创建表SQL + reCreateDataTableTriggers(db); // 重建触发器 + db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL); // 创建索引 Log.d(TAG, "data table has been created"); } + /** + * 重建数据表相关的触发器 + * @param db SQLiteDatabase对象 + */ private void reCreateDataTableTriggers(SQLiteDatabase db) { + // 删除所有现有的触发器 db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert"); db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update"); db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_delete"); + // 重新创建所有触发器 db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER); db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER); db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER); } + /** + * 获取单例实例 + * @param context 上下文对象 + * @return NotesDatabaseHelper实例 + */ static synchronized NotesDatabaseHelper getInstance(Context context) { if (mInstance == null) { mInstance = new NotesDatabaseHelper(context); @@ -294,69 +334,98 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { return mInstance; } + /** + * 创建数据库时调用 + * @param db SQLiteDatabase对象 + */ @Override public void onCreate(SQLiteDatabase db) { - createNoteTable(db); - createDataTable(db); + createNoteTable(db); // 创建便签表 + createDataTable(db); // 创建数据表 } + /** + * 升级数据库时调用 + * @param db SQLiteDatabase对象 + * @param oldVersion 旧版本号 + * @param newVersion 新版本号 + */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - boolean reCreateTriggers = false; - boolean skipV2 = false; + boolean reCreateTriggers = false; // 是否需要重建触发器 + boolean skipV2 = false; // 是否跳过V2升级 + // 从V1升级到V2 if (oldVersion == 1) { upgradeToV2(db); - skipV2 = true; // this upgrade including the upgrade from v2 to v3 + skipV2 = true; // 这个升级包含从V2到V3的升级 oldVersion++; } + // 从V2升级到V3 if (oldVersion == 2 && !skipV2) { upgradeToV3(db); reCreateTriggers = true; oldVersion++; } + // 从V3升级到V4 if (oldVersion == 3) { upgradeToV4(db); oldVersion++; } + // 如果需要,重建触发器 if (reCreateTriggers) { reCreateNoteTableTriggers(db); reCreateDataTableTriggers(db); } + // 检查版本号是否匹配 if (oldVersion != newVersion) { throw new IllegalStateException("Upgrade notes database to version " + newVersion + "fails"); } } + /** + * 升级到V2版本:重建所有表 + * @param db SQLiteDatabase对象 + */ private void upgradeToV2(SQLiteDatabase db) { - db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); - db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); - createNoteTable(db); - createDataTable(db); + db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); // 删除便签表 + db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); // 删除数据表 + createNoteTable(db); // 重新创建便签表 + createDataTable(db); // 重新创建数据表 } + /** + * 升级到V3版本:添加GTASK_ID列和回收站文件夹 + * @param db SQLiteDatabase对象 + */ private void upgradeToV3(SQLiteDatabase db) { - // drop unused triggers + // 删除不再使用的触发器 db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_delete"); db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_update"); - // add a column for gtask id + + // 添加GTASK_ID列 db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''"); - // add a trash system folder + + // 添加回收站系统文件夹 ContentValues values = new ContentValues(); values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); db.insert(TABLE.NOTE, null, values); } + /** + * 升级到V4版本:添加VERSION列 + * @param db SQLiteDatabase对象 + */ private void upgradeToV4(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0"); } -} +} \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/data/NotesProvider.java b/src/Notes-master/src/net/micode/notes/data/NotesProvider.java index edb0a60..f68161d 100644 --- a/src/Notes-master/src/net/micode/notes/data/NotesProvider.java +++ b/src/Notes-master/src/net/micode/notes/data/NotesProvider.java @@ -14,9 +14,10 @@ * limitations under the License. */ +// 便签内容提供者,负责处理便签数据的CRUD操作 package net.micode.notes.data; - +// 导入所需的Android类 import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentUris; @@ -29,174 +30,206 @@ import android.net.Uri; import android.text.TextUtils; import android.util.Log; +// 导入应用资源和数据定义 import net.micode.notes.R; import net.micode.notes.data.Notes.DataColumns; import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.data.NotesDatabaseHelper.TABLE; - +// 便签内容提供者类,继承自ContentProvider public class NotesProvider extends ContentProvider { + // URI匹配器,用于匹配不同的URI请求 private static final UriMatcher mMatcher; + // 数据库帮助类实例 private NotesDatabaseHelper mHelper; + // 日志标签 private static final String TAG = "NotesProvider"; - private static final int URI_NOTE = 1; - private static final int URI_NOTE_ITEM = 2; - private static final int URI_DATA = 3; - private static final int URI_DATA_ITEM = 4; - - private static final int URI_SEARCH = 5; - private static final int URI_SEARCH_SUGGEST = 6; + // URI匹配常量定义 + private static final int URI_NOTE = 1; // 便签表URI + private static final int URI_NOTE_ITEM = 2; // 单个便签URI + private static final int URI_DATA = 3; // 数据表URI + private static final int URI_DATA_ITEM = 4; // 单个数据项URI + private static final int URI_SEARCH = 5; // 搜索URI + private static final int URI_SEARCH_SUGGEST = 6; // 搜索建议URI + // 静态初始化块,配置URI匹配器 static { mMatcher = new UriMatcher(UriMatcher.NO_MATCH); - mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); - mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); - mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); - mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); - mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); - mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); - mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); + mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); // 匹配便签表 + mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); // 匹配单个便签 + mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); // 匹配数据表 + mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); // 匹配单个数据项 + mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); // 匹配搜索 + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); // 匹配搜索建议 + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); // 带参数的搜索建议 } /** - * x'0A' represents the '\n' character in sqlite. For title and content in the search result, - * we will trim '\n' and white space in order to show more information. + * 搜索投影字段定义: + * x'0A'在SQLite中代表换行符'\n'。对于搜索结果中的标题和内容, + * 我们将去除'\n'和空格以显示更多信息。 */ - private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," - + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," - + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + "," - + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + "," - + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + "," - + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," - + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; + private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," // 便签ID + + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," // 建议项额外数据 + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + "," // 建议文本1 + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + "," // 建议文本2 + + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + "," // 建议图标 + + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," // 建议动作 + + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; // 建议数据 + // 便签片段搜索查询SQL private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION - + " FROM " + TABLE.NOTE - + " WHERE " + NoteColumns.SNIPPET + " LIKE ?" - + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER - + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; + + " FROM " + TABLE.NOTE // 从便签表查询 + + " WHERE " + NoteColumns.SNIPPET + " LIKE ?" // 按片段匹配 + + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER // 排除回收站中的便签 + + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; // 只查询普通便签类型 + /** + * 创建内容提供者时调用 + * @return 是否成功创建 + */ @Override public boolean onCreate() { - mHelper = NotesDatabaseHelper.getInstance(getContext()); + mHelper = NotesDatabaseHelper.getInstance(getContext()); // 获取数据库帮助类实例 return true; } + /** + * 查询方法 + * @param uri 请求的URI + * @param projection 要返回的列 + * @param selection 选择条件 + * @param selectionArgs 选择参数 + * @param sortOrder 排序方式 + * @return 查询结果的Cursor + */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { + String sortOrder) { Cursor c = null; - SQLiteDatabase db = mHelper.getReadableDatabase(); + SQLiteDatabase db = mHelper.getReadableDatabase(); // 获取可读数据库 String id = null; - switch (mMatcher.match(uri)) { - case URI_NOTE: + switch (mMatcher.match(uri)) { // 根据URI匹配不同操作 + case URI_NOTE: // 查询便签表 c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, sortOrder); break; - case URI_NOTE_ITEM: + case URI_NOTE_ITEM: // 查询单个便签 id = uri.getPathSegments().get(1); c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs, null, null, sortOrder); break; - case URI_DATA: + case URI_DATA: // 查询数据表 c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, sortOrder); break; - case URI_DATA_ITEM: + case URI_DATA_ITEM: // 查询单个数据项 id = uri.getPathSegments().get(1); c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs, null, null, sortOrder); break; - case URI_SEARCH: - case URI_SEARCH_SUGGEST: + case URI_SEARCH: // 搜索请求 + case URI_SEARCH_SUGGEST: // 搜索建议请求 if (sortOrder != null || projection != null) { throw new IllegalArgumentException( "do not specify sortOrder, selection, selectionArgs, or projection" + "with this query"); } String searchString = null; - if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { + if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { // 处理搜索建议请求 if (uri.getPathSegments().size() > 1) { searchString = uri.getPathSegments().get(1); } - } else { + } else { // 处理普通搜索请求 searchString = uri.getQueryParameter("pattern"); } - if (TextUtils.isEmpty(searchString)) { + if (TextUtils.isEmpty(searchString)) { // 搜索字符串为空则返回null return null; } try { - searchString = String.format("%%%s%%", searchString); - c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, + searchString = String.format("%%%s%%", searchString); // 格式化搜索字符串 + c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, // 执行原始查询 new String[] { searchString }); } catch (IllegalStateException ex) { - Log.e(TAG, "got exception: " + ex.toString()); + Log.e(TAG, "got exception: " + ex.toString()); // 记录异常 } break; default: - throw new IllegalArgumentException("Unknown URI " + uri); + throw new IllegalArgumentException("Unknown URI " + uri); // 未知URI抛出异常 } if (c != null) { - c.setNotificationUri(getContext().getContentResolver(), uri); + c.setNotificationUri(getContext().getContentResolver(), uri); // 设置通知URI } return c; } + /** + * 插入方法 + * @param uri 请求的URI + * @param values 要插入的值 + * @return 新插入项的URI + */ @Override public Uri insert(Uri uri, ContentValues values) { - SQLiteDatabase db = mHelper.getWritableDatabase(); + SQLiteDatabase db = mHelper.getWritableDatabase(); // 获取可写数据库 long dataId = 0, noteId = 0, insertedId = 0; - switch (mMatcher.match(uri)) { - case URI_NOTE: + switch (mMatcher.match(uri)) { // 根据URI匹配不同操作 + case URI_NOTE: // 插入便签 insertedId = noteId = db.insert(TABLE.NOTE, null, values); break; - case URI_DATA: - if (values.containsKey(DataColumns.NOTE_ID)) { + case URI_DATA: // 插入数据 + if (values.containsKey(DataColumns.NOTE_ID)) { // 检查是否包含便签ID noteId = values.getAsLong(DataColumns.NOTE_ID); } else { - Log.d(TAG, "Wrong data format without note id:" + values.toString()); + Log.d(TAG, "Wrong data format without note id:" + values.toString()); // 记录格式错误 } insertedId = dataId = db.insert(TABLE.DATA, null, values); break; default: - throw new IllegalArgumentException("Unknown URI " + uri); + throw new IllegalArgumentException("Unknown URI " + uri); // 未知URI抛出异常 } - // Notify the note uri + // 通知便签URI变化 if (noteId > 0) { getContext().getContentResolver().notifyChange( ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); } - // Notify the data uri + // 通知数据URI变化 if (dataId > 0) { getContext().getContentResolver().notifyChange( ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); } - return ContentUris.withAppendedId(uri, insertedId); + return ContentUris.withAppendedId(uri, insertedId); // 返回新插入项的URI } + /** + * 删除方法 + * @param uri 请求的URI + * @param selection 选择条件 + * @param selectionArgs 选择参数 + * @return 删除的行数 + */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; String id = null; - SQLiteDatabase db = mHelper.getWritableDatabase(); + SQLiteDatabase db = mHelper.getWritableDatabase(); // 获取可写数据库 boolean deleteData = false; - switch (mMatcher.match(uri)) { - case URI_NOTE: - selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; + switch (mMatcher.match(uri)) { // 根据URI匹配不同操作 + case URI_NOTE: // 删除便签 + selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; // 只允许删除ID大于0的便签 count = db.delete(TABLE.NOTE, selection, selectionArgs); break; - case URI_NOTE_ITEM: + case URI_NOTE_ITEM: // 删除单个便签 id = uri.getPathSegments().get(1); /** - * ID that smaller than 0 is system folder which is not allowed to - * trash + * ID小于0的是系统文件夹,不允许删除 */ long noteId = Long.valueOf(id); if (noteId <= 0) { @@ -205,101 +238,124 @@ public class NotesProvider extends ContentProvider { count = db.delete(TABLE.NOTE, NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); break; - case URI_DATA: + case URI_DATA: // 删除数据 count = db.delete(TABLE.DATA, selection, selectionArgs); deleteData = true; break; - case URI_DATA_ITEM: + case URI_DATA_ITEM: // 删除单个数据项 id = uri.getPathSegments().get(1); count = db.delete(TABLE.DATA, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); deleteData = true; break; default: - throw new IllegalArgumentException("Unknown URI " + uri); + throw new IllegalArgumentException("Unknown URI " + uri); // 未知URI抛出异常 } - if (count > 0) { + if (count > 0) { // 如果删除了数据 if (deleteData) { - getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); // 通知便签URI变化 } - getContext().getContentResolver().notifyChange(uri, null); + getContext().getContentResolver().notifyChange(uri, null); // 通知当前URI变化 } return count; } + /** + * 更新方法 + * @param uri 请求的URI + * @param values 要更新的值 + * @param selection 选择条件 + * @param selectionArgs 选择参数 + * @return 更新的行数 + */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; String id = null; - SQLiteDatabase db = mHelper.getWritableDatabase(); + SQLiteDatabase db = mHelper.getWritableDatabase(); // 获取可写数据库 boolean updateData = false; - switch (mMatcher.match(uri)) { - case URI_NOTE: - increaseNoteVersion(-1, selection, selectionArgs); + switch (mMatcher.match(uri)) { // 根据URI匹配不同操作 + case URI_NOTE: // 更新便签 + increaseNoteVersion(-1, selection, selectionArgs); // 增加便签版本 count = db.update(TABLE.NOTE, values, selection, selectionArgs); break; - case URI_NOTE_ITEM: + case URI_NOTE_ITEM: // 更新单个便签 id = uri.getPathSegments().get(1); - increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); + increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); // 增加便签版本 count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); break; - case URI_DATA: + case URI_DATA: // 更新数据 count = db.update(TABLE.DATA, values, selection, selectionArgs); updateData = true; break; - case URI_DATA_ITEM: + case URI_DATA_ITEM: // 更新单个数据项 id = uri.getPathSegments().get(1); count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); updateData = true; break; default: - throw new IllegalArgumentException("Unknown URI " + uri); + throw new IllegalArgumentException("Unknown URI " + uri); // 未知URI抛出异常 } - if (count > 0) { + if (count > 0) { // 如果更新了数据 if (updateData) { - getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); // 通知便签URI变化 } - getContext().getContentResolver().notifyChange(uri, null); + getContext().getContentResolver().notifyChange(uri, null); // 通知当前URI变化 } return count; } + /** + * 解析选择条件,添加AND连接符 + * @param selection 原始选择条件 + * @return 解析后的选择条件 + */ private String parseSelection(String selection) { return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); } + /** + * 增加便签版本号 + * @param id 便签ID,-1表示不指定 + * @param selection 选择条件 + * @param selectionArgs 选择参数 + */ private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { StringBuilder sql = new StringBuilder(120); sql.append("UPDATE "); sql.append(TABLE.NOTE); sql.append(" SET "); sql.append(NoteColumns.VERSION); - sql.append("=" + NoteColumns.VERSION + "+1 "); + sql.append("=" + NoteColumns.VERSION + "+1 "); // 版本号加1 - if (id > 0 || !TextUtils.isEmpty(selection)) { + if (id > 0 || !TextUtils.isEmpty(selection)) { // 如果有ID或选择条件 sql.append(" WHERE "); } - if (id > 0) { + if (id > 0) { // 如果指定了ID sql.append(NoteColumns.ID + "=" + String.valueOf(id)); } - if (!TextUtils.isEmpty(selection)) { + if (!TextUtils.isEmpty(selection)) { // 如果有选择条件 String selectString = id > 0 ? parseSelection(selection) : selection; - for (String args : selectionArgs) { + for (String args : selectionArgs) { // 替换参数 selectString = selectString.replaceFirst("\\?", args); } sql.append(selectString); } - mHelper.getWritableDatabase().execSQL(sql.toString()); + mHelper.getWritableDatabase().execSQL(sql.toString()); // 执行SQL } + /** + * 获取URI对应的MIME类型 + * @param uri 请求的URI + * @return MIME类型字符串 + */ @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } - -} +} \ No newline at end of file