rhodes 1.5.5 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (529) hide show
  1. data/CHANGELOG +5 -0
  2. data/Manifest.txt +214 -32
  3. data/Rakefile +33 -10
  4. data/bin/upgrade-rhodes-app +0 -1
  5. data/lib/build/compileERB/bb.rb +2 -2
  6. data/lib/build/compileERB/default.rb +7 -5
  7. data/lib/build/jake.rb +1 -1
  8. data/lib/extensions/digest-md5/ext.yml +1 -1
  9. data/lib/extensions/digest-md5/ext/Rakefile +35 -36
  10. data/lib/extensions/digest-md5/ext/build.bat +1 -0
  11. data/lib/extensions/digest-md5/ext/digest-md5.vcproj +203 -0
  12. data/lib/extensions/digest-sha1/ext.yml +1 -1
  13. data/lib/extensions/digest/ext.yml +1 -1
  14. data/lib/extensions/digest/ext/Rakefile +35 -39
  15. data/lib/extensions/digest/ext/build.bat +1 -2
  16. data/lib/extensions/digest/ext/digest.vcproj +203 -0
  17. data/lib/framework/rho/render.rb +79 -22
  18. data/lib/framework/rho/rho.rb +294 -56
  19. data/lib/framework/rho/rhoapplication.rb +10 -0
  20. data/lib/framework/rho/rhofsconnector.rb +2 -6
  21. data/lib/framework/rho/rhoutils.rb +56 -14
  22. data/lib/framework/rho/rhoviewhelpers.rb +2 -0
  23. data/lib/framework/rhodes.rb +2 -2
  24. data/lib/framework/rhom/rhom.rb +42 -15
  25. data/lib/framework/rhom/rhom_db_adapter.rb +165 -159
  26. data/lib/framework/rhom/rhom_object.rb +0 -1
  27. data/lib/framework/rhom/rhom_object_factory.rb +343 -166
  28. data/lib/framework/rhom/rhom_source.rb +28 -15
  29. data/lib/framework/version.rb +2 -2
  30. data/lib/rhodes.rb +2 -2
  31. data/platform/android/Rhodes/AndroidManifest.xml +2 -2
  32. data/platform/android/Rhodes/gen/com/rhomobile/rhodes/R.java +39 -44
  33. data/platform/android/Rhodes/jni/include/JNIRhodes.h +1 -1
  34. data/platform/android/Rhodes/jni/include/details/rhojava.inc +23 -20
  35. data/platform/android/Rhodes/jni/include/jni/com_rhomobile_rhodes_RhoMenu.h +61 -0
  36. data/platform/android/Rhodes/jni/include/jni/com_rhomobile_rhodes_Rhodes.h +16 -0
  37. data/platform/android/Rhodes/jni/include/jni/com_rhomobile_rhodes_alert_Alert.h +21 -0
  38. data/platform/android/Rhodes/jni/include/sslimpl.h +1 -1
  39. data/platform/android/Rhodes/jni/src/alert.cpp +32 -5
  40. data/platform/android/Rhodes/jni/src/callbacks.cpp +51 -21
  41. data/platform/android/Rhodes/jni/src/mapview.cpp +3 -8
  42. data/platform/android/Rhodes/jni/src/menu.cpp +70 -0
  43. data/platform/android/Rhodes/jni/src/navbar.cpp +16 -0
  44. data/platform/android/Rhodes/jni/src/rhodes.cpp +37 -0
  45. data/platform/android/Rhodes/jni/src/sslimpl.cpp +3 -3
  46. data/platform/android/Rhodes/jni/src/webview.cpp +21 -7
  47. data/platform/android/Rhodes/res/drawable/alert_alert.png +0 -0
  48. data/platform/android/Rhodes/res/drawable/alert_info.png +0 -0
  49. data/platform/android/Rhodes/res/drawable/alert_question.png +0 -0
  50. data/platform/android/Rhodes/res/drawable/camera.png +0 -0
  51. data/platform/android/Rhodes/res/layout/camera.xml +18 -3
  52. data/platform/android/Rhodes/res/menu/options.xml +0 -10
  53. data/platform/android/Rhodes/src/com/rhomobile/rhodes/AndroidR.java +5 -10
  54. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Capabilities.java +12 -0
  55. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhoMenu.java +105 -0
  56. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +157 -122
  57. data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +7 -58
  58. data/platform/android/Rhodes/src/com/rhomobile/rhodes/WebView.java +16 -0
  59. data/platform/android/Rhodes/src/com/rhomobile/rhodes/alert/Alert.java +220 -17
  60. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/Camera.java +22 -4
  61. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/ImageCapture.java +44 -25
  62. data/platform/android/Rhodes/src/com/rhomobile/rhodes/geolocation/GeoLocation.java +10 -0
  63. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/MainView.java +3 -0
  64. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +10 -21
  65. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +15 -12
  66. data/platform/android/Rhodes/src/com/rhomobile/rhodes/phonebook/Phonebook.java +44 -0
  67. data/platform/android/Rhodes/src/com/rhomobile/rhodes/socket/SSLImpl.java +47 -3
  68. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java +13 -6
  69. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/TelUriHandler.java +11 -5
  70. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/UriHandler.java +1 -4
  71. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/VideoUriHandler.java +61 -0
  72. data/platform/android/build/RhodesSRC_build.files +3 -0
  73. data/platform/android/build/android.rake +173 -60
  74. data/platform/android/build/androidcommon.rb +1 -2
  75. data/platform/android/build/librhocommon_build.files +5 -0
  76. data/platform/android/build/librhodes_build.files +2 -0
  77. data/platform/android/build/libruby_build.files +2 -1
  78. data/platform/bb/Hsqldb/Hsqldb.jdp +0 -3
  79. data/platform/bb/Hsqldb/src/com/rho/db/FileUtilBB.java +1 -1
  80. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBResult.java +16 -1
  81. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBRowResult.java +5 -0
  82. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBStorage.java +25 -4
  83. data/platform/bb/Hsqldb/src/com/rho/db/Journal.java +1 -1
  84. data/platform/bb/Hsqldb/src/com/rho/file/FileAccessBB.java +0 -1
  85. data/platform/bb/Hsqldb/src/j2me/math/Number.java +6 -3
  86. data/platform/bb/Hsqldb/src/org/hsqldb/CompiledStatementExecutor.java +2 -1
  87. data/platform/bb/Hsqldb/src/org/hsqldb/Expression.java +1 -0
  88. data/platform/bb/Hsqldb/src/org/hsqldb/Parser.java +1 -0
  89. data/platform/bb/Hsqldb/src/org/hsqldb/Result.java +2 -0
  90. data/platform/bb/Hsqldb/src/org/hsqldb/Select.java +12 -6
  91. data/platform/bb/Hsqldb/src/org/hsqldb/Session.java +19 -12
  92. data/platform/bb/Hsqldb/src/org/hsqldb/Table.java +10 -4
  93. data/platform/bb/Hsqldb/src/org/hsqldb/Token.java +10 -2
  94. data/platform/bb/Hsqldb/src/org/hsqldb/Tokenizer.java +3 -3
  95. data/platform/bb/Hsqldb/src/org/hsqldb/lib/java/JavaSystem.java +1 -1
  96. data/platform/bb/Hsqldb/src/org/hsqldb/persist/HsqlProperties.java +2 -1
  97. data/platform/bb/Hsqldb/src/org/hsqldb/persist/ScaledRAFile.java +1 -1
  98. data/platform/bb/Hsqldb/src/org/hsqldb/scriptio/ScriptReaderText.java +1 -1
  99. data/platform/bb/Hsqldb/src/org/hsqldb/scriptio/ScriptWriterBase.java +1 -1
  100. data/platform/bb/RubyVM/RubyVM.jdp +9 -10
  101. data/platform/bb/build/RubyVM_build.files +9 -7
  102. data/platform/bb/build/bb.rake +13 -3
  103. data/platform/bb/build/hsqldb_build.files +0 -2
  104. data/platform/bb/build/rhodes_build.files +5 -2
  105. data/platform/bb/rhodes/platform/4.7/com/rho/RhoMainScreen.java +8 -0
  106. data/platform/bb/rhodes/platform/5.0/com/rho/BrowserAdapter5.java +154 -0
  107. data/platform/bb/rhodes/platform/5.0/com/rho/RhoMainScreen.java +8 -0
  108. data/platform/bb/rhodes/platform/common/com/rho/BrowserAdapter5.java +28 -0
  109. data/platform/bb/rhodes/rhodes.jdp +12 -7
  110. data/platform/bb/rhodes/src/com/rho/BrowserAdapter.java +331 -0
  111. data/platform/bb/rhodes/src/com/rho/BrowserAdapter5.java +28 -0
  112. data/platform/bb/rhodes/src/com/rho/IBrowserAdapter.java +10 -0
  113. data/platform/bb/rhodes/src/com/rho/RhoMainScreen.java +4 -0
  114. data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +2 -4
  115. data/platform/bb/rhodes/src/com/rho/{Jsr75File.java → file/Jsr75File.java} +83 -36
  116. data/platform/bb/{Hsqldb → rhodes}/src/com/rho/file/Jsr75RAFileImpl.java +0 -1
  117. data/platform/bb/{Hsqldb → rhodes}/src/com/rho/file/PersistRAFileImpl.java +0 -2
  118. data/platform/bb/rhodes/src/com/rho/net/NetworkAccess.java +8 -10
  119. data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +1 -1
  120. data/platform/bb/rhodes/src/com/rho/rubyext/GeoLocation.java +39 -0
  121. data/platform/bb/rhodes/src/com/rho/rubyext/System.java +63 -2
  122. data/platform/bb/rhodes/src/com/rho/rubyext/WebView.java +100 -0
  123. data/platform/bb/rhodes/src/rhomobile/LogScreen.java +1 -1
  124. data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +13 -1
  125. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +138 -492
  126. data/platform/bb/rhodes/src/rhomobile/SecondaryResourceFetchThread.java +11 -2
  127. data/platform/bb/rhodes/src/rhomobile/Utilities.java +14 -10
  128. data/platform/bb/rhodes/src/rhomobile/camera/CameraScreen.java +5 -14
  129. data/platform/bb/rhodes/src/rhomobile/camera/ImageBrowserScreen.java +1 -1
  130. data/platform/bb/rhodes/src/rhomobile/mapview/GoogleMapField.java +2 -2
  131. data/platform/iphone/Classes/AppManager/AppManager.m +37 -14
  132. data/platform/iphone/Classes/Camera/PickImageDelegate.h +15 -4
  133. data/platform/iphone/Classes/Camera/PickImageDelegate.m +53 -50
  134. data/platform/iphone/Classes/DateTimePicker.h +17 -0
  135. data/platform/iphone/Classes/DateTimePicker.m +35 -0
  136. data/platform/iphone/Classes/GeoLocation/LocationController.m +2 -3
  137. data/platform/iphone/Classes/LogOptionsController.m +3 -2
  138. data/platform/iphone/Classes/LogViewController.m +4 -2
  139. data/platform/iphone/Classes/MapView/GoogleGeocoder.m +12 -20
  140. data/platform/iphone/Classes/MapView/MapAnnotation.h +9 -13
  141. data/platform/iphone/Classes/MapView/MapAnnotation.m +17 -65
  142. data/platform/iphone/Classes/MapView/MapViewController.h +1 -7
  143. data/platform/iphone/Classes/MapView/MapViewController.m +51 -25
  144. data/platform/iphone/Classes/NativeBar.h +0 -12
  145. data/platform/iphone/Classes/NativeBar.m +121 -2
  146. data/platform/iphone/Classes/NavBar.h +16 -0
  147. data/platform/iphone/Classes/NavBar.m +115 -0
  148. data/platform/iphone/Classes/RhoAlert.h +19 -0
  149. data/platform/iphone/Classes/RhoAlert.m +258 -0
  150. data/platform/iphone/Classes/RhoDelegate.m +1 -0
  151. data/platform/iphone/Classes/RhoMainView.h +33 -0
  152. data/platform/iphone/Classes/Rhodes.h +56 -0
  153. data/platform/iphone/Classes/Rhodes.m +533 -0
  154. data/platform/iphone/Classes/RingtoneManager.h +17 -0
  155. data/platform/iphone/Classes/RingtoneManager.m +73 -0
  156. data/platform/iphone/Classes/SimpleMainView.h +30 -0
  157. data/platform/iphone/Classes/SimpleMainView.m +380 -0
  158. data/platform/iphone/Classes/TabbedMainView.h +24 -0
  159. data/platform/iphone/Classes/TabbedMainView.m +202 -0
  160. data/platform/iphone/Classes/WebView.m +123 -0
  161. data/platform/iphone/Classes/rho/net/NetRequestImpl.m +2 -2
  162. data/platform/iphone/Classes/rho/net/sslimpl.cpp +13 -1
  163. data/platform/iphone/Classes/rho/net/sslimpl.h +1 -1
  164. data/platform/iphone/Info.plist +1 -1
  165. data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +44 -0
  166. data/platform/iphone/main.m +1 -2
  167. data/platform/iphone/rbuild/iphone.rake +8 -16
  168. data/platform/iphone/rhoextlib/dosyscall.c +1 -1
  169. data/platform/iphone/rhoextlib/rhoextlib.xcodeproj/project.pbxproj +6 -4
  170. data/platform/iphone/rhorubylib/rhorubylib.xcodeproj/project.pbxproj +12 -0
  171. data/platform/iphone/rhorunner.xcodeproj/project.pbxproj +97 -62
  172. data/platform/iphone/rhosynclib/rhosynclib.xcodeproj/project.pbxproj +12 -0
  173. data/platform/osx/Rhodes Launcher/launch.rb +14 -21
  174. data/platform/shared/common/AppMenu.cpp +122 -0
  175. data/platform/shared/common/AppMenu.h +46 -0
  176. data/platform/shared/common/PosixThreadImpl.cpp +1 -1
  177. data/platform/shared/common/RhoConf.cpp +27 -2
  178. data/platform/shared/common/RhoConf.h +5 -0
  179. data/platform/shared/common/RhoFilePath.h +21 -0
  180. data/platform/shared/common/RhoStd.h +44 -5
  181. data/platform/shared/common/RhoTime.h +20 -7
  182. data/platform/shared/common/RhodesApp.cpp +236 -177
  183. data/platform/shared/common/RhodesApp.h +36 -13
  184. data/platform/shared/common/SplashScreen.cpp +2 -2
  185. data/platform/shared/common/StringConverter.h +10 -11
  186. data/platform/shared/common/rhoparams.c +0 -6
  187. data/platform/shared/curl/lib/rhossl.c +3 -2
  188. data/platform/shared/curl/lib/url.c +0 -5
  189. data/platform/shared/db/DBAdapter.cpp +304 -81
  190. data/platform/shared/db/DBAdapter.h +24 -7
  191. data/platform/shared/db/DBAttrManager.cpp +83 -30
  192. data/platform/shared/db/DBAttrManager.h +6 -0
  193. data/platform/shared/db/DBResult.h +15 -4
  194. data/platform/shared/json/JSONIterator.cpp +100 -3
  195. data/platform/shared/json/JSONIterator.h +28 -3
  196. data/platform/shared/net/AsyncHttp.cpp +25 -22
  197. data/platform/shared/net/AsyncHttp.h +10 -6
  198. data/platform/shared/net/CURLNetRequest.cpp +115 -36
  199. data/platform/shared/net/CURLNetRequest.h +6 -0
  200. data/platform/shared/net/HttpServer.cpp +6 -4
  201. data/platform/shared/net/HttpServer.h +0 -1
  202. data/platform/shared/net/INetRequest.h +19 -3
  203. data/platform/shared/net/URI.cpp +2 -2
  204. data/platform/shared/net/ssl.cpp +2 -2
  205. data/platform/shared/net/ssl.h +2 -2
  206. data/platform/shared/ruby/ext/alert/alert.i +14 -2
  207. data/platform/shared/ruby/ext/alert/alert_wrap.c +40 -20
  208. data/platform/shared/ruby/ext/asynchttp/asynchttp.i +8 -8
  209. data/platform/shared/ruby/ext/asynchttp/asynchttp_wrap.c +112 -16
  210. data/platform/shared/ruby/ext/geolocation/geolocation.i +16 -12
  211. data/platform/shared/ruby/ext/geolocation/geolocation_wrap.c +481 -125
  212. data/platform/shared/ruby/ext/navbar/navbar.i +20 -0
  213. data/platform/shared/ruby/ext/navbar/navbar_wrap.c +1859 -0
  214. data/platform/shared/ruby/ext/rho/extensions.c +1 -1
  215. data/platform/shared/ruby/ext/rho/rhoruby.c +32 -2
  216. data/platform/shared/ruby/ext/rho/rhoruby.h +7 -2
  217. data/platform/shared/ruby/ext/rhoconf/rhoconf.i +4 -0
  218. data/platform/shared/ruby/ext/rhoconf/rhoconf_wrap.c +31 -0
  219. data/platform/shared/ruby/ext/sqlite3_api/sqlite3_api_wrap.c +188 -3226
  220. data/platform/shared/ruby/ext/syncengine/syncengine.i +14 -25
  221. data/platform/shared/ruby/ext/syncengine/syncengine_wrap.c +96 -104
  222. data/platform/shared/ruby/ext/system/system.i +12 -0
  223. data/platform/shared/ruby/ext/system/system_wrap.c +101 -7
  224. data/platform/shared/ruby/ext/webview/webview.i +20 -15
  225. data/platform/shared/ruby/ext/webview/webview_wrap.c +42 -16
  226. data/platform/shared/ruby/thread_pthread.c +4 -4
  227. data/platform/shared/ruby/thread_win32.c +4 -4
  228. data/platform/shared/ruby/wince/io_wce.c +0 -1
  229. data/platform/shared/rubyJVM/src/com/rho/FilePath.java +18 -2
  230. data/platform/shared/rubyJVM/src/com/rho/IRhoRubyHelper.java +1 -0
  231. data/platform/shared/rubyJVM/src/com/rho/Properties.java +9 -0
  232. data/platform/shared/rubyJVM/src/com/rho/RhoClassFactory.java +2 -3
  233. data/platform/shared/rubyJVM/src/com/rho/RhoConf.java +47 -8
  234. data/platform/shared/rubyJVM/src/com/rho/RhoLogConf.java +1 -0
  235. data/platform/shared/rubyJVM/src/com/rho/RhoLogFileSink.java +1 -0
  236. data/platform/shared/rubyJVM/src/com/rho/RhoRuby.java +43 -5
  237. data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +98 -3
  238. data/platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java +460 -175
  239. data/platform/shared/rubyJVM/src/com/rho/db/DBAttrManager.java +81 -33
  240. data/platform/shared/rubyJVM/src/com/rho/db/IDBCallback.java +3 -5
  241. data/platform/shared/rubyJVM/src/com/rho/db/IDBResult.java +2 -0
  242. data/platform/shared/rubyJVM/src/com/rho/db/IDBStorage.java +2 -0
  243. data/platform/shared/rubyJVM/src/com/rho/{IFile.java → file/IFile.java} +1 -1
  244. data/platform/shared/rubyJVM/src/com/rho/{IFileAccess.java → file/IFileAccess.java} +1 -1
  245. data/platform/shared/rubyJVM/src/com/rho/{IRAFile.java → file/IRAFile.java} +1 -1
  246. data/platform/{bb/Hsqldb/src/com/rho/db → shared/rubyJVM/src/com/rho/file}/RandomAccessFile.java +1 -2
  247. data/platform/shared/rubyJVM/src/com/rho/{SimpleFile.java → file/SimpleFile.java} +5 -1
  248. data/platform/shared/rubyJVM/src/com/rho/net/AsyncHttp.java +23 -18
  249. data/platform/shared/rubyJVM/src/com/rho/net/NetRequest.java +167 -250
  250. data/platform/shared/rubyJVM/src/com/rho/net/RhoConnection.java +100 -30
  251. data/platform/shared/rubyJVM/src/com/rho/net/URI.java +0 -1
  252. data/platform/shared/rubyJVM/src/com/rho/sync/ClientRegister.java +30 -33
  253. data/platform/shared/rubyJVM/src/com/rho/sync/ISyncProtocol.java +20 -0
  254. data/platform/shared/rubyJVM/src/com/rho/sync/JSONEntry.java +5 -0
  255. data/platform/shared/rubyJVM/src/com/rho/sync/JSONStructIterator.java +74 -0
  256. data/platform/shared/rubyJVM/src/com/rho/sync/SyncEngine.java +486 -257
  257. data/platform/shared/rubyJVM/src/com/rho/sync/SyncNotify.java +89 -58
  258. data/platform/shared/rubyJVM/src/com/rho/sync/SyncProtocol_3.java +79 -0
  259. data/platform/shared/rubyJVM/src/com/rho/sync/SyncSource.java +634 -495
  260. data/platform/shared/rubyJVM/src/com/rho/sync/SyncThread.java +74 -90
  261. data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubySymbol_Methods.java +1 -0
  262. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyThread.java +6 -0
  263. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubyRuntime.java +6 -2
  264. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubySymbol.java +17 -1
  265. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubyValue.java +1 -0
  266. data/platform/shared/rubyJVM/src/org/json/me/JSONObject.java +3 -0
  267. data/platform/shared/rubyext/GeoLocation.cpp +23 -0
  268. data/platform/shared/rubyext/GeoLocation.h +2 -0
  269. data/platform/shared/rubyext/RhoRuby.cpp +31 -0
  270. data/platform/shared/rubyext/RhoRuby.h +32 -0
  271. data/platform/shared/rubyext/System.cpp +14 -3
  272. data/platform/shared/rubyext/WebView.h +21 -0
  273. data/platform/shared/sync/ClientRegister.cpp +23 -28
  274. data/platform/shared/sync/ClientRegister.h +6 -2
  275. data/platform/shared/sync/ISyncProtocol.h +29 -0
  276. data/platform/shared/sync/SyncEngine.cpp +450 -190
  277. data/platform/shared/sync/SyncEngine.h +28 -38
  278. data/platform/shared/sync/SyncNotify.cpp +43 -41
  279. data/platform/shared/sync/SyncNotify.h +7 -7
  280. data/platform/shared/sync/SyncProtocol_3.h +86 -0
  281. data/platform/shared/sync/SyncSource.cpp +535 -371
  282. data/platform/shared/sync/SyncSource.h +48 -55
  283. data/platform/shared/sync/SyncThread.cpp +59 -103
  284. data/platform/shared/sync/SyncThread.h +10 -23
  285. data/platform/shared/unzip/unzip.cpp +3 -2
  286. data/platform/shared/unzip/unzip.h +5 -1
  287. data/platform/shared/wtl80/include/atlapp.h +10 -10
  288. data/platform/wm/RhoLib/RhoLib.vcproj +32 -0
  289. data/platform/wm/build/build_inf.js +40 -3
  290. data/platform/wm/build/wm.rake +95 -9
  291. data/platform/wm/rhodes/Alert.cpp +4 -0
  292. data/platform/wm/rhodes/DateTimePicker.cpp +183 -0
  293. data/platform/wm/rhodes/DateTimePicker.h +100 -0
  294. data/platform/wm/rhodes/MainWindow.cpp +222 -209
  295. data/platform/wm/rhodes/MainWindow.h +28 -35
  296. data/platform/wm/rhodes/Rhodes.cpp +20 -60
  297. data/platform/wm/rhodes/Rhodes.rc +41 -7
  298. data/platform/wm/rhodes/Utils.cpp +65 -0
  299. data/platform/wm/rhodes/Utils.h +9 -0
  300. data/platform/wm/rhodes/camera/Camera.cpp +2 -2
  301. data/platform/wm/rhodes/menubar.cpp +2 -33
  302. data/platform/wm/rhodes/menubar.h +0 -14
  303. data/platform/wm/rhodes/resource.h +13 -11
  304. data/platform/wm/rhodes/rho/net/NetRequest.cpp +16 -35
  305. data/platform/wm/rhodes/rho/net/NetRequest.h +8 -2
  306. data/platform/wm/rhodes/rho/net/NetRequestImpl.cpp +264 -46
  307. data/platform/wm/rhodes/rho/net/NetRequestImpl.h +14 -4
  308. data/platform/wm/rhodes/rho/rubyext/GeoLocationImpl.cpp +1 -1
  309. data/platform/wm/rhodes/rho/rubyext/GeoLocationImpl.h +1 -1
  310. data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +77 -4
  311. data/platform/wm/rhodes/rho/rubyext/WebView.cpp +63 -0
  312. data/platform/wm/rhodes/rhodes.vcproj +20 -66
  313. data/platform/wm/rhodes/stdafx.h +22 -0
  314. data/platform/wm/rubylib/rubylib.vcproj +4 -0
  315. data/platform/wm/syncengine/syncengine.vcproj +8 -0
  316. data/platform/wm/tools/detool.sln +66 -0
  317. data/platform/wm/tools/detool/DEMComInterface.tlb +0 -0
  318. data/platform/wm/tools/detool/ReadMe.txt +33 -0
  319. data/platform/wm/tools/detool/detool.cpp +559 -0
  320. data/platform/wm/tools/detool/detool.h +5 -0
  321. data/platform/wm/tools/detool/detool.vcproj +233 -0
  322. data/platform/wm/tools/detool/stdafx.cpp +8 -0
  323. data/platform/wm/tools/detool/stdafx.h +15 -0
  324. data/platform/wm/tools/detool/targetver.h +24 -0
  325. data/platform/wm/tools/rhosetup/ReadMe.txt +41 -0
  326. data/platform/wm/tools/rhosetup/rhosetup.cpp +52 -0
  327. data/platform/wm/tools/rhosetup/rhosetup.vcproj +641 -0
  328. data/platform/wm/tools/rhosetup/stdafx.cpp +8 -0
  329. data/platform/wm/tools/rhosetup/stdafx.h +59 -0
  330. data/rakefile.rb +33 -10
  331. data/res/build-tools/db/syncdb.schema +25 -23
  332. data/res/build-tools/db/syncdb.triggers +1 -1
  333. data/res/build-tools/detool.exe +0 -0
  334. data/res/build-tools/rhosetup.dll +0 -0
  335. data/res/generators/rhogen.rb +27 -22
  336. data/res/generators/templates/application/app/Settings/controller.rb +3 -1
  337. data/res/generators/templates/application/app/Settings/home.bb.erb +17 -0
  338. data/res/generators/templates/application/app/Settings/home.erb +21 -12
  339. data/res/generators/templates/application/app/Settings/index.bb.erb +32 -0
  340. data/res/generators/templates/application/app/Settings/index.erb +44 -15
  341. data/res/generators/templates/application/app/Settings/login.bb.erb +35 -0
  342. data/res/generators/templates/application/app/Settings/login.erb +29 -30
  343. data/res/generators/templates/application/app/Settings/reset.bb.erb +15 -0
  344. data/res/generators/templates/application/app/Settings/reset.erb +16 -13
  345. data/res/generators/templates/application/app/Settings/wait.bb.erb +3 -0
  346. data/res/generators/templates/application/app/Settings/wait.erb +4 -4
  347. data/res/generators/templates/application/app/application.rb +8 -0
  348. data/res/generators/templates/application/app/helpers/browser_helper.rb +13 -0
  349. data/res/generators/templates/application/app/index.bb.erb +26 -0
  350. data/res/generators/templates/application/app/index.erb +21 -12
  351. data/res/generators/templates/application/app/layout.erb +9 -11
  352. data/res/generators/templates/application/public/css/android.css +285 -0
  353. data/res/generators/templates/application/public/css/blackberry.css +85 -78
  354. data/res/generators/templates/application/public/css/iphone.css +286 -296
  355. data/res/generators/templates/application/public/css/webkit.css +34 -0
  356. data/res/generators/templates/application/public/css/windows_mobile.css +208 -0
  357. data/res/generators/templates/application/public/icons/Read me first - license.txt +14 -0
  358. data/res/generators/templates/application/public/icons/about.png +0 -0
  359. data/res/generators/templates/application/public/icons/airplane.png +0 -0
  360. data/res/generators/templates/application/public/icons/baby.png +0 -0
  361. data/res/generators/templates/application/public/icons/badge.png +0 -0
  362. data/res/generators/templates/application/public/icons/bandaid.png +0 -0
  363. data/res/generators/templates/application/public/icons/bar-chart.png +0 -0
  364. data/res/generators/templates/application/public/icons/battery.png +0 -0
  365. data/res/generators/templates/application/public/icons/beaker.png +0 -0
  366. data/res/generators/templates/application/public/icons/beaker2.png +0 -0
  367. data/res/generators/templates/application/public/icons/beermug.png +0 -0
  368. data/res/generators/templates/application/public/icons/bird.png +0 -0
  369. data/res/generators/templates/application/public/icons/book.png +0 -0
  370. data/res/generators/templates/application/public/icons/bookmark.png +0 -0
  371. data/res/generators/templates/application/public/icons/brightness.png +0 -0
  372. data/res/generators/templates/application/public/icons/bug.png +0 -0
  373. data/res/generators/templates/application/public/icons/cabinet.png +0 -0
  374. data/res/generators/templates/application/public/icons/calendar.png +0 -0
  375. data/res/generators/templates/application/public/icons/camera.png +0 -0
  376. data/res/generators/templates/application/public/icons/changeName.rb +22 -0
  377. data/res/generators/templates/application/public/icons/chat2.png +0 -0
  378. data/res/generators/templates/application/public/icons/chicken.png +0 -0
  379. data/res/generators/templates/application/public/icons/clock.png +0 -0
  380. data/res/generators/templates/application/public/icons/cloud.png +0 -0
  381. data/res/generators/templates/application/public/icons/coffee.png +0 -0
  382. data/res/generators/templates/application/public/icons/compass.png +0 -0
  383. data/res/generators/templates/application/public/icons/contrast.png +0 -0
  384. data/res/generators/templates/application/public/icons/dashboard.png +0 -0
  385. data/res/generators/templates/application/public/icons/display.png +0 -0
  386. data/res/generators/templates/application/public/icons/dogpaw.png +0 -0
  387. data/res/generators/templates/application/public/icons/download.png +0 -0
  388. data/res/generators/templates/application/public/icons/dumbbell.png +0 -0
  389. data/res/generators/templates/application/public/icons/ekg.png +0 -0
  390. data/res/generators/templates/application/public/icons/envelope.png +0 -0
  391. data/res/generators/templates/application/public/icons/equalizer.png +0 -0
  392. data/res/generators/templates/application/public/icons/eye.png +0 -0
  393. data/res/generators/templates/application/public/icons/film-roll.png +0 -0
  394. data/res/generators/templates/application/public/icons/flag.png +0 -0
  395. data/res/generators/templates/application/public/icons/fork-and-knife.png +0 -0
  396. data/res/generators/templates/application/public/icons/fuel.png +0 -0
  397. data/res/generators/templates/application/public/icons/gameplan.png +0 -0
  398. data/res/generators/templates/application/public/icons/gear.png +0 -0
  399. data/res/generators/templates/application/public/icons/gear2.png +0 -0
  400. data/res/generators/templates/application/public/icons/gift.png +0 -0
  401. data/res/generators/templates/application/public/icons/heart.png +0 -0
  402. data/res/generators/templates/application/public/icons/house.png +0 -0
  403. data/res/generators/templates/application/public/icons/inbox.png +0 -0
  404. data/res/generators/templates/application/public/icons/index-cards.png +0 -0
  405. data/res/generators/templates/application/public/icons/iphone.png +0 -0
  406. data/res/generators/templates/application/public/icons/ipod.png +0 -0
  407. data/res/generators/templates/application/public/icons/key.png +0 -0
  408. data/res/generators/templates/application/public/icons/lifebuoy.png +0 -0
  409. data/res/generators/templates/application/public/icons/lightbulb.png +0 -0
  410. data/res/generators/templates/application/public/icons/line-chart.png +0 -0
  411. data/res/generators/templates/application/public/icons/location.png +0 -0
  412. data/res/generators/templates/application/public/icons/lock.png +0 -0
  413. data/res/generators/templates/application/public/icons/loopback.png +0 -0
  414. data/res/generators/templates/application/public/icons/magnifying-glass.png +0 -0
  415. data/res/generators/templates/application/public/icons/map-marker.png +0 -0
  416. data/res/generators/templates/application/public/icons/map.png +0 -0
  417. data/res/generators/templates/application/public/icons/medical-bag.png +0 -0
  418. data/res/generators/templates/application/public/icons/medical.png +0 -0
  419. data/res/generators/templates/application/public/icons/microphone.png +0 -0
  420. data/res/generators/templates/application/public/icons/movie1.png +0 -0
  421. data/res/generators/templates/application/public/icons/movie2.png +0 -0
  422. data/res/generators/templates/application/public/icons/network.png +0 -0
  423. data/res/generators/templates/application/public/icons/note.png +0 -0
  424. data/res/generators/templates/application/public/icons/outlet.png +0 -0
  425. data/res/generators/templates/application/public/icons/palette.png +0 -0
  426. data/res/generators/templates/application/public/icons/paperclip.png +0 -0
  427. data/res/generators/templates/application/public/icons/phone.png +0 -0
  428. data/res/generators/templates/application/public/icons/photos.png +0 -0
  429. data/res/generators/templates/application/public/icons/piano.png +0 -0
  430. data/res/generators/templates/application/public/icons/picture-frame.png +0 -0
  431. data/res/generators/templates/application/public/icons/pill.png +0 -0
  432. data/res/generators/templates/application/public/icons/pin.png +0 -0
  433. data/res/generators/templates/application/public/icons/pinetree.png +0 -0
  434. data/res/generators/templates/application/public/icons/planet.png +0 -0
  435. data/res/generators/templates/application/public/icons/puzzle.png +0 -0
  436. data/res/generators/templates/application/public/icons/radar.png +0 -0
  437. data/res/generators/templates/application/public/icons/redo.png +0 -0
  438. data/res/generators/templates/application/public/icons/refresh.png +0 -0
  439. data/res/generators/templates/application/public/icons/runner.png +0 -0
  440. data/res/generators/templates/application/public/icons/shoebox.png +0 -0
  441. data/res/generators/templates/application/public/icons/shopping-bag.png +0 -0
  442. data/res/generators/templates/application/public/icons/shopping-cart.png +0 -0
  443. data/res/generators/templates/application/public/icons/shuffle.png +0 -0
  444. data/res/generators/templates/application/public/icons/signpost.png +0 -0
  445. data/res/generators/templates/application/public/icons/skull-n-crossbones.png +0 -0
  446. data/res/generators/templates/application/public/icons/skull.png +0 -0
  447. data/res/generators/templates/application/public/icons/sliders.png +0 -0
  448. data/res/generators/templates/application/public/icons/spraycan.png +0 -0
  449. data/res/generators/templates/application/public/icons/squiggle.png +0 -0
  450. data/res/generators/templates/application/public/icons/star.png +0 -0
  451. data/res/generators/templates/application/public/icons/stopwatch.png +0 -0
  452. data/res/generators/templates/application/public/icons/suitcase.png +0 -0
  453. data/res/generators/templates/application/public/icons/tag.png +0 -0
  454. data/res/generators/templates/application/public/icons/tags.png +0 -0
  455. data/res/generators/templates/application/public/icons/target.png +0 -0
  456. data/res/generators/templates/application/public/icons/testtube.png +0 -0
  457. data/res/generators/templates/application/public/icons/thermometer.png +0 -0
  458. data/res/generators/templates/application/public/icons/toolbox.png +0 -0
  459. data/res/generators/templates/application/public/icons/trophy.png +0 -0
  460. data/res/generators/templates/application/public/icons/tshirt.png +0 -0
  461. data/res/generators/templates/application/public/icons/tv.png +0 -0
  462. data/res/generators/templates/application/public/icons/umbrella.png +0 -0
  463. data/res/generators/templates/application/public/icons/walk.png +0 -0
  464. data/res/generators/templates/application/public/icons/weather.png +0 -0
  465. data/res/generators/templates/application/public/icons/widescreen.png +0 -0
  466. data/res/generators/templates/application/public/icons/wineglass.png +0 -0
  467. data/res/generators/templates/application/public/icons/zap.png +0 -0
  468. data/res/generators/templates/application/public/images/android/btn_check_off.png +0 -0
  469. data/res/generators/templates/application/public/images/android/btn_check_on.png +0 -0
  470. data/res/generators/templates/application/public/images/android/btn_radio_off.png +0 -0
  471. data/res/generators/templates/application/public/images/android/btn_radio_on.png +0 -0
  472. data/res/generators/templates/application/public/images/android/ic_menu_more.png +0 -0
  473. data/res/generators/templates/application/public/images/iphone/disclosure.png +0 -0
  474. data/res/generators/templates/application/public/images/iphone/disclosure_detail.png +0 -0
  475. data/res/generators/templates/application/public/images/iphone/radiobutton.png +0 -0
  476. data/res/generators/templates/application/public/images/iphone/select.png +0 -0
  477. data/res/generators/templates/application/public/images/iphone/switch.png +0 -0
  478. data/res/generators/templates/application/public/images/listArrow.png +0 -0
  479. data/res/generators/templates/application/public/images/listArrowDown.png +0 -0
  480. data/res/generators/templates/model/controller.rb +2 -0
  481. data/res/generators/templates/model/edit.bb.erb +24 -0
  482. data/res/generators/templates/model/edit.erb +21 -25
  483. data/res/generators/templates/model/index.bb.erb +21 -0
  484. data/res/generators/templates/model/index.erb +28 -14
  485. data/res/generators/templates/model/new.bb.erb +24 -0
  486. data/res/generators/templates/model/new.erb +20 -20
  487. data/res/generators/templates/model/show.bb.erb +21 -0
  488. data/res/generators/templates/model/show.erb +15 -15
  489. data/rhobuild.yml +37 -0
  490. data/rhodes.gemspec +1 -1
  491. data/spec/framework_spec/app/Account/config.rb +57 -1
  492. data/spec/framework_spec/app/Case/config.rb +1 -1
  493. data/spec/framework_spec/app/Customer/config.rb +1 -1
  494. data/spec/framework_spec/app/Product/config.rb +15 -1
  495. data/spec/framework_spec/app/spec/fixtures/object_values.txt +90 -90
  496. data/spec/framework_spec/app/spec/pagination/fixtures/object_values.txt +91 -91
  497. data/spec/framework_spec/app/spec/rho_spec.rb +1 -1
  498. data/spec/framework_spec/app/spec/rhom_object_spec.rb +47 -28
  499. data/spec/framework_spec/app/spec/rhom_spec.rb +8 -8
  500. data/spec/framework_spec/app/spec/spec_helper.rb +13 -5
  501. data/spec/framework_spec/app/spec_runner.rb +5 -4
  502. data/spec/framework_spec/public/css/base.css +0 -1
  503. data/spec/framework_spec/public/css/iphone.css +0 -1
  504. data/spec/framework_spec/rhoconfig.txt +3 -1
  505. metadata +220 -37
  506. data/platform/bb/rhodes/src/rhomobile/WebView.java +0 -90
  507. data/platform/iphone/Classes/BarItem.h +0 -27
  508. data/platform/iphone/Classes/BarItem.m +0 -32
  509. data/platform/iphone/Classes/JSString.h +0 -12
  510. data/platform/iphone/Classes/JSString.m +0 -7
  511. data/platform/iphone/Classes/RhoRunnerAppDelegate.h +0 -48
  512. data/platform/iphone/Classes/RhoRunnerAppDelegate.m +0 -617
  513. data/platform/iphone/Classes/Server/ServerHost.h +0 -81
  514. data/platform/iphone/Classes/Server/ServerHost.m +0 -597
  515. data/platform/iphone/Classes/Server/WebViewUrl.h +0 -13
  516. data/platform/iphone/Classes/Server/WebViewUrl.m +0 -8
  517. data/platform/iphone/Classes/TabBarDelegate.h +0 -39
  518. data/platform/iphone/Classes/TabBarDelegate.m +0 -151
  519. data/platform/iphone/Classes/Utils/unzip.cpp +0 -4328
  520. data/platform/iphone/Classes/Utils/unzip.h +0 -234
  521. data/platform/iphone/Classes/WebViewController.h +0 -59
  522. data/platform/iphone/Classes/WebViewController.m +0 -472
  523. data/platform/wm/rhodes/GetURLDialog.cpp +0 -64
  524. data/platform/wm/rhodes/GetURLDialog.h +0 -39
  525. data/res/generators/templates/application/public/css/base.css +0 -39
  526. data/res/generators/templates/application/public/css/rho.css +0 -3
  527. data/res/generators/templates/application/public/css/xhtml.css +0 -114
  528. data/spec/framework_spec/app/Question/config.rb +0 -3
  529. data/spec/generator_spec/source_generator_spec.rb +0 -27
@@ -1,12 +1,15 @@
1
1
  #include "SyncSource.h"
2
2
  #include "SyncEngine.h"
3
+ #include "SyncThread.h"
3
4
 
4
- #include "common/RhoFilePath.h"
5
5
  #include "common/RhoTime.h"
6
6
  #include "common/StringConverter.h"
7
7
  #include "common/RhodesApp.h"
8
+ #include "common/Tokenizer.h"
9
+ #include "common/RhoFilePath.h"
10
+ #include "common/RhoFile.h"
8
11
  #include "json/JSONIterator.h"
9
- #include "ruby/ext/rho/rhoruby.h"
12
+ #include "rubyext/RhoRuby.h"
10
13
  #include "statistic/RhoProfiler.h"
11
14
 
12
15
  namespace rho {
@@ -17,106 +20,105 @@ using namespace rho::net;
17
20
  using namespace rho::db;
18
21
  using namespace rho::common;
19
22
  using namespace rho::json;
20
-
23
+ /*
21
24
  CSyncSource::CSyncSource() : m_syncEngine( *new CSyncEngine(*new db::CDBAdapter()))
22
25
  {
23
26
  m_bTokenFromDB = true;
24
- m_token = 0;
27
+
25
28
  m_nCurPageCount = 0;
26
29
  m_nInserted = 0;
27
30
  m_nDeleted = 0;
28
31
  m_nTotalCount = 0;
29
32
  m_bGetAtLeastOnePage = false;
30
- m_eSyncServerDataPass = edpNone;
31
33
 
32
34
  m_nErrCode = RhoRuby.ERR_NONE;
33
- m_bSearchSyncChanges = false;
34
- m_nProgressStep = -1;
35
- m_nRefreshTime = 0;
36
- }
37
35
 
38
- CSyncSource::CSyncSource(CSyncEngine& syncEngine ) : m_syncEngine(syncEngine)
36
+ m_bIsSearch = false;
37
+ }
38
+ */
39
+ CSyncSource::CSyncSource(CSyncEngine& syncEngine, db::CDBAdapter& db ) : m_syncEngine(syncEngine), m_dbAdapter(db)
39
40
  {
40
41
  m_bTokenFromDB = true;
41
- m_token = 0;
42
42
 
43
43
  m_nCurPageCount = 0;
44
44
  m_nInserted = 0;
45
45
  m_nDeleted = 0;
46
46
  m_nTotalCount = 0;
47
47
  m_bGetAtLeastOnePage = false;
48
- m_eSyncServerDataPass = edpNone;
49
48
 
50
49
  m_nErrCode = RhoRuby.ERR_NONE;
51
- m_bSearchSyncChanges = false;
52
- m_nProgressStep = -1;
53
- m_nRefreshTime = 0;
50
+ m_bIsSearch = false;
51
+ m_bSchemaSource = db.isTableExist(m_strName);
54
52
  }
55
53
 
56
- CSyncSource::CSyncSource(int id, const String& strUrl, const String& strName, uint64 token, CSyncEngine& syncEngine ) : m_syncEngine(syncEngine)
54
+ CSyncSource::CSyncSource(int id, const String& strName, const String& strSyncType, db::CDBAdapter& db, CSyncEngine& syncEngine ) : m_syncEngine(syncEngine), m_dbAdapter(db)
57
55
  {
58
56
  m_nID = id;
59
- m_strUrl = strUrl;
60
57
  m_strName = strName;
61
- m_token = token;
62
- m_bTokenFromDB = true;
58
+ m_strSyncType = strSyncType;
63
59
 
64
60
  m_nCurPageCount = 0;
65
61
  m_nInserted = 0;
66
62
  m_nDeleted = 0;
67
63
  m_nTotalCount = 0;
68
64
  m_bGetAtLeastOnePage = false;
69
- m_eSyncServerDataPass = edpNone;
70
65
 
71
66
  m_nErrCode = RhoRuby.ERR_NONE;
72
- m_bSearchSyncChanges = false;
73
- m_nProgressStep = -1;
74
- m_nRefreshTime = 0;
67
+ m_bIsSearch = false;
68
+
69
+ DBResult( res, db.executeSQL("SELECT token,links from sources WHERE source_id=?", m_nID) );
70
+ if ( !res.isEnd() )
71
+ {
72
+ m_token = res.getUInt64ByIdx(0);
73
+ m_bTokenFromDB = true;
74
+ }else
75
+ {
76
+ m_token = 0;
77
+ m_bTokenFromDB = true;
78
+ }
79
+
80
+ m_bSchemaSource = db.isTableExist(m_strName);
81
+ parseLinks(res.getStringByIdx(1));
82
+ }
83
+
84
+ void CSyncSource::parseLinks(const String& strLinks)
85
+ {
86
+ if (strLinks.length() == 0 )
87
+ return;
88
+
89
+ CTokenizer oTokenizer( strLinks, "," );
90
+
91
+ String strSrcName = "";
92
+ while (oTokenizer.hasMoreTokens())
93
+ {
94
+ String tok = oTokenizer.nextToken();
95
+ if (tok.length() == 0)
96
+ continue;
97
+
98
+ if ( strSrcName.length() > 0 )
99
+ {
100
+ m_hashLinks.put(strSrcName, tok);
101
+ strSrcName = "";
102
+ }else
103
+ strSrcName = tok;
104
+ }
75
105
  }
76
106
 
77
- CDBAdapter& CSyncSource::getDB(){ return getSync().getDB(); }
78
107
  INetRequest& CSyncSource::getNet(){ return getSync().getNet(); }
79
108
  CSyncNotify& CSyncSource::getNotify(){ return getSync().getNotify(); }
109
+ ISyncProtocol& CSyncSource::getProtocol(){ return getSync().getProtocol(); }
80
110
 
81
111
  void CSyncSource::sync()
82
112
  {
83
113
  getNotify().fireSyncNotification(null, false, RhoRuby.ERR_NONE, RhoRuby.getMessageText("syncronizing") + getName() + "...");
84
114
 
85
115
  CTimeInterval startTime = CTimeInterval::getCurrentTime();
116
+ m_bIsSearch = false;
86
117
 
87
- PROF_START("Pull");
88
118
  if ( isEmptyToken() )
89
119
  processToken(1);
90
120
 
91
- boolean bSyncedServer = false;
92
- if ( m_strParams.length() == 0 || m_bSearchSyncChanges )
93
- {
94
- if ( isPendingClientChanges() )
95
- {
96
- syncServerChanges();
97
- bSyncedServer = true;
98
- }
99
-
100
- if ( bSyncedServer && isPendingClientChanges() )
101
- getSync().setState(CSyncEngine::esStop);
102
- else
103
- {
104
- boolean bSyncClient = false;
105
- {
106
- DBResult( res, getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? LIMIT 1 OFFSET 0", getID()) );
107
- bSyncClient = !res.isEnd();
108
- }
109
- if ( bSyncClient )
110
- {
111
- syncClientChanges();
112
- getAndremoveAsk();
113
- bSyncedServer = false;
114
- }
115
- }
116
- }
117
-
118
- PROF_STOP("Pull");
119
-
121
+ boolean bSyncedServer = syncClientChanges();
120
122
  if ( !bSyncedServer )
121
123
  syncServerChanges();
122
124
 
@@ -129,82 +131,114 @@ void CSyncSource::sync()
129
131
  getID() );
130
132
  }
131
133
 
134
+ boolean CSyncSource::syncClientChanges()
135
+ {
136
+ boolean bSyncedServer = false;
137
+ if ( isPendingClientChanges() )
138
+ {
139
+ syncServerChanges();
140
+ bSyncedServer = true;
141
+ }
142
+
143
+ if ( bSyncedServer && isPendingClientChanges() )
144
+ getSync().setState(CSyncEngine::esStop);
145
+ else
146
+ {
147
+ PROF_START("Pull");
148
+
149
+ boolean bSyncClient = false;
150
+ {
151
+ DBResult( res, getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? LIMIT 1 OFFSET 0", getID()) );
152
+ bSyncClient = !res.isEnd();
153
+ }
154
+ if ( bSyncClient )
155
+ {
156
+ doSyncClientChanges();
157
+ bSyncedServer = false;
158
+ }
159
+
160
+ PROF_STOP("Pull");
161
+ }
162
+
163
+ return bSyncedServer;
164
+ }
165
+
132
166
  boolean CSyncSource::isPendingClientChanges()
133
167
  {
134
168
  DBResult( res, getDB().executeSQL("SELECT object FROM changed_values WHERE source_id=? and update_type='create' and sent>1 LIMIT 1 OFFSET 0", getID()) );
135
169
  return !res.isEnd();
136
170
  }
137
171
 
138
- void CSyncSource::syncClientBlobs(const String& strBaseQuery)
172
+ void CSyncSource::doSyncClientChanges()
139
173
  {
140
- String strQuery;
141
- for( int i = 0; i < (int)m_arSyncBlobs.size(); i ++)
174
+ String arUpdateTypes[] = {"create", "update", "delete"};
175
+ boolean arUpdateSent[] = {false, false, false};
176
+
177
+ m_arMultipartItems.removeAllElements();
178
+ m_arBlobAttrs.removeAllElements();
179
+ String strBody = "{\"source_name\":\"" + getName() + "\",\"client_id\":\"" + getSync().getClientID() + "\"";
180
+ boolean bSend = false;
181
+ int i = 0;
182
+ for( i = 0; i < 3 && getSync().isContinueSync(); i++ )
142
183
  {
143
- CSyncBlob& blob = *m_arSyncBlobs.elementAt(i);
184
+ String strBody1;
185
+ makePushBody_Ver3(strBody1, arUpdateTypes[i]);
186
+ if (strBody1.length() > 0)
187
+ {
188
+ strBody += "," + strBody1;
144
189
 
145
- String strFilePath = RHODESAPP().getRhoRootPath() + "apps" + blob.getFilePath() ;
190
+ String strBlobAttrs = "";
191
+ for ( int j = 0; j < (int)m_arBlobAttrs.size(); j++)
192
+ {
193
+ if ( strBlobAttrs.length() > 0 )
194
+ strBlobAttrs += ",";
146
195
 
147
- strQuery = strBaseQuery + "&" + blob.getBody();
148
- NetResponse( resp, getNet().pushFile(strQuery, strFilePath, &getSync(), null) );
149
- if ( !resp.isOK() )
150
- {
151
- getSync().setState(CSyncEngine::esStop);
152
- if (resp.isResponseRecieved())
153
- m_nErrCode = RhoRuby.ERR_REMOTESERVER;
154
- else
155
- m_nErrCode = RhoRuby.ERR_NETWORK;
156
- return;
157
- }
196
+ strBlobAttrs += "\"" + m_arBlobAttrs.elementAt(j) + "\"";
197
+ }
158
198
 
159
- getDB().startTransaction();
160
- getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and attrib_type=? and value=?", getID(), "blob.file", blob.getFilePath() );
161
- getDB().executeSQL("DELETE FROM object_values WHERE source_id=? and attrib_type=? and value=?", getID(), "blob.file", blob.getFilePath() );
162
- getDB().endTransaction();
163
- }
199
+ if ( strBlobAttrs.length() > 0 )
200
+ strBody += ",\"blob_fields\":[" + strBlobAttrs + "]";
164
201
 
165
- m_arSyncBlobs.clear();
166
- }
202
+ arUpdateSent[i] = true;
203
+ bSend = true;
204
+ }
205
+ }
206
+ strBody += "}";
167
207
 
168
- void CSyncSource::syncClientChanges()
169
- {
170
- const char* arUpdateTypes[] = {"create", "update", "delete"};
171
- for( int i = 0; i < 3 && getSync().isContinueSync(); i++ )
208
+ if ( bSend )
172
209
  {
173
- String strUrl = getUrl() + "/" + arUpdateTypes[i];
174
- strUrl += "objects";
175
- String strQuery = CSyncEngine::SYNC_SOURCE_FORMAT() + "&client_id=" + getSync().getClientID();
210
+ LOG(INFO) + "Push client changes to server. Source: " + getName() + "Size :" + strBody.length();
211
+ LOG(TRACE) + "Push body: " + strBody;
176
212
 
177
- m_arSyncBlobs.removeAllElements();
178
- String strBody;
179
- makePushBody(strBody, arUpdateTypes[i]);
180
- if ( strBody.length() > 0 )
213
+ if ( m_arMultipartItems.size() > 0 )
181
214
  {
182
- LOG(INFO) + "Push client changes to server. Source: " + getName() + "Size :" + strBody.length();
183
- LOG(TRACE) + "Push body: " + strBody;
184
-
185
- NetResponse( resp, getNet().pushData(strUrl+strQuery,strBody, &getSync()) );
215
+ CMultipartItem* pItem = new CMultipartItem();
216
+ CMultipartItem& oItem = *pItem;
217
+ oItem.m_strBody = strBody;
218
+ //oItem.m_strContentType = getProtocol().getContentType();
219
+ oItem.m_strName = "cud";
220
+ m_arMultipartItems.addElement(pItem);
221
+
222
+ NetResponse( resp, getNet().pushMultipartData( getProtocol().getClientChangesUrl(), m_arMultipartItems, &getSync(), null) );
186
223
  if ( !resp.isOK() )
187
224
  {
188
225
  getSync().setState(CSyncEngine::esStop);
189
226
  m_nErrCode = RhoRuby.ERR_REMOTESERVER;
190
- continue;
191
227
  }
192
- }
193
-
194
- if ( m_arSyncBlobs.size() > 0 )
228
+ }else
195
229
  {
196
- LOG(INFO) + "Push blobs to server. Source: " + getName() + "Count :" + m_arSyncBlobs.size();
197
- //oo conflicts
198
- if ( i < 1 ) //create
199
- getDB().executeSQL("UPDATE changed_values SET sent=2 WHERE source_id=? and update_type=? and (attrib_type IS NULL or attrib_type!=?) and sent=1",
200
- getID(), arUpdateTypes[i], "blob.file" );
201
- else
202
- //
203
- getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=? and (attrib_type IS NULL or attrib_type!=? and sent=1)",
204
- getID(), arUpdateTypes[i], "blob.file" );
230
+ NetResponse( resp, getNet().pushData( getProtocol().getClientChangesUrl(), strBody, &getSync()) );
231
+ if ( !resp.isOK() )
232
+ {
233
+ getSync().setState(CSyncEngine::esStop);
234
+ m_nErrCode = RhoRuby.ERR_REMOTESERVER;
235
+ }
236
+ }
237
+ }
205
238
 
206
- syncClientBlobs(strUrl+strQuery);
207
- }else if ( strBody.length() > 0 )
239
+ for( i = 0; i < 3 && getSync().isContinueSync(); i++ )
240
+ {
241
+ if ( arUpdateSent[i] )
208
242
  {
209
243
  //oo conflicts
210
244
  if ( i < 1 ) //create
@@ -214,21 +248,20 @@ void CSyncSource::syncClientChanges()
214
248
  getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=? and sent=1", getID(), arUpdateTypes[i] );
215
249
  }
216
250
  }
251
+
252
+ m_arMultipartItems.removeAllElements();
253
+ m_arBlobAttrs.removeAllElements();
217
254
  }
218
255
 
219
- /*
220
- * Construct the body of the request by filtering
221
- * the attr_filter string. The body format should
222
- * look like the following:
223
- * create: attrvals[][attrib]=<name|industry>&attrvals[][object]=<locallygeneratedid>&attrvals[][value]=<some value>
224
- * update: attrvals[][attrib]=<name|industry>&attrvals[][object]=<remoteid>&attrvals[][value]=<some new value>
225
- * delete: attrvals[][attrib]=<name|industry>&attrvals[][object]=<remoteid>
226
- */
227
- void CSyncSource::makePushBody(String& strBody, const char* szUpdateType)
256
+ //{"source_name":"SampleAdapter","client_id":1,"create":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
257
+ //{"source_name":"SampleAdapter","client_id":1,"update":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
258
+ //{"source_name":"SampleAdapter","client_id":1,"delete":{"1":{"brand":"Apple","name":"iPhone","price":"199.99"}}}
259
+ //{"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"}}}
260
+ void CSyncSource::makePushBody_Ver3(String& strBody, const String& strUpdateType)
228
261
  {
229
262
  getDB().Lock();
230
- DBResult( res , getDB().executeSQL("SELECT attrib, object, value, attrib_type, main_id "
231
- "FROM changed_values where source_id=? and update_type =? and sent<=1 ORDER BY sent DESC", getID(), szUpdateType ) );
263
+ DBResult( res , getDB().executeSQL("SELECT attrib, object, value, attrib_type "
264
+ "FROM changed_values where source_id=? and update_type =? and sent<=1 ORDER BY object", getID(), strUpdateType.c_str() ) );
232
265
 
233
266
  if ( res.isEnd() )
234
267
  {
@@ -236,64 +269,67 @@ void CSyncSource::makePushBody(String& strBody, const char* szUpdateType)
236
269
  return;
237
270
  }
238
271
 
272
+ String strCurObject = "";
273
+ boolean bFirst = true;
239
274
  for( ; !res.isEnd(); res.next() )
240
275
  {
241
- String strSrcBody = "attrvals[][attrib]=" + res.getStringByIdx(0);
242
-
243
- if ( res.getStringByIdx(1).length() > 0 )
244
- strSrcBody += "&attrvals[][object]=" + res.getStringByIdx(1);
245
-
246
- uint64 main_id = res.getUInt64ByIdx(4);
247
- if ( main_id != 0 )
248
- strSrcBody += "&attrvals[][id]=" + convertToStringA(main_id);
249
-
276
+ String strAttrib = res.getStringByIdx(0);
277
+ String strObject = res.getStringByIdx(1);
250
278
  String value = res.getStringByIdx(2);
251
279
  String attribType = res.getStringByIdx(3);
252
280
 
253
- //if ( value.length() > 0 )
281
+ if ( attribType.compare("blob.file") == 0 )
254
282
  {
255
- if ( attribType == "blob.file" )
256
- {
257
- common::CFilePath oBlobPath(value);
258
- strSrcBody += "&attrvals[][value]=";
259
- strSrcBody += oBlobPath.getBaseName();
260
- strSrcBody += "&attrvals[][attrib_type]=blob";
261
-
262
- if ( value.length() > 0 )
263
- m_arSyncBlobs.addElement(new CSyncBlob(strSrcBody,value));
264
- continue;
265
- }else
266
- strSrcBody += "&attrvals[][value]=" + value;
283
+ CMultipartItem* pItem = new CMultipartItem();
284
+ CMultipartItem& oItem = *pItem;
285
+ oItem.m_strFilePath = RHODESAPP().resolveDBFilesPath(value);
286
+ oItem.m_strContentType = "application/octet-stream";
287
+ oItem.m_strName = strAttrib + "-" + strObject;
288
+
289
+ m_arBlobAttrs.addElement(strAttrib);
290
+ m_arMultipartItems.addElement(pItem);
267
291
  }
268
292
 
269
- if ( strBody.length() > 0 )
270
- strBody += "&";
293
+ if ( strBody.length() == 0 )
294
+ strBody += "\"" + strUpdateType + "\":{";
271
295
 
272
- strBody += strSrcBody;
273
- }
296
+ if ( strObject.compare(strCurObject) != 0 )
297
+ {
298
+ if ( strCurObject.length() > 0 )
299
+ {
300
+ if ( !bFirst )
301
+ strBody += "}";
302
+ strBody += ",";
303
+ }
274
304
 
275
- getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), szUpdateType );
276
- getDB().Unlock();
277
- }
305
+ bFirst = true;
306
+ strBody += "\"" + strObject + "\"";
307
+ strCurObject = strObject;
308
+ }
309
+
310
+ if (!bFirst)
311
+ strBody += ",";
278
312
 
279
- void CSyncSource::getAndremoveAsk()
280
- {
281
- String askParams = "";
282
- {
283
- DBResult( res , getDB().executeSQL("SELECT object, attrib, value "
284
- "FROM changed_values WHERE source_id=? and update_type =?", getID(), "ask" ) );
285
- if ( !res.isEnd() )
313
+ if ( strAttrib.length() > 0 )
286
314
  {
287
- askParams = res.getStringByIdx(2);
315
+ if ( bFirst )
316
+ strBody += ":{";
288
317
 
289
- getDB().executeSQL("DELETE FROM object_values WHERE object=? and attrib=? and source_id=?",
290
- res.getStringByIdx(0), res.getStringByIdx(1), getID() );
318
+ strBody += "\"" + strAttrib + "\":\"" + value + "\"";
319
+ bFirst = false;
291
320
  }
292
321
  }
293
322
 
294
- getDB().executeSQL("DELETE FROM changed_values WHERE source_id=? and update_type=?", getID(), "ask" );
323
+ if ( strBody.length() > 0 )
324
+ {
325
+ if ( !bFirst )
326
+ strBody += "}";
327
+
328
+ strBody += "}";
329
+ }
295
330
 
296
- setAskParams(askParams);
331
+ getDB().executeSQL("UPDATE changed_values SET sent=1 WHERE source_id=? and update_type=? and sent=0", getID(), strUpdateType.c_str() );
332
+ getDB().Unlock();
297
333
  }
298
334
 
299
335
  void CSyncSource::syncServerChanges()
@@ -303,25 +339,11 @@ void CSyncSource::syncServerChanges()
303
339
  while( getSync().isContinueSync() )
304
340
  {
305
341
  setCurPageCount(0);
306
- String strUrl = getUrl();
307
- if ( m_strAction.length() > 0 )
308
- strUrl = CFilePath::join( strUrl, m_strAction);
309
-
310
- String strQuery = getSync().SYNC_SOURCE_FORMAT() + "&client_id=" + getSync().getClientID() +
311
- "&p_size=" + getSync().SYNC_PAGE_SIZE() + "&version=" + convertToStringA(getSync().SYNC_VERSION());
312
- if ( m_strParams.length() > 0 )
313
- strQuery += m_strParams;
314
- if( m_strUrlParams.length() > 0 )
315
- strQuery += "&" + m_strUrlParams;
316
-
317
- if ( getAskParams().length() > 0 )
318
- {
319
- strUrl += getSync().SYNC_ASK_ACTION();
320
- strQuery += "&question=" + getAskParams();
321
- }
342
+ String strUrl = getProtocol().getServerQueryUrl("");
343
+ String strQuery = getProtocol().getServerQueryBody(getName(), getSync().getClientID(), getSync().getSyncPageSize());
322
344
 
323
345
  if ( !m_bTokenFromDB && getToken() > 1 )
324
- strQuery += "&ack_token=" + convertToStringA(getToken());
346
+ strQuery += "&token=" + convertToStringA(getToken());
325
347
 
326
348
  LOG(INFO) + "Pull changes from server. Url: " + (strUrl+strQuery);
327
349
  PROF_START("Net");
@@ -331,61 +353,29 @@ void CSyncSource::syncServerChanges()
331
353
  if ( !resp.isOK() )
332
354
  {
333
355
  getSync().stopSync();
334
- if (resp.isResponseRecieved())
335
- m_nErrCode = RhoRuby.ERR_REMOTESERVER;
336
- else
337
- m_nErrCode = RhoRuby.ERR_NETWORK;
356
+ m_nErrCode = RhoRuby.getErrorFromResponse(resp);
338
357
  continue;
339
358
  }
340
359
 
341
- processServerData(resp.getCharData());
342
-
343
- //String strData =
344
- //"[{count:10},{version:1},{total_count: 5425},{token: 123},{s:\"RhoDeleteSource\",ol:[{o:\"rho_del_obj\",av:[{i:55550425},{i:75665819},{i:338165272},{i:402396629},{i:521753981},{i:664143530},{i:678116186},{i:831092394},{i:956041217},{i:970452458}]}]}]";
345
- /*"[{count: 124},{version: 1},{total_count: 5425},{token: 123},"
346
- "{s:\"Product\",ol:["
347
- "{oo:\"123\",o:\"2ed2e0c7-8c4c-99c6-1b37-498d250bb8e7\",av:["
348
- "{a:\"first_name\",i:47354289,v:\"Lars. \n\n Burgess\", t:\"blob\"},"
349
- "{a:\"second_name\",i:55555,v:\"Burgess\"}]},"
350
- "{oo:\"456\", e:\"Something went wrong creating this record on the backend: code 7\"}"
351
- "]}]"; */
352
- /*"[{count: 1},{version: 1},{total_count: 1},{token: 123},"
353
- "{s:\"Product\",ol:["
354
- "{oo:\"94\", e:\"Something went wrong creating this record on the backend: code 7\"}"
355
- "]}]";*/
356
- /*"[{count: 1},{version: 1},{total_count: 1},{token: 123},"
357
- "{s:\"Product\",ol:["
358
- "{o:\"94\", av:["
359
- "{a:\"TEST\",i:55555,v:\"Geny\"}]},"
360
- "]}]";
361
-
362
- //u:\"query\",
363
- processServerData(strData.c_str()); */
364
-
365
- if ( getAskParams().length() > 0 || getCurPageCount() == 0 )
360
+ const char* szData = resp.getCharData();
361
+
362
+ //const char* szData = "[{\"version\":3},{\"token\":\"35639160294387\"},{\"count\":3},{\"progress_count\":0},{\"total_count\":3},{\"metadata\":\"{\\\"foo\\\":\\\"bar\\\"}\",\"insert\":{\"1\":{\"price\":\"199.99\",\"brand\":\"Apple\",\"name\":\"iPhone\"}}}]";
363
+
364
+ PROF_START("Parse");
365
+ CJSONArrayIterator oJsonArr(szData);
366
+ PROF_STOP("Parse");
367
+
368
+ processServerResponse_ver3(oJsonArr);
369
+
370
+ if ( getToken() == 0 )
366
371
  break;
367
372
  }
368
373
  }
369
374
 
370
- void CSyncSource::processServerData(const char* szData)
375
+ void CSyncSource::processServerResponse_ver3(CJSONArrayIterator& oJsonArr)
371
376
  {
372
- PROF_START("Parse");
373
- CJSONArrayIterator oJsonArr(szData);
374
- PROF_STOP("Parse");
375
377
  PROF_START("Data1");
376
- if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("error") )
377
- {
378
- m_strError = oJsonArr.getCurItem().getString("error");
379
- m_nErrCode = RhoRuby.ERR_CUSTOMSYNCSERVER;
380
- getSync().stopSync();
381
- return;
382
- }
383
378
 
384
- if ( !oJsonArr.isEnd() )
385
- {
386
- setCurPageCount(oJsonArr.getCurItem().getInt("count"));
387
- oJsonArr.next();
388
- }
389
379
  int nVersion = 0;
390
380
  if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("version") )
391
381
  {
@@ -393,18 +383,43 @@ void CSyncSource::processServerData(const char* szData)
393
383
  oJsonArr.next();
394
384
  }
395
385
 
396
- if ( nVersion != getSync().SYNC_VERSION() )
386
+ if ( nVersion != getProtocol().getVersion() )
397
387
  {
398
- LOG(ERROR) + "Sync server send data with incompatible version. Client version: " + convertToStringA(getSync().SYNC_VERSION()) +
388
+ LOG(ERROR) + "Sync server send data with incompatible version. Client version: " + convertToStringA(getProtocol().getVersion()) +
399
389
  "; Server response version: " + convertToStringA(nVersion) + ". Source name: " + getName();
400
390
  getSync().stopSync();
401
391
  m_nErrCode = RhoRuby.ERR_SYNCVERSION;
402
392
  return;
403
393
  }
404
394
 
405
- if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("rt") )
395
+ if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("source") )
396
+ {
397
+ //skip it. it uses in search only
398
+ oJsonArr.next();
399
+ }
400
+
401
+ if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("token"))
402
+ {
403
+ processToken(oJsonArr.getCurItem().getUInt64("token"));
404
+ oJsonArr.next();
405
+ }
406
+
407
+ if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("count") )
406
408
  {
407
- setRefreshTime(oJsonArr.getCurItem().getInt("rt"));
409
+ setCurPageCount(oJsonArr.getCurItem().getInt("count"));
410
+ oJsonArr.next();
411
+ }
412
+
413
+ if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("refresh_time") )
414
+ {
415
+ setRefreshTime(oJsonArr.getCurItem().getInt("refresh_time"));
416
+ oJsonArr.next();
417
+ }
418
+
419
+ if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("progress_count") )
420
+ {
421
+ //TODO: progress_count
422
+ //setTotalCount(oJsonArr.getCurItem().getInt("progress_count"));
408
423
  oJsonArr.next();
409
424
  }
410
425
 
@@ -413,19 +428,25 @@ void CSyncSource::processServerData(const char* szData)
413
428
  setTotalCount(oJsonArr.getCurItem().getInt("total_count"));
414
429
  oJsonArr.next();
415
430
  }
431
+
432
+ /* if ( !oJsonArr.isEnd() && oJsonArr.getCurItem().hasName("source-error") )
433
+ {
434
+ CJSONEntry oJsonErr = oJsonArr.getCurItem().getEntry("source-error");
435
+ m_strError = oJsonErr.getString("message");
436
+ m_nErrCode = RhoRuby.ERR_CUSTOMSYNCSERVER;
437
+ getSync().stopSync();
438
+ return;
439
+ }*/
440
+
416
441
  //if ( getServerObjectsCount() == 0 )
417
442
  // getNotify().fireSyncNotification(this, false, RhoRuby.ERR_NONE, "");
418
443
 
419
- if ( !oJsonArr.isEnd() )
420
- {
421
- processToken(oJsonArr.getCurItem().getUInt64("token"));
422
- oJsonArr.next();
423
- }else if ( getCurPageCount() == 0 )
444
+ if ( getToken() == 0 )
424
445
  {
425
446
  //oo conflicts
426
447
  getDB().executeSQL("DELETE FROM changed_values where source_id=? and sent>=3", getID() );
427
448
  //
428
- processToken(0);
449
+
429
450
  }
430
451
 
431
452
  LOG(INFO) + "Got " + getCurPageCount() + "(Processed: " + getServerObjectsCount() + ") records of " + getTotalCount() + " from server. Source: " + getName()
@@ -434,22 +455,34 @@ void CSyncSource::processServerData(const char* szData)
434
455
  PROF_STOP("Data1");
435
456
  if ( !oJsonArr.isEnd() && getSync().isContinueSync() )
436
457
  {
458
+ CJSONEntry oCmds = oJsonArr.getCurItem();
437
459
  PROF_START("Data");
438
- //TODO: support DBExceptions
439
- getDB().startTransaction();
460
+ //TODO: use isUIWaitDB inside processSyncCommand
461
+ // if ( getDB().isUIWaitDB() )
462
+ // {
463
+ // LOG(INFO) + "Commit transaction because of UI request.";
464
+ // getDB().endTransaction();
465
+ // getDB().startTransaction();
466
+ // }
440
467
 
441
- int nSavedPos = oJsonArr.getCurPos();
442
- setSyncServerDataPass(edpNone);
443
- processServerData_Ver1(oJsonArr);
468
+ getDB().startTransaction();
469
+ if ( oCmds.hasName("metadata") && getSync().isContinueSync() )
470
+ {
471
+ String strMetadata = oCmds.getString("metadata");
472
+ getDB().executeSQL("UPDATE sources SET metadata=? WHERE source_id=?", strMetadata, getID() );
473
+ }
474
+ if ( oCmds.hasName("links") && getSync().isContinueSync() )
475
+ processSyncCommand("links", oCmds.getEntry("links") );
476
+ if ( oCmds.hasName("delete") && getSync().isContinueSync() )
477
+ processSyncCommand("delete", oCmds.getEntry("delete") );
478
+ if ( oCmds.hasName("insert") && getSync().isContinueSync() )
479
+ processSyncCommand("insert", oCmds.getEntry("insert") );
444
480
 
445
- setSyncServerDataPass(edpDeleteObjects);
446
- oJsonArr.reset(nSavedPos);
447
- processServerData_Ver1(oJsonArr);
481
+ PROF_STOP("Data");
448
482
 
449
- PROF_STOP("Data");
450
- PROF_START("DB");
483
+ PROF_START("DB");
451
484
  getDB().endTransaction();
452
- PROF_STOP("DB");
485
+ PROF_STOP("DB");
453
486
 
454
487
  getNotify().fireObjectsNotification();
455
488
  }
@@ -460,162 +493,290 @@ void CSyncSource::processServerData(const char* szData)
460
493
  PROF_STOP("Data1");
461
494
  }
462
495
 
463
- boolean CSyncSource::processSyncObject_ver1(CJSONEntry oJsonObject, int nSrcID)//throws Exception
496
+ void CSyncSource::processSyncCommand(const String& strCmd, CJSONEntry oCmdEntry)
464
497
  {
465
- const char* strOldObject = oJsonObject.getString("oo");
466
- if ( isDeleteObjectsPass() != (nSrcID < 0) )
467
- return true;
498
+ CJSONStructIterator objIter(oCmdEntry);
468
499
 
469
- if ( oJsonObject.hasName("e") )
500
+ for( ; !objIter.isEnd() && getSync().isContinueSync(); objIter.next() )
470
501
  {
471
- const char* strError = oJsonObject.getString("e");
472
- getNotify().addCreateObjectError(nSrcID,strOldObject,strError);
473
- return true;
474
- }
502
+ String strObject = objIter.getCurKey();
503
+ CJSONStructIterator attrIter( objIter.getCurValue() );
504
+ if ( m_bSchemaSource )
505
+ processServerCmd_Ver3_Schema(strCmd,strObject,attrIter);
506
+ else
507
+ {
508
+ for( ; !attrIter.isEnd() && getSync().isContinueSync(); attrIter.next() )
509
+ {
510
+ String strAttrib = attrIter.getCurKey();
511
+ String strValue = attrIter.getCurString();
475
512
 
476
- const char* strObject = oJsonObject.getString("o");
477
- CJSONArrayIterator oJsonArr(oJsonObject, "av");
478
- //oo conflicts
479
- boolean bUpdatedOO = false;
480
- //
481
- for( ; !oJsonArr.isEnd() && getSync().isContinueSync(); oJsonArr.next() )
482
- {
483
- CJSONEntry oJsonEntry = oJsonArr.getCurItem();
484
- if ( oJsonEntry.isEmpty() )
485
- continue;
513
+ processServerCmd_Ver3(strCmd,strObject,strAttrib,strValue);
514
+ }
515
+ }
486
516
 
487
- if ( nSrcID >= 0 ) //insert
517
+ int nSyncObjectCount = getNotify().incLastSyncObjectCount(getID());
518
+ if ( getProgressStep() > 0 && (nSyncObjectCount%getProgressStep() == 0) )
519
+ getNotify().fireSyncNotification(this, false, RhoRuby.ERR_NONE, "");
520
+
521
+ if ( getDB().isUIWaitDB() )
488
522
  {
489
- CValue value(oJsonEntry,1);
490
- if ( !downloadBlob(value) )
491
- return false;
523
+ LOG(INFO) + "Commit transaction because of UI request.";
524
+ getDB().endTransaction();
525
+ CSyncThread::getInstance()->sleep(1000);
526
+ getDB().startTransaction();
527
+ }
492
528
 
493
- String strAttrib = oJsonEntry.getString("a");
494
- //oo conflicts
495
- if ( strOldObject != null && !bUpdatedOO )
496
- {
497
- getDB().executeSQL("UPDATE object_values SET object=? where object=? and source_id=?", strObject, strOldObject, nSrcID );
498
- getDB().executeSQL("UPDATE changed_values SET object=? where object=? and source_id=?", strObject, strOldObject, nSrcID );
529
+ }
530
+ }
499
531
 
500
- getNotify().onObjectChanged(nSrcID,strOldObject, CSyncNotify::enCreate);
532
+ void CSyncSource::processLinks(const String& strOldObject, const String& strNewObject)
533
+ {
534
+ for ( Hashtable<String,String>::iterator it = m_hashLinks.begin(); it != m_hashLinks.end(); ++it )
535
+ {
536
+ CSyncSource* pSrc = getSync().findSourceByName(it->first);
537
+ if ( pSrc != null )
538
+ pSrc->updateLink(strOldObject, strNewObject, it->second);
539
+ }
540
+ }
501
541
 
502
- bUpdatedOO = true;
503
- }
542
+ void CSyncSource::updateLink(const String& strOldObject, const String& strNewObject, const String& strAttrib)
543
+ {
544
+ if ( m_bSchemaSource )
545
+ {
546
+ String strSqlUpdate = "UPDATE ";
547
+ strSqlUpdate += getName() + " SET " + strAttrib + "=? where " + strAttrib + "=?";
504
548
 
505
- DBResult(resInsert, getDB().executeSQLReportNonUnique("INSERT INTO object_values \
506
- (id, attrib, source_id, object, value, attrib_type) VALUES(?,?,?,?,?,?)",
507
- value.m_nID, strAttrib, nSrcID, strObject,
508
- value.m_strValue, value.m_strAttrType ) );
509
- if ( resInsert.isNonUnique() )
510
- {
511
- getDB().executeSQL("UPDATE object_values \
512
- SET id=?, value=?, attrib_type=? WHERE object=? and attrib=? and source_id=?",
513
- value.m_nID, value.m_strValue, value.m_strAttrType,
514
- strObject, strAttrib, nSrcID );
515
-
516
- // oo conflicts
517
- getDB().executeSQL("UPDATE changed_values SET main_id=? where object=? and attrib=? and source_id=? and sent<=1", value.m_nID, strObject, strAttrib, nSrcID );
518
- getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1", strObject, strAttrib, nSrcID );
519
- //
520
- }
549
+ getDB().executeSQL(strSqlUpdate.c_str(), strNewObject, strOldObject );
550
+ }
551
+ else
552
+ getDB().executeSQL("UPDATE object_values SET value=? where attrib=? and source_id=? and value=?",
553
+ strNewObject, strAttrib, getID(), strOldObject );
521
554
 
522
- getNotify().onObjectChanged(nSrcID,strObject, CSyncNotify::enUpdate);
555
+ getDB().executeSQL("UPDATE changed_values SET value=? where attrib=? and source_id=? and value=?",
556
+ strNewObject, strAttrib, getID(), strOldObject );
557
+ }
523
558
 
524
- m_nInserted++;
525
- }else
559
+ void CSyncSource::processServerCmd_Ver3_Schema(const String& strCmd, const String& strObject, CJSONStructIterator& attrIter)//throws Exception
560
+ {
561
+ if ( strCmd.compare("insert") == 0 )
562
+ {
563
+ Vector<String> vecValues, vecAttrs;
564
+ String strCols = "", strQuest = "", strSet = "";
565
+ for( ; !attrIter.isEnd() && getSync().isContinueSync(); attrIter.next() )
526
566
  {
527
- uint64 id = oJsonEntry.getUInt64("i");
528
- DBResult( res , getDB().executeSQL("SELECT source_id, object FROM object_values where id=?", id ));
529
- if ( !res.isEnd() )
530
- {
531
- int nDelSrcID = res.getIntByIdx(0);
532
- String strDelObject = res.getStringByIdx(1);
533
- getDB().executeSQL("DELETE FROM object_values where id=?", id );
534
- getNotify().onObjectChanged(nDelSrcID, strDelObject, CSyncNotify::enDelete);
535
- }
536
- // oo conflicts
537
- getDB().executeSQL("UPDATE changed_values SET sent=3 where main_id=?", id );
538
- //
567
+ CAttrValue oAttrValue(attrIter.getCurKey(),attrIter.getCurString());
568
+ if ( !processBlob(strCmd,strObject,oAttrValue) )
569
+ continue;
539
570
 
540
- m_nDeleted++;
571
+ if ( strCols.length() > 0 )
572
+ strCols += ",";
573
+ if ( strQuest.length() > 0)
574
+ strQuest += ",";
575
+ if ( strSet.length() > 0)
576
+ strSet += ",";
577
+
578
+ strCols += oAttrValue.m_strAttrib;
579
+ strQuest += "?";
580
+ strSet += oAttrValue.m_strAttrib + "=?";
581
+ vecAttrs.addElement(oAttrValue.m_strAttrib);
582
+ vecValues.addElement(oAttrValue.m_strValue);
541
583
  }
542
- }
543
-
544
- return true;
545
- }
584
+ vecValues.addElement(strObject);
585
+ if ( strCols.length() > 0 )
586
+ strCols += ",";
587
+ if ( strQuest.length() > 0)
588
+ strQuest += ",";
546
589
 
547
- void CSyncSource::processServerData_Ver1(CJSONArrayIterator& oJsonArr)
548
- {
549
- for( ; !oJsonArr.isEnd() && getSync().isContinueSync(); oJsonArr.next() )
550
- {
551
- CJSONEntry oJsonSource = oJsonArr.getCurItem();
552
- String strSrcName = oJsonSource.getString("s");
553
- int nSrcID = getID();
554
- if ( strSrcName.compare("RhoDeleteSource") == 0 )
555
- nSrcID = -1;
556
- else if ( strSrcName.compare(getName()) != 0 )
590
+ strCols += "object";
591
+ strQuest += "?";
592
+
593
+ String strSqlInsert = "INSERT INTO ";
594
+ strSqlInsert += getName() + " (";
595
+ strSqlInsert += strCols + ") VALUES(" + strQuest + ")";
596
+
597
+ if ( !getSync().isContinueSync() )
598
+ return;
599
+
600
+ DBResult(resInsert, getDB().executeSQLReportNonUniqueEx(strSqlInsert.c_str(), vecValues ) );
601
+ if ( resInsert.isNonUnique() )
557
602
  {
558
- CSyncSource* pSrc = getSync().findSourceByName(strSrcName);
559
- if ( pSrc == null )
603
+ String strSqlUpdate = "UPDATE ";
604
+ strSqlUpdate += getName() + " SET " + strSet + " WHERE object=?";
605
+ getDB().executeSQLEx(strSqlUpdate.c_str(), vecValues);
606
+
607
+ // oo conflicts
608
+ for( int i = 0; i < (int)vecAttrs.size(); i++ )
560
609
  {
561
- LOG(ERROR) + "Sync server send data for unknown source name:" + strSrcName;
562
- getSync().stopSync();
563
- m_nErrCode = RhoRuby.ERR_UNEXPECTEDSERVERRESPONSE;
564
- break;
610
+ getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1",
611
+ strObject, vecAttrs.elementAt(i), getID() );
565
612
  }
566
- nSrcID = pSrc->getID();
613
+ //
567
614
  }
568
615
 
569
- CJSONArrayIterator oJsonObjList(oJsonSource, "ol");
570
- for( ; !oJsonObjList.isEnd() && getSync().isContinueSync(); oJsonObjList.next() )
616
+ getNotify().onObjectChanged(getID(),strObject, CSyncNotify::enUpdate);
617
+ m_nInserted++;
618
+ }else if (strCmd.compare("delete") == 0)
619
+ {
620
+ Vector<String> vecAttrs;
621
+ String strSet = "";
622
+ for( ; !attrIter.isEnd() && getSync().isContinueSync(); attrIter.next() )
571
623
  {
572
- if ( getDB().isUIWaitDB() )
573
- {
574
- LOG(INFO) + "Commit transaction because of UI request.";
575
- getDB().endTransaction();
576
- getDB().startTransaction();
577
- }
624
+ CAttrValue oAttrValue(attrIter.getCurKey(),attrIter.getCurString());
625
+
626
+ if ( strSet.length() > 0 )
627
+ strSet += ",";
628
+
629
+ vecAttrs.addElement(oAttrValue.m_strAttrib);
630
+ strSet += oAttrValue.m_strAttrib + "=NULL";
631
+ }
632
+
633
+ String strSqlUpdate = "UPDATE ";
634
+ strSqlUpdate += getName() + " SET " + strSet + " WHERE object=?";
578
635
 
579
- CJSONEntry oJsonObject = oJsonObjList.getCurItem();
580
- if( !processSyncObject_ver1(oJsonObject,nSrcID))
636
+ if ( strSet.length() == 0 || !getSync().isContinueSync() )
637
+ return;
638
+
639
+ getDB().executeSQL(strSqlUpdate.c_str(), strObject);
640
+ //Remove item if all nulls
641
+ String strSelect = String("SELECT * FROM ") + getName() + " WHERE object=?";
642
+ DBResult(res, getDB().executeSQL( strSelect.c_str(), strObject ) );
643
+ if ( !res.isEnd() )
644
+ {
645
+ boolean bAllNulls = true;
646
+ for( int i = 0; i < res.getColCount(); i ++)
581
647
  {
582
- getSync().stopSync();
583
- break;
648
+ if ( !res.isNullByIdx(i) && res.getColName(i).compare("object")!=0 )
649
+ {
650
+ bAllNulls = false;
651
+ break;
652
+ }
584
653
  }
585
654
 
586
- if ( !isDeleteObjectsPass() && nSrcID >=0 )
655
+ if (bAllNulls)
587
656
  {
588
- int nSyncObjectCount = getNotify().incLastSyncObjectCount(nSrcID);
589
-
590
- if ( getProgressStep() > 0 && (nSyncObjectCount%getProgressStep() == 0) )
591
- getNotify().fireSyncNotification(this, false, RhoRuby.ERR_NONE, "");
657
+ String strDelete = String("DELETE FROM ") + getName() + " WHERE object=?";
658
+ getDB().executeSQL( strDelete.c_str(), strObject);
592
659
  }
660
+ }
593
661
 
594
- m_bGetAtLeastOnePage = true;
662
+ getNotify().onObjectChanged(getID(), strObject, CSyncNotify::enDelete);
663
+ // oo conflicts
664
+ for( int i = 0; i < (int)vecAttrs.size(); i++ )
665
+ {
666
+ getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?",
667
+ strObject, vecAttrs.elementAt(i), getID() );
595
668
  }
669
+ //
670
+
671
+ m_nDeleted++;
672
+ }else if ( strCmd.compare("links") == 0 )
673
+ {
674
+ String strValue = attrIter.getCurString();
675
+ processLinks(strObject, strValue);
676
+
677
+ String strSqlUpdate = "UPDATE ";
678
+ strSqlUpdate += getName() + " SET object=? WHERE object=?";
679
+ getDB().executeSQL(strSqlUpdate.c_str(), strValue, strObject);
680
+
681
+ getDB().executeSQL("UPDATE changed_values SET object=?,sent=3 where object=? and source_id=?", strValue, strObject, getID() );
682
+ getNotify().onObjectChanged(getID(), strObject, CSyncNotify::enCreate);
596
683
  }
684
+
597
685
  }
598
686
 
599
- CValue::CValue(json::CJSONEntry& oJsonEntry)//throws JSONException
687
+ boolean CSyncSource::processBlob( const String& strCmd, const String& strObject, CAttrValue& oAttrValue )
600
688
  {
601
- m_strValue = oJsonEntry.getString("value");
602
- const char* szAttribType = oJsonEntry.getString("attrib_type");
603
- m_strAttrType = szAttribType ? szAttribType : "";
604
- m_nID = oJsonEntry.getUInt64("id");
689
+ //TODO: when server return delete with rhoblob postfix - delete isBlobAttr
690
+ if ( !(oAttrValue.m_strBlobSuffix.length() > 0 || getDB().getAttrMgr().isBlobAttr(getID(), oAttrValue.m_strAttrib.c_str())) )
691
+ return true;
692
+
693
+ boolean bDownload = true;
694
+ String strDbValue = "";
695
+ if ( !getDB().getAttrMgr().isOverwriteBlobFromServer(getID(), oAttrValue.m_strAttrib) )
696
+ {
697
+ if ( m_bSchemaSource )
698
+ {
699
+ String strSelect = String("SELECT ") + oAttrValue.m_strAttrib + " FROM " + getName() + " WHERE object=?";
700
+ DBResult(res, getDB().executeSQL( strSelect.c_str(), strObject));
701
+ if (!res.isEnd())
702
+ {
703
+ strDbValue = res.getStringByIdx(0);
704
+ bDownload = strDbValue.length() == 0;
705
+ }
706
+ }else
707
+ {
708
+ DBResult(res, getDB().executeSQL(
709
+ "SELECT value FROM object_values WHERE object=? and attrib=? and source_id=?",
710
+ strObject, oAttrValue.m_strAttrib, getID() ) );
711
+ if (!res.isEnd())
712
+ {
713
+ strDbValue = res.getStringByIdx(0);
714
+ bDownload = strDbValue.length() == 0;
715
+ }
716
+ }
717
+ }
718
+
719
+ if ( bDownload )
720
+ {
721
+ getDB().endTransaction();
722
+ boolean bRes = downloadBlob(oAttrValue);
723
+ getDB().startTransaction();
724
+
725
+ return bRes;
726
+ }
727
+
728
+ oAttrValue.m_strValue = strDbValue;
729
+ return true;
605
730
  }
606
731
 
607
- CValue::CValue(json::CJSONEntry& oJsonEntry, int nVer)//throws JSONException
732
+ void CSyncSource::processServerCmd_Ver3(const String& strCmd, const String& strObject, const String& strAttriba, const String& strValuea)//throws Exception
608
733
  {
609
- if ( nVer == 1 )
734
+ CAttrValue oAttrValue(strAttriba,strValuea);
735
+
736
+ if ( strCmd.compare("insert") == 0 )
737
+ {
738
+ if ( !processBlob(strCmd,strObject,oAttrValue) )
739
+ return;
740
+
741
+ DBResult(resInsert, getDB().executeSQLReportNonUnique("INSERT INTO object_values \
742
+ (attrib, source_id, object, value) VALUES(?,?,?,?)",
743
+ oAttrValue.m_strAttrib, getID(), strObject, oAttrValue.m_strValue ) );
744
+ if ( resInsert.isNonUnique() )
745
+ {
746
+ getDB().executeSQL("UPDATE object_values \
747
+ SET value=? WHERE object=? and attrib=? and source_id=?",
748
+ oAttrValue.m_strValue, strObject, oAttrValue.m_strAttrib, getID() );
749
+
750
+ // oo conflicts
751
+ getDB().executeSQL("UPDATE changed_values SET sent=4 where object=? and attrib=? and source_id=? and sent>1",
752
+ strObject, oAttrValue.m_strAttrib, getID() );
753
+ //
754
+ }
755
+
756
+ getNotify().onObjectChanged(getID(),strObject, CSyncNotify::enUpdate);
757
+ m_nInserted++;
758
+ }else if (strCmd.compare("delete") == 0)
610
759
  {
611
- m_strValue = oJsonEntry.getString("v");
612
- const char* szAttribType = oJsonEntry.getString("t");
613
- m_strAttrType = szAttribType ? szAttribType : "";
614
- m_nID = oJsonEntry.getUInt64("i");
760
+ getDB().executeSQL("DELETE FROM object_values where object=? and attrib=? and source_id=?", strObject, oAttrValue.m_strAttrib, getID() );
761
+ getNotify().onObjectChanged(getID(), strObject, CSyncNotify::enDelete);
762
+ // oo conflicts
763
+ getDB().executeSQL("UPDATE changed_values SET sent=3 where object=? and attrib=? and source_id=?", strObject, oAttrValue.m_strAttrib, getID() );
764
+ //
765
+
766
+ m_nDeleted++;
767
+ }else if ( strCmd.compare("links") == 0 )
768
+ {
769
+ processLinks(strObject, oAttrValue.m_strValue);
770
+
771
+ getDB().executeSQL("UPDATE object_values SET object=? where object=? and source_id=?", oAttrValue.m_strValue, strObject, getID() );
772
+ getDB().executeSQL("UPDATE changed_values SET object=?,sent=3 where object=? and source_id=?", oAttrValue.m_strValue, strObject, getID() );
773
+
774
+ getNotify().onObjectChanged(getID(), strObject, CSyncNotify::enCreate);
615
775
  }
776
+
616
777
  }
617
778
 
618
- String CSyncSource::makeFileName(const CValue& value)//throws Exception
779
+ String CSyncSource::makeFileName(const CAttrValue& value)//throws Exception
619
780
  {
620
781
  String strExt = ".bin";
621
782
 
@@ -655,16 +816,25 @@ String CSyncSource::makeFileName(const CValue& value)//throws Exception
655
816
  if ( szExt[0] )
656
817
  strExt = szExt;
657
818
 
658
- String fName = RHODESAPP().getBlobsDirPath() + "/id_" + convertToStringA(value.m_nID) + strExt;
819
+ String fName = RHODESAPP().getBlobsDirPath() + "/id_" + CLocalTime().toString(true,true) + strExt;
659
820
 
660
821
  return fName;
661
822
  }
662
823
 
663
- boolean CSyncSource::downloadBlob(CValue& value)//throws Exception
824
+ CAttrValue::CAttrValue(const String& strAttrib, const String& strValue)
825
+ {
826
+ m_strAttrib = strAttrib;
827
+ m_strValue = strValue;
828
+
829
+ if ( String_endsWith(m_strAttrib,"-rhoblob") )
830
+ {
831
+ m_strBlobSuffix = "-rhoblob";
832
+ m_strAttrib = m_strAttrib.substr(0,m_strAttrib.length()-m_strBlobSuffix.length());
833
+ }
834
+ }
835
+
836
+ boolean CSyncSource::downloadBlob(CAttrValue& value)//throws Exception
664
837
  {
665
- if ( value.m_strAttrType != "blob.url" )
666
- return true;
667
-
668
838
  String fName = makeFileName( value );
669
839
  String url = value.m_strValue;
670
840
  const char* nQuest = strchr(url.c_str(),'?');
@@ -677,19 +847,13 @@ boolean CSyncSource::downloadBlob(CValue& value)//throws Exception
677
847
  NetResponse(resp, getNet().pullFile(url, fName, &getSync(), null));
678
848
  if ( !resp.isOK() )
679
849
  {
680
- if (resp.isResponseRecieved())
681
- m_nErrCode = RhoRuby.ERR_REMOTESERVER;
682
- else
683
- m_nErrCode = RhoRuby.ERR_NETWORK;
850
+ getSync().stopSync();
851
+ m_nErrCode = RhoRuby.getErrorFromResponse(resp);
684
852
  //m_strError = resp.getCharData();
685
-
686
853
  return false;
687
854
  }
688
855
 
689
- value.m_strAttrType = "blob.file";
690
-
691
- String strAppsPath = RHODESAPP().getRhoRootPath() + "apps";
692
- value.m_strValue = fName.substr(strAppsPath.length());
856
+ value.m_strValue = CFilePath::getRelativePath( fName, RHODESAPP().getRhoRootPath());
693
857
 
694
858
  return true;
695
859
  }