You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xiaomi/src/net/micode/notes/data/NotesProvider.java

312 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.data;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
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用于提供对Notes数据库的访问
public class NotesProvider extends ContentProvider {
// Uri匹配器用于区分不同的URI请求
private static final UriMatcher mMatcher;
// 数据库帮助类实例,用于操作数据库
private NotesDatabaseHelper mHelper;
// 日志标签
private static final String TAG = "NotesProvider";
// 定义不同的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
// 静态代码块初始化UriMatcher
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);
}
// 搜索投影列,用于搜索建议
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 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;
// ContentProvider创建时调用
@Override
public boolean onCreate() {
mHelper = NotesDatabaseHelper.getInstance(getContext());
return true;
}
// 查询方法
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor c = null;
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
// 根据URI类型执行不同的查询操作
switch (mMatcher.match(uri)) {
case URI_NOTE:
// 查询笔记集合
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder);
break;
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:
// 查询笔记数据集合
c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null,
sortOrder);
break;
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:
// 搜索或搜索建议,不允许指定排序、选择条件等
if (sortOrder != null || projection != null) {
throw new IllegalArgumentException(
"do not specify sortOrder, selection, selectionArgs, or projection" + "with this query");
}
// 注意:此处缺少实现搜索或搜索建议的代码
break;
}
// 注意此处缺少返回Cursor前的null检查和处理代码
return c;
}
// 注意其他如insert, update, delete, getType等方法未展示需根据需求实现
}
// 这是一个自定义的ContentProvider类的一部分用于处理对数据库内容的插入、删除、更新和查询操作。
// 插入数据到数据库
@Override
public Uri insert(Uri uri, ContentValues values) {
// 获取可写的数据库实例
SQLiteDatabase db = mHelper.getWritableDatabase();
long dataId = 0, noteId = 0, insertedId = 0;
// 根据URI匹配器的结果决定插入到哪个表
switch (mMatcher.match(uri)) {
case URI_NOTE: // 如果是笔记URI
insertedId = noteId = db.insert(TABLE.NOTE, null, values); // 插入到笔记表
break;
case URI_DATA: // 如果是数据URI
if (values.containsKey(DataColumns.NOTE_ID)) { // 如果包含笔记ID
noteId = values.getAsLong(DataColumns.NOTE_ID); // 获取笔记ID
} else {
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); // 如果URI未知抛出异常
}
// 如果插入了笔记,通知监听器
if (noteId > 0) {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null);
}
// 如果插入了数据,通知监听器
if (dataId > 0) {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
}
// 返回新插入数据的URI
return ContentUris.withAppendedId(uri, insertedId);
}
// 从数据库中删除数据
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean deleteData = false;
// 根据URI匹配器的结果决定从哪个表删除数据
switch (mMatcher.match(uri)) {
case URI_NOTE: // 如果是笔记URI
selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; // 添加额外的筛选条件
count = db.delete(TABLE.NOTE, selection, selectionArgs); // 从笔记表删除
break;
case URI_NOTE_ITEM: // 如果是单个笔记项的URI
id = uri.getPathSegments().get(1); // 获取笔记ID
long noteId = Long.valueOf(id);
if (noteId <= 0) {
break; // 如果ID无效则不执行删除
}
count = db.delete(TABLE.NOTE,
NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); // 从笔记表删除单个项
break;
case URI_DATA: // 如果是数据URI
count = db.delete(TABLE.DATA, selection, selectionArgs); // 从数据表删除
deleteData = true; // 标记为删除了数据
break;
case URI_DATA_ITEM: // 如果是单个数据项的URI
id = uri.getPathSegments().get(1); // 获取数据ID
count = db.delete(TABLE.DATA,
DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); // 从数据表删除单个项
deleteData = true; // 标记为删除了数据
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri); // 如果URI未知抛出异常
}
// 如果删除了数据,通知监听器
if (count > 0) {
if (deleteData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); // 通知笔记URI的监听器
}
getContext().getContentResolver().notifyChange(uri, null); // 通知操作URI的监听器
}
return count; // 返回删除的行数
}
// 更新数据库中的数据
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean updateData = false;
// 根据URI匹配器的结果决定更新哪个表
switch (mMatcher.match(uri)) {
case URI_NOTE: // 如果是笔记URI
increaseNoteVersion(-1, selection, selectionArgs); // 更新笔记版本(特殊逻辑)
count = db.update(TABLE.NOTE, values, selection, selectionArgs); // 更新笔记表
break;
case URI_NOTE_ITEM: // 如果是单个笔记项的URI
id = uri.getPathSegments().get(1); // 获取笔记ID
increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); // 更新笔记版本(特殊逻辑)
count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs); // 更新笔记表中的单个项
break;
case URI_DATA: // 如果是数据URI
count = db.update(TABLE.DATA, values, selection, selectionArgs); // 更新数据表
updateData = true; // 标记为更新了数据
break;
case URI_DATA_ITEM: // 如果是单个数据项的URI
id = uri.getPathSegments().get(1); // 获取数据ID
count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs); // 更新数据表中的单个项
updateData = true; // 标记为更新了数据
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri); // 如果URI未知抛出异常
}
// 如果更新了数据,通知监听器
if (count > 0) {
if (updateData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); // 通知笔记URI的监听器
}
getContext().getContentResolver().notifyChange(uri, null); // 通知操作URI的监听器
}
return count; // 返回更新的行数
}
// 解析额外的筛选条件字符串
private String parseSelection(String selection) {
return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
}
// 增加笔记的版本号
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 "); // 更新版本号
// 构建WHERE子句
if (id > 0 || !TextUtils.isEmpty(selection)) {
sql.append(" WHERE ");
}
if (id > 0) {
sql.append(NoteColumns.ID + "=" + String.valueOf(id)); // 根据ID更新
}
if (!TextUtils.isEmpty(selection)) {
String selectString = id > 0 ? parseSelection(selection) : selection; // 解析筛选条件
for (String args : selectionArgs) {
selectString = selectString.replaceFirst("\\?", args); // 替换占位符
}
sql.append(selectString); // 添加筛选条件
}
// 执行SQL语句
mHelper.getWritableDatabase().execSQL(sql.toString());
}
// 获取URI的类型未实现
@Override
public String getType(Uri uri) {
return null; // 此处应返回MIME类型但代码未实现
}
// 其他方法和成员变量如mMatcher, TABLE, mHelper等已省略假设它们在其他地方定义。