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

213 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 java.util.Objects;
import java.util.function.Function;
import javax.naming.Context;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.ContentResolver; //应用程序需要访问其他应用的数据或者系统提供的数据时就会使用ContentResolver来进行数据访问操作
import android.content.ContentUris;
import android.content.ContentValues;
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;
//数据库中基本数据,方法包括读取数据、获取数据库中数据、提交数据到数据库
public class SqlData {
private static final String TAG = SqlData.class.getSimpleName(); // 得到类的简写名称存入字符串TAG中
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表示查询结果中每个数据行的唯一标识符。
// DataColumns.MIME_TYPE表示查询结果中每个数据行的MIME类型。
// DataColumns.CONTENT表示查询结果中每个数据行的内容。 标识不同的数据列
// DataColumns.DATA1表示查询结果中每个数据行的第一个数据项。
// DataColumns.DATA3表示查询结果中每个数据行的第三个数据项。
};
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;
// 每个数据行中各个信息的位置
private ContentResolver mContentResolver;
private boolean mIsCreate;
private long mDataId;
private String mDataMimeType;
private String mDataContent;
private long mDataContentData1;
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();
} // 初始化SqlData对象的字段和属性
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(c);
mDiffDataValues = new ContentValues();
} // 传入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);
} // 从传入的 Cursor 对象中加载数据并设置给类中的字段,具体来说,根据 Cursor 中的列索引,将特定列的值提取出来
public void setContent(JSONObject js) throws JSONException {
setDataValue(js, DataColumns.ID, mDataId, Long::parseLong);
setDataValue(js, DataColumns.MIME_TYPE, mDataMimeType, Function.identity());
setDataValue(js, DataColumns.CONTENT, mDataContent, Function.identity());
setDataValue(js, DataColumns.DATA1, mDataContentData1, Long::parseLong);
setDataValue(js, DataColumns.DATA3, mDataContentData3, Function.identity());
}
private <T> void setDataValue(JSONObject jsonObject, String key, T currentValue, Function<String, T> parser)
throws JSONException {
T newValue = jsonObject.has(key) ? parser.apply(jsonObject.getString(key)) : null;
if (mIsCreate || !Objects.equals(currentValue, newValue)) {
mDiffDataValues.put(key, newValue);
}
setFieldValue(key, newValue);
}
private void setFieldValue(String key, Object value) {
switch (key) {
case DataColumns.ID:
mDataId = (Long) value;
break;
case DataColumns.MIME_TYPE:
mDataMimeType = (String) value;
break;
case DataColumns.CONTENT:
mDataContent = (String) value;
break;
case DataColumns.DATA1:
mDataContentData1 = (Long) value;
break;
case DataColumns.DATA3:
mDataContentData3 = (String) value;
break;
}
}
public JSONObject getContent() throws JSONException { // 获取对象的内容并返回一个 JSON格式的对象。
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;
// 首先判断变量 mIsCreate 的值,如果为 true表示当前对象还未在数据库中创建则记录错误日志并返回 null。
// 如果对象在数据库中已经创建,则创建一个新的 JSONObject 对象 js。
// 将对象中的数据以键值对的形式存储到 JSON 对象 js 中,键包括 DataColumns.ID等对应的值分别为对象中的 mDataId等
// 最后返回构建好的 JSON 对象 js
}
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) { // 如果是创建操作
// 判断是否需要移除无效的ID
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
mDiffDataValues.remove(DataColumns.ID);
}
// 将笔记ID放入差异数据值中
mDiffDataValues.put(DataColumns.NOTE_ID, noteId);
// 插入数据并获取新的数据ID
Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);
try {
mDataId = Long.parseLong(uri.getLastPathSegment());
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error: " + e.toString());
throw new ActionFailureException("Failed to create note");
}
} else { // 如果不是创建操作
// 如果有差异数据值需要更新
if (!mDiffDataValues.isEmpty()) {
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,
NoteColumns.ID + " IN (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.ID + "=? AND " + NoteColumns.VERSION + "=? )",
new String[] { String.valueOf(noteId), String.valueOf(version) });
}
// 如果没有更新数据,则打印警告信息
if (result == 0) {
Log.w(TAG, "No data update. Perhaps the user has updated the note while syncing.");
}
}
}
// 清空差异数据值并标记不再是创建操作
mDiffDataValues.clear();
mIsCreate = false;
}
public long getId() {
return mDataId;
}
}