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.
Notes/SqlData.java

270 lines
12 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.

/**
* @ProiectName:MiNote
* @Package: gtask.data
* @ClassName: SqlData
* @Description:用于支持小米便签最底层的数据库相关操作和sqlnote的关系上是子集关系即data是note的子集节点,SqlData其实就是也就是所谓数据中的数据
* @Author: wmq
*/
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;
public class SqlData {
/**
* @功能描述: 得到类的简写名称存入字符串TAG中
* @实现过程: 调用getSimpleName ()函数
* @Author: wmq
*/
private static final String TAG = SqlData.class.getSimpleName();
private static final int INVALID_ID = -99999;
/*
* 来自Notes类中定义的DataColumn中的一些常量
*/
// 集合了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;
//以下定义了8个内部的变量
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;
/**
* @功能名: SqlData
* @参数 :context
* @功能描述: 构造函数,初始化数据
* @Author: wmq
*/
public SqlData(Context context) {
//mContentResolver用于获取ContentProvider提供的数据
mContentResolver = context.getContentResolver();
//IsCreate表征当前数据是用哪种方式创建两种构造函数的参数不同
mIsCreate = true;
mDataId = INVALID_ID;//mDataId置初始值-99999
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
mDataContentData1 = 0;
mDataContentData3 = "";
mDiffDataValues = new ContentValues();
}
/**
* @功能名: SqlData
* @参数 :context / Cursor c
* @功能描述: 初始化一个SqlData对象
* @Author: wmq
*/
public SqlData(Context context, Cursor c) {
/**
* 通过传入的Context对象获取内容解析器用于访问应用程序的数据。这个内容解析器可以用来查询、插入、更新和删除数据等操作。
*/
mContentResolver = context.getContentResolver();
mIsCreate = false;//用于表示是否新建了数据
/**
* 根据传入的Cursor对象加载数据。该方法会从Cursor对象中读取便签内容和元数据
* 并将它们存储到SqlData对象中对应的成员变量中
*/
loadFromCursor(c);
/**
* 建一个ContentValues对象mDiffDataValues用于存储差异化的数据内容。在后续的操作中
* 如果需要更新便签的数据就可以将更新的内容存储到这个ContentValues对象中然后再通过内容解析器进
* 行相应的更新操作。
*/
mDiffDataValues = new ContentValues();
}
/**
* @功能名: loadFromCursor
* @参数 : Cursor c
* @功能描述: 从传入的Cursor对象中读取数据并将这些数据存储到SqlData对象的相应成员变量中。
* @实现过程:
* 从Cursor对象中获取一条记录的数据ID
* 从Cursor对象中获取一条记录的MIME类型
* 从Cursor对象中获取一条记录的内容
* 从Cursor对象中获取一条记录的附加数据1并将其赋值给SqlData对象的mDataContentData1成员变量。
* @Author: wmq
*/
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);
}
/**
* @功能名: setContent
* @参数 : JSONObject js
* @功能描述: 根据该JSONObject中的数据设置SqlData对象的内容(更新)
* @Author: wmq
*/
public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;//从JSONObject中获取并设置数据ID
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
}
mDataId = dataId;
String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE)
: DataConstants.NOTE;
if (mIsCreate || !mDataMimeType.equals(dataMimeType)) {
mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType);
}
mDataMimeType = dataMimeType;
String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : "";
if (mIsCreate || !mDataContent.equals(dataContent)) {
mDiffDataValues.put(DataColumns.CONTENT, dataContent);
}
mDataContent = dataContent;
long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0;
/**
* 如果处于创建状态或者数据内容有变化则将新的数据内容记录到mDiffDataValues中并更新SqlData对象的mDataContent成员变量。
*/
if (mIsCreate || mDataContentData1 != dataContentData1) {
mDiffDataValues.put(DataColumns.DATA1, dataContentData1);
}
mDataContentData1 = dataContentData1;//获取并设置附加数据1dataContentData1
String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : "";
/**
* 如果处于创建状态或者附加数据1有变化则将新的附加数据1记录到mDiffDataValues中并更新SqlData对象的mDataContentData1成员变量。
*/
if (mIsCreate || !mDataContentData3.equals(dataContentData3)) {
mDiffDataValues.put(DataColumns.DATA3, dataContentData3);
}
mDataContentData3 = dataContentData3;//取并设置附加数据3dataContentData3
}
/**
* @功能名: getContent
* @功能描述: getContent()方法它返回一个JSONObject对象其中包含了SqlData对象的内容
* @实现过程:
* 首先检查是否处于创建状态mIsCreate为true如果是则输出错误日志并返回null。
* 然后创建一个新的JSONObject对象并将SqlData对象的数据IDmDataId、MIME类型mDataMimeType
* 数据内容mDataContent、附加数据1mDataContentData1和附加数据3mDataContentData3放入其中。
* 最后返回这个包含了SqlData对象内容的JSONObject对象
* @Author: wmq
*/
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);
js.put(DataColumns.CONTENT, mDataContent);
js.put(DataColumns.DATA1, mDataContentData1);
js.put(DataColumns.DATA3, mDataContentData3);
return js;
}
// 功能描述:
/**
* @功能名: commit
* @参数 : noteId / validateVersion / version
* @功能描述: commit函数用于把当前造作所做的修改保存到数据库
* @实现过程: 首先检查SqlData对象是否处于创建状态然后将笔记IDnoteId放入mDiffDataValues中然后再调用ContentResolver的update()方法进行更新。
* @Author: wmq
*/
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
mDiffDataValues.remove(DataColumns.ID);
}
mDiffDataValues.put(DataColumns.NOTE_ID, noteId);
Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);
try {
mDataId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString());
throw new ActionFailureException("create note failed");
}
} else {
/**
* 首先判断mDiffDataValues的大小如果大于0则表示有需要更新的字段。接下来根据validateVersion参数的值
* 决定使用不同的更新方式。
*/
if (mDiffDataValues.size() > 0) {
int result = 0;
//如果validateVersion为false表示不需要验证版本直接调用ContentResolver的update()方法更新数据库中对应数据的字段值
if (!validateVersion) {//构造字符串
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
} else {
/**
* 如果validateVersion为true表示需要验证版本构造一个SQL语句使用NoteColumns.ID和NoteColumns.VERSION字段
* 进行查询以确保要更新的数据ID和版本号与笔记表中的对应记录匹配。然后再调用ContentResolver的update()方法进行更新
*/
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)
});
}
//检查返回的更新结果result是否为0如果是表示没有进行更新操作
if (result == 0) {
Log.w(TAG, "there is no update. maybe user updates note when syncing");
}
}
}
mDiffDataValues.clear();
mIsCreate = false;
}
/**
* @功能名: getId
* @功能描述: 获取当前id
* @Author: wmq
*/
public long getId() {
return mDataId;
}
}