/* * 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;//声名gtask下的data包 import android.content.ContentResolver;//引用android中content的几个类 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;//引用JSON使用失败异常处理类 import org.json.JSONObject;//引用JSON对象库类 public class SqlData {//定义数据库中基本数据类:读取数据、获取数据库中数据、提交数据到数据库 private static final String TAG = SqlData.class.getSimpleName();//调用getSimpleName()函数,得到类的简写名称存入字符串TAG中 private static final int INVALID_ID = -99999;//将INVALID_ID初始化为-99999 public static final String[] PROJECTION_DATA = new String[] {//新建一个字符串数组,集合了interface DataColumns中所有SF常量 DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.DATA3//获得数据列id,mime类型,内容,1类型数据,3类型数据 }; public static final int DATA_ID_COLUMN = 0;//0号列的名称为DATA_ID_COLUMN public static final int DATA_MIME_TYPE_COLUMN = 1;//1号列的名称为DATA_MIME_TYPE_COLUMN public static final int DATA_CONTENT_COLUMN = 2;//2号列的名称为DATA_CONTENT_COLUMN public static final int DATA_CONTENT_DATA_1_COLUMN = 3;//3号列的名称为DATA_CONTENT_DATA_1_COLUMN public static final int DATA_CONTENT_DATA_3_COLUMN = 4;//4号列的名称为DATA_CONTENT_DATA_3_COLUMN private ContentResolver mContentResolver;//定义私有全局变量 private boolean mIsCreate;//mIsCreate用于下文中选择SqlData的生成方式 private long mDataId;//数据ID号 private String mDataMimeType;//数据mime类型 private String mDataContent;//数据内容 private long mDataContentData1;//数据内容中的1类型数据 private String mDataContentData3;//数据内容中的3类型数据 private ContentValues mDiffDataValues;//mDiffDataValues用于构造SqiData,操作数据库 public SqlData(Context context) {//构造函数,初始化数据,参数类型为Context mContentResolver = context.getContentResolver();//获取ContentResovler对象,如果需要查询数据,可以直接在mContetResolver上操作 mIsCreate = true;//mIsCreate为TRUE是这种构造方式的标志 mDataId = INVALID_ID;//mDataId 置初始值-99999。 mDataMimeType = DataConstants.NOTE;//设置数据mime类型为note mDataContent = "";//数据内容 mDataContentData1 = 0;//1数据类型 mDataContentData3 = "";//3数据类型 mDiffDataValues = new ContentValues();//创建内容 } public SqlData(Context context, Cursor c) {//构造函数,初始化数据,参数类型分别为Context和Cursor mContentResolver = context.getContentResolver();//获取ContentProvider提供的数据 mIsCreate = false;//记录当前数据创建方式 loadFromCursor(c);//从光标处载入数据 mDiffDataValues = new ContentValues(); } private void loadFromCursor(Cursor c) {//从光标c处加载数据,帮助实现SqlData的第二种构造,将5列的数据赋给该类的对象 mDataId = c.getLong(DATA_ID_COLUMN);//调用cursor类的方法,获取数据id,参数为id长度 mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);//调用cursor类的方法,获取数据mime类型,参数为其长度 mDataContent = c.getString(DATA_CONTENT_COLUMN);//调用cursor类的方法,获取数据内容,参数为其长度 mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN);//1类型数据 mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);//3类型数据 } public void setContent(JSONObject js) throws JSONException {//设置共享数据,并且抛出JSON类型的异常处理机制 long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;//如果传入的JSONObject对象有DataColumns.ID这一项,则设置dataID为这个ID,否则设为INVALID_ID if (mIsCreate || mDataId != dataId) {//如果采用的是第一种SqlData构造方式,或者这个对象的ID不是共享数据ID mDiffDataValues.put(DataColumns.ID, dataId);//将共享数据ID加入数据库中 } mDataId = dataId;//共享数据同步后,共享数据ID等于该数据ID String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE)//问号语句,若json中有MIME_TYPE这一项,则将其获取,否则,将其定义为notes类中定义的文本类型 : DataConstants.NOTE; if (mIsCreate || !mDataMimeType.equals(dataMimeType)) {//如果采用的是第一种SqlData构造方式,或者这个对象的MimeType不和共享数据一样 mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType);//则将共享数据.MIME_TYPE加入数据库中 } mDataMimeType = dataMimeType;//共享数据同步后,共享数据mime类型等于该数据mime类型 String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : "";//如果传入的JSONObject对象有DataColumn.CONTENT一项,那么将其获取,否则。将其设置为空 if (mIsCreate || !mDataContent.equals(dataContent)) {//如果是第一种sqldata函数,或者该数据内容和共享数据内容不同 mDiffDataValues.put(DataColumns.CONTENT, dataContent);//那么就把这个数据内容添加到数据库这一数据内容列中 } mDataContent = dataContent;//共享数据同步后,共享数据内容等于该数据内容 long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0;//如果js中有这一列1类型数据,则将datacontentdata1设为这个数据 ,否则设为0 if (mIsCreate || mDataContentData1 != dataContentData1) {//如果是第一种sqldata函数,或者该1类型数据和共享1类型数据不同 mDiffDataValues.put(DataColumns.DATA1, dataContentData1);//那么就把这个1类型数据添加到数据库这一1类型数据列中 } mDataContentData1 = dataContentData1;//共享数据同步后,共享1类型数据等于该1类型数据 String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : "";//如果js中有这一列3类型数据,则将datacontentdata1设为这个数据 ,否则设为空 if (mIsCreate || !mDataContentData3.equals(dataContentData3)) {//如果是第一种sqldata函数,或者该3类型数据和共享3类型数据不同 mDiffDataValues.put(DataColumns.DATA3, dataContentData3);//那么就把这个3类型数据添加到数据库这一3类型数据列中 } mDataContentData3 = dataContentData3;//共享数据同步后,共享3类型数据等于该3类型数据 } public JSONObject getContent() throws JSONException {//获取共享的数据内容,并抛出json异常与处理机制 if (mIsCreate) {//当采用的是第一种SqlData构造方式时 Log.e(TAG, "it seems that we haven't created this in database yet");//在日志中显示错误“没有在数据库中创建这个数据” return null;//返回null } JSONObject js = new JSONObject();//将相关数据放入新创建的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);//将JSON中放入数据,这个JSON一共有五个数据,对应着SqlData中的五行数据 return js; } public void commit(long noteId, boolean validateVersion, long version) {//commit函数把当前所做的修改保存到数据库 if (mIsCreate) {//当采用的是第一种SqlData构造方式时 if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {如果该id是无效id且在共享数据中不存在该数据id对应的键 mDiffDataValues.remove(DataColumns.ID);//则从共享数据中移除ID } mDiffDataValues.put(DataColumns.NOTE_ID, noteId);//更新共享数据,键为NOTE_ID,值为noteId Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);//在note的资源标识下加入data数据,并往URI中插入共享数据。 try { mDataId = Long.valueOf(uri.getPathSegments().get(1));//获取有效便签id并创建 } catch (NumberFormatException e) {//处理异常 Log.e(TAG, "Get note id error :" + e.toString());//获取note id错误,e.toString()获取异常类型和异常详细消息 throw new ActionFailureException("create note failed");//抛出异常“创建note失败” } } else {//当采用的是第二种SqlData构造方式时 if (mDiffDataValues.size() > 0) { int result = 0;//若共享数据存在,则通过内容解析器更新关于新URI的共享数据 if (!validateVersion) {//如果版本还没确认 result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);//则结果记录下的只是data的ID,还有data内容 } 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) });//则从数据库中选取对应版本的id进行更新 } if (result == 0)//{如果更新不存在(或许用户在同步时已经完成更新 Log.w(TAG, "there is no update. maybe user updates note when syncing");//报错 } } } mDiffDataValues.clear();//回到初始化,清空,表示已经更新 mIsCreate = false; } public long getId() { return mDataId;//获取当前id } }