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

199 lines
9.2 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类可能用于处理与数据库相关的数据操作比如从数据库读取数据、将数据更新到数据库以及和JSON数据的相互转换等
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
};
// 表示在查询结果游标中数据ID列的索引位置方便从游标中获取对应的数据
public static final int DATA_ID_COLUMN = 0;
// 表示在查询结果游标中数据MIME类型列的索引位置
public static final int DATA_MIME_TYPE_COLUMN = 1;
// 表示在查询结果游标中数据内容列的索引位置
public static final int DATA_CONTENT_COLUMN = 2;
// 表示在查询结果游标中数据特定内容字段DATA1列的索引位置
public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
// 表示在查询结果游标中数据特定内容字段DATA3列的索引位置
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
// 用于操作内容提供器,实现和数据库的数据交互,比如查询、插入、更新等操作
private ContentResolver mContentResolver;
// 标记是否是创建操作的标志位true表示正在创建新数据初始化为true
private boolean mIsCreate;
// 存储数据的ID初始化为无效ID值
private long mDataId;
// 存储数据的MIME类型初始化为默认的笔记类型从DataConstants.NOTE获取
private String mDataMimeType;
// 存储数据的内容,初始化为空字符串
private String mDataContent;
// 存储数据内容中特定的长整型数据对应DATA1字段初始化为0
private long mDataContentData1;
// 存储数据内容中特定的字符串数据对应DATA3字段初始化为空字符串
private String mDataContentData3;
// 用于存放要更新到数据库的数据值,类似一个键值对集合,方便批量更新操作
private ContentValues mDiffDataValues;
// 构造函数,传入上下文用于获取内容提供器,初始化相关成员变量,通常用于创建新数据的情况
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
mDataContentData1 = 0;
mDataContentData3 = "";
mDiffDataValues = new ContentValues();
}
// 另一个构造函数,传入上下文和游标,用于从已有的游标数据中加载信息初始化成员变量,通常用于读取现有数据的情况
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);
}
// 根据传入的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;
}
// 根据当前成员变量的数据生成对应的JSON对象若处于创建状态则记录错误日志并返回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;
}
// 将数据提交到数据库的方法,根据是否是创建操作执行不同的逻辑,创建则插入数据,否则根据条件更新数据
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;
}
}