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.
rass/gtask/data/SqlData.java

210 lines
10 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.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;
// SqlData类从命名来看可能用于处理与SQL数据库相关的数据操作比如数据的读取、更新、插入等
public class SqlData {
// 用于日志输出的标签,取类的简单名称,方便在日志中识别该类相关的日志信息
private static final String TAG = SqlData.class.getSimpleName();
// 定义一个表示无效ID的值可能用于初始化或者判断某些ID相关的异常情况
private static final int INVALID_ID = -99999;
// 定义一个字符串数组,用于指定从数据库查询数据时需要获取的列名,这些列名与数据相关的字段对应
public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
// 定义常量表示在查询结果的游标中对应DataColumns.ID列所在的索引位置从0开始计数方便后续从游标中获取对应列的数据
public static final int DATA_ID_COLUMN = 0;
// 表示在查询结果的游标中对应DataColumns.MIME_TYPE列所在的索引位置
public static final int DATA_MIME_TYPE_COLUMN = 1;
// 表示在查询结果的游标中对应DataColumns.CONTENT列所在的索引位置
public static final int DATA_CONTENT_COLUMN = 2;
// 表示在查询结果的游标中对应DataColumns.DATA1列所在的索引位置
public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
// 表示在查询结果的游标中对应DataColumns.DATA3列所在的索引位置
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
// 用于与内容提供器进行交互,通过它可以操作数据库中的数据(如插入、更新、查询等)
private ContentResolver mContentResolver;
// 标记是否是创建操作初始化为true后续根据具体情况会改变该值
private boolean mIsCreate;
// 用于存储数据的ID初始化为无效IDINVALID_ID
private long mDataId;
// 用于存储数据的MIME类型初始化为DataConstants.NOTE具体值要看DataConstants类的定义
private String mDataMimeType;
// 用于存储数据的内容,初始化为空字符串
private String mDataContent;
// 用于存储数据内容相关的某个长整型数据具体含义可能要看业务逻辑初始化为0
private long mDataContentData1;
// 用于存储数据内容相关的另一个字符串数据(具体含义依业务而定),初始化为空字符串
private String mDataContentData3;
// 用于暂存要更新的数据值以ContentValues的形式存在便于后续批量更新数据库操作
private ContentValues mDiffDataValues;
// 构造函数接收一个Context上下文对象用于初始化一些属性通常在创建新的数据对象时调用
public SqlData(Context context) {
// 获取上下文对应的内容提供器,以便后续操作数据库
mContentResolver = context.getContentResolver();
mIsCreate = true;
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
mDataContentData1 = 0;
mDataContentData3 = "";
mDiffDataValues = new ContentValues();
}
// 另一个构造函数接收一个Context上下文对象和一个Cursor游标对象用于从已有的游标数据中初始化相关属性通常在从数据库查询数据后构建对象时使用
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
// 调用内部方法从游标中加载数据到相应属性
loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
// 私有方法,从给定的游标中读取数据并赋值给相应的成员变量,按照之前定义的列索引位置来获取对应的数据
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);
}
// 设置内容的方法接收一个JSONObject对象尝试从该JSON对象中提取数据并更新相应的成员变量以及要更新的数据值mDiffDataValues根据是否是创建操作以及数据是否有变化来决定是否放入更新数据集合
public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID)? js.getLong(DataColumns.ID) : INVALID_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;
if (mIsCreate || mDataContentData1!= dataContentData1) {
mDiffDataValues.put(DataColumns.DATA1, dataContentData1);
}
mDataContentData1 = dataContentData1;
String dataContentData3 = js.has(DataColumns.DATA3)? js.getString(DataColumns.DATA3) : "";
if (mIsCreate ||!mDataContentData3.equals(dataContentData3)) {
mDiffDataValues.put(DataColumns.DATA3, dataContentData3);
}
mDataContentData3 = dataContentData3;
}
// 获取内容的方法将当前对象的相关属性封装成一个JSONObject对象返回如果是创建操作尚未在数据库中创建则记录错误日志并返回null
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return 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;
}
// 提交数据的方法根据是否是创建操作执行不同的数据库操作若是创建操作则向数据库插入数据若不是则根据验证版本等条件更新数据库中的数据操作完成后会清空要更新的数据值并更改创建标记为false
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 {
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,
"? 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");
}
}
}
mDiffDataValues.clear();
mIsCreate = false;
}
// 获取数据ID的方法用于外部获取当前对象所关联的数据的ID值
public long getId() {
return mDataId;
}
}