rhodes 2.2.3 → 2.2.4.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/Rakefile +1 -1
- data/bin/c2dm.rb +59 -0
- data/lib/extensions/barcode/ext/barcode/platform/iphone/Rakefile +4 -0
- data/lib/framework/rho/rho.rb +2 -0
- data/lib/framework/rho/rhoapplication.rb +1 -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 +1 -1
- data/platform/android/Rhodes/jni/src/callbacks.cpp +21 -0
- data/platform/android/Rhodes/jni/src/nativebar.cpp +4 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhoActivity.java +3 -1
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +68 -7
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesService.java +113 -10
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +34 -3
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothManager.java +21 -17
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/datetime/DateTimePickerScreen.java +29 -5
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +7 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/ExternalHttpHandler.java +37 -0
- data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java +0 -1
- data/platform/android/build/RhodesSRC_build.files +24 -23
- data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBStorage.java +6 -0
- data/platform/bb/RubyVM/src/com/rho/RhoLogger.java +42 -20
- data/platform/bb/RubyVM/src/com/rho/db/DBAdapter.java +111 -19
- data/platform/bb/RubyVM/src/com/rho/db/IDBStorage.java +2 -0
- data/platform/bb/RubyVM/src/com/rho/net/NetRequest.java +2 -1
- data/platform/bb/RubyVM/src/com/rho/net/URI.java +80 -0
- data/platform/bb/RubyVM/src/com/rho/sync/SyncEngine.java +21 -1
- data/platform/bb/RubyVM/src/com/rho/sync/SyncNotify.java +6 -1
- data/platform/bb/RubyVM/src/com/rho/sync/SyncSource.java +139 -46
- data/platform/bb/build/bb.rake +8 -3
- data/platform/bb/rhodes/platform/5.0/com/rho/RhodesApplicationPlatform.java +32 -21
- data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +31 -14
- data/platform/bb/rhodes/src/com/rho/file/Jsr75File.java +3 -2
- data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +3 -2
- data/platform/bb/rhodes/src/com/rho/rubyext/System.java +28 -0
- data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +111 -26
- data/platform/iphone/Classes/AppManager/AppManager.m +22 -0
- data/platform/iphone/Classes/DateTimePickerDelegate.m +3 -0
- data/platform/iphone/Classes/MapView/MapViewController.h +8 -3
- data/platform/iphone/Classes/MapView/MapViewController.m +63 -12
- data/platform/iphone/Classes/NativeBar.h +4 -3
- data/platform/iphone/Classes/NativeBar.m +28 -1
- data/platform/iphone/Classes/Rhodes.m +87 -20
- data/platform/iphone/Classes/Signature/SignatureView.m +16 -10
- data/platform/iphone/Classes/Signature/SignatureViewController.m +2 -0
- data/platform/iphone/Classes/SimpleMainView.h +2 -0
- data/platform/iphone/Classes/SimpleMainView.m +120 -35
- data/platform/iphone/Classes/SplashViewController.h +8 -1
- data/platform/iphone/Classes/SplashViewController.m +233 -11
- data/platform/iphone/Classes/SplitView/LeftViewController.h +30 -0
- data/platform/iphone/Classes/SplitView/LeftViewController.m +189 -0
- data/platform/iphone/Classes/SplitView/RightViewController.h +54 -0
- data/platform/iphone/Classes/SplitView/RightViewController.m +268 -0
- data/platform/iphone/Classes/SplitView/SplitViewDelegate.h +22 -0
- data/platform/iphone/Classes/SplitView/SplitViewDelegate.m +92 -0
- data/platform/iphone/Classes/SplitView/SplittedMainView.h +65 -0
- data/platform/iphone/Classes/SplitView/SplittedMainView.m +304 -0
- data/platform/iphone/Classes/TabbedMainView.m +23 -6
- data/platform/iphone/Classes/WebView.m +1 -1
- data/platform/iphone/Info.plist +11 -2
- data/platform/iphone/rbuild/iphone.rake +80 -3
- data/platform/iphone/rhorunner.xcodeproj/project.pbxproj +50 -3
- data/platform/shared/common/RhoConf.cpp +5 -5
- data/platform/shared/db/DBAdapter.cpp +81 -3
- data/platform/shared/db/DBAdapter.h +1 -0
- data/platform/shared/json/JSONIterator.cpp +5 -0
- data/platform/shared/json/JSONIterator.h +1 -0
- data/platform/shared/net/CURLNetRequest.cpp +2 -2
- data/platform/shared/net/URI.cpp +53 -0
- data/platform/shared/net/URI.h +5 -1
- data/platform/shared/ruby/ext/system/system.i +9 -1
- data/platform/shared/ruby/ext/system/system_wrap.c +2632 -2574
- data/platform/shared/ruby/win32/win32.c +2 -0
- data/platform/shared/ruby/wince/direct.c +4 -0
- data/platform/shared/sync/SyncEngine.cpp +20 -1
- data/platform/shared/sync/SyncEngine.h +6 -1
- data/platform/shared/sync/SyncNotify.cpp +6 -1
- data/platform/shared/sync/SyncSource.cpp +130 -74
- data/platform/shared/sync/SyncSource.h +3 -1
- data/platform/wm/rhodes.sln +30 -22
- data/platform/wm/rhodes/Alert.cpp +4 -3
- data/platform/wm/rhodes/MainWindow.cpp +73 -20
- data/platform/wm/rhodes/RingtoneManager.cpp +4 -4
- data/platform/wm/rhodes/RingtoneManager.h +2 -1
- data/platform/wm/rhodes/Vibrate.cpp +1 -2
- data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +37 -0
- data/platform/wm/rhodes/rhodes.vcproj +219 -5
- data/platform/wm/rhodes/stdafx.h +1 -0
- data/platform/wm/rubylib/rubylib.vcproj +10 -8
- data/platform/wm/sqlite3/sqlite3.vcproj +6 -4
- data/platform/wm/syncengine/syncengine.vcproj +7 -5
- data/platform/wm/tcmalloc/tcmalloc.vcproj +11 -8
- data/rakefile.rb +1 -1
- data/res/generators/templates/application/public/jqtouch/jqtouch.js +9 -1
- data/rhodes.gemspec +1 -1
- data/spec/phone_spec/app/spec/bulksync_spec.rb +71 -1
- metadata +17 -5
@@ -29,6 +29,8 @@ public class DBAdapter extends RubyBasic
|
|
29
29
|
|
30
30
|
static String USER_PARTITION_NAME(){return "user";}
|
31
31
|
static Hashtable/*Ptr<String,CDBAdapter*>&*/ getDBPartitions(){ return m_mapDBPartitions; }
|
32
|
+
String m_strClientInfoInsert = "";
|
33
|
+
Object[] m_dataClientInfo = null;
|
32
34
|
|
33
35
|
DBAdapter(RubyClass c) {
|
34
36
|
super(c);
|
@@ -98,6 +100,11 @@ public class DBAdapter extends RubyBasic
|
|
98
100
|
Object[] values = { new Integer(arg1)};
|
99
101
|
return executeSQL(strStatement,values);
|
100
102
|
}
|
103
|
+
public IDBResult executeSQL(String strStatement, int arg1, int arg2)throws DBException{
|
104
|
+
Object[] values = { new Integer(arg1), new Integer(arg2)};
|
105
|
+
return executeSQL(strStatement,values);
|
106
|
+
}
|
107
|
+
|
101
108
|
public IDBResult executeSQL(String strStatement, long arg1)throws DBException{
|
102
109
|
Object[] values = { new Long(arg1)};
|
103
110
|
return executeSQL(strStatement,values);
|
@@ -453,6 +460,32 @@ public class DBAdapter extends RubyBasic
|
|
453
460
|
|
454
461
|
if ( bRhoReset || bAppReset )
|
455
462
|
{
|
463
|
+
IDBStorage db = null;
|
464
|
+
try
|
465
|
+
{
|
466
|
+
db = RhoClassFactory.createDBStorage();
|
467
|
+
if ( db.isDbFileExists(m_strDBPath) )
|
468
|
+
{
|
469
|
+
db.open( m_strDBPath, "" );
|
470
|
+
IDBResult res = db.executeSQL("SELECT * FROM client_info", null, false);
|
471
|
+
if ( !res.isEnd() )
|
472
|
+
{
|
473
|
+
m_strClientInfoInsert = createInsertStatement(res, "client_info");
|
474
|
+
m_dataClientInfo = res.getCurData();
|
475
|
+
}
|
476
|
+
}
|
477
|
+
}catch(Exception exc)
|
478
|
+
{
|
479
|
+
LOG.ERROR("Copy client_info table failed.", exc);
|
480
|
+
}catch(Throwable e)
|
481
|
+
{
|
482
|
+
LOG.ERROR("Copy client_info table crashed.", e);
|
483
|
+
}finally
|
484
|
+
{
|
485
|
+
if (db != null )
|
486
|
+
try{ db.close(); }catch(Exception e){}
|
487
|
+
}
|
488
|
+
|
456
489
|
m_dbStorage.deleteAllFiles(m_strDBPath);
|
457
490
|
|
458
491
|
String fName = makeBlobFolderName();
|
@@ -497,13 +530,15 @@ public class DBAdapter extends RubyBasic
|
|
497
530
|
}
|
498
531
|
}
|
499
532
|
|
500
|
-
private void openDB(String strDBName)throws Exception
|
533
|
+
private void openDB(String strDBName, boolean bTemp)throws Exception
|
501
534
|
{
|
502
535
|
if ( m_bIsOpen )
|
503
536
|
return;
|
504
537
|
|
505
538
|
initFilePaths(strDBName);
|
506
|
-
|
539
|
+
if ( !bTemp )
|
540
|
+
checkDBVersion();
|
541
|
+
|
507
542
|
m_dbStorage.open(m_strDBPath, getSqlScript() );
|
508
543
|
|
509
544
|
//executeSQL("CREATE INDEX by_src ON object_values (source_id)", null);
|
@@ -514,6 +549,24 @@ public class DBAdapter extends RubyBasic
|
|
514
549
|
m_dbStorage.setDbCallback(new DBCallback(this));
|
515
550
|
|
516
551
|
m_dbAdapters.addElement(this);
|
552
|
+
|
553
|
+
//copy client_info table
|
554
|
+
if ( !bTemp && m_strClientInfoInsert != null && m_strClientInfoInsert.length() > 0 &&
|
555
|
+
m_dataClientInfo != null )
|
556
|
+
{
|
557
|
+
LOG.INFO("Copy client_info table from old database");
|
558
|
+
|
559
|
+
m_dbStorage.executeSQL(m_strClientInfoInsert, m_dataClientInfo, false );
|
560
|
+
|
561
|
+
IDBResult res = executeSQL( "SELECT client_id FROM client_info" );
|
562
|
+
if ( !res.isEnd() && res.getStringByIdx(0).length() > 0 )
|
563
|
+
{
|
564
|
+
LOG.INFO("Set reset=1 in client_info");
|
565
|
+
executeSQL( "UPDATE client_info SET reset=1" );
|
566
|
+
}
|
567
|
+
|
568
|
+
}
|
569
|
+
|
517
570
|
}
|
518
571
|
|
519
572
|
private String createInsertStatement(IDBResult res, String tableName)
|
@@ -693,34 +746,77 @@ public class DBAdapter extends RubyBasic
|
|
693
746
|
}
|
694
747
|
}
|
695
748
|
|
749
|
+
void copyChangedValues(DBAdapter db)throws DBException
|
750
|
+
{
|
751
|
+
copyTable("changed_values", m_dbStorage, db.m_dbStorage );
|
752
|
+
{
|
753
|
+
Vector/*<int>*/ arOldSrcs = new Vector();
|
754
|
+
{
|
755
|
+
IDBResult resSrc = db.executeSQL( "SELECT DISTINCT(source_id) FROM changed_values" );
|
756
|
+
for ( ; !resSrc.isEnd(); resSrc.next() )
|
757
|
+
arOldSrcs.addElement( new Integer(resSrc.getIntByIdx(0)) );
|
758
|
+
}
|
759
|
+
for( int i = 0; i < arOldSrcs.size(); i++)
|
760
|
+
{
|
761
|
+
int nOldSrcID = ((Integer)arOldSrcs.elementAt(i)).intValue();
|
762
|
+
|
763
|
+
IDBResult res = executeSQL("SELECT name from sources WHERE source_id=?", nOldSrcID);
|
764
|
+
if ( !res.isEnd() )
|
765
|
+
{
|
766
|
+
String strSrcName = res.getStringByIdx(0);
|
767
|
+
IDBResult res2 = db.executeSQL("SELECT source_id from sources WHERE name=?", strSrcName );
|
768
|
+
if ( !res2.isEnd() )
|
769
|
+
{
|
770
|
+
if ( nOldSrcID != res2.getIntByIdx(0) )
|
771
|
+
{
|
772
|
+
db.executeSQL("UPDATE changed_values SET source_id=? WHERE source_id=?", res2.getIntByIdx(0), nOldSrcID);
|
773
|
+
}
|
774
|
+
continue;
|
775
|
+
}
|
776
|
+
}
|
777
|
+
|
778
|
+
//source not exist in new partition, remove this changes
|
779
|
+
db.executeSQL("DELETE FROM changed_values WHERE source_id=?", nOldSrcID);
|
780
|
+
}
|
781
|
+
}
|
782
|
+
}
|
783
|
+
|
696
784
|
public void setBulkSyncDB(String fDbName, String fScriptName)
|
697
785
|
{
|
698
|
-
|
786
|
+
DBAdapter db = null;
|
699
787
|
try{
|
700
|
-
|
701
|
-
|
702
|
-
|
788
|
+
db = (DBAdapter)alloc(null);
|
789
|
+
db.openDB(fDbName, true);
|
790
|
+
db.setDbPartition(m_strDbPartition);
|
791
|
+
|
703
792
|
db.startTransaction();
|
704
793
|
|
705
|
-
copyTable("client_info",
|
794
|
+
copyTable("client_info", m_dbStorage, db.m_dbStorage );
|
795
|
+
copyChangedValues(db);
|
706
796
|
|
707
797
|
//update User partition
|
708
798
|
if ( m_strDbPartition.compareTo(USER_PARTITION_NAME()) == 0 )
|
709
799
|
{
|
710
800
|
//copy all NOT user sources from current db to bulk db
|
801
|
+
startTransaction();
|
711
802
|
executeSQL("DELETE FROM sources WHERE partition=?", m_strDbPartition);
|
712
|
-
copyTable("sources",
|
803
|
+
copyTable("sources", m_dbStorage, db.m_dbStorage );
|
804
|
+
rollback();
|
713
805
|
}else
|
714
806
|
{
|
715
807
|
//remove all m_strDbPartition sources from user db
|
716
808
|
//copy all sources from bulk db to user db
|
717
809
|
DBAdapter dbUser = getDB(USER_PARTITION_NAME());
|
810
|
+
dbUser.startTransaction();
|
718
811
|
dbUser.executeSQL("DELETE FROM sources WHERE partition=?", m_strDbPartition);
|
719
|
-
|
720
|
-
|
812
|
+
copyTable("sources", db.m_dbStorage, dbUser.m_dbStorage );
|
813
|
+
dbUser.endTransaction();
|
721
814
|
}
|
722
|
-
|
723
|
-
|
815
|
+
getDBPartitions().put(m_strDbPartition, db);
|
816
|
+
com.rho.sync.SyncThread.getSyncEngine().applyChangedValues(db);
|
817
|
+
getDBPartitions().put(m_strDbPartition, this);
|
818
|
+
|
819
|
+
db.endTransaction();
|
724
820
|
db.close();
|
725
821
|
|
726
822
|
m_dbStorage.close();
|
@@ -769,12 +865,8 @@ public class DBAdapter extends RubyBasic
|
|
769
865
|
}
|
770
866
|
}
|
771
867
|
|
772
|
-
|
773
|
-
|
774
|
-
db.close();
|
775
|
-
} catch (DBException e1) {
|
776
|
-
LOG.ERROR("closing of DB caused exception: " + e1.getMessage());
|
777
|
-
}
|
868
|
+
if ( db != null)
|
869
|
+
db.close();
|
778
870
|
|
779
871
|
throw (e instanceof RubyException ? (RubyException)e : new RubyException(e.getMessage()));
|
780
872
|
}
|
@@ -932,7 +1024,7 @@ public class DBAdapter extends RubyBasic
|
|
932
1024
|
{
|
933
1025
|
String szDbName = arg1.toStr();
|
934
1026
|
String szDbPartition = arg2.toStr();
|
935
|
-
((DBAdapter)receiver).openDB(szDbName);
|
1027
|
+
((DBAdapter)receiver).openDB(szDbName, false);
|
936
1028
|
((DBAdapter)receiver).setDbPartition(szDbPartition);
|
937
1029
|
|
938
1030
|
DBAdapter.getDBPartitions().put(szDbPartition, receiver);
|
@@ -162,7 +162,8 @@ public class NetRequest
|
|
162
162
|
|
163
163
|
writeHeaders(headers);
|
164
164
|
LOG.INFO("writeHeaders done");
|
165
|
-
m_connection.setRequestMethod(IHttpConnection.POST);
|
165
|
+
//m_connection.setRequestMethod(IHttpConnection.POST);
|
166
|
+
m_connection.setRequestMethod(strMethod);
|
166
167
|
|
167
168
|
os = m_connection.openOutputStream();
|
168
169
|
os.write(strBody.getBytes(), 0, strBody.length());
|
@@ -836,6 +836,21 @@ import com.rho.Tokenizer;
|
|
836
836
|
return schemespec.toString();
|
837
837
|
}
|
838
838
|
|
839
|
+
public String getLastNamePart()
|
840
|
+
{
|
841
|
+
int nSlash = m_path.lastIndexOf('/');
|
842
|
+
if ( nSlash < 0 )
|
843
|
+
nSlash = m_path.lastIndexOf('\\');
|
844
|
+
|
845
|
+
String strRes;
|
846
|
+
if ( nSlash >= 0 )
|
847
|
+
strRes = m_path.substring(nSlash+1);
|
848
|
+
else
|
849
|
+
strRes = m_path;
|
850
|
+
|
851
|
+
return strRes;
|
852
|
+
}
|
853
|
+
|
839
854
|
public String getUserinfo() {
|
840
855
|
return m_userinfo;
|
841
856
|
}
|
@@ -1199,6 +1214,71 @@ import com.rho.Tokenizer;
|
|
1199
1214
|
return sb.toString();
|
1200
1215
|
}
|
1201
1216
|
|
1217
|
+
static public String urlDecode(String fullPath )
|
1218
|
+
{
|
1219
|
+
StringBuffer sb = new StringBuffer();
|
1220
|
+
int len = fullPath.length();
|
1221
|
+
|
1222
|
+
for (int index=0; index < len ; index++)
|
1223
|
+
{
|
1224
|
+
char c1 = fullPath.charAt(index);
|
1225
|
+
if (c1 != '%')
|
1226
|
+
{
|
1227
|
+
sb.append(c1);
|
1228
|
+
continue;
|
1229
|
+
}
|
1230
|
+
index++;
|
1231
|
+
c1 = fullPath.charAt(index);
|
1232
|
+
|
1233
|
+
if (c1 >= '0' && c1 <= '9')
|
1234
|
+
c1 = (char)(c1 - '0');
|
1235
|
+
else if (c1 >= 'a' && c1 <= 'f')
|
1236
|
+
c1 = (char)(c1 - 'a' + 10);
|
1237
|
+
else if (c1 >= 'A' && c1 <= 'F')
|
1238
|
+
c1 = (char)(c1 - 'A' + 10);
|
1239
|
+
else
|
1240
|
+
break;
|
1241
|
+
|
1242
|
+
index++;
|
1243
|
+
char c2 = fullPath.charAt(index);
|
1244
|
+
if (c2 >= '0' && c2 <= '9')
|
1245
|
+
c2 = (char)(c2 - '0');
|
1246
|
+
else if (c2 >= 'a' && c2 <= 'f')
|
1247
|
+
c2 = (char)(c2 - 'a' + 10);
|
1248
|
+
else if (c2 >= 'A' && c2 <= 'F')
|
1249
|
+
c2 = (char)(c2 - 'A' + 10);
|
1250
|
+
else
|
1251
|
+
break;
|
1252
|
+
|
1253
|
+
char c = (char)((c1 << 4) | c2);
|
1254
|
+
sb.append(c);
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
return sb.toString();
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
static public String urlEscapeSymbols(String fullPath)
|
1261
|
+
{
|
1262
|
+
StringBuffer sb = new StringBuffer();
|
1263
|
+
int len = fullPath.length();
|
1264
|
+
|
1265
|
+
char c;
|
1266
|
+
for (int index=0; index < len ; index++)
|
1267
|
+
{
|
1268
|
+
c = fullPath.charAt(index);
|
1269
|
+
if ( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
|
1270
|
+
c == '_' || c == '.')
|
1271
|
+
{
|
1272
|
+
sb.append(c);
|
1273
|
+
}else
|
1274
|
+
{
|
1275
|
+
sb.append('_');;
|
1276
|
+
}
|
1277
|
+
}
|
1278
|
+
|
1279
|
+
return sb.toString();
|
1280
|
+
}
|
1281
|
+
|
1202
1282
|
static public String ampEncode(String fullPath)
|
1203
1283
|
{
|
1204
1284
|
StringBuffer sb = new StringBuffer();
|
@@ -80,7 +80,7 @@ public class SyncEngine implements NetRequest.IRhoSession
|
|
80
80
|
boolean m_bNoThreaded = false;
|
81
81
|
int m_nErrCode = RhoAppAdapter.ERR_NONE;
|
82
82
|
String m_strError = "";
|
83
|
-
boolean m_bIsSearch;
|
83
|
+
boolean m_bIsSearch, m_bIsSchemaChanged;
|
84
84
|
|
85
85
|
void setState(int eState){ m_syncState = eState; }
|
86
86
|
int getState(){ return m_syncState; }
|
@@ -96,6 +96,9 @@ public class SyncEngine implements NetRequest.IRhoSession
|
|
96
96
|
void setSession(String strSession){m_strSession=strSession;}
|
97
97
|
boolean isSessionExist(){ return m_strSession != null && m_strSession.length() > 0; }
|
98
98
|
|
99
|
+
void setSchemaChanged(boolean bChanged){ m_bIsSchemaChanged = bChanged; }
|
100
|
+
boolean isSchemaChanged(){ return m_bIsSchemaChanged; }
|
101
|
+
|
99
102
|
DBAdapter getUserDB(){ return DBAdapter.getUserDB(); }
|
100
103
|
DBAdapter getDB(String strPartition){ return DBAdapter.getDB(strPartition); }
|
101
104
|
|
@@ -136,6 +139,7 @@ public class SyncEngine implements NetRequest.IRhoSession
|
|
136
139
|
m_bStopByUser = false;
|
137
140
|
m_nErrCode = RhoAppAdapter.ERR_NONE;
|
138
141
|
m_strError = "";
|
142
|
+
m_bIsSchemaChanged = false;
|
139
143
|
|
140
144
|
loadAllSources();
|
141
145
|
|
@@ -418,6 +422,22 @@ public class SyncEngine implements NetRequest.IRhoSession
|
|
418
422
|
return findSource(new SourceID(strSrcName));
|
419
423
|
}
|
420
424
|
|
425
|
+
public void applyChangedValues(DBAdapter db)throws Exception
|
426
|
+
{
|
427
|
+
IDBResult resSrc = db.executeSQL( "SELECT DISTINCT(source_id) FROM changed_values" );
|
428
|
+
for ( ; !resSrc.isEnd(); resSrc.next() )
|
429
|
+
{
|
430
|
+
int nSrcID = resSrc.getIntByIdx(0);
|
431
|
+
IDBResult res = db.executeSQL("SELECT source_id,sync_type,name, partition from sources WHERE source_id=?", nSrcID);
|
432
|
+
if ( res.isEnd() )
|
433
|
+
continue;
|
434
|
+
|
435
|
+
SyncSource src = new SyncSource( res.getIntByIdx(0), res.getStringByIdx(2), "none", db, this );
|
436
|
+
|
437
|
+
src.applyChangedValues();
|
438
|
+
}
|
439
|
+
}
|
440
|
+
|
421
441
|
void loadAllSources()throws DBException
|
422
442
|
{
|
423
443
|
m_sources.removeAllElements();
|
@@ -450,7 +450,12 @@ public class SyncNotify {
|
|
450
450
|
if ( bFinish )
|
451
451
|
{
|
452
452
|
if ( nErrCode == RhoAppAdapter.ERR_NONE )
|
453
|
-
|
453
|
+
{
|
454
|
+
if ( getSync().isSchemaChanged() )
|
455
|
+
strBody += "schema_changed";
|
456
|
+
else
|
457
|
+
strBody += (src == null && strParams.length() == 0) ? "complete" : "ok";
|
458
|
+
}
|
454
459
|
else
|
455
460
|
{
|
456
461
|
if ( getSync().isStoppedByUser() )
|
@@ -286,7 +286,7 @@ class SyncSource
|
|
286
286
|
for( i = 0; i < 3 && getSync().isContinueSync(); i++ )
|
287
287
|
{
|
288
288
|
String strBody1;
|
289
|
-
strBody1 = makePushBody_Ver3(arUpdateTypes[i]);
|
289
|
+
strBody1 = makePushBody_Ver3(arUpdateTypes[i], true);
|
290
290
|
if (strBody1.length() > 0)
|
291
291
|
{
|
292
292
|
strBody += "," + strBody1;
|
@@ -360,7 +360,7 @@ class SyncSource
|
|
360
360
|
//{"source_name":"SampleAdapter","client_id":1,"update":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
|
361
361
|
//{"source_name":"SampleAdapter","client_id":1,"delete":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
|
362
362
|
//{"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"}}}
|
363
|
-
String makePushBody_Ver3( String strUpdateType)throws DBException
|
363
|
+
String makePushBody_Ver3( String strUpdateType, boolean isSync)throws DBException
|
364
364
|
{
|
365
365
|
String strBody = "";
|
366
366
|
getDB().Lock();
|
@@ -394,7 +394,12 @@ class SyncSource
|
|
394
394
|
}
|
395
395
|
|
396
396
|
if ( strBody.length() == 0 )
|
397
|
-
|
397
|
+
{
|
398
|
+
if ( !isSync )
|
399
|
+
strBody += "{";
|
400
|
+
else
|
401
|
+
strBody += "\"" + strUpdateType + "\":{";
|
402
|
+
}
|
398
403
|
|
399
404
|
if ( strObject.compareTo(strCurObject) != 0 )
|
400
405
|
{
|
@@ -431,12 +436,38 @@ class SyncSource
|
|
431
436
|
strBody += "}";
|
432
437
|
}
|
433
438
|
|
434
|
-
|
439
|
+
if ( isSync )
|
440
|
+
getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), strUpdateType );
|
441
|
+
|
435
442
|
getDB().Unlock();
|
436
443
|
|
437
444
|
return strBody;
|
438
445
|
}
|
439
446
|
|
447
|
+
void applyChangedValues()throws Exception
|
448
|
+
{
|
449
|
+
String strBody = makePushBody_Ver3("create", false);
|
450
|
+
if ( strBody != null && strBody.length() > 0 )
|
451
|
+
{
|
452
|
+
JSONEntry oEntry = new JSONEntry(strBody);
|
453
|
+
processSyncCommand("insert", oEntry );
|
454
|
+
}
|
455
|
+
|
456
|
+
strBody = makePushBody_Ver3("delete", false);
|
457
|
+
if ( strBody != null && strBody.length() > 0 )
|
458
|
+
{
|
459
|
+
JSONEntry oEntry = new JSONEntry(strBody);
|
460
|
+
processSyncCommand("delete", oEntry );
|
461
|
+
}
|
462
|
+
|
463
|
+
strBody = makePushBody_Ver3("update", false);
|
464
|
+
if ( strBody != null && strBody.length() > 0 )
|
465
|
+
{
|
466
|
+
JSONEntry oEntry = new JSONEntry(strBody);
|
467
|
+
processSyncCommand("insert", oEntry );
|
468
|
+
}
|
469
|
+
}
|
470
|
+
|
440
471
|
void syncServerChanges()throws Exception
|
441
472
|
{
|
442
473
|
LOG.INFO("Sync server changes source ID :" + getID() );
|
@@ -569,26 +600,33 @@ class SyncSource
|
|
569
600
|
JSONEntry oCmds = oJsonArr.getCurItem();
|
570
601
|
PROF.START("Data");
|
571
602
|
|
572
|
-
|
573
|
-
if ( oCmds.hasName("metadata") && getSync().isContinueSync() )
|
603
|
+
if ( oCmds.hasName("schema-changed") )
|
574
604
|
{
|
575
|
-
|
576
|
-
|
605
|
+
getSync().stopSync();
|
606
|
+
getSync().setSchemaChanged(true);
|
607
|
+
}else
|
608
|
+
{
|
609
|
+
getDB().startTransaction();
|
610
|
+
if ( oCmds.hasName("metadata") && getSync().isContinueSync() )
|
611
|
+
{
|
612
|
+
String strMetadata = oCmds.getString("metadata");
|
613
|
+
getDB().executeSQL("UPDATE sources SET metadata=? WHERE source_id=?", strMetadata, getID() );
|
614
|
+
}
|
615
|
+
if ( oCmds.hasName("links") && getSync().isContinueSync() )
|
616
|
+
processSyncCommand("links", oCmds.getEntry("links") );
|
617
|
+
if ( oCmds.hasName("delete") && getSync().isContinueSync() )
|
618
|
+
processSyncCommand("delete", oCmds.getEntry("delete") );
|
619
|
+
if ( oCmds.hasName("insert") && getSync().isContinueSync() )
|
620
|
+
processSyncCommand("insert", oCmds.getEntry("insert") );
|
621
|
+
|
622
|
+
PROF.STOP("Data");
|
623
|
+
|
624
|
+
PROF.START("DB");
|
625
|
+
getDB().endTransaction();
|
626
|
+
PROF.STOP("DB");
|
627
|
+
|
628
|
+
getNotify().fireObjectsNotification();
|
577
629
|
}
|
578
|
-
if ( oCmds.hasName("links") && getSync().isContinueSync() )
|
579
|
-
processSyncCommand("links", oCmds.getEntry("links") );
|
580
|
-
if ( oCmds.hasName("delete") && getSync().isContinueSync() )
|
581
|
-
processSyncCommand("delete", oCmds.getEntry("delete") );
|
582
|
-
if ( oCmds.hasName("insert") && getSync().isContinueSync() )
|
583
|
-
processSyncCommand("insert", oCmds.getEntry("insert") );
|
584
|
-
|
585
|
-
PROF.STOP("Data");
|
586
|
-
|
587
|
-
PROF.START("DB");
|
588
|
-
getDB().endTransaction();
|
589
|
-
PROF.STOP("DB");
|
590
|
-
|
591
|
-
getNotify().fireObjectsNotification();
|
592
630
|
}
|
593
631
|
|
594
632
|
PROF.START("Data1");
|
@@ -618,6 +656,9 @@ class SyncSource
|
|
618
656
|
}
|
619
657
|
}
|
620
658
|
|
659
|
+
if ( getSyncType().compareTo("none") == 0 )
|
660
|
+
continue;
|
661
|
+
|
621
662
|
int nSyncObjectCount = getNotify().incLastSyncObjectCount(getID());
|
622
663
|
if ( getProgressStep() > 0 && (nSyncObjectCount%getProgressStep() == 0) )
|
623
664
|
getNotify().fireSyncNotification(this, false, RhoAppAdapter.ERR_NONE, "");
|
@@ -707,16 +748,21 @@ class SyncSource
|
|
707
748
|
strSqlUpdate += getName() + " SET " + strSet + " WHERE object=?";
|
708
749
|
getDB().executeSQLEx(strSqlUpdate, vecValues);
|
709
750
|
|
710
|
-
|
711
|
-
for( int i = 0; i < (int)vecAttrs.size(); i++ )
|
751
|
+
if ( getSyncType().compareTo("none") != 0 )
|
712
752
|
{
|
713
|
-
|
714
|
-
|
753
|
+
// oo conflicts
|
754
|
+
for( int i = 0; i < (int)vecAttrs.size(); i++ )
|
755
|
+
{
|
756
|
+
getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1",
|
757
|
+
strObject, vecAttrs.elementAt(i), getID() );
|
758
|
+
}
|
759
|
+
//
|
715
760
|
}
|
716
|
-
//
|
717
761
|
}
|
718
762
|
|
719
|
-
|
763
|
+
if ( getSyncType().compareTo("none") != 0 )
|
764
|
+
getNotify().onObjectChanged(getID(),strObject, SyncNotify.enUpdate);
|
765
|
+
|
720
766
|
m_nInserted++;
|
721
767
|
}else if (strCmd.compareTo("delete") == 0)
|
722
768
|
{
|
@@ -762,15 +808,18 @@ class SyncSource
|
|
762
808
|
}
|
763
809
|
}
|
764
810
|
|
765
|
-
|
766
|
-
// oo conflicts
|
767
|
-
for( int i = 0; i < (int)vecAttrs.size(); i++ )
|
811
|
+
if ( getSyncType().compareTo("none") != 0 )
|
768
812
|
{
|
769
|
-
|
770
|
-
|
813
|
+
getNotify().onObjectChanged(getID(), strObject, SyncNotify.enDelete);
|
814
|
+
// oo conflicts
|
815
|
+
for( int i = 0; i < (int)vecAttrs.size(); i++ )
|
816
|
+
{
|
817
|
+
getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?",
|
818
|
+
strObject, vecAttrs.elementAt(i), getID() );
|
819
|
+
}
|
820
|
+
//
|
771
821
|
}
|
772
|
-
|
773
|
-
|
822
|
+
|
774
823
|
m_nDeleted++;
|
775
824
|
}else if ( strCmd.compareTo("links") == 0 )
|
776
825
|
{
|
@@ -860,22 +909,30 @@ class SyncSource
|
|
860
909
|
"SET value=? WHERE object=? and attrib=? and source_id=?",
|
861
910
|
oAttrValue.m_strValue, strObject, oAttrValue.m_strAttrib, getID() );
|
862
911
|
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
912
|
+
if ( getSyncType().compareTo("none") != 0 )
|
913
|
+
{
|
914
|
+
// oo conflicts
|
915
|
+
getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1",
|
916
|
+
strObject, oAttrValue.m_strAttrib, getID() );
|
917
|
+
//
|
918
|
+
}
|
867
919
|
}
|
868
920
|
|
869
|
-
|
921
|
+
if ( getSyncType().compareTo("none") != 0 )
|
922
|
+
getNotify().onObjectChanged(getID(),strObject, SyncNotify.enUpdate);
|
923
|
+
|
870
924
|
m_nInserted++;
|
871
925
|
}else if (strCmd.compareTo("delete") == 0)
|
872
926
|
{
|
873
927
|
getDB().executeSQL("DELETE FROM object_values where object=? and attrib=? and source_id=?", strObject, oAttrValue.m_strAttrib, getID() );
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
928
|
+
|
929
|
+
if ( getSyncType().compareTo("none") != 0 )
|
930
|
+
{
|
931
|
+
getNotify().onObjectChanged(getID(), strObject, SyncNotify.enDelete);
|
932
|
+
// oo conflicts
|
933
|
+
getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?", strObject, oAttrValue.m_strAttrib, getID() );
|
934
|
+
//
|
935
|
+
}
|
879
936
|
m_nDeleted++;
|
880
937
|
}else if ( strCmd.compareTo("links") == 0 )
|
881
938
|
{
|
@@ -891,6 +948,42 @@ class SyncSource
|
|
891
948
|
|
892
949
|
private String makeFileName(CAttrValue value)throws Exception
|
893
950
|
{
|
951
|
+
String strExt = "";
|
952
|
+
|
953
|
+
URI uri = new URI(value.m_strValue);
|
954
|
+
String strQuest = uri.getQueryString();
|
955
|
+
|
956
|
+
if (strQuest != null && strQuest.length() > 0)
|
957
|
+
{
|
958
|
+
int nExt = strQuest.indexOf("extension=");
|
959
|
+
if ( nExt >= 0 )
|
960
|
+
{
|
961
|
+
int nExtEnd = strQuest.indexOf("&", nExt);
|
962
|
+
if (nExtEnd < 0 )
|
963
|
+
nExtEnd = strQuest.length();
|
964
|
+
|
965
|
+
strExt = strQuest.substring(nExt+10, nExtEnd);
|
966
|
+
}
|
967
|
+
}
|
968
|
+
|
969
|
+
if ( strExt.length() == 0 )
|
970
|
+
{
|
971
|
+
String strFileName = uri.getLastNamePart();
|
972
|
+
int nExt = strFileName != null ? strFileName.lastIndexOf('.') : -1;
|
973
|
+
if ( nExt >= 0 )
|
974
|
+
strExt = strFileName.substring(nExt);
|
975
|
+
}
|
976
|
+
|
977
|
+
if ( strExt.length() == 0 )
|
978
|
+
strExt = ".bin";
|
979
|
+
else if ( strExt.charAt(0) != '.' )
|
980
|
+
strExt = "." + strExt;
|
981
|
+
|
982
|
+
String fName = RhodesApp.getInstance().getBlobsDirPath() + "/id_" + TimeInterval.getCurrentTime().toULong() + strExt;
|
983
|
+
|
984
|
+
return fName;
|
985
|
+
|
986
|
+
/*
|
894
987
|
String strExt = ".bin";
|
895
988
|
URI uri = new URI(value.m_strValue);
|
896
989
|
int nDot = uri.getPath().lastIndexOf('.');
|
@@ -909,7 +1002,7 @@ class SyncSource
|
|
909
1002
|
|
910
1003
|
String fName = RhodesApp.getInstance().getBlobsDirPath() + "/id_" + TimeInterval.getCurrentTime().toULong() + strExt;
|
911
1004
|
|
912
|
-
return fName
|
1005
|
+
return fName;*/
|
913
1006
|
}
|
914
1007
|
|
915
1008
|
boolean downloadBlob(CAttrValue value)throws Exception
|