测试提交

pull/1/head
sycorax 3 months ago
parent bc8f7d0467
commit 578685fc43

@ -1,19 +1,3 @@
/*
* 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.database.Cursor;
@ -24,59 +8,99 @@ import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Task
* Google Task
*
*/
public class MetaData extends Task {
// 日志标签(使用类名简化)
private final static String TAG = MetaData.class.getSimpleName();
// 关联的Google Task服务端ID
private String mRelatedGid = null;
/**
*
* @param gid Google Task ID
* @param metaInfo JSON
*/
public void setMeta(String gid, JSONObject metaInfo) {
try {
// 将Google Task ID注入元数据头部
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
Log.e(TAG, "failed to put related gid");
Log.e(TAG, "failed to put related gid"); // 理论上不会触发因META_HEAD_GTASK_ID是合法key
}
// 将元数据存储到父类的notes字段
setNotes(metaInfo.toString());
// 设置固定名称标识
setName(GTaskStringUtils.META_NOTE_NAME);
}
/**
* Google Task ID
*/
public String getRelatedGid() {
return mRelatedGid;
}
/**
*
* @return true
*/
@Override
public boolean isWorthSaving() {
return getNotes() != null;
return getNotes() != null; // 仅当存在元数据时需要保存
}
/**
* JSON
* @param js JSON
*/
@Override
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
if (getNotes() != null) {
try {
// 解析notes字段中的元数据去除前后空格确保格式正确
JSONObject metaInfo = new JSONObject(getNotes().trim());
// 提取关联的Google Task ID
mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
} catch (JSONException e) {
Log.w(TAG, "failed to get related gid");
Log.w(TAG, "failed to get related gid"); // 处理元数据格式错误
mRelatedGid = null;
}
}
}
//------------------------ 以下方法禁用 ------------------------
// 设计约束:此类仅用于处理服务端元数据,禁止本地操作
/**
* JSON
* @throws IllegalAccessError
*/
@Override
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
/**
* JSON
* @throws IllegalAccessError
*/
@Override
public JSONObject getLocalJSONFromContent() {
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
}
/**
*
* @throws IllegalAccessError
*/
@Override
public int getSyncAction(Cursor c) {
throw new IllegalAccessError("MetaData:getSyncAction should not be called");
}
}
}

@ -1,101 +1,143 @@
/*
* 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.database.Cursor;
import org.json.JSONObject;
/**
*
*
*
* 1. GID
* 2.
* 3. /
* 4. 访
*
* Note/Task
*/
public abstract class Node {
/* 同步动作类型常量定义 */
/** 无需同步操作 */
public static final int SYNC_ACTION_NONE = 0;
/** 需要在远程服务端创建新节点 */
public static final int SYNC_ACTION_ADD_REMOTE = 1;
/** 需要在本地创建新节点 */
public static final int SYNC_ACTION_ADD_LOCAL = 2;
/** 需要删除远程节点 */
public static final int SYNC_ACTION_DEL_REMOTE = 3;
/** 需要删除本地节点 */
public static final int SYNC_ACTION_DEL_LOCAL = 4;
/** 需要更新远程节点数据 */
public static final int SYNC_ACTION_UPDATE_REMOTE = 5;
/** 需要更新本地节点数据 */
public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
/** 数据冲突需要解决(本地和远程版本都有修改) */
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
/** 同步过程中发生错误 */
public static final int SYNC_ACTION_ERROR = 8;
private String mGid;
private String mName;
private long mLastModified;
private boolean mDeleted;
// 节点基础属性
private String mGid; // 全局唯一标识(服务端分配)
private String mName; // 节点显示名称
private long mLastModified; // 最后修改时间戳(毫秒)
private boolean mDeleted; // 软删除标记
/** 初始化节点默认属性 */
public Node() {
mGid = null;
mName = "";
mLastModified = 0;
mDeleted = false;
mGid = null; // 新建节点尚未分配GID
mName = ""; // 空名称初始化
mLastModified = 0; // 时间戳初始为0表示未同步
mDeleted = false; // 初始为非删除状态
}
/* 抽象方法定义(需子类实现) */
/**
* JSON
* @param actionId
* @return JSON
*/
public abstract JSONObject getCreateAction(int actionId);
/**
* JSON
* @param actionId
* @return JSON
*/
public abstract JSONObject getUpdateAction(int actionId);
/**
* JSON
* @param js JSON
*/
public abstract void setContentByRemoteJSON(JSONObject js);
/**
* JSON
* @param js JSON
*/
public abstract void setContentByLocalJSON(JSONObject js);
/**
* JSON
* @return JSON
*/
public abstract JSONObject getLocalJSONFromContent();
/**
*
* @param c
* @return
*/
public abstract int getSyncAction(Cursor c);
/* 基础属性访问方法 */
/** 设置全局唯一标识(通常由服务端分配) */
public void setGid(String gid) {
this.mGid = gid;
}
/** 设置节点显示名称 */
public void setName(String name) {
this.mName = name;
}
/** 设置最后修改时间戳UTC毫秒数 */
public void setLastModified(long lastModified) {
this.mLastModified = lastModified;
}
/** 标记节点删除状态true=已删除) */
public void setDeleted(boolean deleted) {
this.mDeleted = deleted;
}
/** 获取全局唯一标识 */
public String getGid() {
return this.mGid;
}
/** 获取节点显示名称 */
public String getName() {
return this.mName;
}
/** 获取最后修改时间戳 */
public long getLastModified() {
return this.mLastModified;
}
/** 获取删除状态 */
public boolean getDeleted() {
return this.mDeleted;
}
}
}

@ -1,29 +1,14 @@
/*
* 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;
// 导入所需的Android包
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;
@ -31,46 +16,42 @@ import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE;
import net.micode.notes.gtask.exception.ActionFailureException;
// 导入JSON相关类
import org.json.JSONException;
import org.json.JSONObject;
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;
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;
// 数据成员用于存储内容解析器、是否创建、数据ID、MIME类型、内容等信息
private ContentResolver mContentResolver;
private boolean mIsCreate;
private long mDataId;
private String mDataMimeType;
private String mDataContent;
private long mDataContentData1;
private String mDataContentData3;
private ContentValues mDiffDataValues;
// 构造函数用于创建新的SqlData对象
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;
@ -82,6 +63,7 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
// 构造函数,用于从游标加载现有数据
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
@ -89,6 +71,7 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
// 从游标加载数据到SqlData对象
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
@ -97,6 +80,7 @@ public class SqlData {
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
// 设置内容更新内部状态和ContentValues
public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
@ -130,6 +114,7 @@ public class SqlData {
mDataContentData3 = dataContentData3;
}
// 获取当前数据的内容封装为JSONObject
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
@ -144,6 +129,7 @@ public class SqlData {
return js;
}
// 提交更改到数据库
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
@ -167,7 +153,7 @@ public class SqlData {
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
} else {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
" ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.VERSION + "=?)", new String[] {
String.valueOf(noteId), String.valueOf(version)
@ -183,7 +169,8 @@ public class SqlData {
mIsCreate = false;
}
// 获取当前数据的ID
public long getId() {
return mDataId;
}
}
}
Loading…
Cancel
Save