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.
Files changed (99) hide show
  1. data/CHANGELOG +13 -0
  2. data/Rakefile +1 -1
  3. data/bin/c2dm.rb +59 -0
  4. data/lib/extensions/barcode/ext/barcode/platform/iphone/Rakefile +4 -0
  5. data/lib/framework/rho/rho.rb +2 -0
  6. data/lib/framework/rho/rhoapplication.rb +1 -0
  7. data/lib/framework/rhodes.rb +1 -1
  8. data/lib/framework/version.rb +1 -1
  9. data/lib/rhodes.rb +1 -1
  10. data/platform/android/Rhodes/AndroidManifest.xml +1 -1
  11. data/platform/android/Rhodes/jni/src/callbacks.cpp +21 -0
  12. data/platform/android/Rhodes/jni/src/nativebar.cpp +4 -0
  13. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhoActivity.java +3 -1
  14. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +68 -7
  15. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesService.java +113 -10
  16. data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +34 -3
  17. data/platform/android/Rhodes/src/com/rhomobile/rhodes/bluetooth/RhoBluetoothManager.java +21 -17
  18. data/platform/android/Rhodes/src/com/rhomobile/rhodes/datetime/DateTimePickerScreen.java +29 -5
  19. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +7 -0
  20. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/ExternalHttpHandler.java +37 -0
  21. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java +0 -1
  22. data/platform/android/build/RhodesSRC_build.files +24 -23
  23. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBStorage.java +6 -0
  24. data/platform/bb/RubyVM/src/com/rho/RhoLogger.java +42 -20
  25. data/platform/bb/RubyVM/src/com/rho/db/DBAdapter.java +111 -19
  26. data/platform/bb/RubyVM/src/com/rho/db/IDBStorage.java +2 -0
  27. data/platform/bb/RubyVM/src/com/rho/net/NetRequest.java +2 -1
  28. data/platform/bb/RubyVM/src/com/rho/net/URI.java +80 -0
  29. data/platform/bb/RubyVM/src/com/rho/sync/SyncEngine.java +21 -1
  30. data/platform/bb/RubyVM/src/com/rho/sync/SyncNotify.java +6 -1
  31. data/platform/bb/RubyVM/src/com/rho/sync/SyncSource.java +139 -46
  32. data/platform/bb/build/bb.rake +8 -3
  33. data/platform/bb/rhodes/platform/5.0/com/rho/RhodesApplicationPlatform.java +32 -21
  34. data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +31 -14
  35. data/platform/bb/rhodes/src/com/rho/file/Jsr75File.java +3 -2
  36. data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +3 -2
  37. data/platform/bb/rhodes/src/com/rho/rubyext/System.java +28 -0
  38. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +111 -26
  39. data/platform/iphone/Classes/AppManager/AppManager.m +22 -0
  40. data/platform/iphone/Classes/DateTimePickerDelegate.m +3 -0
  41. data/platform/iphone/Classes/MapView/MapViewController.h +8 -3
  42. data/platform/iphone/Classes/MapView/MapViewController.m +63 -12
  43. data/platform/iphone/Classes/NativeBar.h +4 -3
  44. data/platform/iphone/Classes/NativeBar.m +28 -1
  45. data/platform/iphone/Classes/Rhodes.m +87 -20
  46. data/platform/iphone/Classes/Signature/SignatureView.m +16 -10
  47. data/platform/iphone/Classes/Signature/SignatureViewController.m +2 -0
  48. data/platform/iphone/Classes/SimpleMainView.h +2 -0
  49. data/platform/iphone/Classes/SimpleMainView.m +120 -35
  50. data/platform/iphone/Classes/SplashViewController.h +8 -1
  51. data/platform/iphone/Classes/SplashViewController.m +233 -11
  52. data/platform/iphone/Classes/SplitView/LeftViewController.h +30 -0
  53. data/platform/iphone/Classes/SplitView/LeftViewController.m +189 -0
  54. data/platform/iphone/Classes/SplitView/RightViewController.h +54 -0
  55. data/platform/iphone/Classes/SplitView/RightViewController.m +268 -0
  56. data/platform/iphone/Classes/SplitView/SplitViewDelegate.h +22 -0
  57. data/platform/iphone/Classes/SplitView/SplitViewDelegate.m +92 -0
  58. data/platform/iphone/Classes/SplitView/SplittedMainView.h +65 -0
  59. data/platform/iphone/Classes/SplitView/SplittedMainView.m +304 -0
  60. data/platform/iphone/Classes/TabbedMainView.m +23 -6
  61. data/platform/iphone/Classes/WebView.m +1 -1
  62. data/platform/iphone/Info.plist +11 -2
  63. data/platform/iphone/rbuild/iphone.rake +80 -3
  64. data/platform/iphone/rhorunner.xcodeproj/project.pbxproj +50 -3
  65. data/platform/shared/common/RhoConf.cpp +5 -5
  66. data/platform/shared/db/DBAdapter.cpp +81 -3
  67. data/platform/shared/db/DBAdapter.h +1 -0
  68. data/platform/shared/json/JSONIterator.cpp +5 -0
  69. data/platform/shared/json/JSONIterator.h +1 -0
  70. data/platform/shared/net/CURLNetRequest.cpp +2 -2
  71. data/platform/shared/net/URI.cpp +53 -0
  72. data/platform/shared/net/URI.h +5 -1
  73. data/platform/shared/ruby/ext/system/system.i +9 -1
  74. data/platform/shared/ruby/ext/system/system_wrap.c +2632 -2574
  75. data/platform/shared/ruby/win32/win32.c +2 -0
  76. data/platform/shared/ruby/wince/direct.c +4 -0
  77. data/platform/shared/sync/SyncEngine.cpp +20 -1
  78. data/platform/shared/sync/SyncEngine.h +6 -1
  79. data/platform/shared/sync/SyncNotify.cpp +6 -1
  80. data/platform/shared/sync/SyncSource.cpp +130 -74
  81. data/platform/shared/sync/SyncSource.h +3 -1
  82. data/platform/wm/rhodes.sln +30 -22
  83. data/platform/wm/rhodes/Alert.cpp +4 -3
  84. data/platform/wm/rhodes/MainWindow.cpp +73 -20
  85. data/platform/wm/rhodes/RingtoneManager.cpp +4 -4
  86. data/platform/wm/rhodes/RingtoneManager.h +2 -1
  87. data/platform/wm/rhodes/Vibrate.cpp +1 -2
  88. data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +37 -0
  89. data/platform/wm/rhodes/rhodes.vcproj +219 -5
  90. data/platform/wm/rhodes/stdafx.h +1 -0
  91. data/platform/wm/rubylib/rubylib.vcproj +10 -8
  92. data/platform/wm/sqlite3/sqlite3.vcproj +6 -4
  93. data/platform/wm/syncengine/syncengine.vcproj +7 -5
  94. data/platform/wm/tcmalloc/tcmalloc.vcproj +11 -8
  95. data/rakefile.rb +1 -1
  96. data/res/generators/templates/application/public/jqtouch/jqtouch.js +9 -1
  97. data/rhodes.gemspec +1 -1
  98. data/spec/phone_spec/app/spec/bulksync_spec.rb +71 -1
  99. 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
- checkDBVersion();
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
- IDBStorage db = null;
786
+ DBAdapter db = null;
699
787
  try{
700
- db = RhoClassFactory.createDBStorage();
701
- db.open( fDbName, "" );
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", this.m_dbStorage, db );
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", this.m_dbStorage, db );
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
- copyTable("sources", db, dbUser.m_dbStorage );
812
+ copyTable("sources", db.m_dbStorage, dbUser.m_dbStorage );
813
+ dbUser.endTransaction();
721
814
  }
722
-
723
- db.commit();
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
- try {
773
- if ( db != null)
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);
@@ -19,4 +19,6 @@ public interface IDBStorage {
19
19
  public abstract void setDbCallback(IDBCallback callback);
20
20
 
21
21
  public abstract String[] getAllTableNames()throws DBException;
22
+
23
+ public boolean isDbFileExists(String strPath);
22
24
  }
@@ -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
- strBody += (src == null && strParams.length() == 0) ? "complete" : "ok";
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
- strBody += "\"" + strUpdateType + "\":{";
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
- getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), strUpdateType );
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
- getDB().startTransaction();
573
- if ( oCmds.hasName("metadata") && getSync().isContinueSync() )
603
+ if ( oCmds.hasName("schema-changed") )
574
604
  {
575
- String strMetadata = oCmds.getString("metadata");
576
- getDB().executeSQL("UPDATE sources SET metadata=? WHERE source_id=?", strMetadata, getID() );
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
- // oo conflicts
711
- for( int i = 0; i < (int)vecAttrs.size(); i++ )
751
+ if ( getSyncType().compareTo("none") != 0 )
712
752
  {
713
- getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1",
714
- strObject, vecAttrs.elementAt(i), getID() );
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
- getNotify().onObjectChanged(getID(),strObject, SyncNotify.enUpdate);
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
- getNotify().onObjectChanged(getID(), strObject, SyncNotify.enDelete);
766
- // oo conflicts
767
- for( int i = 0; i < (int)vecAttrs.size(); i++ )
811
+ if ( getSyncType().compareTo("none") != 0 )
768
812
  {
769
- getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?",
770
- strObject, vecAttrs.elementAt(i), getID() );
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
- // oo conflicts
864
- getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1",
865
- strObject, oAttrValue.m_strAttrib, getID() );
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
- getNotify().onObjectChanged(getID(),strObject, SyncNotify.enUpdate);
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
- getNotify().onObjectChanged(getID(), strObject, SyncNotify.enDelete);
875
- // oo conflicts
876
- getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?", strObject, oAttrValue.m_strAttrib, getID() );
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