rhodes 2.4.0 → 2.4.1.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|