rhodes 2.4.0 → 2.4.1.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/lib/framework/rhodes.rb +1 -1
- data/lib/framework/version.rb +1 -1
- data/lib/rhodes.rb +1 -1
- data/platform/android/Rhodes/AndroidManifest.xml +2 -2
- data/platform/android/Rhodes/jni/src/rhodes.cpp +2 -2
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesActivity.java +28 -37
- data/platform/android/build/androidcommon.rb +1 -1
- data/platform/bb/RubyVM/src/com/rho/sync/SyncEngine.java +4 -1
- data/platform/bb/RubyVM/src/com/rho/sync/SyncSource.java +120 -25
- data/platform/iphone/Info.plist +1 -1
- data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +3 -0
- data/platform/iphone/curl/curl.xcodeproj/project.pbxproj +10 -0
- data/platform/iphone/rhoextlib/rhoextlib.xcodeproj/project.pbxproj +7 -0
- data/platform/iphone/rhorubylib/rhorubylib.xcodeproj/project.pbxproj +3 -0
- data/platform/iphone/rhosynclib/rhosynclib.xcodeproj/project.pbxproj +7 -0
- data/platform/shared/common/RhodesAppBase.cpp +5 -11
- data/platform/shared/sync/SyncEngine.cpp +4 -1
- data/platform/shared/sync/SyncSource.cpp +89 -0
- data/platform/shared/sync/SyncSource.h +8 -2
- data/platform/wm/rhodes.sln +0 -34
- data/rhodes.gemspec +1 -1
- data/spec/phone_spec/app/spec/syncengine_spec.rb +98 -0
- data/spec/phone_spec/build.yml +1 -1
- metadata +8 -8
data/CHANGELOG
CHANGED
data/lib/framework/rhodes.rb
CHANGED
data/lib/framework/version.rb
CHANGED
data/lib/rhodes.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
3
3
|
package="com.rhomobile.rhodes"
|
4
4
|
android:installLocation="auto"
|
5
|
-
android:versionCode="
|
6
|
-
android:versionName="2.4.
|
5
|
+
android:versionCode="31"
|
6
|
+
android:versionName="2.4.1">
|
7
7
|
|
8
8
|
<uses-sdk android:minSdkVersion="4" />
|
9
9
|
|
@@ -564,9 +564,9 @@ RHO_GLOBAL void JNICALL Java_com_rhomobile_rhodes_RhodesService_doSyncSource
|
|
564
564
|
}
|
565
565
|
|
566
566
|
RHO_GLOBAL void JNICALL Java_com_rhomobile_rhodes_RhodesApplication_setStartParameters
|
567
|
-
(JNIEnv
|
567
|
+
(JNIEnv *env, jclass, jstring strUrl)
|
568
568
|
{
|
569
|
-
std::string
|
569
|
+
std::string url = rho_cast<std::string>(env, strUrl);
|
570
570
|
RHODESAPP().setStartParameters(url.c_str());
|
571
571
|
}
|
572
572
|
|
@@ -76,19 +76,6 @@ public class RhodesActivity extends BaseActivity {
|
|
76
76
|
Thread ct = Thread.currentThread();
|
77
77
|
//ct.setPriority(Thread.MAX_PRIORITY);
|
78
78
|
uiThreadId = ct.getId();
|
79
|
-
|
80
|
-
Intent intent = getIntent();
|
81
|
-
//intent.putExtra(RHO_URL_START_KEY, "/app/BrowserStart");
|
82
|
-
//intent.putExtra(RHO_URL_PARAMS_KEY, "param1=value1¶m2=value2");
|
83
|
-
//Log.d(TAG, "MY URI: " + intent.toUri(Intent.URI_INTENT_SCHEME));
|
84
|
-
|
85
|
-
// Check if we really started through URI
|
86
|
-
if(intent.getData() != null)
|
87
|
-
{
|
88
|
-
//Workaround to get URI string from intent since intent.getData() badly initialized
|
89
|
-
Log.d(TAG, "Application URI: " + intent.toUri(0));
|
90
|
-
RhodesApplication.setStartParameters(intent.toUri(0).toString());
|
91
|
-
}
|
92
79
|
|
93
80
|
if (!RhodesService.isEnableTitle()) {
|
94
81
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
@@ -356,30 +343,34 @@ public class RhodesActivity extends BaseActivity {
|
|
356
343
|
@Override
|
357
344
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
358
345
|
super.onServiceConnected(name, service);
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
346
|
+
|
347
|
+
Logger.D(TAG, "onServiceConnected: " + name.toShortString());
|
348
|
+
|
349
|
+
Intent intent = getIntent();
|
350
|
+
String startParams = (intent.getData() != null) ? intent.toUri(0) : "";
|
351
|
+
Uri uri = Uri.parse(startParams);
|
352
|
+
String scheme = uri.getScheme();
|
353
|
+
if(startParams.compareTo("") != 0)
|
354
|
+
{
|
355
|
+
startParams = startParams.substring(scheme.length() + 1);
|
356
|
+
if(startParams.startsWith("//"))
|
357
|
+
startParams = startParams.substring(2);
|
358
|
+
}
|
359
|
+
|
360
|
+
if(!RhodesService.canStartApp(startParams, "&#"))
|
361
|
+
{
|
362
|
+
Logger.E(TAG, "This is hidden app and can be started only with security key.");
|
363
|
+
getRhodesApplication().exit();
|
364
|
+
return;
|
365
|
+
}
|
366
|
+
|
367
|
+
String urlStart = uri.getPath();
|
368
|
+
if (urlStart.compareTo("") != 0)
|
369
|
+
{
|
370
|
+
Logger.D(TAG, "PROCESS URL START: " + urlStart);
|
371
|
+
RhoConf.setString("start_path", Uri.decode(urlStart));
|
372
|
+
}
|
373
|
+
|
383
374
|
ENABLE_LOADING_INDICATION = !RhoConf.getBool("disable_loading_indication");
|
384
375
|
}
|
385
376
|
|
@@ -39,7 +39,7 @@ def setup_ndk(ndkpath,apilevel)
|
|
39
39
|
$ndktools = nil
|
40
40
|
$ndkabi = "unknown"
|
41
41
|
$ndkgccver = "unknown"
|
42
|
-
["arm-
|
42
|
+
["arm-eabi-4.4.0", "arm-eabi-4.2.1"].each do |abi|
|
43
43
|
variants = []
|
44
44
|
variants << File.join(ndkpath, "toolchains", abi, "prebuilt", $ndkhost)
|
45
45
|
variants << File.join(ndkpath, "build/prebuilt", $ndkhost, abi)
|
@@ -578,7 +578,7 @@ public class SyncEngine implements NetRequest.IRhoSession
|
|
578
578
|
{
|
579
579
|
Hashtable/*<String, int>*/ hashPassed = new Hashtable();
|
580
580
|
|
581
|
-
for( int nCurSrc = m_sources.size()-1; nCurSrc
|
581
|
+
for( int nCurSrc = m_sources.size()-1; nCurSrc >= 0 ; )
|
582
582
|
{
|
583
583
|
SyncSource oCurSrc = (SyncSource)m_sources.elementAt(nCurSrc);
|
584
584
|
if ( oCurSrc.getAssociations().size() == 0 || hashPassed.containsKey(oCurSrc.getName()) )
|
@@ -590,6 +590,9 @@ public class SyncEngine implements NetRequest.IRhoSession
|
|
590
590
|
{
|
591
591
|
SyncSource.CAssociation oAssoc = (SyncSource.CAssociation)oCurSrc.getAssociations().elementAt(i);
|
592
592
|
int nAssocSrcIndex = findSrcIndex( m_sources, oAssoc.m_strSrcName);
|
593
|
+
if ( nAssocSrcIndex >= 0 )
|
594
|
+
((SyncSource)m_sources.elementAt(nAssocSrcIndex)).addBelongsTo( oAssoc.m_strAttrib, oCurSrc.getID() );
|
595
|
+
|
593
596
|
if ( nAssocSrcIndex >=0 && nAssocSrcIndex < nSrc )
|
594
597
|
{
|
595
598
|
m_sources.removeElementAt( nSrc );
|
@@ -91,6 +91,8 @@ public class SyncSource
|
|
91
91
|
Vector/*<CAssociation>*/ m_arAssociations = new Vector();
|
92
92
|
Vector/*Ptr<net::CMultipartItem*>*/ m_arMultipartItems = new Vector();
|
93
93
|
Vector/*<String>*/ m_arBlobAttrs = new Vector();
|
94
|
+
Hashtable/*<String,int>*/ m_hashIgnorePushObjects = new Hashtable();
|
95
|
+
Hashtable/*<String,int>*/ m_hashBelongsTo = new Hashtable();
|
94
96
|
|
95
97
|
Integer getID() { return m_nID; }
|
96
98
|
String getName() { return m_strName; }
|
@@ -215,10 +217,14 @@ public class SyncSource
|
|
215
217
|
{
|
216
218
|
if ( isEmptyToken() )
|
217
219
|
processToken(1);
|
218
|
-
|
220
|
+
|
221
|
+
syncClientChanges();
|
222
|
+
syncServerChanges();
|
223
|
+
/*
|
219
224
|
boolean bSyncedServer = syncClientChanges();
|
220
225
|
if ( !bSyncedServer )
|
221
226
|
syncServerChanges();
|
227
|
+
*/
|
222
228
|
}
|
223
229
|
}catch(Exception exc)
|
224
230
|
{
|
@@ -233,7 +239,23 @@ public class SyncSource
|
|
233
239
|
new Integer(m_bGetAtLeastOnePage?1:0), new Integer(m_nRefreshTime), getID() );
|
234
240
|
}
|
235
241
|
}
|
242
|
+
|
243
|
+
void syncClientChanges()throws Exception
|
244
|
+
{
|
245
|
+
PROF.START("Pull");
|
246
|
+
|
247
|
+
boolean bSyncClient = false;
|
248
|
+
{
|
249
|
+
IDBResult res = getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? and sent<=1 LIMIT 1 OFFSET 0", getID());
|
250
|
+
bSyncClient = !res.isEnd();
|
251
|
+
}
|
252
|
+
if ( bSyncClient )
|
253
|
+
doSyncClientChanges();
|
236
254
|
|
255
|
+
PROF.STOP("Pull");
|
256
|
+
}
|
257
|
+
|
258
|
+
/*
|
237
259
|
boolean syncClientChanges()throws Exception
|
238
260
|
{
|
239
261
|
boolean bSyncedServer = false;
|
@@ -274,8 +296,69 @@ public class SyncSource
|
|
274
296
|
{
|
275
297
|
IDBResult res = getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? and update_type='create' and sent>1 LIMIT 1 OFFSET 0", getID());
|
276
298
|
return !res.isEnd();
|
299
|
+
}*/
|
300
|
+
|
301
|
+
void addBelongsTo(String strAttrib, Integer nSrcID)
|
302
|
+
{
|
303
|
+
m_hashBelongsTo.put(strAttrib, nSrcID);
|
304
|
+
}
|
305
|
+
|
306
|
+
Integer getBelongsToSrcID(String strAttrib)
|
307
|
+
{
|
308
|
+
if ( m_hashBelongsTo.containsKey(strAttrib) )
|
309
|
+
return (Integer)m_hashBelongsTo.get(strAttrib);
|
310
|
+
|
311
|
+
return new Integer(-1);
|
277
312
|
}
|
278
313
|
|
314
|
+
void checkIgnorePushObjects()throws Exception
|
315
|
+
{
|
316
|
+
// ignore changes in pending creates
|
317
|
+
{
|
318
|
+
IDBResult res = getDB().executeSQL("SELECT distinct(object) FROM changed_values where source_id=? and sent>=2", getID() );
|
319
|
+
for( ; !res.isEnd(); res.next() )
|
320
|
+
{
|
321
|
+
String strObject = res.getStringByIdx(0);
|
322
|
+
m_hashIgnorePushObjects.put(strObject, new Integer(1));
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
//check for belongs_to
|
327
|
+
String strAttribQuests = "";
|
328
|
+
Vector/*<String>*/ arValues = new Vector();
|
329
|
+
arValues.addElement(getID());
|
330
|
+
Enumeration keys = m_hashBelongsTo.keys();
|
331
|
+
while (keys.hasMoreElements())
|
332
|
+
{
|
333
|
+
if ( strAttribQuests.length() > 0 )
|
334
|
+
strAttribQuests += ",";
|
335
|
+
|
336
|
+
strAttribQuests += "?";
|
337
|
+
arValues.addElement(keys.nextElement());
|
338
|
+
}
|
339
|
+
|
340
|
+
if ( strAttribQuests.length() > 0 )
|
341
|
+
{
|
342
|
+
IDBResult res = getDB().executeSQLEx( "SELECT object, attrib, value FROM changed_values where source_id=? and sent<=1 and attrib IN ( " + strAttribQuests + " )",
|
343
|
+
arValues );
|
344
|
+
|
345
|
+
for( ; !res.isEnd(); res.next() )
|
346
|
+
{
|
347
|
+
String strObject = res.getStringByIdx(0);
|
348
|
+
String strAttrib = res.getStringByIdx(1);
|
349
|
+
String strValue = res.getStringByIdx(2);
|
350
|
+
|
351
|
+
IDBResult res2 = getDB().executeSQL(
|
352
|
+
"SELECT object FROM changed_values where source_id=? and sent>=2 and object=? LIMIT 1 OFFSET 0",
|
353
|
+
getBelongsToSrcID(strAttrib), strValue );
|
354
|
+
|
355
|
+
if (!res2.isEnd())
|
356
|
+
m_hashIgnorePushObjects.put(strObject, new Integer(1) );
|
357
|
+
|
358
|
+
}
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
279
362
|
void doSyncClientChanges()throws Exception
|
280
363
|
{
|
281
364
|
String arUpdateTypes[] = {"create", "update", "delete"};
|
@@ -286,32 +369,41 @@ public class SyncSource
|
|
286
369
|
String strBody = "{\"source_name\":" + JSONEntry.quoteValue(getName()) + ",\"client_id\":" + JSONEntry.quoteValue(getSync().getClientID());
|
287
370
|
boolean bSend = false;
|
288
371
|
int i = 0;
|
289
|
-
|
372
|
+
|
373
|
+
getDB().Lock();
|
374
|
+
try{
|
375
|
+
checkIgnorePushObjects();
|
376
|
+
|
377
|
+
for( i = 0; i < 3 && getSync().isContinueSync(); i++ )
|
378
|
+
{
|
379
|
+
String strBody1;
|
380
|
+
strBody1 = makePushBody_Ver3(arUpdateTypes[i], true);
|
381
|
+
if (strBody1.length() > 0)
|
382
|
+
{
|
383
|
+
strBody += "," + strBody1;
|
384
|
+
|
385
|
+
String strBlobAttrs = "";
|
386
|
+
for ( int j = 0; j < (int)m_arBlobAttrs.size(); j++)
|
387
|
+
{
|
388
|
+
if ( strBlobAttrs.length() > 0 )
|
389
|
+
strBlobAttrs += ",";
|
390
|
+
|
391
|
+
strBlobAttrs += JSONEntry.quoteValue((String)m_arBlobAttrs.elementAt(j));
|
392
|
+
}
|
393
|
+
|
394
|
+
if ( strBlobAttrs.length() > 0 )
|
395
|
+
strBody += ",\"blob_fields\":[" + strBlobAttrs + "]";
|
396
|
+
|
397
|
+
arUpdateSent[i] = true;
|
398
|
+
bSend = true;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
strBody += "}";
|
402
|
+
}finally
|
290
403
|
{
|
291
|
-
|
292
|
-
strBody1 = makePushBody_Ver3(arUpdateTypes[i], true);
|
293
|
-
if (strBody1.length() > 0)
|
294
|
-
{
|
295
|
-
strBody += "," + strBody1;
|
296
|
-
|
297
|
-
String strBlobAttrs = "";
|
298
|
-
for ( int j = 0; j < (int)m_arBlobAttrs.size(); j++)
|
299
|
-
{
|
300
|
-
if ( strBlobAttrs.length() > 0 )
|
301
|
-
strBlobAttrs += ",";
|
302
|
-
|
303
|
-
strBlobAttrs += JSONEntry.quoteValue((String)m_arBlobAttrs.elementAt(j));
|
304
|
-
}
|
305
|
-
|
306
|
-
if ( strBlobAttrs.length() > 0 )
|
307
|
-
strBody += ",\"blob_fields\":[" + strBlobAttrs + "]";
|
308
|
-
|
309
|
-
arUpdateSent[i] = true;
|
310
|
-
bSend = true;
|
311
|
-
}
|
404
|
+
getDB().Unlock();
|
312
405
|
}
|
313
|
-
|
314
|
-
|
406
|
+
|
315
407
|
if ( bSend )
|
316
408
|
{
|
317
409
|
LOG.INFO( "Push client changes to server. Source: " + getName() + "Size :" + strBody.length() );
|
@@ -399,6 +491,9 @@ public class SyncSource
|
|
399
491
|
String value = res.getStringByIdx(2);
|
400
492
|
String attribType = res.getStringByIdx(3);
|
401
493
|
|
494
|
+
if ( m_hashIgnorePushObjects.containsKey(strObject) )
|
495
|
+
continue;
|
496
|
+
|
402
497
|
if ( attribType.compareTo("blob.file") == 0 )
|
403
498
|
{
|
404
499
|
MultipartItem oItem = new MultipartItem();
|
data/platform/iphone/Info.plist
CHANGED
@@ -471,6 +471,7 @@
|
|
471
471
|
);
|
472
472
|
PRODUCT_NAME = rholib;
|
473
473
|
SDKROOT = iphoneos;
|
474
|
+
SKIP_INSTALL = YES;
|
474
475
|
SYMROOT = ../build;
|
475
476
|
USER_HEADER_SEARCH_PATHS = "../../shared/curl/include ../../shared";
|
476
477
|
};
|
@@ -491,6 +492,7 @@
|
|
491
492
|
);
|
492
493
|
PRODUCT_NAME = rholib;
|
493
494
|
SDKROOT = iphoneos;
|
495
|
+
SKIP_INSTALL = YES;
|
494
496
|
SYMROOT = ../build;
|
495
497
|
USER_HEADER_SEARCH_PATHS = "../../shared/curl/include ../../shared";
|
496
498
|
};
|
@@ -552,6 +554,7 @@
|
|
552
554
|
);
|
553
555
|
PRODUCT_NAME = rholib;
|
554
556
|
SDKROOT = iphoneos;
|
557
|
+
SKIP_INSTALL = YES;
|
555
558
|
SYMROOT = ../build;
|
556
559
|
USER_HEADER_SEARCH_PATHS = "../../shared/curl/include ../../shared";
|
557
560
|
};
|
@@ -643,7 +643,11 @@
|
|
643
643
|
isa = PBXProject;
|
644
644
|
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "curl" */;
|
645
645
|
compatibilityVersion = "Xcode 3.1";
|
646
|
+
developmentRegion = English;
|
646
647
|
hasScannedForEncodings = 1;
|
648
|
+
knownRegions = (
|
649
|
+
en,
|
650
|
+
);
|
647
651
|
mainGroup = 08FB7794FE84155DC02AAC07 /* curl */;
|
648
652
|
projectDirPath = "";
|
649
653
|
projectRoot = "";
|
@@ -757,7 +761,9 @@
|
|
757
761
|
);
|
758
762
|
PRODUCT_NAME = curl;
|
759
763
|
SDKROOT = iphoneos;
|
764
|
+
SKIP_INSTALL = YES;
|
760
765
|
SYMROOT = ../build;
|
766
|
+
TARGETED_DEVICE_FAMILY = "1,2";
|
761
767
|
};
|
762
768
|
name = Debug;
|
763
769
|
};
|
@@ -775,7 +781,9 @@
|
|
775
781
|
);
|
776
782
|
PRODUCT_NAME = curl;
|
777
783
|
SDKROOT = iphoneos;
|
784
|
+
SKIP_INSTALL = YES;
|
778
785
|
SYMROOT = ../build;
|
786
|
+
TARGETED_DEVICE_FAMILY = "1,2";
|
779
787
|
};
|
780
788
|
name = Release;
|
781
789
|
};
|
@@ -834,7 +842,9 @@
|
|
834
842
|
);
|
835
843
|
PRODUCT_NAME = curl;
|
836
844
|
SDKROOT = iphoneos;
|
845
|
+
SKIP_INSTALL = YES;
|
837
846
|
SYMROOT = ../build;
|
847
|
+
TARGETED_DEVICE_FAMILY = "1,2";
|
838
848
|
};
|
839
849
|
name = Distribution;
|
840
850
|
};
|
@@ -119,7 +119,11 @@
|
|
119
119
|
isa = PBXProject;
|
120
120
|
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "rhoextlib" */;
|
121
121
|
compatibilityVersion = "Xcode 3.1";
|
122
|
+
developmentRegion = English;
|
122
123
|
hasScannedForEncodings = 1;
|
124
|
+
knownRegions = (
|
125
|
+
en,
|
126
|
+
);
|
123
127
|
mainGroup = 0867D691FE84028FC02AAC07 /* rhoextlib */;
|
124
128
|
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
|
125
129
|
projectDirPath = "";
|
@@ -161,6 +165,7 @@
|
|
161
165
|
ONLY_ACTIVE_ARCH = YES;
|
162
166
|
PRODUCT_NAME = rhoextlib;
|
163
167
|
SDKROOT = iphoneos;
|
168
|
+
SKIP_INSTALL = YES;
|
164
169
|
TARGETED_DEVICE_FAMILY = "1,2";
|
165
170
|
};
|
166
171
|
name = Debug;
|
@@ -179,6 +184,7 @@
|
|
179
184
|
ONLY_ACTIVE_ARCH = YES;
|
180
185
|
PRODUCT_NAME = rhoextlib;
|
181
186
|
SDKROOT = iphoneos;
|
187
|
+
SKIP_INSTALL = YES;
|
182
188
|
TARGETED_DEVICE_FAMILY = "1,2";
|
183
189
|
};
|
184
190
|
name = Release;
|
@@ -249,6 +255,7 @@
|
|
249
255
|
ONLY_ACTIVE_ARCH = YES;
|
250
256
|
PRODUCT_NAME = rhoextlib;
|
251
257
|
SDKROOT = iphoneos;
|
258
|
+
SKIP_INSTALL = YES;
|
252
259
|
TARGETED_DEVICE_FAMILY = "1,2";
|
253
260
|
};
|
254
261
|
name = Distribution;
|
@@ -834,6 +834,7 @@
|
|
834
834
|
ONLY_ACTIVE_ARCH = YES;
|
835
835
|
PRODUCT_NAME = rhorubylib;
|
836
836
|
SDKROOT = iphoneos;
|
837
|
+
SKIP_INSTALL = YES;
|
837
838
|
SYMROOT = ../build;
|
838
839
|
};
|
839
840
|
name = Debug;
|
@@ -855,6 +856,7 @@
|
|
855
856
|
ONLY_ACTIVE_ARCH = YES;
|
856
857
|
PRODUCT_NAME = rhorubylib;
|
857
858
|
SDKROOT = iphoneos;
|
859
|
+
SKIP_INSTALL = YES;
|
858
860
|
SYMROOT = ../build;
|
859
861
|
};
|
860
862
|
name = Release;
|
@@ -917,6 +919,7 @@
|
|
917
919
|
ONLY_ACTIVE_ARCH = YES;
|
918
920
|
PRODUCT_NAME = rhorubylib;
|
919
921
|
SDKROOT = iphoneos;
|
922
|
+
SKIP_INSTALL = YES;
|
920
923
|
SYMROOT = ../build;
|
921
924
|
};
|
922
925
|
name = Distribution;
|
@@ -255,7 +255,11 @@
|
|
255
255
|
isa = PBXProject;
|
256
256
|
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "rhosynclib" */;
|
257
257
|
compatibilityVersion = "Xcode 3.1";
|
258
|
+
developmentRegion = English;
|
258
259
|
hasScannedForEncodings = 1;
|
260
|
+
knownRegions = (
|
261
|
+
en,
|
262
|
+
);
|
259
263
|
mainGroup = 08FB7794FE84155DC02AAC07 /* rhosynclib */;
|
260
264
|
projectDirPath = "";
|
261
265
|
projectRoot = "";
|
@@ -311,6 +315,7 @@
|
|
311
315
|
);
|
312
316
|
PRODUCT_NAME = rhosynclib;
|
313
317
|
SDKROOT = iphoneos;
|
318
|
+
SKIP_INSTALL = YES;
|
314
319
|
};
|
315
320
|
name = Debug;
|
316
321
|
};
|
@@ -329,6 +334,7 @@
|
|
329
334
|
);
|
330
335
|
PRODUCT_NAME = rhosynclib;
|
331
336
|
SDKROOT = iphoneos;
|
337
|
+
SKIP_INSTALL = YES;
|
332
338
|
};
|
333
339
|
name = Release;
|
334
340
|
};
|
@@ -393,6 +399,7 @@
|
|
393
399
|
);
|
394
400
|
PRODUCT_NAME = rhosynclib;
|
395
401
|
SDKROOT = iphoneos;
|
402
|
+
SKIP_INSTALL = YES;
|
396
403
|
};
|
397
404
|
name = Distribution;
|
398
405
|
};
|
@@ -52,17 +52,11 @@ String CRhodesAppBase::canonicalizeRhoUrl(const String& strUrl)
|
|
52
52
|
if (strUrl.length() == 0 )
|
53
53
|
return m_strHomeUrl;
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
strncmp("wtai:", strUrl.c_str(), 5) == 0 ||
|
61
|
-
strncmp("sms:", strUrl.c_str(), 4) == 0
|
62
|
-
)
|
63
|
-
return strUrl;
|
64
|
-
|
65
|
-
return CFilePath::join(m_strHomeUrl,strUrl);
|
55
|
+
size_t pos = strUrl.find_first_of(":#");
|
56
|
+
if((pos == String::npos) || (strUrl.at(pos) == '#'))
|
57
|
+
return CFilePath::join(m_strHomeUrl,strUrl);
|
58
|
+
|
59
|
+
return strUrl;
|
66
60
|
}
|
67
61
|
|
68
62
|
} //namespace common
|
@@ -446,7 +446,7 @@ void CSyncEngine::checkSourceAssociations()
|
|
446
446
|
{
|
447
447
|
Hashtable<String, int> hashPassed;
|
448
448
|
|
449
|
-
for( int nCurSrc = m_sources.size()-1; nCurSrc
|
449
|
+
for( int nCurSrc = m_sources.size()-1; nCurSrc >= 0 ; )
|
450
450
|
{
|
451
451
|
CSyncSource& oCurSrc = *(m_sources.elementAt(nCurSrc));
|
452
452
|
if ( oCurSrc.getAssociations().size() == 0 || hashPassed.containsKey(oCurSrc.getName()) )
|
@@ -458,6 +458,9 @@ void CSyncEngine::checkSourceAssociations()
|
|
458
458
|
{
|
459
459
|
const CSyncSource::CAssociation& oAssoc = oCurSrc.getAssociations().elementAt(i);
|
460
460
|
int nAssocSrcIndex = findSrcIndex( m_sources, oAssoc.m_strSrcName);
|
461
|
+
if ( nAssocSrcIndex >= 0 )
|
462
|
+
m_sources.elementAt(nAssocSrcIndex)->addBelongsTo( oAssoc.m_strAttrib, oCurSrc.getID() );
|
463
|
+
|
461
464
|
if ( nAssocSrcIndex >=0 && nAssocSrcIndex < nSrc )
|
462
465
|
{
|
463
466
|
m_sources.removeElementAt( nSrc, false );
|
@@ -123,9 +123,13 @@ void CSyncSource::sync()
|
|
123
123
|
if ( isEmptyToken() )
|
124
124
|
processToken(1);
|
125
125
|
|
126
|
+
syncClientChanges();
|
127
|
+
syncServerChanges();
|
128
|
+
/*
|
126
129
|
boolean bSyncedServer = syncClientChanges();
|
127
130
|
if ( !bSyncedServer )
|
128
131
|
syncServerChanges();
|
132
|
+
*/
|
129
133
|
}
|
130
134
|
|
131
135
|
CTimeInterval endTime = CTimeInterval::getCurrentTime();
|
@@ -137,6 +141,22 @@ void CSyncSource::sync()
|
|
137
141
|
getID() );
|
138
142
|
}
|
139
143
|
|
144
|
+
void CSyncSource::syncClientChanges()
|
145
|
+
{
|
146
|
+
PROF_START("Pull");
|
147
|
+
|
148
|
+
boolean bSyncClient = true;
|
149
|
+
{
|
150
|
+
IDBResult res = getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? and sent<=1 LIMIT 1 OFFSET 0", getID());
|
151
|
+
bSyncClient = !res.isEnd();
|
152
|
+
}
|
153
|
+
if ( bSyncClient )
|
154
|
+
doSyncClientChanges();
|
155
|
+
|
156
|
+
PROF_STOP("Pull");
|
157
|
+
}
|
158
|
+
|
159
|
+
/*
|
140
160
|
boolean CSyncSource::syncClientChanges()
|
141
161
|
{
|
142
162
|
boolean bSyncedServer = false;
|
@@ -177,6 +197,66 @@ boolean CSyncSource::isPendingClientChanges()
|
|
177
197
|
{
|
178
198
|
IDBResult res = getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? and update_type='create' and sent>1 LIMIT 1 OFFSET 0", getID());
|
179
199
|
return !res.isEnd();
|
200
|
+
}*/
|
201
|
+
|
202
|
+
void CSyncSource::addBelongsTo(const String& strAttrib, int nSrcID)
|
203
|
+
{
|
204
|
+
m_hashBelongsTo.put(strAttrib, nSrcID);
|
205
|
+
}
|
206
|
+
|
207
|
+
int CSyncSource::getBelongsToSrcID(const String& strAttrib)
|
208
|
+
{
|
209
|
+
if ( m_hashBelongsTo.containsKey(strAttrib) )
|
210
|
+
return m_hashBelongsTo.get(strAttrib);
|
211
|
+
|
212
|
+
return -1;
|
213
|
+
}
|
214
|
+
|
215
|
+
void CSyncSource::checkIgnorePushObjects()
|
216
|
+
{
|
217
|
+
// ignore changes in pending creates
|
218
|
+
{
|
219
|
+
IDBResult res = getDB().executeSQL("SELECT distinct(object) FROM changed_values where source_id=? and sent>=2", getID() );
|
220
|
+
for( ; !res.isEnd(); res.next() )
|
221
|
+
{
|
222
|
+
String strObject = res.getStringByIdx(0);
|
223
|
+
m_hashIgnorePushObjects.put(strObject, 1);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
//check for belongs_to
|
228
|
+
String strAttribQuests = "";
|
229
|
+
Vector<String> arValues;
|
230
|
+
arValues.addElement(convertToStringA(getID()));
|
231
|
+
for ( Hashtable<String,int>::iterator it = m_hashBelongsTo.begin(); it != m_hashBelongsTo.end(); ++it )
|
232
|
+
{
|
233
|
+
if ( strAttribQuests.length() > 0 )
|
234
|
+
strAttribQuests += ",";
|
235
|
+
|
236
|
+
strAttribQuests += "?";
|
237
|
+
arValues.addElement(it->first);
|
238
|
+
}
|
239
|
+
|
240
|
+
if ( strAttribQuests.length() > 0 )
|
241
|
+
{
|
242
|
+
IDBResult res = getDB().executeSQLEx( (String("SELECT object, attrib, value FROM changed_values where source_id=? and sent<=1 and attrib IN ( ") + strAttribQuests + " )").c_str(),
|
243
|
+
arValues );
|
244
|
+
|
245
|
+
for( ; !res.isEnd(); res.next() )
|
246
|
+
{
|
247
|
+
String strObject = res.getStringByIdx(0);
|
248
|
+
String strAttrib = res.getStringByIdx(1);
|
249
|
+
String strValue = res.getStringByIdx(2);
|
250
|
+
|
251
|
+
IDBResult res2 = getDB().executeSQL(
|
252
|
+
"SELECT object FROM changed_values where source_id=? and sent>=2 and object=? LIMIT 1 OFFSET 0",
|
253
|
+
getBelongsToSrcID(strAttrib), strValue );
|
254
|
+
|
255
|
+
if (!res2.isEnd())
|
256
|
+
m_hashIgnorePushObjects.put(strObject, 1);
|
257
|
+
|
258
|
+
}
|
259
|
+
}
|
180
260
|
}
|
181
261
|
|
182
262
|
void CSyncSource::doSyncClientChanges()
|
@@ -189,6 +269,10 @@ void CSyncSource::doSyncClientChanges()
|
|
189
269
|
String strBody = "{\"source_name\":" + CJSONEntry::quoteValue(getName()) + ",\"client_id\":" + CJSONEntry::quoteValue(getSync().getClientID());
|
190
270
|
boolean bSend = false;
|
191
271
|
int i = 0;
|
272
|
+
|
273
|
+
getDB().Lock();
|
274
|
+
checkIgnorePushObjects();
|
275
|
+
|
192
276
|
for( i = 0; i < 3 && getSync().isContinueSync(); i++ )
|
193
277
|
{
|
194
278
|
String strBody1;
|
@@ -215,6 +299,8 @@ void CSyncSource::doSyncClientChanges()
|
|
215
299
|
}
|
216
300
|
strBody += "}";
|
217
301
|
|
302
|
+
getDB().Unlock();
|
303
|
+
|
218
304
|
if ( bSend )
|
219
305
|
{
|
220
306
|
LOG(INFO) + "Push client changes to server. Source: " + getName() + "Size :" + strBody.length();
|
@@ -308,6 +394,9 @@ void CSyncSource::makePushBody_Ver3(String& strBody, const String& strUpdateType
|
|
308
394
|
String value = res.getStringByIdx(2);
|
309
395
|
String attribType = res.getStringByIdx(3);
|
310
396
|
|
397
|
+
if ( m_hashIgnorePushObjects.containsKey(strObject) )
|
398
|
+
continue;
|
399
|
+
|
311
400
|
if ( attribType.compare("blob.file") == 0 )
|
312
401
|
{
|
313
402
|
CMultipartItem* pItem = new CMultipartItem();
|
@@ -62,6 +62,8 @@ private:
|
|
62
62
|
Vector<CAssociation> m_arAssociations;
|
63
63
|
VectorPtr<net::CMultipartItem*> m_arMultipartItems;
|
64
64
|
Vector<String> m_arBlobAttrs;
|
65
|
+
Hashtable<String,int> m_hashIgnorePushObjects;
|
66
|
+
Hashtable<String,int> m_hashBelongsTo;
|
65
67
|
|
66
68
|
public:
|
67
69
|
int m_nErrCode;
|
@@ -70,7 +72,7 @@ public:
|
|
70
72
|
public:
|
71
73
|
CSyncSource(int id, const String& strName, const String& strSyncType, db::CDBAdapter& db, CSyncEngine& syncEngine );
|
72
74
|
virtual void sync();
|
73
|
-
virtual
|
75
|
+
virtual void syncClientChanges();
|
74
76
|
|
75
77
|
int getID()const { return m_nID; }
|
76
78
|
String getName() { return m_strName; }
|
@@ -100,7 +102,11 @@ public:
|
|
100
102
|
CSyncSource(CSyncEngine& syncEngine, db::CDBAdapter& db );
|
101
103
|
|
102
104
|
void doSyncClientChanges();
|
103
|
-
|
105
|
+
void checkIgnorePushObjects();
|
106
|
+
int getBelongsToSrcID(const String& strAttrib);
|
107
|
+
void addBelongsTo(const String& strAttrib, int nSrcID);
|
108
|
+
|
109
|
+
//boolean isPendingClientChanges();
|
104
110
|
|
105
111
|
void syncServerChanges();
|
106
112
|
void makePushBody_Ver3(String& strBody, const String& strUpdateType, boolean isSync);
|
data/platform/wm/rhodes.sln
CHANGED
@@ -30,12 +30,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "syncengine", "syncengine\sy
|
|
30
30
|
Release.AspNetCompiler.Debug = "False"
|
31
31
|
EndProjectSection
|
32
32
|
EndProject
|
33
|
-
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcmalloc", "tcmalloc\tcmalloc.vcproj", "{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}"
|
34
|
-
ProjectSection(WebsiteProperties) = preProject
|
35
|
-
Debug.AspNetCompiler.Debug = "True"
|
36
|
-
Release.AspNetCompiler.Debug = "False"
|
37
|
-
EndProjectSection
|
38
|
-
EndProject
|
39
33
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RhoLib", "RhoLib\RhoLib.vcproj", "{F196A418-11F1-4067-9F4F-BCC7D70E6EC5}"
|
40
34
|
ProjectSection(WebsiteProperties) = preProject
|
41
35
|
Debug.AspNetCompiler.Debug = "True"
|
@@ -210,34 +204,6 @@ Global
|
|
210
204
|
{6F57C60E-C083-4D46-A3B9-E17948A33518}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
211
205
|
{6F57C60E-C083-4D46-A3B9-E17948A33518}.Release|Windows Mobile 6 Professional SDK (ARMV4I).Build.0 = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
212
206
|
{6F57C60E-C083-4D46-A3B9-E17948A33518}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
213
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Mixed Platforms.ActiveCfg = Debug|RhodesCE6 (ARMV4I)
|
214
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Mixed Platforms.Build.0 = Debug|RhodesCE6 (ARMV4I)
|
215
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Mixed Platforms.Deploy.0 = Debug|RhodesCE6 (ARMV4I)
|
216
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Pocket PC 2003 (ARMV4).ActiveCfg = Debug|RhodesCE6 (ARMV4I)
|
217
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|RhodesCE6 (ARMV4I).ActiveCfg = Debug|RhodesCE6 (ARMV4I)
|
218
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|RhodesCE6 (ARMV4I).Build.0 = Debug|RhodesCE6 (ARMV4I)
|
219
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|RhodesCE6 (ARMV4I).Deploy.0 = Debug|RhodesCE6 (ARMV4I)
|
220
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|RhodesCE6 (ARMV4I)
|
221
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Win32.ActiveCfg = Debug|Win32
|
222
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Win32.Build.0 = Debug|Win32
|
223
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
|
224
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
|
225
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
|
226
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Debug|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 6 Professional SDK (ARMV4I)
|
227
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Mixed Platforms.ActiveCfg = Release|RhodesCE6 (ARMV4I)
|
228
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Mixed Platforms.Build.0 = Release|RhodesCE6 (ARMV4I)
|
229
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Mixed Platforms.Deploy.0 = Release|RhodesCE6 (ARMV4I)
|
230
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Pocket PC 2003 (ARMV4).ActiveCfg = Release|RhodesCE6 (ARMV4I)
|
231
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|RhodesCE6 (ARMV4I).ActiveCfg = Release|RhodesCE6 (ARMV4I)
|
232
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|RhodesCE6 (ARMV4I).Build.0 = Release|RhodesCE6 (ARMV4I)
|
233
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|RhodesCE6 (ARMV4I).Deploy.0 = Release|RhodesCE6 (ARMV4I)
|
234
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|RhodesCE6 (ARMV4I)
|
235
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Win32.ActiveCfg = Release|Win32
|
236
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Win32.Build.0 = Release|Win32
|
237
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
238
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
239
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
240
|
-
{DCD9FEEA-AEB5-4787-AF75-B8D66C1CDC3B}.Release|Windows Mobile 6 Standard SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 6 Professional SDK (ARMV4I)
|
241
207
|
{F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.Debug|Mixed Platforms.ActiveCfg = Debug|RhodesCE6 (ARMV4I)
|
242
208
|
{F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.Debug|Mixed Platforms.Build.0 = Debug|RhodesCE6 (ARMV4I)
|
243
209
|
{F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.Debug|Mixed Platforms.Deploy.0 = Debug|RhodesCE6 (ARMV4I)
|
data/rhodes.gemspec
CHANGED
@@ -3,7 +3,7 @@ require "lib/rhodes.rb"
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = %q{rhodes}
|
6
|
-
s.version =
|
6
|
+
s.version = "2.4.1.beta.1"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.authors = ["Rhomobile"]
|
@@ -100,6 +100,7 @@ if !defined?(RHO_WP7)
|
|
100
100
|
Rho::RhoConfig.syncserver.should == saveSrv
|
101
101
|
end
|
102
102
|
end
|
103
|
+
|
103
104
|
it "should not sync without login" do
|
104
105
|
SyncEngine.logged_in.should == 0
|
105
106
|
|
@@ -107,6 +108,7 @@ end
|
|
107
108
|
res['error_code'].to_i.should == ::Rho::RhoError::ERR_CLIENTISNOTLOGGEDIN
|
108
109
|
|
109
110
|
end
|
111
|
+
|
110
112
|
=begin
|
111
113
|
it "should update sources from database" do
|
112
114
|
uniq_sources = Rho::RhoConfig::sources.values
|
@@ -636,6 +638,102 @@ end
|
|
636
638
|
|
637
639
|
end
|
638
640
|
|
641
|
+
it "should NOT push pending created objects" do
|
642
|
+
item = getProduct.create({:name => 'Test', :brand => "Rho"})
|
643
|
+
records = getTestDB().select_from_table('changed_values','*', 'update_type' => 'create')
|
644
|
+
records.length.should == 1
|
645
|
+
records[0]['attrib'].should == 'object'
|
646
|
+
|
647
|
+
err_resp = "[{\"version\":3},{\"token\":\"\"},{\"count\":0},{\"progress_count\":0},{\"total_count\":0},{\"create-error\":{\"" + item.object + "\":{\"name\":\"wrongname\",\"an_attribute\":\"error create\"},\"" + item.object + "-error\":{\"message\":\"error create\"}}}]"
|
648
|
+
|
649
|
+
SyncEngine.set_source_property(getProduct().get_source_id.to_i(), "rho_server_response", err_resp )
|
650
|
+
res = ::Rho::RhoSupport::parse_query_parameters getProduct.sync( "/app/Settings/sync_notify")
|
651
|
+
|
652
|
+
item.update_attributes({:price => "123"})
|
653
|
+
|
654
|
+
records2 = getTestDB().select_from_table('changed_values','*', 'update_type' => 'create')
|
655
|
+
records2.length.should == ($spec_settings[:schema_model] ? 7 : 2)
|
656
|
+
|
657
|
+
records2 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'create', "sent"=>0})
|
658
|
+
records2.length.should == 0
|
659
|
+
|
660
|
+
records3 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'update', "sent"=>0})
|
661
|
+
records3.length.should == 1
|
662
|
+
|
663
|
+
SyncEngine.set_source_property(getProduct().get_source_id.to_i(), "rho_server_response", err_resp )
|
664
|
+
res = ::Rho::RhoSupport::parse_query_parameters getProduct.sync( "/app/Settings/sync_notify")
|
665
|
+
|
666
|
+
records3 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'update', "sent"=>1})
|
667
|
+
records3.length.should == 1
|
668
|
+
|
669
|
+
end
|
670
|
+
|
671
|
+
it "should push when pending created objects" do
|
672
|
+
item = getProduct.create({:name => 'Test', :brand => "Rho"})
|
673
|
+
records = getTestDB().select_from_table('changed_values','*', 'update_type' => 'create')
|
674
|
+
records.length.should == 1
|
675
|
+
records[0]['attrib'].should == 'object'
|
676
|
+
|
677
|
+
err_resp = "[{\"version\":3},{\"token\":\"\"},{\"count\":0},{\"progress_count\":0},{\"total_count\":0},{\"create-error\":{\"" + item.object + "\":{\"name\":\"wrongname\",\"an_attribute\":\"error create\"},\"" + item.object + "-error\":{\"message\":\"error create\"}}}]"
|
678
|
+
|
679
|
+
SyncEngine.set_source_property(getProduct().get_source_id.to_i(), "rho_server_response", err_resp )
|
680
|
+
res = ::Rho::RhoSupport::parse_query_parameters getProduct.sync( "/app/Settings/sync_notify")
|
681
|
+
|
682
|
+
item2 = getProduct.create({:name => 'Test2', :brand => "Rho2"})
|
683
|
+
records2 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'create', "sent"=>0} )
|
684
|
+
records2.length.should == 1
|
685
|
+
records2[0]['attrib'].should == 'object'
|
686
|
+
|
687
|
+
SyncEngine.set_source_property(getProduct().get_source_id.to_i(), "rho_server_response", "" )
|
688
|
+
res = ::Rho::RhoSupport::parse_query_parameters getProduct.sync( "/app/Settings/sync_notify")
|
689
|
+
res['status'].should == 'ok'
|
690
|
+
res['error_code'].to_i.should == ::Rho::RhoError::ERR_NONE
|
691
|
+
|
692
|
+
records2 = getTestDB().select_from_table('changed_values','*')
|
693
|
+
records2.length.should == 0
|
694
|
+
|
695
|
+
item3 = getProduct.find(item2.object)
|
696
|
+
item3.should be_nil
|
697
|
+
|
698
|
+
end
|
699
|
+
|
700
|
+
it "should NOT push when children pending created objects" do
|
701
|
+
cust1 = getCustomer.create( {:first => "CustTest1"})
|
702
|
+
cust2 = getCustomer.create( {:first => "CustTest2"})
|
703
|
+
|
704
|
+
@product_test_name = Rho::RhoConfig.generate_id().to_s
|
705
|
+
item = getProduct.create({:name => @product_test_name, :quantity => cust1.object, :sku => cust2.object})
|
706
|
+
item2 = getProduct.find(item.object)
|
707
|
+
item2.vars.should == item.vars
|
708
|
+
|
709
|
+
err_resp = "[{\"version\":3},{\"token\":\"\"},{\"count\":0},{\"progress_count\":0},{\"total_count\":0},{\"create-error\":{\"" + cust1.object + "\":{\"name\":\"wrongname\",\"an_attribute\":\"error create\"},\"" + cust1.object + "-error\":{\"message\":\"error create\"}}}]"
|
710
|
+
SyncEngine.set_source_property(getCustomer().get_source_id.to_i(), "rho_server_response", err_resp )
|
711
|
+
res = ::Rho::RhoSupport::parse_query_parameters getCustomer.sync( "/app/Settings/sync_notify")
|
712
|
+
|
713
|
+
records2 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'create',
|
714
|
+
'source_id'=>getCustomer().get_source_id.to_i(), 'sent'=>2})
|
715
|
+
records2.length.should > 0
|
716
|
+
records2 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'create',
|
717
|
+
'source_id'=>getProduct().get_source_id.to_i(), 'sent'=>0})
|
718
|
+
records2.length.should > 0
|
719
|
+
|
720
|
+
SyncEngine.set_source_property(getCustomer().get_source_id.to_i(), "rho_server_response", "" )
|
721
|
+
res = ::Rho::RhoSupport::parse_query_parameters getProduct.sync( "/app/Settings/sync_notify")
|
722
|
+
res['status'].should == 'ok'
|
723
|
+
res['error_code'].to_i.should == ::Rho::RhoError::ERR_NONE
|
724
|
+
|
725
|
+
getTestDB().select_from_table('changed_values','*')
|
726
|
+
records2 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'create',
|
727
|
+
'source_id'=>getCustomer().get_source_id.to_i(), 'sent'=>2})
|
728
|
+
records2.length.should > 0
|
729
|
+
records2 = getTestDB().select_from_table('changed_values','*', {'update_type' => 'create',
|
730
|
+
'source_id'=>getProduct().get_source_id.to_i(), 'sent'=>1})
|
731
|
+
records2.length.should > 0
|
732
|
+
|
733
|
+
item2 = getProduct.find(item.object)
|
734
|
+
item2.vars.should_not be_nil
|
735
|
+
end
|
736
|
+
|
639
737
|
it "should logout" do
|
640
738
|
SyncEngine.logout()
|
641
739
|
|
data/spec/phone_spec/build.yml
CHANGED
metadata
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rhodes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 62196393
|
5
|
+
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
|
9
|
+
- 1
|
10
|
+
- beta
|
11
|
+
- 1
|
12
|
+
version: 2.4.1.beta.1
|
11
13
|
platform: ruby
|
12
14
|
authors:
|
13
15
|
- Rhomobile
|
@@ -15,8 +17,7 @@ autorequire:
|
|
15
17
|
bindir: bin
|
16
18
|
cert_chain: []
|
17
19
|
|
18
|
-
date: 2011-04-
|
19
|
-
default_executable:
|
20
|
+
date: 2011-04-20 00:00:00 Z
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: templater
|
@@ -6268,7 +6269,6 @@ files:
|
|
6268
6269
|
- spec/phone_spec/Rakefile
|
6269
6270
|
- spec/phone_spec/rhoconfig.txt
|
6270
6271
|
- spec/phone_spec/server.rb
|
6271
|
-
has_rdoc: true
|
6272
6272
|
homepage: http://www.rhomobile.com
|
6273
6273
|
licenses: []
|
6274
6274
|
|
@@ -6299,7 +6299,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
6299
6299
|
requirements: []
|
6300
6300
|
|
6301
6301
|
rubyforge_project: rhodes
|
6302
|
-
rubygems_version: 1.
|
6302
|
+
rubygems_version: 1.7.2
|
6303
6303
|
signing_key:
|
6304
6304
|
specification_version: 2
|
6305
6305
|
summary: The Rhodes framework is the easiest way to develop NATIVE apps with full device capabilities (GPS, PIM, camera, etc.) for any smartphone.
|