Type: INTEGER (long)
@@ -184,6 +171,8 @@ public class Notes { *Type : INTEGER (long)
*/ public static final String VERSION = "version"; + + public static final String LOCKED = "lock_type"; } public interface DataColumns { @@ -191,87 +180,75 @@ public class Notes { * The unique ID for a row *Type: INTEGER (long)
*/ - - // DataColumns的接口,这个接口包含了一系列静态常量,这些常量代表了数据库表中用于存储数据的列名。 - // 每个常量都有相应的注释,说明该列的作用和数据类型。 public static final String ID = "_id"; /** * The MIME type of the item represented by this row. *Type: Text
*/ - //MIME类型是一种标准,用于标识文档、文件或字节流的性质和格式。在数据库中,这个字段可以用来识别不同类型的数据,例如文本、图片、音频或视频等。 public static final String MIME_TYPE = "mime_type"; /** * The reference id to note that this data belongs to *Type: INTEGER (long)
*/ - //归属的Note的ID public static final String NOTE_ID = "note_id"; /** * Created data for note or folder *Type: INTEGER (long)
*/ - //创建日期 public static final String CREATED_DATE = "created_date"; /** * Latest modified date *Type: INTEGER (long)
*/ - - //最近修改日期 public static final String MODIFIED_DATE = "modified_date"; /** * Data's content *Type: TEXT
*/ - //数据内容 public static final String CONTENT = "content"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * Generic data column, the meaning is specific, used for * integer data type *Type: INTEGER
*/ - // 以下5个是通用数据列,它们的具体意义取决于MIME类型(由MIME_TYPE字段指定)。 - // 不同的MIME类型可能需要存储不同类型的数据,这五个字段提供了灵活性,允许根据MIME类型来存储相应的数据。 public static final String DATA1 = "data1"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * Generic data column, the meaning is specific, used for * integer data type *Type: INTEGER
*/ public static final String DATA2 = "data2"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * Generic data column, the meaning is specific, used for * TEXT data type *Type: TEXT
*/ public static final String DATA3 = "data3"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * Generic data column, the meaning is specific, used for * TEXT data type *Type: TEXT
*/ public static final String DATA4 = "data4"; /** - * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * Generic data column, the meaning is specific, used for * TEXT data type *Type: TEXT
*/ public static final String DATA5 = "data5"; } - //以下是文本便签的定义 public static final class TextNote implements DataColumns { /** * Mode to indicate the text in check list mode or not @@ -301,10 +278,10 @@ public class Notes { */ public static final String PHONE_NUMBER = DATA3; - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note";// 定义了MIME类型,用于标识文本标签的目录 + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note"; - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note";// 定义了MIME类型,用于标识文本标签的目录 + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note"; - public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note");//文本标签内容提供者(Content Provider)的URI,用于访问文本标签数据 + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note"); } } diff --git a/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java b/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java index c723213..7fb3222 100644 --- a/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java +++ b/Notesmaster/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -28,28 +28,20 @@ import net.micode.notes.data.Notes.NoteColumns; public class NotesDatabaseHelper extends SQLiteOpenHelper { - // 数据库帮助类,用于管理名为 note.db 的 SQLite 数据库。 -// 它继承自 SQLiteOpenHelper 类,这是 Android提供的一个方便的工具类,用于管理数据库的创建和版本更新. - // 数据库的基本信息;数据库名称和版本信息(在创建实例对象时会用到) - private static final String DB_NAME = "note.db"; + private static final String DB_NAME = "note4.db"; private static final int DB_VERSION = 4; - //内部接口:个人理解为两个表名,一个note,一个data public interface TABLE { public static final String NOTE = "note"; public static final String DATA = "data"; } - //一个标签,方便日志输出时识别出信息来自哪里 private static final String TAG = "NotesDatabaseHelper"; - //静态所有变量,提供一个全局访问点来获取数据库辅助类的唯一实例,使得在应用的任何地方都可以方便地使用它 private static NotesDatabaseHelper mInstance; - /* 以下都是一些SQL语句,辅助我们来对数据库进行操作 */ - //创建note表的语句,这里的NoteColumns就是我们刚刚在Notes中定义的一个接口,里面定义了一系列静态的数据库表中的列名 private static final String CREATE_NOTE_TABLE_SQL = "CREATE TABLE " + TABLE.NOTE + "(" + NoteColumns.ID + " INTEGER PRIMARY KEY," + @@ -67,11 +59,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.LOCKED + " TEXT NOT NULL DEFAULT '"+Notes.UNLOCKED+"'," + NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" + ")"; - //同上,创建data表的语句,这里的DataColumns就是我们刚刚在Notes中定义的一个接口,里面定义了一系列静态的数据库表中的列名 private static final String CREATE_DATA_TABLE_SQL = "CREATE TABLE " + TABLE.DATA + "(" + DataColumns.ID + " INTEGER PRIMARY KEY," + @@ -87,31 +79,13 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" + ")"; - // 功能简介: - // 创建一个以note的ID为索引 - // 解读: - // 用于在TABLE.DATA表上创建一个名为note_id_index的索引。 - // 这个索引是基于DataColumns.NOTE_ID列的。IF NOT EXISTS确保了如果索引已经存在,那么就不会尝试重新创建它,避免了可能的错误。 - // 索引通常用于提高查询性能,特别是在对某个字段进行频繁查询时。 private static final String CREATE_DATA_NOTE_ID_INDEX_SQL = "CREATE INDEX IF NOT EXISTS note_id_index ON " + TABLE.DATA + "(" + DataColumns.NOTE_ID + ");"; - /* 以下是一些对便签增删改定义的触发器 */ - /* 总结 - * 这些触发器都是用来维护NOTE表和与之相关联的DATA表之间数据一致性的。 - * 当在NOTE表中发生删除或更新操作时,这些触发器会自动执行相应的数据清理或更新操作,确保数据库中的数据保持正确和一致。 - * 特别是在处理文件夹和回收站等逻辑时,这些触发器起到了非常重要的作用,可以自动管理数据的移动和删除。*/ /** * Increase folder's note count when move note to the folder */ - // 功能简介: - // 添加触发器:增加文件夹的便签个数记录(因为我们会移动便签进入文件夹,这时候文件夹的计数要进行更新) - // 解读: - // 定义了一个SQL触发器increase_folder_count_on_update。 - // 触发器是一种特殊的存储过程,它会在指定表上的指定事件(如INSERT、UPDATE、DELETE)发生时自动执行。 - // 这个触发器会在TABLE.NOTE表的NoteColumns.PARENT_ID字段更新后执行。 - // 触发器的逻辑是:当某个笔记的PARENT_ID(即父文件夹ID)被更新时,它会找到对应的文件夹(通过新的PARENT_ID),并将该文件夹的NOTES_COUNT(即笔记数)增加1。 private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = "CREATE TRIGGER increase_folder_count_on_update "+ " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + @@ -124,8 +98,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Decrease folder's note count when move note from folder */ - // 功能简介:(触发器和上面的 “增加文件夹的便签个数记录” 同理,就不细节解读了) - // 添加触发器:减少文件夹的便签个数记录(因为我们会移动便签移出文件夹,这时候文件夹的计数要进行更新) private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = "CREATE TRIGGER decrease_folder_count_on_update " + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + @@ -139,8 +111,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * 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 + @@ -153,8 +123,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * 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 + @@ -168,11 +136,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Update note's content when insert data with type {@link DataConstants#NOTE} */ - // 功能简介: - // 添加触发器:当向DATA表中插入类型为NOTE(便签)的数据时,更新note表对应的笔记内容。 - // 解读: - // 在DATA表上进行INSERT操作后,如果新插入的数据的MIME_TYPE为NOTE,则触发此操作。 - // 它会更新NOTE表,将与新插入数据相关联的标签的SNIPPET(摘要)字段设置为新插入数据的CONTENT字段的值 private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER = "CREATE TRIGGER update_note_content_on_insert " + " AFTER INSERT ON " + TABLE.DATA + @@ -186,11 +149,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Update note's content when data with {@link DataConstants#NOTE} type has changed */ - // 功能简介: - // 添加触发器:当DATA表中,类型为NOTE(便签)的数据更改时,更新note表对应的笔记内容。 - // 解读: - // 在DATA表上进行UPDATE操作后,如果更新前的数据的MIME_TYPE为NOTE,则触发此操作。 - // 它会更新NOTE表,将与更新后的数据相关联的笔记的SNIPPET字段设置为新数据的CONTENT字段的值 private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER = "CREATE TRIGGER update_note_content_on_update " + " AFTER UPDATE ON " + TABLE.DATA + @@ -204,11 +162,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Update note's content when data with {@link DataConstants#NOTE} type has deleted */ - // 功能简介: - // 添加触发器:当DATA表中,类型为NOTE(便签)的数据删除时,更新note表对应的笔记内容(置空)。 - // 解读: - // 在DATA表上进行DELETE操作后,如果删除的数据的MIME_TYPE为NOTE,则触发此操作。 - // 它会更新NOTE表,将与删除的数据相关联的笔记的SNIPPET字段设置为空字符串。 private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER = "CREATE TRIGGER update_note_content_on_delete " + " AFTER delete ON " + TABLE.DATA + @@ -222,11 +175,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Delete datas belong to note which has been deleted */ - // 功能简介: - // 添加触发器:当从NOTE表中删除笔记时,删除与该笔记相关联的数据(就是删除data表中为该note的数据) - // 解读: - // 在NOTE表上进行DELETE操作后,此触发器被激活。 - // 它会从DATA表中删除所有与已删除的笔记(由old.ID表示)相关联的数据行(通过比较DATA表中的NOTE_ID字段与已删除笔记的ID来实现) private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER = "CREATE TRIGGER delete_data_on_delete " + " AFTER DELETE ON " + TABLE.NOTE + @@ -238,11 +186,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Delete notes belong to folder which has been deleted */ - // 功能简介: - // 添加触发器:当从NOTE表中删除一个文件夹时,删除该文件夹下的所有笔记。 - // 解读: - // 在NOTE表上进行DELETE操作后,如果删除的是一个文件夹(由old.ID表示) - // 触发器会删除所有以该文件夹为父级(PARENT_ID)的笔记(通过比较NOTE表中的PARENT_ID字段与已删除文件夹的ID来实现) private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER = "CREATE TRIGGER folder_delete_notes_on_delete " + " AFTER DELETE ON " + TABLE.NOTE + @@ -254,11 +197,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * Move notes belong to folder which has been moved to trash folder */ - // 功能简介: - // 添加触发器:当某个文件夹被移动到回收站时,移动该文件夹下的所有笔记到回收站 - // 解读: - // 在NOTE表上进行UPDATE操作后,如果某个文件夹的新PARENT_ID字段值等于回收站的ID(Notes.ID_TRASH_FOLER) - // 触发器会更新所有以该文件夹为父级(PARENT_ID)的笔记,将它们也移动到回收站。 private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER = "CREATE TRIGGER folder_move_notes_on_trash " + " AFTER UPDATE ON " + TABLE.NOTE + @@ -269,12 +207,10 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + " END"; - // 构造器 public NotesDatabaseHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } - // 创建note(标签)表 public void createNoteTable(SQLiteDatabase db) { db.execSQL(CREATE_NOTE_TABLE_SQL); reCreateNoteTableTriggers(db); @@ -282,9 +218,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { Log.d(TAG, "note table has been created"); } - // 重新创建或更新与笔记表相关的触发器。 - // 首先,使用DROP TRIGGER IF EXISTS语句删除已存在的触发器。确保在重新创建触发器之前,不存在同名的触发器。 - // 然后,使用db.execSQL()方法执行预定义的SQL语句,这些语句用于创建新的触发器。 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"); @@ -303,17 +236,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER); } - /* 以下部分是操作SQLite数据库部分 */ - // 功能简介: - // 创建通话记录文件夹、默认文件夹、临时文件夹和回收站,并插入相关数据 - // 具体解读: - // ContentValues是一个用于存储键值对的类,常用于SQLite数据库的插入操作 - // values.put方法可以向ContentValues对象中添加数据。 - // NoteColumns.ID是存储文件夹ID的列名,Notes.ID_CALL_RECORD_FOLDER是通话记录文件夹的ID。 - // NoteColumns.TYPE是存储文件夹类型的列名,Notes.TYPE_SYSTEM表示这是一个系统文件夹。 - // 使用db.insert方法将values中的数据插入到TABLE.NOTE(即标签表)中。 - // 每次插入新数据前,都使用values.clear()方法清除ContentValues对象中的旧数据,确保不会重复插入旧数据。 - // 然后分别创建默认文件夹、临时文件夹和回收站,并以同样的方法插入数据。 private void createSystemFolder(SQLiteDatabase db) { ContentValues values = new ContentValues(); @@ -327,7 +249,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * root folder which is default folder */ - // 创建默认文件夹:重复上述步骤,但这次是为根文件夹插入数据。 values.clear(); values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER); values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); @@ -336,7 +257,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * temporary folder which is used for moving note */ - // 创建“临时”文件夹:同样地,为临时文件夹插入数据。 values.clear(); values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER); values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); @@ -345,21 +265,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { /** * create trash folder */ - // 创建“回收站”文件夹:最后,为回收站文件夹插入数据。 values.clear(); values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); db.insert(TABLE.NOTE, null, values); } - //功能简介: - //创建data(数据)表 - //解读: - //这个方法用于创建数据表,以及与之相关的触发器。 - //创建数据表:使用db.execSQL方法执行预定义的SQL语句CREATE_DATA_TABLE_SQL,用于创建数据表。 - //重新创建数据表触发器:调用reCreateDataTableTriggers方法,用于删除并重新创建与数据表相关的触发器。 - //创建索引:使用db.execSQL方法执行CREATE_DATA_NOTE_ID_INDEX_SQL语句,为数据表创建索引。 - //记录日志:使用Log.d方法记录一条调试级别的日志,表示数据表已经创建。 public void createDataTable(SQLiteDatabase db) { db.execSQL(CREATE_DATA_TABLE_SQL); reCreateDataTableTriggers(db); @@ -367,10 +278,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { Log.d(TAG, "data table has been created"); } - //和上面的note表的reCreate...同理 - //重新创建或更新与笔记表相关的触发器。 - //首先,使用DROP TRIGGER IF EXISTS语句删除已存在的触发器。确保在重新创建触发器之前,不存在同名的触发器。 - //然后,使用db.execSQL()方法执行预定义的SQL语句,这些语句用于创建新的触发器。 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"); @@ -381,11 +288,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER); } - //解读: - //synchronized关键字确保在多线程环境下,只有一个线程能够进入这个方法,防止了同时创建多个实例的情况 - //getInstance(Context context)方法使用了单例模式来确保整个应用程序中只有一个NotesDatabaseHelper实例。 - //它首先检查mInstance(类的静态成员变量,没有在代码片段中显示)是否为null。 - //如果是null,则创建一个新的NotesDatabaseHelper实例,并将其赋值给mInstance。最后返回mInstance。 static synchronized NotesDatabaseHelper getInstance(Context context) { if (mInstance == null) { mInstance = new NotesDatabaseHelper(context); @@ -393,19 +295,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { return mInstance; } - //功能简介: - //当数据库首次创建时,onCreate方法会被调用。 - //这里重写onCreate方法,它调用了上述createNoteTable(db)和createDataTable(db)两个方法 - //这样首次创建数据库时就多出了两张表。 @Override public void onCreate(SQLiteDatabase db) { createNoteTable(db); createDataTable(db); } - //功能简介: - //当数据库需要升级时(即数据库的版本号改变),onUpgrade方法会被调用。 - //该方法会根据当前的oldVersion和新的newVersion来执行相应的升级操作 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { boolean reCreateTriggers = false; @@ -433,17 +328,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { reCreateDataTableTriggers(db); } - if (oldVersion != newVersion) { //数据库升级失败,抛出一个异常,表示数据库升级失败 + if (oldVersion != newVersion) { throw new IllegalStateException("Upgrade notes database to version " + newVersion + "fails"); } } - //功能简介: - // 将数据库从版本1升级到版本2。 - //解读: - // 首先,它删除了已经存在的NOTE和DATA表(如果存在的话)。DROP TABLE IF EXISTS语句确保了即使这些表不存在,也不会抛出错误。 - // 然后,它调用了createNoteTable(db)和createDataTable(db)方法来重新创建这两个表。这意味着在升级到版本2时,这两个表的内容会被完全清除,并重新创建新的空表。 private void upgradeToV2(SQLiteDatabase db) { db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); @@ -451,12 +341,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { createDataTable(db); } - //功能简介: - // 将数据库从版本2(或可能是跳过版本2的某个状态)升级到版本3。 - //解读: - // 首先,删除了三个不再使用的触发器(如果存在的话)。触发器是数据库中的一种对象,可以在插入、更新或删除记录时自动执行某些操作。 - // 然后,使用ALTER TABLE语句修改表结构,向NOTE表中添加了一个名为GTASK_ID的新列,并设置默认值为空字符串。 - // 最后,向NOTE表中插入了一条新的系统文件夹记录,表示一个名为“trash folder”的系统文件夹。这可能是用于存储已删除笔记的回收站功能。 private void upgradeToV3(SQLiteDatabase db) { // drop unused triggers db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); @@ -472,12 +356,8 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.insert(TABLE.NOTE, null, values); } - //功能简介: - // 这个方法负责将数据库从版本3升级到版本4。 - //解读: - // 它向NOTE表中添加了一个名为VERSION的新列,并设置了默认值为0。这个新列用于记录标签版本信息。 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/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java b/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java index 3be3da2..71a1d47 100644 --- a/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java +++ b/Notesmaster/app/src/main/java/net/micode/notes/data/NotesProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -//NotesProvider的主要功能是作为一个内容提供者,为其他应用程序或组件提供对“Notes”数据的访问。它允许其他应用程序查询、插入、更新或删除标签数据。 + package net.micode.notes.data; @@ -36,24 +36,12 @@ import net.micode.notes.data.NotesDatabaseHelper.TABLE; public class NotesProvider extends ContentProvider { -// Android 应用程序中的一部分:内容提供者(ContentProvider)。 -// 内容提供者是 Android 四大组件之一,它允许应用程序之间共享数据。 - - //概述: - //NotesProvider的主要功能是作为一个内容提供者,为其他应用程序或组件提供对“Notes”数据的访问。 - //它允许其他应用程序查询、插入、更新或删除标签数据。 - //通过URI匹配,NotesProvider能够区分对哪种数据类型的请求(例如,单独的标签、标签的数据、文件夹操作等),并执行相应的操作。 - - //用于匹配不同URI的UriMatcher对象,通常用于解析传入的URI,并确定应该执行哪种操作。 private static final UriMatcher mMatcher; - //NotesDatabaseHelper实类,用来操作SQLite数据库,负责创建、更新和查询数据库。 private NotesDatabaseHelper mHelper; - //标签,输出日志时用来表示是该类发出的消息 private static final String TAG = "NotesProvider"; - //6个URI的匹配码,用于区分不同的URI类型 private static final int URI_NOTE = 1; private static final int URI_NOTE_ITEM = 2; private static final int URI_DATA = 3; @@ -62,23 +50,13 @@ public class NotesProvider extends ContentProvider { private static final int URI_SEARCH = 5; private static final int URI_SEARCH_SUGGEST = 6; - //进一步定义了URI匹配规则和搜索查询的投影 - //功能概述: - //初始化了一个UriMatcher对象mMatcher,并添加了一系列的URI匹配规则。 - //解读: static { - //创建了一个UriMatcher实例,并设置默认匹配码为NO_MATCH,表示如果没有任何URI匹配,则返回这个码。 mMatcher = new UriMatcher(UriMatcher.NO_MATCH); - //添加规则,当URI的authority为Notes.AUTHORITY,路径为note时,返回匹配码URI_NOTE。 mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); - //添加规则,当URI的authority为Notes.AUTHORITY,路径为note/后跟一个数字(#代表数字)时,返回匹配码URI_NOTE_ITEM。 mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); - //和上面两句同理,但用于匹配数据相关的URI mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); - //用于匹配搜索相关的URI mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); - //这两行用于匹配搜索建议相关的URI mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); } @@ -87,17 +65,7 @@ public class NotesProvider extends ContentProvider { * 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. */ - //功能概述: - //一个 SQL 查询的投影部分,用于定义查询返回的结果集中应该包含哪些列。 - //解读:(每行对应) - //返回笔记的 ID。 - //笔记的 ID 也被重命名为 SUGGEST_COLUMN_INTENT_EXTRA_DATA,这通常用于 Android 的搜索建议中,作为传递给相关 Intent 的额外数据。 - //对 SNIPPET 列的处理:首先使用 REPLACE 函数将 x'0A'(即换行符 \n)替换为空字符串,然后使用 TRIM 函数删除前后的空白字符,处理后的结果分别重命名为 SUGGEST_COLUMN_TEXT_1 - //对 SNIPPET 列的处理:首先使用 REPLACE 函数将 x'0A'(即换行符 \n)替换为空字符串,然后使用 TRIM 函数删除前后的空白字符,处理后的结果分别重命名为 SUGGEST_COLUMN_TEXT_2 - //返回一个用于搜索建议图标的资源 ID,并命名为 SUGGEST_COLUMN_ICON_1。 - //返回一个固定的 Intent 动作 ACTION_VIEW,并命名为 SUGGEST_COLUMN_INTENT_ACTION。 - //返回一个内容类型,并命名为 SUGGEST_COLUMN_INTENT_DATA。 - private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," //返回笔记的 ID + 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 + "," @@ -105,48 +73,25 @@ public class NotesProvider extends ContentProvider { + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; - //功能概述: - //完整的 SQL 查询语句,用于从 TABLE.NOTE 表中检索信息 - //解读: - // 使用上面定义的投影来选择数据。 - // 并指定从哪个表中选择数据。 - //WHERE子句包含三个条件: - // ①搜索 SNIPPET 列中包含特定模式的行(? 是一个占位符,实际查询时会用具体的值替换)。 - // ②父ID不为回收站的ID:排除那些父 ID 为回收站的行。 - // ③只选择类型为note(标签)的行。 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; - //重写onCreate方法: - //getContext() 方法被调用以获取当前组件的上下文(Context),以便 NotesDatabaseHelper 能够访问应用程序的资源和其他功能 - //mHelper用于存储从 NotesDatabaseHelper.getInstance 方法返回的实例。这样,该实例就可以在整个组件的其他方法中被访问和使用。 @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,用来存储查询结果 - //使用 NotesDatabaseHelper 的实例 mHelper来获取一个可读的数据库实例 - //定义一个字符串id,用来存储从URI中解析出的ID Cursor c = null; SQLiteDatabase db = mHelper.getReadableDatabase(); String id = null; - - //根据匹配不同的URI来进行不同的查询 switch (mMatcher.match(uri)) { - // URI_NOTE:查询整个 NOTE 表。 - // URI_NOTE_ITEM:查询 NOTE 表中的特定项。ID 从 URI 的路径段中获取,并添加到查询条件中。 - // URI_DATA:查询整个 DATA 表。 - // URI_DATA_ITEM:查询 DATA 表中的特定项。ID 的获取和处理方式与 URI_NOTE_ITEM 相同。 case URI_NOTE: c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, sortOrder); @@ -165,12 +110,6 @@ public class NotesProvider extends ContentProvider { c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs, null, null, sortOrder); break; - - //URI_SEARCH 和 URI_SEARCH_SUGGEST:处理搜索查询。 - // 代码首先检查是否提供了不应与搜索查询一起使用的参数(如 sortOrder, selection, selectionArgs, 或 projection)。 - // 如果提供了这些参数,则抛出一个 IllegalArgumentException。 - // 根据 URI 类型,从 URI 的路径段或查询参数中获取搜索字符串 searchString。 - // 如果 searchString 为空或无效,则返回 null,表示没有搜索结果。 case URI_SEARCH: case URI_SEARCH_SUGGEST: if (sortOrder != null || projection != null) { @@ -191,8 +130,6 @@ public class NotesProvider extends ContentProvider { return null; } - //字符串格式化:格式化后的字符串就会是 "%s%",即包含s是任何文本 - //然后执行原始SQL查询 try { searchString = String.format("%%%s%%", searchString); c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, @@ -201,31 +138,19 @@ public class NotesProvider extends ContentProvider { Log.e(TAG, "got exception: " + ex.toString()); } break; - - //未知URI处理: default: throw new IllegalArgumentException("Unknown URI " + uri); } - //如果查询结果不为空(即 Cursor 对象 c 不是 null),则为其设置一个通知 URI。 - //这意味着当与这个 URI 关联的数据发生变化时,任何注册了监听这个 URI 的 ContentObserver 都会被通知。 if (c != null) { c.setNotificationUri(getContext().getContentResolver(), uri); } return c; } - //功能:插入数据 - //参数:Uri 用来标识要插入数据的表,ContentValues对象包含要插入的键值对 @Override public Uri insert(Uri uri, ContentValues values) { - //获取数据库 - //三个长整型变量,分别用来存储数据项ID、便签ID 和插入行的ID SQLiteDatabase db = mHelper.getWritableDatabase(); long dataId = 0, noteId = 0, insertedId = 0; - - //对于 URI_NOTE,将values插入到 TABLE.NOTE 表中,并返回插入行的 ID。 - //对于 URI_DATA,首先检查values是否包含 DataColumns.NOTE_ID,如果包含,则获取其值。如果不包含,记录一条日志信息。然后,将 values 插入到 TABLE.DATA 表中,并返回插入行的 ID。 - //如果 uri 不是已知的 URI 类型,则抛出一个 IllegalArgumentException。 switch (mMatcher.match(uri)) { case URI_NOTE: insertedId = noteId = db.insert(TABLE.NOTE, null, values); @@ -241,10 +166,6 @@ public class NotesProvider extends ContentProvider { default: throw new IllegalArgumentException("Unknown URI " + uri); } - - //功能:通知变化 - //如果noteId 或 dataId 大于 0(即成功插入了数据),则使用 ContentResolver 的 notifyChange 方法通知监听这些 URI 的观察者,告知数据已经改变。 - //ContentUris.withAppendedId 方法用于在基本 URI 后面追加一个 ID,形成完整的 URI。 // Notify the note uri if (noteId > 0) { getContext().getContentResolver().notifyChange( @@ -257,28 +178,16 @@ public class NotesProvider extends ContentProvider { ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); } - //返回包含新插入数据项ID 的 Uri。允许调用者知道新插入的数据项的位置 return ContentUris.withAppendedId(uri, insertedId); } - //功能:删除数据项 - //参数:uri:标识要删除数据的表或数据项。 selection:一个可选的 WHERE 子句,用于指定删除条件。 selectionArgs:一个可选的字符串数组,用于替换 selection 中的占位符 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { - //count:记录被删除的行数。 - //id:用于存储从 URI 中解析出的数据项 ID。 - //db:可写的数据库对象,用于执行删除操作。 - //deleteData:一个布尔值,用于标记是否删除了 DATA 表中的数据。 int count = 0; String id = null; SQLiteDatabase db = mHelper.getWritableDatabase(); boolean deleteData = false; - switch (mMatcher.match(uri)) { - //URI_NOTE: 修改 selection 语句:确保只删除 ID 大于 0 的笔记。然后执行删除操作并返回被删除的行数。 - //URI_NOTE_ITEM: 从 URI 中解析出 ID。检查 ID 是否小于等于 0,如果是,则不执行删除操作;否则执行删除操作并返回被删除的行数 - //URI_DATA: 执行删除操作并返回被删除的行数。设置 deleteData 为 true,表示删除了 DATA 表中的数据。 - //URI_DATA_ITEM: 先从 URI 中解析出 ID,然后执行删除操作并返回被删除的行数,并设置 deleteData 为 true,表示删除了 DATA 表中的数据。 case URI_NOTE: selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; count = db.delete(TABLE.NOTE, selection, selectionArgs); @@ -309,39 +218,22 @@ public class NotesProvider extends ContentProvider { default: throw new IllegalArgumentException("Unknown URI " + uri); } - - //如果 count 大于 0,说明有数据被删除。 - //如果 deleteData 为 true,则通知监听 Notes.CONTENT_NOTE_URI 的观察者,数据已改变。 - //通知监听传入 uri 的观察者数据已改变。 if (count > 0) { if (deleteData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); } getContext().getContentResolver().notifyChange(uri, null); } - return count; } - //功能:更新数据库的数据 - //参数:uri:标识要更新数据的表或数据项。 values:一个包含新值的键值对集合。 - // selection:一个可选的 WHERE 子句,用于指定更新条件。 selectionArgs:一个可选的字符串数组,用于替换 selection 中的占位符。 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - //count:记录被更新的行数。 - //id:用于存储从 URI 中解析出的数据项 ID。 - //db:可写的 SQLite 数据库对象,用于执行更新操作。 - //updateData:用于标记是否更新了 data 表中的数据。 int count = 0; String id = null; SQLiteDatabase db = mHelper.getWritableDatabase(); boolean updateData = false; - switch (mMatcher.match(uri)) { - //URI_NOTE:调用 increaseNoteVersion 方法(用于增加便签版本),然后在note表执行更新操作并返回被更新的行数。 - //URI_NOTE_ITEM:从 URI 中解析出 ID,并调用 increaseNoteVersion 方法,传入解析出的 ID,最后在note表执行更新操作并返回被更新的行数。 - //URI_DATA:在data表执行更新操作并返回被更新的行数。设置 updateData 为 true,表示更新了 DATA 表中的数据。 - //URI_DATA_ITEM:从 URI 中解析出 ID。执行更新操作并返回被更新的行数。置 updateData 为 true,表示更新了 DATA 表中的数据。 case URI_NOTE: increaseNoteVersion(-1, selection, selectionArgs); count = db.update(TABLE.NOTE, values, selection, selectionArgs); @@ -366,9 +258,6 @@ public class NotesProvider extends ContentProvider { throw new IllegalArgumentException("Unknown URI " + uri); } - //如果 count 大于 0,说明有数据被更新。 - //如果 updateData 为 true,则通知监听 Notes.CONTENT_NOTE_URI 的观察者数据已改变。 - //通知监听传入 uri 的观察者数据已改变。 if (count > 0) { if (updateData) { getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); @@ -378,12 +267,10 @@ public class NotesProvider extends ContentProvider { return count; } - //解析传入的条件语句:一个 SQL WHERE 子句的一部分 private String parseSelection(String selection) { return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); } - //更新note表的version列,将其值增加 1。 private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { StringBuilder sql = new StringBuilder(120); sql.append("UPDATE "); @@ -415,4 +302,4 @@ public class NotesProvider extends ContentProvider { return null; } -} \ No newline at end of file +} diff --git a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java index ec41adc..919a5d4 100644 --- a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java +++ b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/MetaData.java @@ -24,103 +24,100 @@ import net.micode.notes.tool.GTaskStringUtils; import org.json.JSONException; import org.json.JSONObject; - +/** + * MetaData类继承自Task类,用于管理任务的元数据。 + * 该类提供了设置和获取与任务相关的GID的方法,以及处理远程JSON内容的方法。 + */ public class MetaData extends Task { - /* - * 功能描述:得到类的简写名称存入字符串TAG中 - * 实现过程:调用getSimpleName ()函数 - */ + // 日志标签,用于调试输出 private final static String TAG = MetaData.class.getSimpleName(); + // 相关的GID private String mRelatedGid = null; - /* - * 功能描述:设置数据,即生成元数据库 - * 实现过程:调用JSONObject库函数put (),Task类中的setNotes ()和setName ()函数 - * 参数注解: + /** + * 设置元数据 + * @param gid 任务的GID + * @param metaInfo 元数据的JSON对象 */ public void setMeta(String gid, JSONObject metaInfo) { try { + // 将GID添加到元数据JSON对象中 metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); - /* - * 将这对键值放入metaInfo这个jsonobject对象中 - */ } catch (JSONException e) { + // 输出错误日志 Log.e(TAG, "failed to put related gid"); - /* - * 输出错误信息 - */ } + // 将元数据转换为字符串并设置为任务的备注 setNotes(metaInfo.toString()); + // 设置任务名称 setName(GTaskStringUtils.META_NOTE_NAME); } - /* - * 功能描述:获取相关联的Gid + /** + * 获取相关的GID + * @return 相关的GID */ public String getRelatedGid() { return mRelatedGid; } + /** + * 判断任务是否值得保存 + * @return 如果任务的备注不为空,则返回true;否则返回false + */ @Override public boolean isWorthSaving() { return getNotes() != null; } - /* - * 功能描述:使用远程json数据对象设置元数据内容 - * 实现过程:调用父类Task中的setContentByRemoteJSON ()函数,并 - * 参数注解: + /** + * 通过远程JSON内容设置任务内容 + * @param js 远程JSON对象 */ @Override public void setContentByRemoteJSON(JSONObject js) { super.setContentByRemoteJSON(js); if (getNotes() != null) { try { + // 解析备注中的元数据JSON对象 JSONObject metaInfo = new JSONObject(getNotes().trim()); + // 获取元数据中的GID mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); } catch (JSONException e) { + // 输出警告日志 Log.w(TAG, "failed to get related gid"); mRelatedGid = null; } } } - /* - * 功能描述:使用本地json数据对象设置元数据内容,一般不会用到,若用到,则抛出异常 + + /** + * 禁止通过本地JSON内容设置任务内容 + * @param js 本地JSON对象 */ @Override public void setContentByLocalJSON(JSONObject js) { - // this function should not be called + // 此方法不应被调用 throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); - - /* - * 传递非法参数异常 - */ - } - /* - * 功能描述:从元数据内容中获取本地json对象,一般不会用到,若用到,则抛出异常 + /** + * 禁止从任务内容中获取本地JSON对象 + * @return 本地JSON对象 */ @Override public JSONObject getLocalJSONFromContent() { throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); - - /* - * 传递非法参数异常 - */ - } - /* - * 功能描述:获取同步动作状态,一般不会用到,若用到,则抛出异常 + + /** + * 禁止获取同步动作 + * @param c 游标对象 + * @return 同步动作 */ @Override public int getSyncAction(Cursor c) { throw new IllegalAccessError("MetaData:getSyncAction should not be called"); - /* - * 传递非法参数异常 - */ - } - } diff --git a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java index 9bc7f75..fdee51f 100644 --- a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java +++ b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/Node.java @@ -21,37 +21,37 @@ import android.database.Cursor; import org.json.JSONObject; /** - * 应该是同步操作的基础数据类型,定义了相关指示同步操作的常量 - * 关键字:abstract + * Node类是一个抽象类,用于表示任务节点。 + * 该类定义了任务节点的基本属性和操作,包括同步动作的常量、任务节点的GID、名称、最后修改时间、删除状态等。 + * 具体的任务节点需要继承该类并实现抽象方法。 */ public abstract class Node { - //定义了各种用于表征同步状态的常量 - public static final int SYNC_ACTION_NONE = 0;// 本地和云端都无可更新内容(即本地和云端内容一致) - - public static final int SYNC_ACTION_ADD_REMOTE = 1;// 需要在远程云端增加内容 - - public static final int SYNC_ACTION_ADD_LOCAL = 2;// 需要在本地增加内容 - - public static final int SYNC_ACTION_DEL_REMOTE = 3;// 需要在远程云端删除内容 - - public static final int SYNC_ACTION_DEL_LOCAL = 4;// 需要在本地删除内容 - - public static final int SYNC_ACTION_UPDATE_REMOTE = 5;// 需要将本地内容更新到远程云端 - - public static final int SYNC_ACTION_UPDATE_LOCAL = 6;// 需要将远程云端内容更新到本地 - - public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;// 同步出现冲突 - - public static final int SYNC_ACTION_ERROR = 8;// 同步出现错误 - + // 同步动作的常量 + public static final int SYNC_ACTION_NONE = 0; + public static final int SYNC_ACTION_ADD_REMOTE = 1; + public static final int SYNC_ACTION_ADD_LOCAL = 2; + public static final int SYNC_ACTION_DEL_REMOTE = 3; + public static final int SYNC_ACTION_DEL_LOCAL = 4; + public static final int SYNC_ACTION_UPDATE_REMOTE = 5; + public static final int SYNC_ACTION_UPDATE_LOCAL = 6; + public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; + public static final int SYNC_ACTION_ERROR = 8; + + // 任务节点的GID private String mGid; + // 任务节点的名称 private String mName; - private long mLastModified;//记录最后一次修改时间 + // 任务节点的最后修改时间 + private long mLastModified; - private boolean mDeleted;//表征是否被删除 + // 任务节点的删除状态 + private boolean mDeleted; + /** + * Node类的构造函数,初始化任务节点的属性 + */ public Node() { mGid = null; mName = ""; @@ -59,48 +59,107 @@ public abstract class Node { mDeleted = false; } + /** + * 获取创建操作的JSON对象 + * @param actionId 操作ID + * @return 创建操作的JSON对象 + */ public abstract JSONObject getCreateAction(int actionId); + /** + * 获取更新操作的JSON对象 + * @param actionId 操作ID + * @return 更新操作的JSON对象 + */ public abstract JSONObject getUpdateAction(int actionId); + /** + * 通过远程JSON对象设置任务节点的内容 + * @param js 远程JSON对象 + */ public abstract void setContentByRemoteJSON(JSONObject js); + /** + * 通过本地JSON对象设置任务节点的内容 + * @param js 本地JSON对象 + */ public abstract void setContentByLocalJSON(JSONObject js); + /** + * 从任务节点的内容中获取本地JSON对象 + * @return 本地JSON对象 + */ public abstract JSONObject getLocalJSONFromContent(); + /** + * 获取同步动作 + * @param c 游标对象 + * @return 同步动作 + */ public abstract int getSyncAction(Cursor c); + /** + * 设置任务节点的GID + * @param gid 任务节点的GID + */ public void setGid(String gid) { this.mGid = gid; } + /** + * 设置任务节点的名称 + * @param name 任务节点的名称 + */ public void setName(String name) { this.mName = name; } + /** + * 设置任务节点的最后修改时间 + * @param lastModified 任务节点的最后修改时间 + */ public void setLastModified(long lastModified) { this.mLastModified = lastModified; } + /** + * 设置任务节点的删除状态 + * @param deleted 任务节点的删除状态 + */ public void setDeleted(boolean deleted) { this.mDeleted = deleted; } + /** + * 获取任务节点的GID + * @return 任务节点的GID + */ public String getGid() { return this.mGid; } + /** + * 获取任务节点的名称 + * @return 任务节点的名称 + */ public String getName() { return this.mName; } + /** + * 获取任务节点的最后修改时间 + * @return 任务节点的最后修改时间 + */ public long getLastModified() { return this.mLastModified; } + /** + * 获取任务节点的删除状态 + * @return 任务节点的删除状态 + */ public boolean getDeleted() { return this.mDeleted; } -} \ No newline at end of file +} diff --git a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java index 94ee5f0..85e4d5b 100644 --- a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java +++ b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlData.java @@ -14,14 +14,8 @@ * limitations under the License. */ -/* - * Description:用于支持小米便签最底层的数据库相关操作,和sqldata的关系上是父集关系,即note是data的子父集。 - * 和SqlData相比,SqlNote算是真正意义上的数据了。 - */ - package net.micode.notes.gtask.data; - import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -40,62 +34,50 @@ import net.micode.notes.gtask.exception.ActionFailureException; import org.json.JSONException; import org.json.JSONObject; - +/** + * SqlData类用于处理数据库中的笔记数据。 + * 该类提供了从数据库加载数据、设置数据内容、获取数据内容以及提交数据的功能。 + */ public class SqlData { - /* - * 功能描述:得到类的简写名称存入字符串TAG中 - * 实现过程:调用getSimpleName ()函数 - */ + // 日志标签,用于调试输出 private static final String TAG = SqlData.class.getSimpleName(); - private static final int INVALID_ID = -99999;//为mDataId置初始值-99999 - - /** - * 来自Notes类中定义的DataColumn中的一些常量 - */ + // 无效的ID常量 + private static final int INVALID_ID = -99999; - // 集合了interface DataColumns中所有SF常量 + // 数据表的字段投影 public static final String[] PROJECTION_DATA = new String[] { DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.DATA3 }; - /** - * 以下五个变量作为sql表中5列的编号 - */ + // 数据表字段的列索引 public static final int DATA_ID_COLUMN = 0; - public static final int DATA_MIME_TYPE_COLUMN = 1; - public static final int DATA_CONTENT_COLUMN = 2; - public static final int DATA_CONTENT_DATA_1_COLUMN = 3; - public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + // 内容解析器,用于访问内容提供者的数据 private ContentResolver mContentResolver; - //判断是否直接用Content生成,是为true,否则为false + // 标识数据是否为新创建的 private boolean mIsCreate; + // 数据的各个字段 private long mDataId; - private String mDataMimeType; - private String mDataContent; - private long mDataContentData1; - private String mDataContentData3; + // 存储数据变更的内容值 private ContentValues mDiffDataValues; - /* - * 功能描述:构造函数,用于初始化数据 - * 参数注解:mContentResolver用于获取ContentProvider提供的数据 - * 参数注解: mIsCreate表征当前数据是用哪种方式创建(两种构造函数的参数不同) - * 参数注解: - */ + /** + * SqlData类的构造函数,用于新创建的数据 + * @param context 应用上下文 + */ public SqlData(Context context) { mContentResolver = context.getContentResolver(); mIsCreate = true; @@ -106,11 +88,11 @@ public class SqlData { mDataContentData3 = ""; mDiffDataValues = new ContentValues(); } - /* - * 功能描述:构造函数,初始化数据 - * 参数注解:mContentResolver用于获取ContentProvider提供的数据 - * 参数注解: mIsCreate表征当前数据是用哪种方式创建(两种构造函数的参数不同) - * 参数注解: + + /** + * SqlData类的构造函数,用于从数据库加载的数据 + * @param context 应用上下文 + * @param c 游标对象,指向加载的数据 */ public SqlData(Context context, Cursor c) { mContentResolver = context.getContentResolver(); @@ -118,9 +100,10 @@ public class SqlData { loadFromCursor(c); mDiffDataValues = new ContentValues(); } - /* - * 功能描述:从光标处加载数据 - * 从当前的光标处将五列的数据加载到该类的对象 + + /** + * 从游标加载数据 + * @param c 游标对象,指向加载的数据 */ private void loadFromCursor(Cursor c) { mDataId = c.getLong(DATA_ID_COLUMN); @@ -129,12 +112,13 @@ public class SqlData { mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); } - /* - * 功能描述:设置用于共享的数据,并提供异常抛出与处理机制 - * 参数注解: + + /** + * 设置数据内容 + * @param js JSON对象,包含数据内容 + * @throws JSONException 如果JSON解析错误 */ public void setContent(JSONObject js) throws JSONException { - //如果传入的JSONObject对象中有DataColumns.ID这一项,则设置,否则设为INVALID_ID long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; if (mIsCreate || mDataId != dataId) { mDiffDataValues.put(DataColumns.ID, dataId); @@ -167,17 +151,16 @@ public class SqlData { mDataContentData3 = dataContentData3; } - /* - * 功能描述:获取共享的数据内容,并提供异常抛出与处理机制 - * 参数注解: + /** + * 获取数据内容 + * @return JSON对象,包含数据内容 + * @throws JSONException 如果JSON解析错误 */ - public JSONObject getContent() throws JSONException { if (mIsCreate) { Log.e(TAG, "it seems that we haven't created this in database yet"); return null; } - //创建JSONObject对象。并将相关数据放入其中,并返回。 JSONObject js = new JSONObject(); js.put(DataColumns.ID, mDataId); js.put(DataColumns.MIME_TYPE, mDataMimeType); @@ -186,20 +169,27 @@ public class SqlData { js.put(DataColumns.DATA3, mDataContentData3); return js; } - /* - * 功能描述:commit函数用于把当前造作所做的修改保存到数据库 - * 参数注解: + + /** + * 提交数据到数据库 + * @param noteId 笔记ID + * @param validateVersion 是否验证版本 + * @param version 版本号 */ public void commit(long noteId, boolean validateVersion, long version) { if (mIsCreate) { + // 如果是新创建的数据且ID无效,则移除ID字段 if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { mDiffDataValues.remove(DataColumns.ID); } + // 将笔记ID添加到内容值中 mDiffDataValues.put(DataColumns.NOTE_ID, noteId); + // 插入新数据 Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); try { + // 从插入结果的URI中获取数据ID mDataId = Long.valueOf(uri.getPathSegments().get(1)); } catch (NumberFormatException e) { Log.e(TAG, "Get note id error :" + e.toString()); @@ -209,11 +199,13 @@ public class SqlData { if (mDiffDataValues.size() > 0) { int result = 0; if (!validateVersion) { + // 更新数据 result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); } else { + // 更新数据并验证版本 result = mContentResolver.update(ContentUris.withAppendedId( - Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE + " WHERE " + NoteColumns.VERSION + "=?)", new String[] { String.valueOf(noteId), String.valueOf(version) @@ -225,13 +217,14 @@ public class SqlData { } } + // 清空变更内容值并重置创建标识 mDiffDataValues.clear(); mIsCreate = false; } - /* - * 功能描述:获取当前id - * 实现过程: - * 参数注解: + + /** + * 获取数据ID + * @return 数据ID */ public long getId() { return mDataId; diff --git a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java index 89a551d..6e6039f 100644 --- a/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java +++ b/Notesmaster/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java @@ -37,21 +37,18 @@ import org.json.JSONObject; import java.util.ArrayList; -/* - * Description:用于支持小米便签最底层的数据库相关操作,和sqldata的关系上是父集关系,即note是data的子父集。 - * 和SqlData相比,SqlNote算是真正意义上的数据了。 +/** + * SqlNote类用于处理数据库中的笔记数据。 + * 该类提供了从数据库加载笔记、设置笔记内容、获取笔记内容以及提交笔记的功能。 */ - - public class SqlNote { - /* - * 功能描述:得到类的简写名称存入字符串TAG中 - * 实现过程:调用getSimpleName ()函数 - */ + // 日志标签,用于调试输出 private static final String TAG = SqlNote.class.getSimpleName(); + // 无效的ID常量 private static final int INVALID_ID = -99999; - // 集合了interface NoteColumns中所有SF常量(17个) + + // 笔记表的字段投影 public static final String[] PROJECTION_NOTE = new String[] { NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, @@ -61,84 +58,59 @@ public class SqlNote { NoteColumns.VERSION }; - //以下设置17个列的编号 + // 笔记表字段的列索引 public static final int ID_COLUMN = 0; - public static final int ALERTED_DATE_COLUMN = 1; - public static final int BG_COLOR_ID_COLUMN = 2; - public static final int CREATED_DATE_COLUMN = 3; - public static final int HAS_ATTACHMENT_COLUMN = 4; - public static final int MODIFIED_DATE_COLUMN = 5; - public static final int NOTES_COUNT_COLUMN = 6; - public static final int PARENT_ID_COLUMN = 7; - public static final int SNIPPET_COLUMN = 8; - public static final int TYPE_COLUMN = 9; - public static final int WIDGET_ID_COLUMN = 10; - public static final int WIDGET_TYPE_COLUMN = 11; - public static final int SYNC_ID_COLUMN = 12; - public static final int LOCAL_MODIFIED_COLUMN = 13; - public static final int ORIGIN_PARENT_ID_COLUMN = 14; - public static final int GTASK_ID_COLUMN = 15; - public static final int VERSION_COLUMN = 16; - //一下定义了17个内部的变量,其中12个可以由content中获得,5个需要初始化为0或者new + // 应用上下文 private Context mContext; + // 内容解析器,用于访问内容提供者的数据 private ContentResolver mContentResolver; + // 标识笔记是否为新创建的 private boolean mIsCreate; + // 笔记的各个字段 private long mId; - private long mAlertDate; - private int mBgColorId; - private long mCreatedDate; - private int mHasAttachment; - private long mModifiedDate; - private long mParentId; - private String mSnippet; - private int mType; - private int mWidgetId; - private int mWidgetType; - private long mOriginParent; - private long mVersion; + // 存储笔记变更的内容值 private ContentValues mDiffNoteValues; + // 笔记的数据列表 private ArrayListBV@9+aN-UL8hjvH$@(0)I|61EjCgd9+q%Z&z}pRJWf2ut1-z
z?=TV@hThDuuGTH+Fl0b5C4-!kQj0DWHl+FLOdUAM3h7jq{VYNk+fN(l&E0SmT8oIy
zs{3cYhZ8cXf~vGz^X|!WP#&`l*tM)22*ykT=4L^{-=={+8}4ZWcQAppVKdGkngd^|
z1%Lk)D|U#n1RL*rAnq^@+Q7M%!Phu#b*2{+(`K@##Q`Ydwn;S5D!g8}H?tl%CqVLD
z0N~sh^OYn_^ReMrMqW$b+q+#JchZ=h^|Tq7!5JX*P3N4~3J&j?8Ota@ZX?}6P}wq*
zrE9D&B9yt)U1NGVJ^0YVs6yWzh!$14sDJOM^3Imtmov`uoB*PlQL(4ZodUvqZ#pJT
zflL{n8b)b)|JjHghmj9vyJX<8u2lmo{i!eybuU>t#bM8Lg5^G+&yfM05@j2{LGBez
zJ5_ZbDc)%Z?1vq8fhbZ1D+ir*&&{3CbrE)SEDiP}5Imdll7$GI7vl6F=32!kqkq24
ztPDA2S9*G|h3jl@=T+DuqO#cKgbTLBs(W*nTJO`7R(vRDaYc0Q7?yx{Jf|1$*&d2xr4k$wPCu?SF?kBdio4{5|%JoP