From c794004641d0fbe8a720e2e327f810ff36dfe81d Mon Sep 17 00:00:00 2001 From: Jyk <1758766792@qq.com> Date: Thu, 24 Apr 2025 09:17:39 +0800 Subject: [PATCH] gtask/data/Node.java gtask/data/SqlData.java --- src/net/micode/notes/gtask/data/Node.java | 102 ++++----- src/net/micode/notes/gtask/data/SqlData.java | 227 +++++++++++-------- 2 files changed, 176 insertions(+), 153 deletions(-) diff --git a/src/net/micode/notes/gtask/data/Node.java b/src/net/micode/notes/gtask/data/Node.java index 63950e0..cb57f42 100644 --- a/src/net/micode/notes/gtask/data/Node.java +++ b/src/net/micode/notes/gtask/data/Node.java @@ -14,88 +14,84 @@ * limitations under the License. */ -package net.micode.notes.gtask.data; +package net.micode.notes.gtask.data; // 包声明,用于将相关类分组 -import android.database.Cursor; +import android.database.Cursor; // 导入 Cursor 类以进行数据库操作 -import org.json.JSONObject; +import org.json.JSONObject; // 导入 JSONObject 以便进行 JSON 操作 +/** + * 表示同步上下文中通用 Node 的抽象类。 + * 此类提供管理笔记或任务在远程/本地数据库上下文中的同步操作的结构。 + */ 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; - - private String mGid; - - private String mName; - - private long mLastModified; - - private boolean mDeleted; + // 常量,表示 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; // 操作错误 + + // 实例变量,表示 Node 的属性 + private String mGid; // Node 的唯一标识符 + private String mName; // Node 的名称或标题 + private long mLastModified; // 最后修改时间的时间戳 + private boolean mDeleted; // 标记 Node 是否已删除的标志 + + /** + * Node 类的构造函数,初始化默认值。 + */ public Node() { - mGid = null; - mName = ""; - mLastModified = 0; - mDeleted = false; + mGid = null; // 初始化 GID 为 null + mName = ""; // 初始化名称为空字符串 + mLastModified = 0; // 初始化最后修改时间为零 + mDeleted = false; // 初始化删除状态为 false } - public abstract JSONObject getCreateAction(int actionId); - - public abstract JSONObject getUpdateAction(int actionId); - - public abstract void setContentByRemoteJSON(JSONObject js); - - public abstract void setContentByLocalJSON(JSONObject js); - - public abstract JSONObject getLocalJSONFromContent(); - - public abstract int getSyncAction(Cursor c); + // 抽象方法,供子类实现特定操作 + public abstract JSONObject getCreateAction(int actionId); // 获取创建操作的 JSON 对象 + public abstract JSONObject getUpdateAction(int actionId); // 获取更新操作的 JSON 对象 + public abstract void setContentByRemoteJSON(JSONObject js); // 根据远程 JSON 设置内容 + public abstract void setContentByLocalJSON(JSONObject js); // 根据本地 JSON 设置内容 + public abstract JSONObject getLocalJSONFromContent(); // 从内容获取本地 JSON + public abstract int getSyncAction(Cursor c); // 从 Cursor 获取同步操作 + // 设置私有字段的 setter 方法 public void setGid(String gid) { - this.mGid = gid; + this.mGid = gid; // 设置唯一标识符 } public void setName(String name) { - this.mName = name; + this.mName = name; // 设置 Node 的名称 } public void setLastModified(long lastModified) { - this.mLastModified = lastModified; + this.mLastModified = lastModified; // 设置最后修改时间戳 } public void setDeleted(boolean deleted) { - this.mDeleted = deleted; + this.mDeleted = deleted; // 设置删除状态 } + // 获取私有字段的 getter 方法 public String getGid() { - return this.mGid; + return this.mGid; // 返回唯一标识符 } public String getName() { - return this.mName; + return this.mName; // 返回 Node 的名称 } public long getLastModified() { - return this.mLastModified; + return this.mLastModified; // 返回最后修改时间戳 } public boolean getDeleted() { - return this.mDeleted; + return this.mDeleted; // 返回删除状态 } - -} +} \ No newline at end of file diff --git a/src/net/micode/notes/gtask/data/SqlData.java b/src/net/micode/notes/gtask/data/SqlData.java index d3ec3be..46ccf2f 100644 --- a/src/net/micode/notes/gtask/data/SqlData.java +++ b/src/net/micode/notes/gtask/data/SqlData.java @@ -14,176 +14,203 @@ * limitations under the License. */ -package net.micode.notes.gtask.data; - -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.util.Log; - -import net.micode.notes.data.Notes; -import net.micode.notes.data.Notes.DataColumns; -import net.micode.notes.data.Notes.DataConstants; -import net.micode.notes.data.Notes.NoteColumns; -import net.micode.notes.data.NotesDatabaseHelper.TABLE; -import net.micode.notes.gtask.exception.ActionFailureException; - -import org.json.JSONException; -import org.json.JSONObject; - - +package net.micode.notes.gtask.data; // 包声明,用于将相关类分组 + +import android.content.ContentResolver; // 导入 ContentResolver 类,用于访问内容提供者 +import android.content.ContentUris; // 导入 ContentUris 类,用于处理内容 URI +import android.content.ContentValues; // 导入 ContentValues 类,用于存储数据 +import android.content.Context; // 导入 Context 类,用于获取应用上下文 +import android.database.Cursor; // 导入 Cursor 类,用于数据库操作 +import android.net.Uri; // 导入 Uri 类,用于处理 URI +import android.util.Log; // 导入 Log 类,用于日志记录 + +import net.micode.notes.data.Notes; // 导入 Notes 类,处理笔记数据 +import net.micode.notes.data.Notes.DataColumns; // 导入数据列常量 +import net.micode.notes.data.Notes.DataConstants; // 导入数据常量 +import net.micode.notes.data.Notes.NoteColumns; // 导入笔记字段常量 +import net.micode.notes.data.NotesDatabaseHelper.TABLE; // 导入表常量 +import net.micode.notes.gtask.exception.ActionFailureException; // 导入自定义异常 + +import org.json.JSONException; // 导入 JSONException 类,用于处理 JSON 异常 +import org.json.JSONObject; // 导入 JSONObject 类,用于 JSON 操作 + +/** + * SqlData 类用于处理数据库中的数据操作。 + * 它提供了从数据库加载、设置内容、提交更改等功能。 + */ public class SqlData { - private static final String TAG = SqlData.class.getSimpleName(); + private static final String TAG = SqlData.class.getSimpleName(); // 日志标签 - private static final int INVALID_ID = -99999; + private static final int INVALID_ID = -99999; // 无效 ID 常量 + // 定义要查询的数据列 public static final String[] PROJECTION_DATA = new String[] { DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.DATA3 }; + // 数据列索引常量 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; - - private boolean mIsCreate; - - private long mDataId; - - private String mDataMimeType; - - private String mDataContent; - - private long mDataContentData1; - - private String mDataContentData3; - - private ContentValues mDiffDataValues; - + private ContentResolver mContentResolver; // 用于访问内容提供者 + private boolean mIsCreate; // 标记是否为新创建数据 + private long mDataId; // 数据 ID + private String mDataMimeType; // 数据 MIME 类型 + private String mDataContent; // 数据内容 + private long mDataContentData1; // 数据内容的附加数据 1 + private String mDataContentData3; // 数据内容的附加数据 3 + private ContentValues mDiffDataValues; // 存储更改的数据值 + + /** + * 构造函数,创建新的 SqlData 对象。 + * @param context 应用程序上下文 + */ public SqlData(Context context) { - mContentResolver = context.getContentResolver(); - mIsCreate = true; - mDataId = INVALID_ID; - mDataMimeType = DataConstants.NOTE; - mDataContent = ""; - mDataContentData1 = 0; - mDataContentData3 = ""; - mDiffDataValues = new ContentValues(); + mContentResolver = context.getContentResolver(); // 获取内容解析器 + mIsCreate = true; // 设置为创建模式 + mDataId = INVALID_ID; // 初始化为无效 ID + mDataMimeType = DataConstants.NOTE; // 默认 MIME 类型为笔记 + mDataContent = ""; // 初始化内容为空 + mDataContentData1 = 0; // 初始化附加数据 1 为 0 + mDataContentData3 = ""; // 初始化附加数据 3 为空 + mDiffDataValues = new ContentValues(); // 初始化更改的数据值容器 } + /** + * 构造函数,根据 Cursor 创建 SqlData 对象。 + * @param context 应用程序上下文 + * @param c 数据游标 + */ public SqlData(Context context, Cursor c) { - mContentResolver = context.getContentResolver(); - mIsCreate = false; - loadFromCursor(c); - mDiffDataValues = new ContentValues(); + mContentResolver = context.getContentResolver(); // 获取内容解析器 + mIsCreate = false; // 设置为加载模式 + loadFromCursor(c); // 从 Cursor 加载数据 + mDiffDataValues = new ContentValues(); // 初始化更改的数据值容器 } + /** + * 从 Cursor 加载数据到 SqlData 对象的属性 + * @param c 数据游标 + */ private void loadFromCursor(Cursor c) { - mDataId = c.getLong(DATA_ID_COLUMN); - mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); - mDataContent = c.getString(DATA_CONTENT_COLUMN); - mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); - mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); + mDataId = c.getLong(DATA_ID_COLUMN); // 加载 ID + mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); // 加载 MIME 类型 + mDataContent = c.getString(DATA_CONTENT_COLUMN); // 加载内容 + mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); // 加载附加数据 1 + mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); // 加载附加数据 3 } + /** + * 从 JSON 对象设置内容。 + * @param js 包含数据的 JSON 对象 + * @throws JSONException JSON 解析异常 + */ public void setContent(JSONObject js) throws JSONException { - long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; + long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; // 解析 ID if (mIsCreate || mDataId != dataId) { - mDiffDataValues.put(DataColumns.ID, dataId); + mDiffDataValues.put(DataColumns.ID, dataId); // 更新 ID } - mDataId = dataId; + mDataId = dataId; // 设置 ID String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE) - : DataConstants.NOTE; + : DataConstants.NOTE; // 解析 MIME 类型 if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { - mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); + mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); // 更新 MIME 类型 } - mDataMimeType = dataMimeType; + mDataMimeType = dataMimeType; // 设置 MIME 类型 - String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; + String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; // 解析内容 if (mIsCreate || !mDataContent.equals(dataContent)) { - mDiffDataValues.put(DataColumns.CONTENT, dataContent); + mDiffDataValues.put(DataColumns.CONTENT, dataContent); // 更新内容 } - mDataContent = dataContent; + mDataContent = dataContent; // 设置内容 - long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; + long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; // 解析附加数据 1 if (mIsCreate || mDataContentData1 != dataContentData1) { - mDiffDataValues.put(DataColumns.DATA1, dataContentData1); + mDiffDataValues.put(DataColumns.DATA1, dataContentData1); // 更新附加数据 1 } - mDataContentData1 = dataContentData1; + mDataContentData1 = dataContentData1; // 设置附加数据 1 - String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; + String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; // 解析附加数据 3 if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { - mDiffDataValues.put(DataColumns.DATA3, dataContentData3); + mDiffDataValues.put(DataColumns.DATA3, dataContentData3); // 更新附加数据 3 } - mDataContentData3 = dataContentData3; + mDataContentData3 = dataContentData3; // 设置附加数据 3 } + /** + * 获取当前内容的 JSON 对象。 + * @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; + Log.e(TAG, "it seems that we haven't created this in database yet"); // 日志警告 + return null; // 返回 null } - JSONObject js = new JSONObject(); - js.put(DataColumns.ID, mDataId); - js.put(DataColumns.MIME_TYPE, mDataMimeType); - js.put(DataColumns.CONTENT, mDataContent); - js.put(DataColumns.DATA1, mDataContentData1); - js.put(DataColumns.DATA3, mDataContentData3); - return js; + JSONObject js = new JSONObject(); // 创建新的 JSON 对象 + js.put(DataColumns.ID, mDataId); // 添加 ID + js.put(DataColumns.MIME_TYPE, mDataMimeType); // 添加 MIME 类型 + js.put(DataColumns.CONTENT, mDataContent); // 添加内容 + js.put(DataColumns.DATA1, mDataContentData1); // 添加附加数据 1 + js.put(DataColumns.DATA3, mDataContentData3); // 添加附加数据 3 + return js; // 返回 JSON 对象 } + /** + * 提交当前数据到数据库。 + * @param noteId 关联的笔记 ID + * @param validateVersion 是否验证版本 + * @param version 当前版本号 + */ public void commit(long noteId, boolean validateVersion, long version) { - if (mIsCreate) { + // 创建新记录时 if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { - mDiffDataValues.remove(DataColumns.ID); + mDiffDataValues.remove(DataColumns.ID); // 移除无效 ID } - mDiffDataValues.put(DataColumns.NOTE_ID, noteId); - Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); + mDiffDataValues.put(DataColumns.NOTE_ID, noteId); // 设置笔记 ID + Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); // 插入数据库 try { - mDataId = Long.valueOf(uri.getPathSegments().get(1)); + mDataId = Long.valueOf(uri.getPathSegments().get(1)); // 从 URI 获取新创建的 ID } catch (NumberFormatException e) { - Log.e(TAG, "Get note id error :" + e.toString()); - throw new ActionFailureException("create note failed"); + Log.e(TAG, "Get note id error :" + e.toString()); // 日志错误 + throw new ActionFailureException("create note failed"); // 抛出异常 } - } else { + } else { // 更新已有记录时 if (mDiffDataValues.size() > 0) { int result = 0; if (!validateVersion) { result = mContentResolver.update(ContentUris.withAppendedId( - Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); + 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) - }); + }); // 验证版本后更新 } if (result == 0) { - Log.w(TAG, "there is no update. maybe user updates note when syncing"); + Log.w(TAG, "there is no update. maybe user updates note when syncing"); // 日志警告 } } } - mDiffDataValues.clear(); - mIsCreate = false; + mDiffDataValues.clear(); // 清空更改的数据值 + mIsCreate = false; // 设置为非创建模式 } + /** + * 获取当前数据 ID。 + * @return 数据 ID + */ public long getId() { - return mDataId; + return mDataId; // 返回数据 ID } -} +} \ No newline at end of file