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

227 lines
8.9 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;
/**
* 数据库数据操作类用于处理便签数据在SQLite数据库中的CRUD操作
* 提供与JSON数据格式的相互转换功能
*/
public class SqlData {
private static final String TAG = SqlData.class.getSimpleName();
// 无效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
};
// 字段索引常量
public static final int DATA_ID_COLUMN = 0; // ID字段索引
public static final int DATA_MIME_TYPE_COLUMN = 1; // MIME类型字段索引
public static final int DATA_CONTENT_COLUMN = 2; // 内容字段索引
public static final int DATA_CONTENT_DATA_1_COLUMN = 3; // DATA1字段索引
public static final int DATA_CONTENT_DATA_3_COLUMN = 4; // DATA3字段索引
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; // 存储有变动的字段值
/**
* 构造函数 - 用于创建新数据
* @param context 上下文对象
*/
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true; // 标记为新数据
mDataId = INVALID_ID; // 初始化为无效ID
mDataMimeType = DataConstants.NOTE; // 默认MIME类型为便签
mDataContent = ""; // 内容初始化为空
mDataContentData1 = 0; // 扩展字段1初始化为0
mDataContentData3 = ""; // 扩展字段3初始化为空
mDiffDataValues = new ContentValues(); // 初始化变动字段集合
}
/**
* 构造函数 - 从数据库游标加载已有数据
* @param context 上下文对象
* @param c 数据库游标
*/
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false; // 标记为已有数据
loadFromCursor(c); // 从游标加载数据
mDiffDataValues = new ContentValues(); // 初始化变动字段集合
}
/**
* 从数据库游标加载数据
* @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);
}
/**
* 从JSON对象设置数据内容
* @param js JSON对象
* @throws JSONException JSON解析异常
*/
public void setContent(JSONObject js) throws JSONException {
// 处理ID字段
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
}
mDataId = dataId;
// 处理MIME类型字段
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;
// 处理DATA1字段
long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0;
if (mIsCreate || mDataContentData1 != dataContentData1) {
mDiffDataValues.put(DataColumns.DATA1, dataContentData1);
}
mDataContentData1 = dataContentData1;
// 处理DATA3字段
String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : "";
if (mIsCreate || !mDataContentData3.equals(dataContentData3)) {
mDiffDataValues.put(DataColumns.DATA3, dataContentData3);
}
mDataContentData3 = dataContentData3;
}
/**
* 将数据内容转换为JSON对象
* @return JSON对象
* @throws JSONException JSON转换异常
*/
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "数据尚未创建到数据库中");
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;
}
/**
* 提交数据到数据库
* @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.put(DataColumns.NOTE_ID, noteId);
Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);
try {
// 从返回的URI中获取新创建的ID
mDataId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
Log.e(TAG, "获取便签ID错误:" + e.toString());
throw new ActionFailureException("创建便签失败");
}
} 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, "没有更新记录,可能在同步时用户已更新便签");
}
}
}
// 重置状态
mDiffDataValues.clear();
mIsCreate = false;
}
/**
* 获取数据ID
* @return 数据ID
*/
public long getId() {
return mDataId;
}
}