boolean CSyncSource::processBlob( const String& strCmd, const String& strObject, CAttrValue& oAttrValue ) { //TODO: when server return delete with rhoblob postfix - delete isBlobAttr if ( !(oAttrValue.m_strBlobSuffix.length() > 0 || getDB().getAttrMgr().isBlobAttr(getID(), oAttrValue.m_strAttrib.c_str())) ) return true; boolean bDownload = true; String strDbValue = ""; if ( !getDB().getAttrMgr().isOverwriteBlobFromServer(getID(), oAttrValue.m_strAttrib) ) { if ( m_bSchemaSource ) { String strSelect = String("SELECT ") + oAttrValue.m_strAttrib + " FROM " + getName() + " WHERE object=?"; DBResult(res, getDB().executeSQL( strSelect.c_str(), strObject)); if (!res.isEnd()) { strDbValue = res.getStringByIdx(0); bDownload = strDbValue.length() == 0; } }else { DBResult(res, getDB().executeSQL( "SELECT value FROM object_values WHERE object=? and attrib=? and source_id=?", strObject, oAttrValue.m_strAttrib, getID() ) ); if (!res.isEnd()) { strDbValue = res.getStringByIdx(0); bDownload = strDbValue.length() == 0; } } } if ( bDownload ) { getDB().endTransaction(); boolean bRes = downloadBlob(oAttrValue); getDB().startTransaction(); return bRes; } oAttrValue.m_strValue = strDbValue; return true; }
/* * Construct the body of the request by filtering * the attr_filter string. The body format should * look like the following: * create: attrvals[][attrib]=<name|industry>&attrvals[][object]=<locallygeneratedid>&attrvals[][value]=<some value> * update: attrvals[][attrib]=<name|industry>&attrvals[][object]=<remoteid>&attrvals[][value]=<some new value> * delete: attrvals[][attrib]=<name|industry>&attrvals[][object]=<remoteid> */ void CSyncSource::makePushBody(String& strBody, const char* szUpdateType) { getDB().Lock(); DBResult( res , getDB().executeSQL("SELECT attrib, object, value, attrib_type, main_id " "FROM changed_values where source_id=? and update_type =? and sent<=1 ORDER BY sent DESC", getID(), szUpdateType ) ); if ( res.isEnd() ) { getDB().Unlock(); return; } for( ; !res.isEnd(); res.next() ) { String strSrcBody = "attrvals[][attrib]=" + res.getStringByIdx(0); if ( res.getStringByIdx(1).length() > 0 ) strSrcBody += "&attrvals[][object]=" + res.getStringByIdx(1); uint64 main_id = res.getUInt64ByIdx(4); if ( main_id != 0 ) strSrcBody += "&attrvals[][id]=" + convertToStringA(main_id); String value = res.getStringByIdx(2); String attribType = res.getStringByIdx(3); //if ( value.length() > 0 ) { if ( attribType == "blob.file" ) { common::CFilePath oBlobPath(value); strSrcBody += "&attrvals[][value]="; strSrcBody += oBlobPath.getBaseName(); strSrcBody += "&attrvals[][attrib_type]=blob"; if ( value.length() > 0 ) m_arSyncBlobs.addElement(new CSyncBlob(strSrcBody,value)); continue; }else strSrcBody += "&attrvals[][value]=" + value; } if ( strBody.length() > 0 ) strBody += "&"; strBody += strSrcBody; } getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), szUpdateType ); getDB().Unlock(); }
void CSyncSource::getAndremoveAsk() { String askParams = ""; { DBResult( res , getDB().executeSQL("SELECT object, attrib, value " "FROM changed_values WHERE source_id=? and update_type =?", getID(), "ask" ) ); if ( !res.isEnd() ) { askParams = res.getStringByIdx(2); getDB().executeSQL("DELETE FROM object_values WHERE object=? and attrib=? and source_id=?", res.getStringByIdx(0), res.getStringByIdx(1), getID() ); } } getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=?", getID(), "ask" ); setAskParams(askParams); }
void CSyncSource::processServerCmd_Ver3_Schema(const String& strCmd, const String& strObject, CJSONStructIterator& attrIter)//throws Exception { if ( strCmd.compare("insert") == 0 ) { Vector<String> vecValues, vecAttrs; String strCols = "", strQuest = "", strSet = ""; for( ; !attrIter.isEnd() && getSync().isContinueSync(); attrIter.next() ) { CAttrValue oAttrValue(attrIter.getCurKey(),attrIter.getCurString()); if ( !processBlob(strCmd,strObject,oAttrValue) ) continue; if ( strCols.length() > 0 ) strCols += ","; if ( strQuest.length() > 0) strQuest += ","; if ( strSet.length() > 0) strSet += ","; strCols += oAttrValue.m_strAttrib; strQuest += "?"; strSet += oAttrValue.m_strAttrib + "=?"; vecAttrs.addElement(oAttrValue.m_strAttrib); vecValues.addElement(oAttrValue.m_strValue); } vecValues.addElement(strObject); if ( strCols.length() > 0 ) strCols += ","; if ( strQuest.length() > 0) strQuest += ","; strCols += "object"; strQuest += "?"; String strSqlInsert = "INSERT INTO "; strSqlInsert += getName() + " ("; strSqlInsert += strCols + ") VALUES(" + strQuest + ")"; if ( !getSync().isContinueSync() ) return; DBResult(resInsert, getDB().executeSQLReportNonUniqueEx(strSqlInsert.c_str(), vecValues ) ); if ( resInsert.isNonUnique() ) { String strSqlUpdate = "UPDATE "; strSqlUpdate += getName() + " SET " + strSet + " WHERE object=?"; getDB().executeSQLEx(strSqlUpdate.c_str(), vecValues); if ( getSyncType().compare("none") != 0 ) { // oo conflicts for( int i = 0; i < (int)vecAttrs.size(); i++ ) { getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1", strObject, vecAttrs.elementAt(i), getID() ); } // } } if ( getSyncType().compare("none") != 0 ) getNotify().onObjectChanged(getID(),strObject, CSyncNotify::enUpdate); m_nInserted++; }else if (strCmd.compare("delete") == 0) { Vector<String> vecAttrs; String strSet = ""; for( ; !attrIter.isEnd() && getSync().isContinueSync(); attrIter.next() ) { CAttrValue oAttrValue(attrIter.getCurKey(),attrIter.getCurString()); if ( strSet.length() > 0 ) strSet += ","; vecAttrs.addElement(oAttrValue.m_strAttrib); strSet += oAttrValue.m_strAttrib + "=NULL"; } String strSqlUpdate = "UPDATE "; strSqlUpdate += getName() + " SET " + strSet + " WHERE object=?"; if ( strSet.length() == 0 || !getSync().isContinueSync() ) return; getDB().executeSQL(strSqlUpdate.c_str(), strObject); //Remove item if all nulls String strSelect = String("SELECT * FROM ") + getName() + " WHERE object=?"; DBResult(res, getDB().executeSQL( strSelect.c_str(), strObject ) ); if ( !res.isEnd() ) { boolean bAllNulls = true; for( int i = 0; i < res.getColCount(); i ++) { if ( !res.isNullByIdx(i) && res.getColName(i).compare("object")!=0 ) { bAllNulls = false; break; } } if (bAllNulls) { String strDelete = String("DELETE FROM ") + getName() + " WHERE object=?"; getDB().executeSQL( strDelete.c_str(), strObject); } } if ( getSyncType().compare("none") != 0 ) { getNotify().onObjectChanged(getID(), strObject, CSyncNotify::enDelete); // oo conflicts for( int i = 0; i < (int)vecAttrs.size(); i++ ) { getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?", strObject, vecAttrs.elementAt(i), getID() ); } // } m_nDeleted++; }else if ( strCmd.compare("links") == 0 ) { String strValue = attrIter.getCurString(); processAssociations(strObject, strValue); String strSqlUpdate = "UPDATE "; strSqlUpdate += getName() + " SET object=? WHERE object=?"; getDB().executeSQL(strSqlUpdate.c_str(), strValue, strObject); getDB().executeSQL("UPDATE changed_values SET object=?,sent=3 where object=? and source_id=?", strValue, strObject, getID() ); getNotify().onObjectChanged(getID(), strObject, CSyncNotify::enCreate); } }
//{"source_name":"SampleAdapter","client_id":1,"create":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}} //{"source_name":"SampleAdapter","client_id":1,"update":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}} //{"source_name":"SampleAdapter","client_id":1,"delete":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}} //{"source_name":"SampleAdapter","client_id":1,"delete":{"3":{"brand":"HTC","name":"Fuze","price":"299.99"}},"create":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}},"update":{"2":{"brand":"Android","name":"G2","price":"99.99"}}} void CSyncSource::makePushBody_Ver3(String& strBody, const String& strUpdateType, boolean isSync) { getDB().Lock(); DBResult( res , getDB().executeSQL("SELECT attrib, object, value, attrib_type " "FROM changed_values where source_id=? and update_type =? and sent<=1 ORDER BY object", getID(), strUpdateType.c_str() ) ); if ( res.isEnd() ) { getDB().Unlock(); return; } String strCurObject = ""; boolean bFirst = true; for( ; !res.isEnd(); res.next() ) { String strAttrib = res.getStringByIdx(0); String strObject = res.getStringByIdx(1); String value = res.getStringByIdx(2); String attribType = res.getStringByIdx(3); if ( attribType.compare("blob.file") == 0 ) { CMultipartItem* pItem = new CMultipartItem(); CMultipartItem& oItem = *pItem; oItem.m_strFilePath = RHODESAPPBASE().resolveDBFilesPath(value); oItem.m_strContentType = "application/octet-stream"; oItem.m_strName = strAttrib + "-" + strObject; m_arBlobAttrs.addElement(strAttrib); m_arMultipartItems.addElement(pItem); } if ( strBody.length() == 0 ) { if ( !isSync ) strBody += "{"; else strBody += "\"" + strUpdateType + "\":{"; } if ( strObject.compare(strCurObject) != 0 ) { if ( strCurObject.length() > 0 ) { if ( !bFirst ) strBody += "}"; strBody += ","; } bFirst = true; strBody += CJSONEntry::quoteValue(strObject); strCurObject = strObject; } if (!bFirst) strBody += ","; if ( strAttrib.length() > 0 ) { if ( bFirst ) strBody += ":{"; strBody += CJSONEntry::quoteValue(strAttrib) + ":" + CJSONEntry::quoteValue(value); bFirst = false; } } if ( strBody.length() > 0 ) { if ( !bFirst ) strBody += "}"; strBody += "}"; } if ( isSync ) getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), strUpdateType.c_str() ); getDB().Unlock(); }