/* * Copyright (c) 2010 - 2011, The MiCode Open Source Community (www.micode.net) * (版权所有(c)2010 - 2011,MiCode 开源社区(www.micode.net)。) * * Licensed under the Apache License, Version 2.0 (the "License"); * (根据 Apache License 2.0 版(“许可证”)获得许可;) * 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 * (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.gtask.data; // 包 net.micode.notes.gtask.data;(这个包的名字是 net.micode.notes.gtask.data。) import android.content.ContentResolver; // 导入 android.content.ContentResolver;(导入 Android 的内容解析器类。) import android.content.ContentUris; // 导入 android.content.ContentUris;(导入 Android 的内容 URI 工具类。) import android.content.ContentValues; // 导入 android.content.ContentValues;(导入 Android 的内容值类。) import android.content.Context; // 导入 android.content.Context;(导入 Android 的上下文类。) import android.database.Cursor; // 导入 android.database.Cursor;(导入 Android 的数据库游标类。) import android.net.Uri; // 导入 android.net.Uri;(导入 Android 的统一资源标识符类。) import android.util.Log; // 导入 android.util.Log;(导入 Android 的日志工具类。) import net.micode.notes.data.Notes; // 导入 net.micode.notes.data.Notes;(导入来自 net.micode.notes.data 的 Notes 类。) import net.micode.notes.data.Notes.DataColumns; // 导入 net.micode.notes.data.Notes.DataColumns;(导入 Notes 类中的数据列类。) import net.micode.notes.data.Notes.DataConstants; // 导入 net.micode.notes.data.Notes.DataConstants;(导入 Notes 类中的数据常量类。) import net.micode.notes.data.Notes.NoteColumns; // 导入 net.micode.notes.data.Notes.NoteColumns;(导入 Notes 类中的笔记列类。) import net.micode.notes.data.NotesDatabaseHelper.TABLE; // 导入 net.micode.notes.data.NotesDatabaseHelper.TABLE;(导入 Notes 数据库助手类中的表枚举。) import net.micode.notes.gtask.exception.ActionFailureException; // 导入 net.micode.notes.gtask.exception.ActionFailureException;(导入特定的异常类。) import org.json.JSONException; // 导入 org.json.JSONException;(导入 JSON 处理的异常类。) import org.json.JSONObject; // 导入 org.json.JSONObject;(导入 JSON 对象类。) public class SqlData { // 公共类 SqlData;(定义一个名为 SqlData 的公共类。) private static final String TAG = SqlData.class.getSimpleName(); // 私有静态最终字符串变量 TAG,赋值为 SqlData 类的简单名称;(定义一个私有静态最终的字符串变量 TAG,值为 SqlData 类的简单名称。) private static final int INVALID_ID = -99999; // 私有静态最终整型变量 INVALID_ID,赋值为 -99999;(定义一个私有静态最终的整型变量 INVALID_ID,值为 -99999。) public static final String[] PROJECTION_DATA = new String[] { DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.DATA3 }; // 公共静态最终字符串数组变量 PROJECTION_DATA;(定义一个公共静态最终的字符串数组变量 PROJECTION_DATA,包含特定的数据列名称。) public static final int DATA_ID_COLUMN = 0; // 公共静态最终整型变量 DATA_ID_COLUMN,赋值为 0;(定义一个公共静态最终的整型变量 DATA_ID_COLUMN,值为 0。) public static final int DATA_MIME_TYPE_COLUMN = 1; // 公共静态最终整型变量 DATA_MIME_TYPE_COLUMN,赋值为 1;(定义一个公共静态最终的整型变量 DATA_MIME_TYPE_COLUMN,值为 1。) public static final int DATA_CONTENT_COLUMN = 2; // 公共静态最终整型变量 DATA_CONTENT_COLUMN,赋值为 2;(定义一个公共静态最终的整型变量 DATA_CONTENT_COLUMN,值为 2。) public static final int DATA_CONTENT_DATA_1_COLUMN = 3; // 公共静态最终整型变量 DATA_CONTENT_DATA_1_COLUMN,赋值为 3;(定义一个公共静态最终的整型变量 DATA_CONTENT_DATA_1_COLUMN,值为 3。) public static final int DATA_CONTENT_DATA_3_COLUMN = 4; // 公共静态最终整型变量 DATA_CONTENT_DATA_3_COLUMN,赋值为 4;(定义一个公共静态最终的整型变量 DATA_CONTENT_DATA_3_COLUMN,值为 4。) private ContentResolver mContentResolver; // 私有 ContentResolver 变量 mContentResolver;(定义一个私有变量 mContentResolver,类型为 ContentResolver。) private boolean mIsCreate; // 私有布尔型变量 mIsCreate;(定义一个私有布尔型变量 mIsCreate。) private long mDataId; // 私有长整型变量 mDataId;(定义一个私有长整型变量 mDataId。) private String mDataMimeType; // 私有字符串变量 mDataMimeType;(定义一个私有字符串变量 mDataMimeType。) private String mDataContent; // 私有字符串变量 mDataContent;(定义一个私有字符串变量 mDataContent。) private long mDataContentData1; // 私有长整型变量 mDataContentData1;(定义一个私有长整型变量 mDataContentData1。) private String mDataContentData3; // 私有字符串变量 mDataContentData3;(定义一个私有字符串变量 mDataContentData3。) private ContentValues mDiffDataValues; // 私有 ContentValues 变量 mDiffDataValues;(定义一个私有变量 mDiffDataValues,类型为 ContentValues。) public SqlData(Context context) { // 公共构造函数,接收 Context 参数;(定义一个公共构造函数,接收一个 Context 参数。) mContentResolver = context.getContentResolver(); // 获取内容解析器;(将 context 的内容解析器赋值给 mContentResolver。) mIsCreate = true; // 设置创建标志;(将 mIsCreate 设置为 true。) mDataId = INVALID_ID; // 初始化数据 ID;(将 mDataId 初始化为 INVALID_ID。) mDataMimeType = DataConstants.NOTE; // 初始化数据 MIME 类型;(将 mDataMimeType 初始化为 DataConstants.NOTE。) mDataContent = ""; // 初始化数据内容;(将 mDataContent 初始化为空字符串。) mDataContentData1 = 0; // 初始化数据内容数据 1;(将 mDataContentData1 初始化为 0。) mDataContentData3 = ""; // 初始化数据内容数据 3;(将 mDataContentData3 初始化为空字符串。) mDiffDataValues = new ContentValues(); // 创建新的 ContentValues 对象;(创建一个新的 ContentValues 对象并赋值给 mDiffDataValues。) } public SqlData(Context context, Cursor c) { // 公共构造函数,接收 Context 和 Cursor 参数;(定义一个公共构造函数,接收一个 Context 参数和一个 Cursor 参数。) mContentResolver = context.getContentResolver(); // 获取内容解析器;(将 context 的内容解析器赋值给 mContentResolver。) mIsCreate = false; // 设置创建标志;(将 mIsCreate 设置为 false。) loadFromCursor(c); // 从游标加载数据;(调用 loadFromCursor 方法,从传入的游标中加载数据。) mDiffDataValues = new ContentValues(); // 创建新的 ContentValues 对象;(创建一个新的 ContentValues 对象并赋值给 mDiffDataValues。) } private void loadFromCursor(Cursor c) { // 私有方法 loadFromCursor,接收 Cursor 参数;(定义一个私有方法 loadFromCursor,接收一个 Cursor 参数。) mDataId = c.getLong(DATA_ID_COLUMN); // 获取数据 ID;(从游标中获取指定列的数据 ID,并赋值给 mDataId。) mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); // 获取数据 MIME 类型;(从游标中获取指定列的数据 MIME 类型,并赋值给 mDataMimeType。) mDataContent = c.getString(DATA_CONTENT_COLUMN); // 获取数据内容;(从游标中获取指定列的数据内容,并赋值给 mDataContent。) mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); // 获取数据内容数据 1;(从游标中获取指定列的数据内容数据 1,并赋值给 mDataContentData1。) mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); // 获取数据内容数据 3;(从游标中获取指定列的数据内容数据 3,并赋值给 mDataContentData3。) } public void setContent(JSONObject js) throws JSONException { // 公共方法 setContent,接收 JSONObject 参数;(定义一个公共方法 setContent,接收一个 JSONObject 参数。) long dataId = js.has(DataColumns.ID)? js.getLong(DataColumns.ID) : INVALID_ID; // 获取数据 ID;(如果 JSONObject 中包含指定键,则获取对应的值作为数据 ID,否则设置为 INVALID_ID。) if (mIsCreate || mDataId!= dataId) { // 判断是否创建或数据 ID 不一致;(如果正在创建或者当前数据 ID 与新的数据 ID 不一致。) mDiffDataValues.put(DataColumns.ID, dataId); // 更新差异数据值;(将新的数据 ID 放入差异数据值的对应键中。) } mDataId = dataId; // 更新数据 ID;(将 dataId 赋值给 mDataId。) String dataMimeType = js.has(DataColumns.MIME_TYPE)? js.getString(DataColumns.MIME_TYPE) : DataConstants.NOTE; // 获取数据 MIME 类型;(如果 JSONObject 中包含指定键,则获取对应的值作为数据 MIME 类型,否则设置为 DataConstants.NOTE。) if (mIsCreate ||!mDataMimeType.equals(dataMimeType)) { // 判断是否创建或数据 MIME 类型不一致;(如果正在创建或者当前数据 MIME 类型与新的数据 MIME 类型不一致。) mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); // 更新差异数据值;(将新的数据 MIME 类型放入差异数据值的对应键中。) } mDataMimeType = dataMimeType; // 更新数据 MIME 类型;(将 dataMimeType 赋值给 mDataMimeType。) String dataContent = js.has(DataColumns.CONTENT)? js.getString(DataColumns.CONTENT) : ""; // 获取数据内容;(如果 JSONObject 中包含指定键,则获取对应的值作为数据内容,否则设置为空字符串。) if (mIsCreate ||!mDataContent.equals(dataContent)) { // 判断是否创建或数据内容不一致;(如果正在创建或者当前数据内容与新的数据内容不一致。) mDiffDataValues.put(DataColumns.CONTENT, dataContent); // 更新差异数据值;(将新的数据内容放入差异数据值的对应键中。) } mDataContent = dataContent; // 更新数据内容;(将 dataContent 赋值给 mDataContent。) long dataContentData1 = js.has(DataColumns.DATA1)? js.getLong(DataColumns.DATA1) : 0; // 获取数据内容数据 1;(如果 JSONObject 中包含指定键,则获取对应的值作为数据内容数据 1,否则设置为 0。) if (mIsCreate || mDataContentData1!= dataContentData1) { // 判断是否创建或数据内容数据 1 不一致;(如果正在创建或者当前数据内容数据 1 与新的数据内容数据 1 不一致。) mDiffDataValues.put(DataColumns.DATA1, dataContentData1); // 更新差异数据值;(将新的数据内容数据 1 放入差异数据值的对应键中。) } mDataContentData1 = dataContentData1; // 更新数据内容数据 1;(将 dataContentData1 赋值给 mDataContentData1。) String dataContentData3 = js.has(DataColumns.DATA3)? js.getString(DataColumns.DATA3) : ""; // 获取数据内容数据 3;(如果 JSONObject 中包含指定键,则获取对应的值作为数据内容数据 3,否则设置为空字符串。) if (mIsCreate ||!mDataContentData3.equals(dataContentData3)) { // 判断是否创建或数据内容数据 3 不一致;(如果正在创建或者当前数据内容数据 3 与新的数据内容数据 3 不一致。) mDiffDataValues.put(DataColumns.DATA3, dataContentData3); // 更新差异数据值;(将新的数据内容数据 3 放入差异数据值的对应键中。) } mDataContentData3 = dataContentData3; // 更新数据内容数据 3;(将 dataContentData3 赋值给 mDataContentData3。) } public JSONObject getContent() throws JSONException { // 公共方法 getContent;(定义一个公共方法 getContent。) if (mIsCreate) { // 判断是否正在创建;(如果正在创建。) Log.e(TAG, "it seems that we haven't created this in database yet"); // 输出错误日志;(打印错误日志,提示“看起来我们还没有在数据库中创建这个。”) return null; // 返回 null;(返回 null。) } JSONObject js = new JSONObject(); // 创建新的 JSONObject 对象;(创建一个新的 JSONObject 对象。) js.put(DataColumns.ID, mDataId); // 设置数据 ID;(将 mDataId 放入 JSONObject 的对应键中。) js.put(DataColumns.MIME_TYPE, mDataMimeType); // 设置数据 MIME 类型;(将 mDataMimeType 放入 JSONObject 的对应键中。) js.put(DataColumns.CONTENT, mDataContent); // 设置数据内容;(将 mDataContent 放入 JSONObject 的对应键中。) js.put(DataColumns.DATA1, mDataContentData1); // 设置数据内容数据 1;(将 mDataContentData1 放入 JSONObject 的对应键中。) js.put(DataColumns.DATA3, mDataContentData3); // 设置数据内容数据 3;(将 mDataContentData3 放入 JSONObject 的对应键中。) return js; // 返回 JSONObject 对象;(返回创建好的 JSONObject 对象。) } public void commit(long noteId, boolean validateVersion, long version) { // 公共方法 commit,接收长整型、布尔型和长整型参数;(定义一个公共方法 commit,接收一个长整型 noteId、一个布尔型 validateVersion 和一个长整型 version 参数。) if (mIsCreate) { // 判断是否正在创建;(如果正在创建。) if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { // 判断数据 ID 是否无效且差异数据值包含特定键;(如果数据 ID 无效且差异数据值中包含指定键。) mDiffDataValues.remove(DataColumns.ID); // 移除该键值对;(从差异数据值中移除该键值对。) } mDiffDataValues.put(DataColumns.NOTE_ID, noteId); // 设置笔记 ID;(将 noteId 放入差异数据值的对应键中。) Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); // 插入数据;(向 Notes 的内容数据 URI 中插入差异数据值,获取返回的 URI。) try { // 尝试执行以下代码块;(开始 try 代码块。) mDataId = Long.valueOf(uri.getPathSegments().get(1)); // 获取数据 ID;(从返回的 URI 中获取数据 ID,并赋值给 mDataId。) } catch (NumberFormatException e) { // 如果发生数字格式异常,进入此代码块;(捕获 NumberFormatException 异常。) Log.e(TAG, "Get note id error :" + e.toString()); // 输出错误日志;(打印错误日志,提示“获取笔记 ID 错误:”加上异常信息。) throw new ActionFailureException("create note failed"); // 抛出异常 } else { // 如果不是正在创建;(如果不是正在创建的状态。) if (mDiffDataValues.size() > 0) { // 如果差异数据值不为空;(如果差异数据值有内容。) int result = 0; // 初始化结果变量;(先把结果设为 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, "? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE + " WHERE " + NoteColumns.VERSION + "=?)", new String[]{ String.valueOf(noteId), String.valueOf(version) }); // 更新数据并验证版本;(用内容解析器更新数据,同时验证版本。) } if (result == 0) { // 如果更新结果为 0;(如果更新没有效果。) Log.w(TAG, "there is no update. maybe user updates note when syncing"); // 输出警告日志;(打印警告日志,提示可能是用户在同步时更新了笔记。) } } } mDiffDataValues.clear(); // 清空差异数据值;(把差异数据值清空。) mIsCreate = false; // 设置不是创建状态;(设置当前不是创建新数据的状态。) public long getId() { // 获取 ID 的方法;(定义一个获取数据 ID 的方法。) return mDataId; // 返回数据 ID;(返回当前的数据 ID。) }