rhoconnect-client 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +9 -0
  3. data/CREDITS +0 -0
  4. data/LICENSE +9 -0
  5. data/README.md +47 -0
  6. data/ext/rhoconnect-client/RhoConnectClient.rb +190 -0
  7. data/ext/rhoconnect-client/ext/RhoConnectClient.xml +726 -0
  8. data/ext/rhoconnect-client/ext/build +26 -0
  9. data/ext/rhoconnect-client/ext/build.bat +30 -0
  10. data/ext/rhoconnect-client/ext/platform/android/ext_java.files +1 -0
  11. data/ext/rhoconnect-client/ext/platform/android/ext_native.files +14 -0
  12. data/ext/rhoconnect-client/ext/platform/android/src/com/rhoconnectclient/RhoconnectClient.java +1 -0
  13. data/ext/rhoconnect-client/ext/platform/iphone/.gitignore +1 -0
  14. data/ext/rhoconnect-client/ext/platform/iphone/Rakefile +74 -0
  15. data/ext/rhoconnect-client/ext/platform/iphone/RhoconnectClient.xcodeproj/project.pbxproj +390 -0
  16. data/ext/rhoconnect-client/ext/platform/iphone/RhoconnectClient_Prefix.pch +7 -0
  17. data/ext/rhoconnect-client/ext/platform/iphone/impl/readme.txt +7 -0
  18. data/ext/rhoconnect-client/ext/platform/qt/Rakefile +35 -0
  19. data/ext/rhoconnect-client/ext/platform/qt/rhoconnect-client.pro +88 -0
  20. data/ext/rhoconnect-client/ext/platform/wm/Rhoconnect-client.sln +36 -0
  21. data/ext/rhoconnect-client/ext/platform/wm/Rhoconnect-client.vcproj +774 -0
  22. data/ext/rhoconnect-client/ext/platform/wm/Rhoconnect-client.vsprops +15 -0
  23. data/ext/rhoconnect-client/ext/platform/wm/src/rhoconnectclient_wm.cpp +40 -0
  24. data/ext/rhoconnect-client/ext/platform/wm/src/rhoconnectclient_wm.h +2 -0
  25. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.props +22 -0
  26. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.sln +32 -0
  27. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.vcxproj +220 -0
  28. data/ext/rhoconnect-client/ext/platform/wp8/Rhoconnect-client.vcxproj.filters +103 -0
  29. data/ext/rhoconnect-client/ext/shared/RhoConnectClientImpl.cpp +273 -0
  30. data/ext/rhoconnect-client/ext/shared/RhoConnectClientImpl.h +60 -0
  31. data/ext/rhoconnect-client/ext/shared/RhoConnectClientSingletonImpl.h +53 -0
  32. data/ext/rhoconnect-client/ext/shared/initRhoconnectClient.cpp +207 -0
  33. data/ext/rhoconnect-client/ext/shared/rhoconnectclient.c +18 -0
  34. data/ext/rhoconnect-client/ext/shared/sync/ClientRegister.cpp +398 -0
  35. data/ext/rhoconnect-client/ext/shared/sync/ClientRegister.h +147 -0
  36. data/ext/rhoconnect-client/ext/shared/sync/ISyncProtocol.h +91 -0
  37. data/ext/rhoconnect-client/ext/shared/sync/SyncEngine.cpp +1245 -0
  38. data/ext/rhoconnect-client/ext/shared/sync/SyncEngine.h +213 -0
  39. data/ext/rhoconnect-client/ext/shared/sync/SyncNotify.cpp +737 -0
  40. data/ext/rhoconnect-client/ext/shared/sync/SyncNotify.h +209 -0
  41. data/ext/rhoconnect-client/ext/shared/sync/SyncProtocol_3.h +220 -0
  42. data/ext/rhoconnect-client/ext/shared/sync/SyncProtocol_4.h +259 -0
  43. data/ext/rhoconnect-client/ext/shared/sync/SyncSource.cpp +1694 -0
  44. data/ext/rhoconnect-client/ext/shared/sync/SyncSource.h +212 -0
  45. data/ext/rhoconnect-client/ext/shared/sync/SyncThread.cpp +583 -0
  46. data/ext/rhoconnect-client/ext/shared/sync/SyncThread.h +250 -0
  47. data/ext/rhoconnect-client/ext.yml +12 -0
  48. data/lib/build/run_rhoconnect_spec.rb +135 -0
  49. data/lib/rhoconnect-client.rb +3 -0
  50. data/platform/shared/RhoConnectClient/RhoConnectClient.cpp +1673 -0
  51. data/platform/shared/RhoConnectClient/RhoConnectClient.h +181 -0
  52. data/platform/shared/RhoConnectClient/RhoError.h +77 -0
  53. data/rhoconnect-client/C++/Tests/RhoConnectClientTest.cpp +830 -0
  54. data/rhoconnect-client/C++/Tests/win32/.gitignore +3 -0
  55. data/rhoconnect-client/C++/Tests/win32/RhoConnectClient.sln +65 -0
  56. data/rhoconnect-client/C++/Tests/win32/RhoConnectClient.vcproj +634 -0
  57. data/rhoconnect-client/C++/Tests/win32/RhoConnectClientTest/RhoConnectClientTest.vcproj +222 -0
  58. data/rhoconnect-client/C++/Tests/win32/RhoConnectClientTest/stdafx.h +65 -0
  59. data/rhoconnect-client/C++/Tests/win32/stdafx.h +65 -0
  60. data/rhoconnect-client/CHANGELOG +18 -0
  61. data/rhoconnect-client/Java/Android/build/android.rake +387 -0
  62. data/rhoconnect-client/Java/Android/build/android_sdk.rb +582 -0
  63. data/rhoconnect-client/Java/Android/build/libcurl_build.files +73 -0
  64. data/rhoconnect-client/Java/Android/build/libjson_build.files +9 -0
  65. data/rhoconnect-client/Java/Android/build/librhocommon_build.files +14 -0
  66. data/rhoconnect-client/Java/Android/build/librhodb_build.files +5 -0
  67. data/rhoconnect-client/Java/Android/build/librhoimpl_build.files +13 -0
  68. data/rhoconnect-client/Java/Android/build/librholog_build.files +4 -0
  69. data/rhoconnect-client/Java/Android/build/libsqlite_build.files +1 -0
  70. data/rhoconnect-client/Java/Android/build/libsync_build.files +7 -0
  71. data/rhoconnect-client/Java/Android/build/libunzip_build.files +1 -0
  72. data/rhoconnect-client/Java/Android/build/rhoconnectclient_build.files +3 -0
  73. data/rhoconnect-client/Java/Android/build/rhoimpljava_build.files +21 -0
  74. data/rhoconnect-client/Java/Android/src/com/rhomobile/rhodes/Capabilities.java +63 -0
  75. data/rhoconnect-client/Java/Android/src/com/rhomobile/rhodes/MemoryInfoCollector.java +79 -0
  76. data/rhoconnect-client/Java/Android/src/com/rhomobile/rhodes/util/ContextFactory.java +63 -0
  77. data/rhoconnect-client/Java/Android/test/.classpath +9 -0
  78. data/rhoconnect-client/Java/Android/test/.project +33 -0
  79. data/rhoconnect-client/Java/Android/test/AndroidManifest.xml +14 -0
  80. data/rhoconnect-client/Java/Android/test/assets/apps/androidtest.png +0 -0
  81. data/rhoconnect-client/Java/Android/test/assets/apps/rhoconfig.txt +19 -0
  82. data/rhoconnect-client/Java/Android/test/assets/apps/rhoconfig.txt.timestamp +1 -0
  83. data/rhoconnect-client/Java/Android/test/assets/db/syncdb.schema +44 -0
  84. data/rhoconnect-client/Java/Android/test/assets/db/syncdb.triggers +10 -0
  85. data/rhoconnect-client/Java/Android/test/assets/db/syncdb_java.triggers +21 -0
  86. data/rhoconnect-client/Java/Android/test/assets/rho.dat +9 -0
  87. data/rhoconnect-client/Java/Android/test/proguard.cfg +36 -0
  88. data/rhoconnect-client/Java/Android/test/project.properties +11 -0
  89. data/rhoconnect-client/Java/Android/test/res/drawable-hdpi/icon.png +0 -0
  90. data/rhoconnect-client/Java/Android/test/res/drawable-ldpi/icon.png +0 -0
  91. data/rhoconnect-client/Java/Android/test/res/drawable-mdpi/icon.png +0 -0
  92. data/rhoconnect-client/Java/Android/test/res/layout/main.xml +12 -0
  93. data/rhoconnect-client/Java/Android/test/res/values/strings.xml +5 -0
  94. data/rhoconnect-client/Java/Android/test/rhoimpl.jar +0 -0
  95. data/rhoconnect-client/Java/Android/test/src/com/rhomobile/rhoconnect_client_test/TestRhoConnectClient.java +343 -0
  96. data/rhoconnect-client/Java/Android/test/src/com/rhomobile/rhoconnect_client_test/TestRhoConnectClientBlobs.java +219 -0
  97. data/rhoconnect-client/Java/RhoConnect/.classpath +6 -0
  98. data/rhoconnect-client/Java/RhoConnect/.project +93 -0
  99. data/rhoconnect-client/Java/RhoConnect/assets/apps/rhoconfig.txt +19 -0
  100. data/rhoconnect-client/Java/RhoConnect/assets/apps/rhoconfig.txt.timestamp +1 -0
  101. data/rhoconnect-client/Java/RhoConnect/assets/db/syncdb.schema +44 -0
  102. data/rhoconnect-client/Java/RhoConnect/assets/db/syncdb.triggers +10 -0
  103. data/rhoconnect-client/Java/RhoConnect/assets/db/syncdb_java.triggers +21 -0
  104. data/rhoconnect-client/Java/RhoConnect/assets/rho.dat +8 -0
  105. data/rhoconnect-client/Java/RhoConnect/jni/include/RhoConnectJniNotify.h +61 -0
  106. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectClient.h +181 -0
  107. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectNotify.h +13 -0
  108. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectNotify_IDelegate.h +13 -0
  109. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectObjectNotify.h +13 -0
  110. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhoConnectObjectNotify_IDelegate.h +13 -0
  111. data/rhoconnect-client/Java/RhoConnect/jni/include/com_rhomobile_rhoconnect_RhomModel.h +103 -0
  112. data/rhoconnect-client/Java/RhoConnect/jni/include/rhojava.inc +76 -0
  113. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectJniClient.cpp +401 -0
  114. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectJniModel.cpp +332 -0
  115. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectJniNotify.cpp +223 -0
  116. data/rhoconnect-client/Java/RhoConnect/jni/src/RhoConnectUtil.cpp +82 -0
  117. data/rhoconnect-client/Java/RhoConnect/jni/src/RhodesApp.cpp +114 -0
  118. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhoConnectClient.java +108 -0
  119. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhoConnectNotify.java +78 -0
  120. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhoConnectObjectNotify.java +71 -0
  121. data/rhoconnect-client/Java/RhoConnect/src/com/rhomobile/rhoconnect/RhomModel.java +195 -0
  122. data/rhoconnect-client/JavaScript/.classpath +10 -0
  123. data/rhoconnect-client/JavaScript/.gitignore +4 -0
  124. data/rhoconnect-client/JavaScript/.project +17 -0
  125. data/rhoconnect-client/JavaScript/README.textile +1 -0
  126. data/rhoconnect-client/JavaScript/build.xml +185 -0
  127. data/rhoconnect-client/JavaScript/doc/fsm-sample.js +44 -0
  128. data/rhoconnect-client/JavaScript/doc/fsm-sample.png +0 -0
  129. data/rhoconnect-client/JavaScript/src/RhoSyncJS.gwt.xml +21 -0
  130. data/rhoconnect-client/JavaScript/stubs/RhoSyncStubsJS.gwt.xml +21 -0
  131. data/rhoconnect-client/JavaScript/stubs/com/rho/Capabilities.java +7 -0
  132. data/rhoconnect-client/JavaScript/stubs/com/rho/IRhoRubyHelper.java +7 -0
  133. data/rhoconnect-client/JavaScript/stubs/com/rho/Mutex.java +5 -0
  134. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoAppAdapter.java +39 -0
  135. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoClassFactory.java +29 -0
  136. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoConf.java +100 -0
  137. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoEmptyLogger.java +7 -0
  138. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoEmptyProfiler.java +5 -0
  139. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoLogger.java +32 -0
  140. data/rhoconnect-client/JavaScript/stubs/com/rho/RhoProfiler.java +27 -0
  141. data/rhoconnect-client/JavaScript/stubs/com/rho/RhodesApp.java +25 -0
  142. data/rhoconnect-client/JavaScript/stubs/com/rho/TimeInterval.java +22 -0
  143. data/rhoconnect-client/JavaScript/stubs/com/rho/Tokenizer.java +23 -0
  144. data/rhoconnect-client/JavaScript/stubs/com/rho/db/DBAdapter.java +174 -0
  145. data/rhoconnect-client/JavaScript/stubs/com/rho/db/DBAttrManager.java +15 -0
  146. data/rhoconnect-client/JavaScript/stubs/com/rho/db/DBException.java +5 -0
  147. data/rhoconnect-client/JavaScript/stubs/com/rho/db/IDBResult.java +27 -0
  148. data/rhoconnect-client/JavaScript/stubs/com/rho/file/IFileAccess.java +7 -0
  149. data/rhoconnect-client/JavaScript/stubs/com/rho/file/SimpleFile.java +15 -0
  150. data/rhoconnect-client/JavaScript/stubs/com/rho/net/IHttpConnection.java +22 -0
  151. data/rhoconnect-client/JavaScript/stubs/com/rho/net/NetRequest.java +324 -0
  152. data/rhoconnect-client/JavaScript/stubs/com/rho/net/NetResponse.java +51 -0
  153. data/rhoconnect-client/JavaScript/stubs/com/rho/net/URI.java +64 -0
  154. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/ClientRegister.java +15 -0
  155. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/JSONArrayIterator.java +37 -0
  156. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/JSONEntry.java +48 -0
  157. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/JSONStructIterator.java +41 -0
  158. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/SyncNotify.java +98 -0
  159. data/rhoconnect-client/JavaScript/stubs/com/rho/sync/SyncThread.java +92 -0
  160. data/rhoconnect-client/JavaScript/war/WEB-INF/lib/gwt-servlet-deps.jar +0 -0
  161. data/rhoconnect-client/JavaScript/war/WEB-INF/lib/gwt-servlet.jar +0 -0
  162. data/rhoconnect-client/JavaScript/war/js/fsm-sample.js +54 -0
  163. data/rhoconnect-client/JavaScript/war/js/rhosync-api.js +237 -0
  164. data/rhoconnect-client/JavaScript/war/js/rhosync-fsm.js +307 -0
  165. data/rhoconnect-client/JavaScript/war/rhosyncjs/4C71D69C9BBC9E6F05C6BA49B01BCBC1.cache.html +3122 -0
  166. data/rhoconnect-client/JavaScript/war/rhosyncjs/5146F4FFF34511C8BB2661E920B49E3A.cache.html +3254 -0
  167. data/rhoconnect-client/JavaScript/war/rhosyncjs/5248C67481D9D27AD0703D15CDBD2A1C.cache.html +3147 -0
  168. data/rhoconnect-client/JavaScript/war/rhosyncjs/EE1DC2692C9C32367B53A39E2358AF23.cache.html +3195 -0
  169. data/rhoconnect-client/JavaScript/war/rhosyncjs/clear.cache.gif +0 -0
  170. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/corner.png +0 -0
  171. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/corner_ie6.png +0 -0
  172. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/hborder.png +0 -0
  173. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/hborder_ie6.png +0 -0
  174. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/corner_dialog_topleft.png +0 -0
  175. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/corner_dialog_topright.png +0 -0
  176. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/hborder_blue_shadow.png +0 -0
  177. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/hborder_gray_shadow.png +0 -0
  178. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/vborder_blue_shadow.png +0 -0
  179. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/ie6/vborder_gray_shadow.png +0 -0
  180. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/splitPanelThumb.png +0 -0
  181. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/vborder.png +0 -0
  182. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/images/vborder_ie6.png +0 -0
  183. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/standard.css +1144 -0
  184. data/rhoconnect-client/JavaScript/war/rhosyncjs/gwt/standard/standard_rtl.css +1145 -0
  185. data/rhoconnect-client/JavaScript/war/rhosyncjs/hosted.html +350 -0
  186. data/rhoconnect-client/JavaScript/war/rhosyncjs/rhosyncjs.nocache.js +314 -0
  187. data/rhoconnect-client/JavaScript/war/test/SpecRunner.html +35 -0
  188. data/rhoconnect-client/JavaScript/war/test/dbtest.html +38 -0
  189. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/MIT.LICENSE +20 -0
  190. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/jasmine-html.js +188 -0
  191. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/jasmine.css +166 -0
  192. data/rhoconnect-client/JavaScript/war/test/lib/jasmine-1.0.1/jasmine.js +2421 -0
  193. data/rhoconnect-client/JavaScript/war/test/spec/SpecHelper.js +7 -0
  194. data/rhoconnect-client/JavaScript/war/test/spec/SyncApiSpec.js +573 -0
  195. data/rhoconnect-client/JavaScript/war/test/spec/samples/PlayerSpec.js +58 -0
  196. data/rhoconnect-client/JavaScript/war/test/worker-test.js +17 -0
  197. data/rhoconnect-client/LICENSE +41 -0
  198. data/rhoconnect-client/ObjectiveC/RhoConnectClient.h +118 -0
  199. data/rhoconnect-client/ObjectiveC/RhoConnectClient.m +641 -0
  200. data/rhoconnect-client/ObjectiveC/RhoConnectClient.xcodeproj/project.pbxproj +1434 -0
  201. data/rhoconnect-client/ObjectiveC/RhoConnectNotify.h +83 -0
  202. data/rhoconnect-client/ObjectiveC/RhoConnectNotify.m +181 -0
  203. data/rhoconnect-client/ObjectiveC/RhoConnectObjectNotify.h +65 -0
  204. data/rhoconnect-client/ObjectiveC/RhoConnectObjectNotify.m +73 -0
  205. data/rhoconnect-client/ObjectiveC/RhomModel.h +101 -0
  206. data/rhoconnect-client/ObjectiveC/RhomModel.m +320 -0
  207. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/MainWindow.xib +198 -0
  208. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTest-Info.plist +30 -0
  209. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTest.xcodeproj/project.pbxproj +373 -0
  210. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTestAppDelegate.h +58 -0
  211. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTestAppDelegate.m +84 -0
  212. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/RhoConnectClientTest_Prefix.pch +8 -0
  213. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/invalid_import_db.zip +0 -0
  214. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/main.m +1096 -0
  215. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/test.png +0 -0
  216. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/test2.png +0 -0
  217. data/rhoconnect-client/ObjectiveC/Tests/RhoConnectClientTest/valid_import_db.zip +0 -0
  218. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsAppDelegate.h +62 -0
  219. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsAppDelegate.m +35 -0
  220. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsViewController.h +78 -0
  221. data/rhoconnect-client/ObjectiveC/Tests/ptests/Classes/ptestsViewController.m +549 -0
  222. data/rhoconnect-client/ObjectiveC/Tests/ptests/MainWindow.xib +227 -0
  223. data/rhoconnect-client/ObjectiveC/Tests/ptests/main.m +17 -0
  224. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptests-Info.plist +30 -0
  225. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptests.xcodeproj/project.pbxproj +363 -0
  226. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptestsViewController.xib +641 -0
  227. data/rhoconnect-client/ObjectiveC/Tests/ptests/ptests_Prefix.pch +8 -0
  228. data/rhoconnect-client/README.textile +23 -0
  229. data/rhoconnect-client/Rakefile +20 -0
  230. data/rhoconnect-client/Samples/Java/android_store/.classpath +8 -0
  231. data/rhoconnect-client/Samples/Java/android_store/.project +33 -0
  232. data/rhoconnect-client/Samples/Java/android_store/AndroidManifest.xml +24 -0
  233. data/rhoconnect-client/Samples/Java/android_store/assets/apps/rhoconfig.txt +19 -0
  234. data/rhoconnect-client/Samples/Java/android_store/assets/apps/rhoconfig.txt.timestamp +1 -0
  235. data/rhoconnect-client/Samples/Java/android_store/assets/db/syncdb.schema +44 -0
  236. data/rhoconnect-client/Samples/Java/android_store/assets/db/syncdb.triggers +10 -0
  237. data/rhoconnect-client/Samples/Java/android_store/assets/db/syncdb_java.triggers +21 -0
  238. data/rhoconnect-client/Samples/Java/android_store/assets/rho.dat +8 -0
  239. data/rhoconnect-client/Samples/Java/android_store/default.properties +11 -0
  240. data/rhoconnect-client/Samples/Java/android_store/project.properties +14 -0
  241. data/rhoconnect-client/Samples/Java/android_store/res/drawable-hdpi/icon.png +0 -0
  242. data/rhoconnect-client/Samples/Java/android_store/res/drawable-ldpi/icon.png +0 -0
  243. data/rhoconnect-client/Samples/Java/android_store/res/drawable-mdpi/icon.png +0 -0
  244. data/rhoconnect-client/Samples/Java/android_store/res/layout/main.xml +12 -0
  245. data/rhoconnect-client/Samples/Java/android_store/res/values/strings.xml +5 -0
  246. data/rhoconnect-client/Samples/Java/android_store/rhoimpl.jar +0 -0
  247. data/rhoconnect-client/Samples/Java/android_store/src/com/rhomobile/android_store/StoreActivity.java +68 -0
  248. data/rhoconnect-client/Samples/Java/android_store/src/com/rhomobile/android_store/StoreApplication.java +15 -0
  249. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/LoginViewController.h +70 -0
  250. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/LoginViewController.m +94 -0
  251. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RhoConnectEngine.h +82 -0
  252. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RhoConnectEngine.m +119 -0
  253. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RootViewController.h +63 -0
  254. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/RootViewController.m +314 -0
  255. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/WaitLoginController.h +65 -0
  256. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/WaitLoginController.m +110 -0
  257. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/storeAppDelegate.h +61 -0
  258. data/rhoconnect-client/Samples/ObjectiveC/store/Classes/storeAppDelegate.m +171 -0
  259. data/rhoconnect-client/Samples/ObjectiveC/store/LoginViewController.xib +779 -0
  260. data/rhoconnect-client/Samples/ObjectiveC/store/MainWindow.xib +580 -0
  261. data/rhoconnect-client/Samples/ObjectiveC/store/RootViewController.xib +384 -0
  262. data/rhoconnect-client/Samples/ObjectiveC/store/WaitLoginController.xib +557 -0
  263. data/rhoconnect-client/Samples/ObjectiveC/store/icon.png +0 -0
  264. data/rhoconnect-client/Samples/ObjectiveC/store/main.m +22 -0
  265. data/rhoconnect-client/Samples/ObjectiveC/store/store-Info.plist +30 -0
  266. data/rhoconnect-client/Samples/ObjectiveC/store/store.xcodeproj/project.pbxproj +367 -0
  267. data/rhoconnect-client/Samples/ObjectiveC/store/store_Prefix.pch +14 -0
  268. data/rhoconnect-client/build.yml +3 -0
  269. data/rhoconnect-client/version +1 -0
  270. metadata +314 -0
@@ -0,0 +1,250 @@
1
+ /*------------------------------------------------------------------------
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008-2011 Rhomobile, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ * http://rhomobile.com
25
+
26
+ * Copyright (c) 2011-2016 Symbol Technologies, Inc.
27
+ *
28
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * in the Software without restriction, including without limitation the rights
31
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * furnished to do so, subject to the following conditions:
34
+ *
35
+ * The above copyright notice and this permission notice shall be included in
36
+ * all copies or substantial portions of the Software.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ * THE SOFTWARE.
45
+ *
46
+ * http://symbol.com
47
+ *------------------------------------------------------------------------*/
48
+
49
+ #pragma once
50
+
51
+ #ifdef __cplusplus
52
+
53
+ #include "logging/RhoLog.h"
54
+ #include "db/DBAdapter.h"
55
+ #include "sync/SyncEngine.h"
56
+ #include "common/ThreadQueue.h"
57
+ #include "api_generator/MethodResult.h"
58
+
59
+ namespace rho {
60
+ namespace sync {
61
+
62
+ class CSyncThread : public common::CThreadQueue
63
+ {
64
+ public:
65
+ enum ESyncCommands{ scNone = 0, scSyncAll, scSyncOne, scLogin, scSearchOne};
66
+
67
+ private:
68
+
69
+ DEFINE_LOGCLASS;
70
+
71
+ public:
72
+ static const unsigned int SYNC_WAIT_BEFOREKILL_SECONDS = 3;
73
+
74
+ class CSyncCommand : public IQueueCommand
75
+ {
76
+ public:
77
+ int m_nCmdCode;
78
+ int m_nCmdParam;
79
+ String m_strCmdParam, m_strQueryParams;
80
+ boolean m_bShowStatus;
81
+ boolean m_bSyncOnlyChangedSources;
82
+
83
+ CSyncCommand(int nCode, int nParam, boolean bShowStatus, const char * query_params, boolean bSyncOnlyChangedSources = false)
84
+ {
85
+ m_nCmdCode = nCode;
86
+ m_nCmdParam = nParam;
87
+ m_bShowStatus = bShowStatus;
88
+ m_strQueryParams = query_params ? query_params : "";
89
+ m_bSyncOnlyChangedSources = bSyncOnlyChangedSources;
90
+ }
91
+ CSyncCommand(int nCode, String strParam, boolean bShowStatus, const char * query_params, boolean bSyncOnlyChangedSources = false )
92
+ {
93
+ m_nCmdCode = nCode;
94
+ m_strCmdParam = strParam;
95
+ m_bShowStatus = bShowStatus;
96
+ m_strQueryParams = query_params ? query_params : "";
97
+ m_bSyncOnlyChangedSources = bSyncOnlyChangedSources;
98
+ }
99
+ CSyncCommand(int nCode, String strParam, int nCmdParam, boolean bShowStatus, const char * query_params, boolean bSyncOnlyChangedSources = false)
100
+ {
101
+ m_nCmdCode = nCode;
102
+ m_strCmdParam = strParam;
103
+ m_nCmdParam = nCmdParam;
104
+ m_bShowStatus = bShowStatus;
105
+ m_strQueryParams = query_params ? query_params : "";
106
+ m_bSyncOnlyChangedSources = bSyncOnlyChangedSources;
107
+ }
108
+
109
+ CSyncCommand(int nCode, boolean bShowStatus, const char * query_params, boolean bSyncOnlyChangedSources = false)
110
+ {
111
+ m_nCmdCode = nCode;
112
+ m_nCmdParam = 0;
113
+ m_bShowStatus = bShowStatus;
114
+ m_strQueryParams = query_params ? query_params : "";
115
+ m_bSyncOnlyChangedSources = bSyncOnlyChangedSources;
116
+ }
117
+
118
+ boolean equals(const IQueueCommand& cmd)
119
+ {
120
+ const CSyncCommand& oSyncCmd = (const CSyncCommand&)cmd;
121
+ return m_nCmdCode == oSyncCmd.m_nCmdCode && m_nCmdParam == oSyncCmd.m_nCmdParam &&
122
+ m_strCmdParam == oSyncCmd.m_strCmdParam &&
123
+ m_strQueryParams == oSyncCmd.m_strQueryParams &&
124
+ m_bSyncOnlyChangedSources == oSyncCmd.m_bSyncOnlyChangedSources;
125
+ }
126
+
127
+ virtual String toString();
128
+
129
+ };
130
+
131
+ class CSyncLoginCommand : public CSyncCommand
132
+ {
133
+ public:
134
+ String m_strName, m_strPassword;
135
+ common::CAutoPtr<CSyncNotification> m_pNotify;
136
+ CSyncLoginCommand(String name, String password, CSyncNotification* pNotify) :
137
+ CSyncCommand(CSyncThread::scLogin,"",false,"", false)
138
+ {
139
+ m_strName = name;
140
+ m_strPassword = password;
141
+ m_pNotify = pNotify;
142
+ }
143
+ };
144
+
145
+ class CSyncSearchCommand : public CSyncCommand
146
+ {
147
+ public:
148
+ String m_strFrom;
149
+ boolean m_bSyncChanges;
150
+ rho::Vector<rho::String> m_arSources;
151
+
152
+ CSyncSearchCommand(String from, String params, const rho::Vector<rho::String>& arSources, boolean sync_changes, int nProgressStep) : CSyncCommand(CSyncThread::scSearchOne,params,nProgressStep, false, "")
153
+ {
154
+ m_strFrom = from;
155
+ m_bSyncChanges = sync_changes;
156
+ m_arSources = arSources;
157
+ }
158
+ };
159
+
160
+ private:
161
+ static CSyncThread* m_pInstance;
162
+
163
+ CSyncEngine m_oSyncEngine;
164
+ public:
165
+ ~CSyncThread(void);
166
+
167
+ static CSyncThread* Create();
168
+ static void Destroy();
169
+ static CSyncThread* getInstance(){ return m_pInstance; }
170
+ static CSyncEngine& getSyncEngine(){ return m_pInstance->m_oSyncEngine; }
171
+
172
+ void setPollInterval(int nInterval);
173
+
174
+ void stopAll();
175
+
176
+ unsigned long getRetValue();
177
+ private:
178
+ CSyncThread();
179
+
180
+ virtual int getLastPollInterval();
181
+ virtual void processCommand(IQueueCommand* pCmd);
182
+ virtual boolean isSkipDuplicateCmd() { return true; }
183
+
184
+ virtual void onTimeout();
185
+
186
+ void checkShowStatus(CSyncCommand& oSyncCmd);
187
+ };
188
+
189
+ }
190
+ }
191
+ unsigned long rho_sync_doSearch(unsigned long ar_sources, const char *from, const char *params, bool sync_changes, int nProgressStep, const rho::apiGenerator::CMethodResult& oResult);
192
+ unsigned long rho_sync_login(const char *login, const char *password, const rho::apiGenerator::CMethodResult& oResult);
193
+ void rho_sync_set_notification(int source_id, const rho::apiGenerator::CMethodResult& oResult);
194
+ #endif //__cplusplus
195
+
196
+ #ifdef __cplusplus
197
+ extern "C" {
198
+ #endif //__cplusplus
199
+
200
+ unsigned long rho_sync_doSyncAllSources(int show_status_popup, const char * query_params, int sync_only_changed_sources);
201
+ unsigned long rho_sync_doSyncSource(unsigned long nSrcID,int show_status_popup, const char * query_params);
202
+ unsigned long rho_sync_doSyncSourceByID(int nSrcID);
203
+ unsigned long rho_sync_doSyncSourceByName(const char* szSrcName);
204
+
205
+
206
+
207
+
208
+ int rho_sync_logged_in();
209
+ void rho_sync_logout();
210
+
211
+ void rho_sync_clear_notification(int source_id);
212
+ void rho_sync_set_source_property(int source_id, const char* propName, const char* propValue);
213
+ int rho_sync_set_pollinterval(int nInterval);
214
+ int rho_sync_get_pollinterval();
215
+ void rho_sync_set_bulksyncstate(int new_state);
216
+ bool rho_sync_has_bulksyncstate();
217
+ int rho_sync_get_bulksyncstate();
218
+ void rho_sync_set_syncserver(const char* syncserver);
219
+ void rho_sync_setobjectnotify_url(const char* szUrl);
220
+ void rho_sync_clear_object_notification();
221
+ void rho_sync_addobjectnotify(int nSrcID, const char* szObject);
222
+ void rho_sync_cleanobjectnotify();
223
+ int rho_sync_get_pagesize();
224
+ void rho_sync_set_pagesize(int nPageSize);
225
+
226
+ unsigned long rho_sync_get_attrs(const char* szPartition, int nSrcID);
227
+ int rho_sync_get_lastsync_objectcount(int nSrcID);
228
+
229
+ void rho_sync_set_threaded_mode(int b);
230
+ char* rho_sync_create_string(const char* szStr);
231
+ void rho_sync_free_string(char* szStr);
232
+
233
+ unsigned long rho_sync_login_c(const char *name, const char *password, /*RHOC_CALLBACK*/void* callback, void* callback_data);
234
+ unsigned long rho_sync_doSearchByNames(unsigned long ar_sources, const char *from, const char *params, bool sync_changes, int nProgressStep, /*RHOC_CALLBACK*/void* callback, void* callback_data);
235
+ void rho_sync_set_notification_c(int source_id, /*RHOC_CALLBACK*/void* callback, void* callback_data);
236
+
237
+ void rho_sync_setobjectnotify_url_c(/*RHOC_CALLBACK*/void* callback, void* callback_data);
238
+
239
+ void rho_sync_stop();
240
+ void rho_sync_set_source_property(int nSrcID, const char* szPropName, const char* szPropValue);
241
+ unsigned long rho_sync_get_source_property(int nSrcID, const char* szPropName);
242
+ int rho_sync_issyncing();
243
+
244
+ void rho_sync_enable_status_popup(int b);
245
+ void rho_sync_register_push();
246
+ void rho_sync_set_ssl_verify_peer(int b);
247
+
248
+ #ifdef __cplusplus
249
+ };
250
+ #endif //__cplusplus
@@ -0,0 +1,12 @@
1
+ entry: Init_Rhoconnectclient_extension
2
+ javaentry: com.rhoconnect-client.Rhoconnect-client
3
+ android_additional_sources_list: ext/platform/android/ext_java.files
4
+ libraries: ["Rhoconnect-client"]
5
+
6
+ project_paths:
7
+ wp8: ext/platform/wp8/Rhoconnect-client.vcxproj
8
+ wm: ext/platform/wm/Rhoconnect-client.vcproj
9
+
10
+ xml_api_paths: ext/RhoConnectClient.xml
11
+ android:
12
+ exttype: rakefile
@@ -0,0 +1,135 @@
1
+ require 'fileutils'
2
+ require File.join($rho_root,'lib','build','jake.rb')
3
+ require File.join($rho_root,'lib','build','rhoconnect_helper.rb')
4
+
5
+ def run_rhoconnect_spec(platform,appname,flags)
6
+ test_appname = "testapp"
7
+ puts "run_spec_app(#{platform},#{appname})"
8
+
9
+ rhobuildyml = File.join($rho_root,'rhobuild.yml')
10
+ $app_path = File.expand_path(File.join(File.dirname(__FILE__),'..','..','spec',appname))
11
+ puts "app path: #{$app_path}"
12
+
13
+ $app_config = Jake.config(File.open(File.join($app_path, "build.yml")))
14
+ config = Jake.config(File.open(rhobuildyml,'r'))
15
+
16
+ source_path = File.expand_path(File.join($app_path,'..','server'))
17
+ $tmp_path = File.join(File.dirname(__FILE__),'..','..','tmp')
18
+
19
+ cleanup_apps
20
+
21
+ FileUtils.mkdir_p File.expand_path($tmp_path)
22
+ server_path = File.expand_path(File.join($tmp_path,'testapp'))
23
+
24
+ $rhoconnect_bin = "#{$rhoconnect_root}/bin/rhoconnect"
25
+ puts "$rhoconnect_bin: #{$rhoconnect_bin}"
26
+
27
+ RhoconnectHelper.set_rhoconnect_bin $rhoconnect_root
28
+ puts "rhoconnect_bin: #{RhoconnectHelper.rhoconnect_bin}"
29
+
30
+ RhoconnectHelper.set_rc_out File.open( File.join($app_path, "rhoconnect.log" ), "w")
31
+ RhoconnectHelper.set_redis_out File.open( File.join($app_path, "redis.log" ), "w")
32
+ RhoconnectHelper.set_resque_out File.open( File.join($app_path, "resque.log" ), "w")
33
+ RhoconnectHelper.set_rc_push_out File.open( File.join($app_path, "rc_push.log" ), "w")
34
+ RhoconnectHelper.set_enable_push(false)
35
+ RhoconnectHelper.set_enable_rails(false)
36
+ pong = `redis-cli ping`
37
+ RhoconnectHelper.set_enable_redis(!(pong =~ /PONG/)) # Do not touch redis if it's running
38
+
39
+ RhoconnectHelper.stop_rhoconnect_stack
40
+
41
+ @mutex = Mutex.new
42
+ # @signal = ConditionVariable.new
43
+ @server, @addr, @port = Jake.run_local_server(8081)
44
+ @server.mount_proc('/', nil) do |req, res|
45
+ res.status = 200
46
+ @mutex.synchronize do
47
+ # puts " query_string: #{req.query_string}"
48
+ # puts " Body: #{req.body}"
49
+ @file_name = req.query_string.split("=")[1]
50
+ xml_file = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', @file_name))
51
+ File.open(xml_file, "w") { |f| f << req.body }
52
+ puts "Test results are saved in #{@file_name}"
53
+ # @signal.signal
54
+ end
55
+ end
56
+ trap(:INT) { @server.shutdown }
57
+
58
+ puts "Generating app ..."
59
+ # Generate app, set rhoconnect gem path to its sources, but do not run bundler
60
+ res = RhoconnectHelper.generate_app($tmp_path, test_appname, false)
61
+
62
+ target_gemfile = File.join(server_path, 'Gemfile')
63
+ puts "Patching Gemfile with aws-s3 ..."
64
+ File.open(target_gemfile, 'a') {|f| f.puts "gem 'aws-s3', '>= 0.6.3'" }
65
+ puts "Patching Gemfile with sqlite3 ..."
66
+ File.open(target_gemfile, 'a') {|f| f.puts "gem 'sqlite3', '>= 1.3.3'" }
67
+ puts "Bundle install ..."
68
+ Kernel.system("bundle","install",:chdir => server_path)
69
+
70
+ puts "Adding source files ..."
71
+ FileUtils.cp_r ["#{source_path}/sources","#{source_path}/settings"], server_path
72
+
73
+ puts "Cleanup rhoconnect data ..."
74
+ FileUtils.rm_r(File.join(server_path,"data")) if File.directory?(File.join(server_path,"data"))
75
+
76
+ RhoconnectHelper.start_rhoconnect_stack(server_path,true)
77
+
78
+ generateRuby = flags && flags[:ruby]==true
79
+ generateJS = flags && flags[:js]==true
80
+
81
+ if generateRuby then
82
+ File.open(File.join($app_path, 'app', 'sync_server.rb'), 'w') do |f|
83
+ f.puts "SYNC_SERVER_HOST = '#{RhoconnectHelper.host}'"
84
+ f.puts "SYNC_SERVER_PORT = #{RhoconnectHelper.port}"
85
+ end
86
+ File.open(File.join($app_path, 'app', 'local_server.rb'), 'w') do |f|
87
+ f.puts "SPEC_LOCAL_SERVER_HOST = '#{@addr}'"
88
+ f.puts "SPEC_LOCAL_SERVER_PORT = #{@port}"
89
+ end
90
+ end
91
+
92
+ if generateJS then
93
+ File.open(File.join($app_path, 'public', 'app', 'sync_server.js'), 'w') do |f|
94
+ f.puts "var SYNC_SERVER_HOST = '#{RhoconnectHelper.host}';"
95
+ f.puts "var SYNC_SERVER_PORT = #{RhoconnectHelper.port};"
96
+ end
97
+ File.open(File.join($app_path, 'public', 'app', 'local_server.js'), 'w') do |f|
98
+ f.puts "var SPEC_LOCAL_SERVER_HOST = '#{@addr}';"
99
+ f.puts "var SPEC_LOCAL_SERVER_PORT = #{@port};"
100
+ end
101
+ end
102
+
103
+ puts "Running specs ..."
104
+ chdir $rho_root
105
+ Rake::Task.tasks.each { |t| t.reenable }
106
+ run_specs = $device && $device != "emulator" ? "run:#{platform}:#{$device}:spec" : "run:#{platform}:spec"
107
+
108
+ uninstall_app = false
109
+
110
+ Rake::Task[run_specs].invoke(uninstall_app)
111
+
112
+
113
+ rescue SystemExit => e
114
+ # FIXME: iphone rake task throws SystemExit exception. Swallow it!
115
+ # puts "Got exception: #{e}"
116
+ rescue Exception => e
117
+ puts e.message
118
+ puts e.backtrace.join("\n")
119
+ ensure
120
+ # @mutex.synchronize do
121
+ # @signal.wait(@mutex, 30) # wait timeout
122
+ # puts "Processed #{@file_name}"
123
+ # end
124
+ RhoconnectHelper.stop_rhoconnect_stack
125
+ cleanup_apps
126
+ Rake::Task["stop:#{platform}:#{$device}"].invoke
127
+ # TODO:
128
+ # `killall iphonesim_43 2> /dev/null` if platform == 'iphone'
129
+ puts "run_spec_app(#{platform},#{appname}) done"
130
+ end
131
+
132
+ def cleanup_apps
133
+ puts "cleanup"
134
+ FileUtils.rm_r File.expand_path($tmp_path) if File.directory?($tmp_path)
135
+ end
@@ -0,0 +1,3 @@
1
+ $rhodes_extensions = []
2
+ $rhodes_extensions << File.join(File.dirname(__FILE__),'..','ext')
3
+ $rhodes_join_ext_name = true
@@ -0,0 +1,1673 @@
1
+ /*------------------------------------------------------------------------
2
+ * (The MIT License)
3
+ *
4
+ * Copyright (c) 2008-2011 Rhomobile, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ *
24
+ * http://rhomobile.com
25
+
26
+ * Copyright (c) 2011-2016 Symbol Technologies, Inc.
27
+ *
28
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * in the Software without restriction, including without limitation the rights
31
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * furnished to do so, subject to the following conditions:
34
+ *
35
+ * The above copyright notice and this permission notice shall be included in
36
+ * all copies or substantial portions of the Software.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ * THE SOFTWARE.
45
+ *
46
+ * http://symbol.com
47
+ *------------------------------------------------------------------------*/
48
+
49
+ #include "RhoConnectClient.h"
50
+
51
+ //#include "stdafx.h"
52
+
53
+ #include "common/RhodesAppBase.h"
54
+ #include "sync/SyncThread.h"
55
+ #include "sync/ClientRegister.h"
56
+ #include "common/RhoFile.h"
57
+ #include "common/Tokenizer.h"
58
+ #include "common/RhoConf.h"
59
+ #include "common/RhoTime.h"
60
+ #include "common/RhoAppAdapter.h"
61
+ #include "net/URI.h"
62
+ #include "json/JSONIterator.h"
63
+
64
+ using namespace rho;
65
+ using namespace rho::common;
66
+ using namespace rho::sync;
67
+ using namespace rho::json;
68
+ const char* getSyncTypeName( RHOM_SYNC_TYPE sync_type )
69
+ {
70
+ switch( sync_type)
71
+ {
72
+ case RST_INCREMENTAL:
73
+ return "incremental";
74
+ case RST_BULK_ONLY:
75
+ return "bulk_only";
76
+ }
77
+
78
+ return "none";
79
+ }
80
+
81
+ void parseSyncNotify(const char* msg, RHO_CONNECT_NOTIFY* pNotify);
82
+ String rhom_generate_id();
83
+
84
+ IDBResult rhom_executeSQL(const char* szSql, const char* szModel )
85
+ {
86
+ Hashtable<String,db::CDBAdapter*>& mapDBPartitions = db::CDBAdapter::getDBPartitions();
87
+ IDBResult res = db::DBResultPtr(0);
88
+ for (Hashtable<String,db::CDBAdapter*>::iterator it = mapDBPartitions.begin(); it != mapDBPartitions.end(); ++it )
89
+ {
90
+ res = (it->second)->executeSQL(szSql, szModel );
91
+ if ( !res.isEnd() )
92
+ break;
93
+ }
94
+
95
+ return res;
96
+ }
97
+
98
+ extern "C"
99
+ {
100
+
101
+ void rho_connectclient_initmodel(RHOM_MODEL* model)
102
+ {
103
+ memset( model, 0, sizeof(RHOM_MODEL) );
104
+ model->type = RMT_PROPERTY_BAG;
105
+ model->sync_type = RST_NONE;
106
+ model->sync_priority = 1000;
107
+ model->partition = "user";
108
+ model->associations = rho_connectclient_hash_create();
109
+ model->blob_attribs = NULL;
110
+ }
111
+
112
+ void rho_connectclient_destroymodel(RHOM_MODEL* model)
113
+ {
114
+ // foolproof, user may forget to do init
115
+ if (0 != model->associations) {
116
+ rho_connectclient_hash_delete(model->associations);
117
+ }
118
+ memset( model, 0, sizeof(RHOM_MODEL) );
119
+ }
120
+
121
+ static int get_start_id(const String& strPartition)
122
+ {
123
+ db::CDBAdapter& dbPart = db::CDBAdapter::getDB(strPartition.c_str());
124
+ int nStartModelID = 1;
125
+ {
126
+ IDBResult res = dbPart.executeSQL("SELECT MAX(source_id) AS maxid FROM sources");
127
+ if ( !res.isEnd() )
128
+ nStartModelID = res.getIntByIdx(0)+2;
129
+ }
130
+
131
+ if ( strPartition == "user" && nStartModelID < 1 )
132
+ nStartModelID = 1;
133
+ else if ( strPartition == "app" && nStartModelID < 20001 )
134
+ nStartModelID = 20001 + 2;
135
+ else if ( strPartition == "local" && nStartModelID < 40001 )
136
+ nStartModelID = 40001 + 2;
137
+
138
+ return nStartModelID;
139
+ }
140
+
141
+ static void rho_connectclient_processmodels( RHOM_MODEL* pModels, int nModels, const String& strPartition )
142
+ {
143
+ int nStartModelID = get_start_id(strPartition);
144
+ db::CDBAdapter& dbPart = db::CDBAdapter::getDB(strPartition.c_str());
145
+
146
+ //create associations string
147
+ Hashtable<String, String> hashSrcAssoc;
148
+ for ( int i = 0; i < nModels; i++ )
149
+ {
150
+ RHOM_MODEL& model = pModels[i];
151
+ if ( !model.associations || strPartition != model.partition )
152
+ continue;
153
+
154
+ Hashtable<String, String>& assocHash = *((Hashtable<String, String>*)model.associations);
155
+ for ( Hashtable<String,String>::iterator itAssoc = assocHash.begin(); itAssoc != assocHash.end(); ++itAssoc )
156
+ {
157
+ String strAssoc = hashSrcAssoc[itAssoc->second];
158
+ if (strAssoc.length() > 0 )
159
+ strAssoc += ",";
160
+
161
+ strAssoc += model.name;
162
+ strAssoc += "," + itAssoc->first;
163
+ hashSrcAssoc[itAssoc->second] = strAssoc;
164
+ }
165
+ }
166
+
167
+ for ( int i = 0; i < nModels; i++ )
168
+ {
169
+ RHOM_MODEL& model = pModels[i];
170
+ if ( strPartition != model.partition )
171
+ continue;
172
+
173
+ IDBResult res = dbPart.executeSQL("SELECT sync_priority,source_id,partition, sync_type, schema_version, associations, blob_attribs FROM sources WHERE name=?",
174
+ model.name);
175
+
176
+ String strAssoc = hashSrcAssoc[model.name];
177
+
178
+ if ( !res.isEnd() )
179
+ {
180
+ dbPart.executeSQL("UPDATE sources SET sync_priority=?, sync_type=?, partition=?, schema=?, schema_version=?, associations=?, blob_attribs=? WHERE name=?",
181
+ model.sync_priority, getSyncTypeName(model.sync_type), model.partition,
182
+ (model.type == RMT_PROPERTY_FIXEDSCHEMA ? "schema_model" : ""), "", strAssoc.c_str(), model.blob_attribs, model.name );
183
+
184
+ model.source_id = res.getIntByIdx(1);
185
+
186
+ }else //new model
187
+ {
188
+ dbPart.executeSQL("INSERT INTO sources (source_id,name,sync_priority, sync_type, partition, schema,schema_version, associations, blob_attribs) values (?,?,?,?,?,?,?,?,?) ",
189
+ nStartModelID, model.name, model.sync_priority, getSyncTypeName(model.sync_type), model.partition,
190
+ (model.type == RMT_PROPERTY_FIXEDSCHEMA ? "schema_model" : ""), "", strAssoc.c_str(), model.blob_attribs );
191
+
192
+ model.source_id = nStartModelID;
193
+ nStartModelID++;
194
+ }
195
+ }
196
+ }
197
+
198
+ void rho_connectclient_init(RHOM_MODEL* pModels, int nModels)
199
+ {
200
+ rho_logconf_Init(rho_native_rhopath(), rho_native_rhopath(), "");
201
+ CRhodesAppBase::Create( rho_native_rhopath(), rho_native_rhopath(), rho_native_rhopath() );
202
+
203
+ String strDbPath = rho_native_rhopath();
204
+
205
+ //create db and db-files folder
206
+ CRhoFile::createFolder( (strDbPath + "db/db-files").c_str());
207
+ CRhoFile::createFolder( (strDbPath + "apps").c_str());
208
+
209
+ for( int i = 0; i < nModels; i++ )
210
+ {
211
+ RHOM_MODEL& model = pModels[i];
212
+
213
+ String strDbPartition = strDbPath + "db/syncdb";
214
+ strDbPartition += model.partition;
215
+ strDbPartition += ".sqlite";
216
+
217
+ void* pDB = 0;
218
+ rho_db_open( strDbPartition.c_str(), model.partition, &pDB);
219
+ }
220
+
221
+ //process models
222
+ Hashtable<String,db::CDBAdapter*>& mapDBPartitions = db::CDBAdapter::getDBPartitions();
223
+ for (Hashtable<String,db::CDBAdapter*>::iterator it = mapDBPartitions.begin(); it != mapDBPartitions.end(); ++it )
224
+ {
225
+ rho_connectclient_processmodels(pModels, nModels, it->first);
226
+ }
227
+
228
+ rho_db_init_attr_manager();
229
+
230
+ LOG(INFO) + "Starting sync engine...";
231
+ CSyncThread::Create();
232
+
233
+ }
234
+
235
+ void rho_connectclient_updatemodels(RHOM_MODEL* pModels, int nModels)
236
+ {
237
+ for( int i = 0; i < nModels; i++ )
238
+ {
239
+ RHOM_MODEL& model = pModels[i];
240
+
241
+ db::CDBAdapter& db = db::CDBAdapter::getDB( model.partition );
242
+ //, sync_type, sync_priority, associations, blob_attribs
243
+ IDBResult res = db.executeSQL( "SELECT source_id from sources WHERE name=?", model.name );
244
+ if ( res.isEnd() )
245
+ continue;
246
+
247
+ model.source_id = res.getIntByIdx(0);
248
+ //model.sync_type = (RHOM_SYNC_TYPE)res.getIntByIdx(1);
249
+ }
250
+ }
251
+
252
+ void rho_connectclient_database_client_reset()
253
+ {
254
+ int pollInterval = rho_sync_set_pollinterval(0);
255
+ rho_sync_stop();
256
+
257
+ db::CDBAdapter& oUserDB = db::CDBAdapter::getUserDB();
258
+ oUserDB.executeSQL("UPDATE client_info SET client_id=?, token=?, token_sent=?", "", "", 0);
259
+
260
+ if ( rho_conf_is_property_exists("bulksync_state") )
261
+ rho_conf_setInt("bulksync_state", 0 );
262
+
263
+ Vector<String> arExclude;
264
+ arExclude.addElement("sources");
265
+ arExclude.addElement("client_info");
266
+
267
+ Vector<String> arPartNames = db::CDBAdapter::getDBAllPartitionNames();
268
+ for( int i = 0; i < (int)arPartNames.size(); i++ )
269
+ {
270
+ db::CDBAdapter& dbPart = db::CDBAdapter::getDB(arPartNames.elementAt(i).c_str());
271
+
272
+ dbPart.executeSQL("UPDATE sources SET token=0");
273
+ dbPart.destroy_tables(Vector<String>(), arExclude);
274
+ //db::CDBAdapter::destroy_tables_allpartitions(Vector<String>(), arExclude);
275
+ }
276
+
277
+ rho_db_init_attr_manager();
278
+
279
+ //hash_migrate = {}
280
+ //::Rho::RHO.init_schema_sources(hash_migrate)
281
+
282
+ rho_sync_set_pollinterval(pollInterval);
283
+ }
284
+
285
+ void rho_connectclient_database_full_reset_and_logout()
286
+ {
287
+ rho_sync_logout();
288
+ rho_connectclient_database_full_reset(false);
289
+ }
290
+
291
+ void rho_connectclient_database_fullclient_reset_and_logout()
292
+ {
293
+ rho_sync_logout();
294
+ rho_connectclient_database_full_reset(true);
295
+ }
296
+
297
+ void rho_connectclient_database_full_reset(bool bClientReset)
298
+ {
299
+ int pollInterval = rho_sync_set_pollinterval(0);
300
+ rho_sync_stop();
301
+
302
+ db::CDBAdapter& oUserDB = db::CDBAdapter::getUserDB();
303
+ oUserDB.executeSQL("UPDATE client_info SET reset=1");
304
+
305
+ if ( rho_conf_is_property_exists("bulksync_state") )
306
+ rho_conf_setInt("bulksync_state", 0 );
307
+
308
+ //oUserDB.executeSQL("UPDATE sources SET token=0");
309
+
310
+ Vector<String> arExclude;
311
+ arExclude.addElement("sources");
312
+ if (!bClientReset)
313
+ arExclude.addElement("client_info");
314
+
315
+ Vector<String> arPartNames = db::CDBAdapter::getDBAllPartitionNames();
316
+ for( int i = 0; i < (int)arPartNames.size(); i++ )
317
+ {
318
+ db::CDBAdapter& dbPart = db::CDBAdapter::getDB(arPartNames.elementAt(i).c_str());
319
+
320
+ dbPart.executeSQL("UPDATE sources SET token=0");
321
+ dbPart.destroy_tables(Vector<String>(), arExclude);
322
+ //db::CDBAdapter::destroy_tables_allpartitions(Vector<String>(), arExclude);
323
+ }
324
+
325
+ if (!bClientReset)
326
+ rho_conf_setString("push_pin", "");
327
+
328
+ rho_db_init_attr_manager();
329
+ //hash_migrate = {}
330
+ //::Rho::RHO.init_schema_sources(hash_migrate)
331
+
332
+ rho_sync_set_pollinterval(pollInterval);
333
+ }
334
+
335
+ char* rho_connectclient_database_export(const char* partition)
336
+ {
337
+ db::CDBAdapter& db = db::CDBAdapter::getDB(partition);
338
+ return strdup(db.exportDatabase().c_str());
339
+ }
340
+
341
+ int rho_connectclient_database_import(const char* partition, const char* zipName)
342
+ {
343
+ db::CDBAdapter& db = db::CDBAdapter::getDB(partition);
344
+ return db.importDatabase(zipName) ? 1 : 0;
345
+ }
346
+
347
+ void rho_connectclient_destroy()
348
+ {
349
+ CSyncThread::Destroy();
350
+ }
351
+
352
+ bool rhom_method_name_isreserved(const String& strName)
353
+ {
354
+ static Hashtable<String,int> reserved_names;
355
+ if ( reserved_names.size() == 0 )
356
+ {
357
+ reserved_names.put("object",1);
358
+ reserved_names.put("source_id",1);
359
+ reserved_names.put("update_type",1);
360
+ reserved_names.put("attrib_type",1);
361
+ reserved_names.put("set_notification",1);
362
+ reserved_names.put("clear_notification",1);
363
+ }
364
+
365
+ return reserved_names.get(strName) != 0;
366
+ }
367
+
368
+ void db_insert_into_table( db::CDBAdapter& db, const String& table, Hashtable<String, String>& hashObject, const char* excludes = null)
369
+ {
370
+ String cols = "";
371
+ String quests = "";
372
+ Vector<String> vals;
373
+
374
+ for ( Hashtable<String,String>::iterator it = hashObject.begin(); it != hashObject.end(); ++it )
375
+ {
376
+ String key = it->first;
377
+ String val = it->second;
378
+
379
+ if ( excludes && key.compare(excludes) == 0 )
380
+ continue;
381
+
382
+ if (cols.length() > 0)
383
+ {
384
+ cols += ',';
385
+ quests += ',';
386
+ }
387
+
388
+ cols += key;
389
+ quests += '?';
390
+ vals.addElement( val );
391
+ }
392
+
393
+ String query = "insert into " + table + "(" + cols + ") values (" + quests + ")";
394
+
395
+ db.executeSQLEx(query.c_str(), vals);
396
+ }
397
+
398
+ unsigned long rhom_make_object(IDBResult& res1, int nSrcID, bool isSchemaSrc)
399
+ {
400
+ unsigned long item = 0;
401
+ if ( res1.isEnd() )
402
+ return item;
403
+
404
+ item = rho_connectclient_hash_create();
405
+ rho_connectclient_hash_put(item, "source_id", convertToStringA(nSrcID).c_str() );
406
+
407
+ if (!isSchemaSrc)
408
+ {
409
+ for ( ; !res1.isEnd(); res1.next() )
410
+ {
411
+ if ( !res1.isNullByIdx(1) )
412
+ rho_connectclient_hash_put(item, res1.getStringByIdx(0).c_str(), res1.getStringByIdx(1).c_str() );
413
+ }
414
+ }else
415
+ {
416
+ for (int i = 0; i < res1.getColCount(); i++ )
417
+ {
418
+ if ( !res1.isNullByIdx(i))
419
+ rho_connectclient_hash_put(item, res1.getColName(i).c_str(), res1.getStringByIdx(i).c_str() );
420
+ }
421
+ }
422
+
423
+ return item;
424
+ }
425
+
426
+ unsigned long rhom_load_item_by_object(db::CDBAdapter& db, const String& src_name, int nSrcID, const String& szObject, bool isSchemaSrc )
427
+ {
428
+ unsigned long item = 0;
429
+
430
+ if (!isSchemaSrc)
431
+ {
432
+ String sql = "SELECT attrib,value FROM object_values WHERE object=? AND source_id=?";
433
+ IDBResult res1 = db.executeSQL(sql.c_str(), szObject, nSrcID);
434
+ item = rhom_make_object(res1, nSrcID, isSchemaSrc);
435
+ if (item)
436
+ rho_connectclient_hash_put(item, "object", szObject.c_str() );
437
+ }else
438
+ {
439
+ String sql = "SELECT * FROM " + src_name + " WHERE object=? LIMIT 1 OFFSET 0";
440
+ IDBResult res1 = db.executeSQL(sql.c_str(), szObject);
441
+ item = rhom_make_object(res1, nSrcID, isSchemaSrc);
442
+ }
443
+
444
+ return item;
445
+ }
446
+
447
+ unsigned long rho_connectclient_find(const char* szModel,const char* szObject )
448
+ {
449
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
450
+ if ( res.isEnd())
451
+ {
452
+ //TODO: report error - unknown source
453
+ return 0;
454
+ }
455
+
456
+ int nSrcID = res.getIntByIdx(0);
457
+ String db_partition = res.getStringByIdx(1);
458
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
459
+ //String tableName = isSchemaSrc ? src_name : "object_values";
460
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
461
+
462
+ return rhom_load_item_by_object( db, szModel, nSrcID, szObject, isSchemaSrc);
463
+ }
464
+
465
+ unsigned long rhom_find(const char* szModel, unsigned long hash, int nCount )
466
+ {
467
+ String src_name = szModel;
468
+
469
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
470
+ if ( res.isEnd())
471
+ {
472
+ //TODO: report error - unknown source
473
+ return 0;
474
+ }
475
+
476
+ int nSrcID = res.getIntByIdx(0);
477
+ String strSrcID = convertToStringA(nSrcID);
478
+ String db_partition = res.getStringByIdx(1);
479
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
480
+ //String tableName = isSchemaSrc ? src_name : "object_values";
481
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
482
+
483
+ Hashtable<String, String>& hashCond = *((Hashtable<String, String>*)hash);
484
+ String sql = "";
485
+ Vector<String> arValues;
486
+
487
+ if (!isSchemaSrc)
488
+ {
489
+ if (hashCond.size() == 0) {
490
+ sql = "SELECT distinct(object) FROM object_values WHERE source_id=?";
491
+ arValues.addElement(strSrcID);
492
+ }else
493
+ {
494
+ for ( Hashtable<String,String>::iterator it = hashCond.begin(); it != hashCond.end(); ++it )
495
+ {
496
+ if ( sql.length() > 0 )
497
+ sql += "\nINTERSECT\n";
498
+
499
+ sql += "SELECT object FROM object_values WHERE attrib=? AND source_id=? AND value=?";
500
+ arValues.addElement(it->first);
501
+ arValues.addElement(strSrcID);
502
+ arValues.addElement(it->second);
503
+ }
504
+ }
505
+ }else
506
+ {
507
+ sql = "SELECT object FROM " + src_name;
508
+ if (hashCond.size() != 0)
509
+ {
510
+ sql += " WHERE ";
511
+ for ( Hashtable<String,String>::iterator it = hashCond.begin(); it != hashCond.end(); ++it )
512
+ {
513
+ if (it != hashCond.begin())
514
+ sql += " AND ";
515
+ sql += it->first + "=?" ;
516
+ arValues.addElement(it->second);
517
+ }
518
+ }
519
+ }
520
+
521
+ IDBResult res1 = db.executeSQLEx(sql.c_str(), arValues );
522
+
523
+ if ( nCount == 1 )
524
+ {
525
+ return rhom_load_item_by_object(db, src_name, nSrcID, res1.getStringByIdx(0), isSchemaSrc);
526
+ }
527
+
528
+ unsigned long items = rho_connectclient_strhasharray_create();
529
+ for ( ; !res1.isEnd(); res1.next() )
530
+ {
531
+ rho_connectclient_strhasharray_add(items,
532
+ rhom_load_item_by_object(db, src_name, nSrcID, res1.getStringByIdx(0), isSchemaSrc) );
533
+ }
534
+
535
+ return items;
536
+ }
537
+
538
+ unsigned long rho_connectclient_find_all(const char* szModel, unsigned long hash )
539
+ {
540
+ return rhom_find( szModel, hash, -1 );
541
+ }
542
+
543
+ unsigned long rho_connectclient_find_first(const char* szModel, unsigned long hash )
544
+ {
545
+ return rhom_find( szModel, hash, 1 );
546
+ }
547
+
548
+ unsigned long rho_connectclient_findbysql(const char* szModel, const char* szSql, unsigned long arParams )
549
+ {
550
+ String src_name = szModel;
551
+
552
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
553
+ if ( res.isEnd())
554
+ {
555
+ //TODO: report error - unknown source
556
+ return 0;
557
+ }
558
+
559
+ int nSrcID = res.getIntByIdx(0);
560
+ String db_partition = res.getStringByIdx(1);
561
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
562
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
563
+
564
+ unsigned long items = rho_connectclient_strhasharray_create();
565
+
566
+ IDBResult res1 = !arParams ? db.executeSQL(szSql) : db.executeSQLEx( szSql, *((Vector<String>*) arParams) );
567
+ if ( res1.isEnd() )
568
+ return items;
569
+
570
+ for ( ; !res1.isEnd(); res1.next() )
571
+ {
572
+ unsigned long item = rho_connectclient_hash_create();
573
+
574
+ for (int i = 0; i < res1.getColCount(); i++ )
575
+ {
576
+ if ( !res1.isNullByIdx(i))
577
+ rho_connectclient_hash_put(item, res1.getColName(i).c_str(), res1.getStringByIdx(i).c_str() );
578
+ }
579
+
580
+ rho_connectclient_strhasharray_add(items, item );
581
+ }
582
+
583
+ return items;
584
+
585
+ }
586
+
587
+ void rho_connectclient_start_bulkupdate(const char* szModel)
588
+ {
589
+ String src_name = szModel;
590
+
591
+ IDBResult res = rhom_executeSQL("SELECT partition from sources WHERE name=?", szModel);
592
+ if ( res.isEnd())
593
+ {
594
+ //TODO: report error - unknown source
595
+ return;
596
+ }
597
+ String db_partition = res.getStringByIdx(0);
598
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
599
+
600
+ db.startTransaction();
601
+ }
602
+
603
+ void rho_connectclient_stop_bulkupdate(const char* szModel)
604
+ {
605
+ String src_name = szModel;
606
+ IDBResult res = rhom_executeSQL("SELECT partition from sources WHERE name=?", szModel);
607
+ if ( res.isEnd())
608
+ {
609
+ //TODO: report error - unknown source
610
+ return;
611
+ }
612
+ String db_partition = res.getStringByIdx(0);
613
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
614
+
615
+ db.endTransaction();
616
+ }
617
+
618
+ void rho_connectclient_itemdestroy( const char* szModel, unsigned long hash )
619
+ {
620
+ Hashtable<String, String>& hashObject = *((Hashtable<String, String>*)hash);
621
+ String src_name = szModel;
622
+
623
+ String obj = hashObject.get("object");
624
+ String update_type="delete";
625
+
626
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
627
+ if ( res.isEnd())
628
+ {
629
+ //TODO: report error - unknown source
630
+ return;
631
+ }
632
+
633
+ int nSrcID = res.getIntByIdx(0);
634
+ String db_partition = res.getStringByIdx(1);
635
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
636
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
637
+ String tableName = isSchemaSrc ? src_name : "object_values";
638
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
639
+
640
+ db.startTransaction();
641
+
642
+ //save list of attrs
643
+ unsigned long item = 0;
644
+
645
+ if ( isSchemaSrc )
646
+ {
647
+ IDBResult attrsList = db.executeSQL( ("SELECT * FROM " + tableName + " WHERE object=?").c_str(), obj);
648
+ if ( !attrsList.isEnd() )
649
+ item = rhom_make_object(attrsList,nSrcID,isSchemaSrc);
650
+ }else
651
+ {
652
+ IDBResult attrsList = db.executeSQL( ("SELECT attrib, value FROM " + tableName + " WHERE object=? and source_id=?").c_str(), obj, nSrcID);
653
+ if ( !attrsList.isEnd() )
654
+ item = rhom_make_object(attrsList,nSrcID,isSchemaSrc);
655
+ }
656
+
657
+ //first delete the record from viewable list
658
+ db.executeSQL( ("DELETE FROM " + tableName + " WHERE object=?").c_str(), obj );
659
+
660
+ if ( isSyncSrc )
661
+ {
662
+ IDBResult resCreateType = db.executeSQL("SELECT update_type FROM changed_values WHERE object=? and update_type=? and sent=?",
663
+ obj, "create", 0);
664
+
665
+ db.executeSQL("DELETE FROM changed_values WHERE object=? and sent=?", obj, 0);
666
+
667
+ if ( resCreateType.isEnd() && item != 0 )
668
+ {
669
+ Hashtable<String,String>& hashItem = *((Hashtable<String,String>*)item);
670
+ for ( Hashtable<String,String>::iterator it = hashItem.begin(); it != hashItem.end(); ++it )
671
+ {
672
+ String key = it->first;
673
+ String val = it->second;
674
+
675
+ if ( rhom_method_name_isreserved(key) )
676
+ continue;
677
+
678
+ Hashtable<String,String> fields;
679
+ fields.put("source_id", convertToStringA(nSrcID));
680
+ fields.put("object", obj);
681
+ fields.put("attrib", key);
682
+ fields.put("value", val);
683
+ fields.put("update_type", update_type);
684
+
685
+ db_insert_into_table(db, "changed_values", fields );
686
+ }
687
+
688
+ rho_connectclient_hash_delete(item);
689
+ }
690
+ }
691
+
692
+ db.endTransaction();
693
+ }
694
+
695
+ void rho_connectclient_on_sync_create_error(const char* szModel, RHO_CONNECT_NOTIFY* pNotify, const char* szAction )
696
+ {
697
+ unsigned long hash_create_errors = pNotify->create_errors_messages;
698
+ if (!hash_create_errors)
699
+ return;
700
+
701
+ String src_name = szModel;
702
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
703
+ if ( res.isEnd())
704
+ {
705
+ //TODO: report error - unknown source
706
+ return;
707
+ }
708
+
709
+ int nSrcID = res.getIntByIdx(0);
710
+ String db_partition = res.getStringByIdx(1);
711
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
712
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
713
+ String tableName = isSchemaSrc ? src_name : "object_values";
714
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
715
+ db.startTransaction();
716
+
717
+ Hashtable<String, String>& hashCreateErrors = *((Hashtable<String, String>*)hash_create_errors);
718
+
719
+ for ( Hashtable<String,String>::iterator it = hashCreateErrors.begin(); it != hashCreateErrors.end(); ++it )
720
+ {
721
+ String obj = it->first;
722
+ if ( strcmp(szAction, "recreate") == 0 )
723
+ {
724
+ IDBResult deletes = db.executeSQL( "SELECT object FROM changed_values WHERE update_type=? and object=? and source_id=?", "delete", obj, nSrcID );
725
+ if (deletes.isEnd())
726
+ {
727
+ db.executeSQL( "DELETE FROM changed_values WHERE object=? and source_id=?", obj, nSrcID );
728
+ Hashtable<String,String> fields;
729
+ fields.put("update_type", "create");
730
+ fields.put("attrib", "object");
731
+ fields.put("source_id", convertToStringA(nSrcID));
732
+ fields.put("object", obj);
733
+ db_insert_into_table(db, "changed_values", fields);
734
+ continue;
735
+ }
736
+ }
737
+
738
+ db.executeSQL( "DELETE FROM changed_values WHERE object=? and source_id=?", obj, nSrcID );
739
+ if ( isSchemaSrc )
740
+ db.executeSQL( (String("DELETE FROM ") + tableName + " WHERE object=?").c_str(), obj );
741
+ else
742
+ db.executeSQL( (String("DELETE FROM ") + tableName + " WHERE object=? and source_id=?").c_str(), obj, nSrcID );
743
+ }
744
+
745
+ db.endTransaction();
746
+ }
747
+
748
+ void rho_connectclient_push_changes(const char* szModel )
749
+ {
750
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
751
+ if ( res.isEnd())
752
+ {
753
+ //TODO: report error - unknown source
754
+ return;
755
+ }
756
+
757
+ int nSrcID = res.getIntByIdx(0);
758
+ String db_partition = res.getStringByIdx(1);
759
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
760
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
761
+
762
+ if (!isSyncSrc)
763
+ return;
764
+
765
+ Hashtable<String,String> fields;
766
+ fields.put("update_type", "push_changes");
767
+ fields.put("source_id", convertToStringA(nSrcID));
768
+ db_insert_into_table(db, "changed_values", fields);
769
+ }
770
+
771
+ void _insert_or_update_attr(db::CDBAdapter& db, bool isSchemaSrc, const String& tableName, int nSrcID, const String& obj, const String& attrib, const String& new_val)
772
+ {
773
+ if ( isSchemaSrc )
774
+ {
775
+ IDBResult result = db.executeSQL( ("SELECT * FROM " + tableName + " WHERE object=?").c_str(), obj);
776
+ if ( !result.isEnd() )
777
+ db.executeSQL( (String("UPDATE ") + tableName + " SET " + attrib + "=? WHERE object=?").c_str(), new_val, obj );
778
+ else
779
+ {
780
+ Hashtable<String,String> fields;
781
+ fields.put("object", obj);
782
+ fields.put("attrib", new_val);
783
+ db_insert_into_table(db, tableName, fields);
784
+ }
785
+ }
786
+ else
787
+ {
788
+ IDBResult result = db.executeSQL( ("SELECT attrib, value FROM " + tableName + " WHERE object=? and source_id=?").c_str(), obj, nSrcID);
789
+ if ( !result.isEnd() )
790
+ db.executeSQL( "UPDATE object_values SET value=? WHERE object=? and attrib=? and source_id=?", new_val, obj, attrib, nSrcID );
791
+ else
792
+ {
793
+ Hashtable<String,String> fields;
794
+ fields.put("source_id", convertToStringA(nSrcID));
795
+ fields.put("object", obj);
796
+ fields.put("attrib", attrib);
797
+ fields.put("value", new_val);
798
+ db_insert_into_table(db, tableName, fields);
799
+ }
800
+ }
801
+ }
802
+
803
+ void rho_connectclient_on_sync_update_error(const char* szModel, RHO_CONNECT_NOTIFY* pNotify, const char* szAction )
804
+ {
805
+ String src_name = szModel;
806
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
807
+ if ( res.isEnd())
808
+ {
809
+ //TODO: report error - unknown source
810
+ return;
811
+ }
812
+
813
+ int nSrcID = res.getIntByIdx(0);
814
+ String db_partition = res.getStringByIdx(1);
815
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
816
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
817
+ String tableName = isSchemaSrc ? src_name : "object_values";
818
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
819
+ db.startTransaction();
820
+
821
+ if ( strcmp(szAction, "rollback") == 0 )
822
+ {
823
+ rho::Vector<rho::String>& arObjs = *((rho::Vector<rho::String>*)pNotify->update_rollback_obj);
824
+ for (int i = 0; i < (int)arObjs.size(); i++)
825
+ {
826
+ String obj = arObjs[i];
827
+
828
+ Hashtable<String, String>& hashUpdateAttrs = *((Hashtable<String, String>*)rho_connectclient_strhasharray_get(pNotify->update_rollback_attrs,i));
829
+ for ( Hashtable<String,String>::iterator it = hashUpdateAttrs.begin(); it != hashUpdateAttrs.end(); ++it )
830
+ {
831
+ String attrib = it->first;
832
+ String value = it->second;
833
+
834
+ _insert_or_update_attr(db, isSchemaSrc, tableName, nSrcID, obj, attrib, value);
835
+ }
836
+ }
837
+ }else
838
+ {
839
+ rho::Vector<rho::String>& arObjs = *((rho::Vector<rho::String>*)pNotify->update_errors_obj);
840
+ for (int i = 0; i < (int)arObjs.size(); i++)
841
+ {
842
+ String obj = arObjs[i];
843
+
844
+ Hashtable<String, String>& hashUpdateAttrs = *((Hashtable<String, String>*)rho_connectclient_strhasharray_get(pNotify->update_errors_attrs,i));
845
+ for ( Hashtable<String,String>::iterator it = hashUpdateAttrs.begin(); it != hashUpdateAttrs.end(); ++it )
846
+ {
847
+ String attrib = it->first;
848
+ String value = it->second;
849
+
850
+ IDBResult resUpdateType = db.executeSQL( "SELECT update_type FROM changed_values WHERE object=? and source_id=? and attrib=? and sent=?", obj, nSrcID, attrib, 0 );
851
+ if (resUpdateType.isEnd())
852
+ {
853
+ String attrib_type = db::CDBAdapter::getDB(db_partition.c_str()).getAttrMgr().isBlobAttr(nSrcID, attrib.c_str()) ? "blob.file" : "";
854
+ Hashtable<String,String> fields;
855
+ fields.put("update_type", "update");
856
+ fields.put("attrib", attrib);
857
+ fields.put("attrib_type", attrib_type);
858
+ fields.put("source_id", convertToStringA(nSrcID));
859
+ fields.put("object", obj);
860
+ fields.put("value", value);
861
+ db_insert_into_table(db, "changed_values", fields);
862
+ }
863
+ }
864
+ }
865
+ }
866
+
867
+ db.endTransaction();
868
+ }
869
+
870
+ void rho_connectclient_on_sync_delete_error(const char* szModel, RHO_CONNECT_NOTIFY* pNotify, const char* szAction )
871
+ {
872
+ String src_name = szModel;
873
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
874
+ if ( res.isEnd())
875
+ {
876
+ //TODO: report error - unknown source
877
+ return;
878
+ }
879
+
880
+ int nSrcID = res.getIntByIdx(0);
881
+ String db_partition = res.getStringByIdx(1);
882
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
883
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
884
+ String tableName = isSchemaSrc ? src_name : "object_values";
885
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
886
+ db.startTransaction();
887
+
888
+ rho::Vector<rho::String>& arObjs = *((rho::Vector<rho::String>*)pNotify->delete_errors_obj);
889
+ for (int i = 0; i < (int)arObjs.size(); i++)
890
+ {
891
+ String obj = arObjs[i];
892
+
893
+ Hashtable<String, String>& hashDeleteAttrs = *((Hashtable<String, String>*)rho_connectclient_strhasharray_get(pNotify->delete_errors_attrs,i));
894
+ for ( Hashtable<String,String>::iterator it = hashDeleteAttrs.begin(); it != hashDeleteAttrs.end(); ++it )
895
+ {
896
+ String attrib = it->first;
897
+ String value = it->second;
898
+
899
+ IDBResult resUpdateType = db.executeSQL( "SELECT update_type FROM changed_values WHERE object=? and source_id=? and attrib=? and sent=?", obj, nSrcID, attrib, 0 );
900
+ if (resUpdateType.isEnd())
901
+ {
902
+ String attrib_type = db::CDBAdapter::getDB(db_partition.c_str()).getAttrMgr().isBlobAttr(nSrcID, attrib.c_str()) ? "blob.file" : "";
903
+ Hashtable<String,String> fields;
904
+ fields.put("update_type", "delete");
905
+ fields.put("attrib", attrib);
906
+ fields.put("attrib_type", attrib_type);
907
+ fields.put("source_id", convertToStringA(nSrcID));
908
+ fields.put("object", obj);
909
+ fields.put("value", value);
910
+ db_insert_into_table(db, "changed_values", fields);
911
+ }
912
+ }
913
+ }
914
+
915
+ db.endTransaction();
916
+ }
917
+
918
+ void rho_connectclient_save( const char* szModel, unsigned long hash )
919
+ {
920
+ Hashtable<String, String>& hashObject = *((Hashtable<String, String>*)hash);
921
+ String src_name = szModel;
922
+
923
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
924
+ if ( res.isEnd())
925
+ {
926
+ //TODO: report error - unknown source
927
+ return;
928
+ }
929
+
930
+ int nSrcID = res.getIntByIdx(0);
931
+ String obj = hashObject.get("object");
932
+
933
+ String db_partition = res.getStringByIdx(1);
934
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
935
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
936
+ String tableName = isSchemaSrc ? src_name : "object_values";
937
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
938
+
939
+ db.Lock();
940
+
941
+ String sql;
942
+ Vector<String> arValues;
943
+ bool is_new_item = false;
944
+
945
+ if (isSchemaSrc)
946
+ {
947
+ sql = "SELECT object FROM " + tableName + " WHERE object=? LIMIT 1 OFFSET 0";
948
+ arValues.addElement(obj);
949
+ }
950
+ else
951
+ {
952
+ sql = "SELECT object FROM " + tableName + " WHERE object=? AND source_id=? LIMIT 1 OFFSET 0";
953
+ arValues.addElement(obj);
954
+ arValues.addElement(convertToStringA(nSrcID));
955
+ }
956
+ IDBResult res1 = db.executeSQLEx(sql.c_str(), arValues );
957
+ if (res1.isEnd())
958
+ {
959
+ rho_connectclient_create_object(szModel, hash);
960
+ is_new_item = true;
961
+ }
962
+
963
+ db.Unlock();
964
+
965
+ if ( is_new_item )
966
+ return;
967
+
968
+ db.startTransaction();
969
+ String update_type = "update";
970
+ bool ignore_changed_values = true;
971
+ if (isSyncSrc)
972
+ {
973
+ IDBResult resUpdateType = db.executeSQL( "SELECT update_type FROM changed_values WHERE object=? and source_id=? and sent=?",
974
+ obj, nSrcID, 0 );
975
+ if (!resUpdateType.isEnd())
976
+ update_type = resUpdateType.getStringByIdx(0);
977
+ else
978
+ update_type = "update";
979
+
980
+ ignore_changed_values = update_type=="create";
981
+ }
982
+
983
+ unsigned long item = rhom_load_item_by_object( db, src_name, nSrcID, obj, isSchemaSrc);
984
+ Hashtable<String, String>& hashItem = *((Hashtable<String, String>*)item);
985
+
986
+ for ( Hashtable<String,String>::iterator it = hashObject.begin(); it != hashObject.end(); ++it )
987
+ {
988
+ String key = it->first;
989
+ String val = it->second;
990
+
991
+ if ( rhom_method_name_isreserved(key) )
992
+ continue;
993
+
994
+ // add rows excluding object, source_id and update_type
995
+ Hashtable<String,String> fields;
996
+ fields.put("source_id", convertToStringA(nSrcID));
997
+ fields.put("object", obj);
998
+ fields.put("attrib", key);
999
+ fields.put("value", val);
1000
+ fields.put("update_type", update_type);
1001
+ if ( db::CDBAdapter::getDB(db_partition.c_str()).getAttrMgr().isBlobAttr(nSrcID, key.c_str()) )
1002
+ fields.put( "attrib_type", "blob.file");
1003
+
1004
+ if ( hashItem.containsKey(key) )
1005
+ {
1006
+ bool isModified = hashItem.get(key) != val;
1007
+ if (isModified)
1008
+ {
1009
+ if (!ignore_changed_values)
1010
+ {
1011
+ IDBResult resUpdateType = db.executeSQL( "SELECT update_type FROM changed_values WHERE object=? and attrib=? and source_id=? and sent=?",
1012
+ obj, key, nSrcID, 0 );
1013
+ if (!resUpdateType.isEnd())
1014
+ {
1015
+ fields.put("update_type", resUpdateType.getStringByIdx(0) );
1016
+ db.executeSQL( "DELETE FROM changed_values WHERE object=? and attrib=? and source_id=? and sent=?",
1017
+ obj, key, nSrcID, 0 );
1018
+ }
1019
+
1020
+ db_insert_into_table(db, "changed_values", fields);
1021
+ }
1022
+
1023
+ if ( isSchemaSrc )
1024
+ db.executeSQL( (String("UPDATE ") + tableName + " SET " + key + "=? WHERE object=?").c_str(), val, obj );
1025
+ else
1026
+ db.executeSQL( "UPDATE object_values SET value=? WHERE object=? and attrib=? and source_id=?", val, obj, key, nSrcID );
1027
+ }
1028
+
1029
+ }else
1030
+ {
1031
+ if (!ignore_changed_values )
1032
+ db_insert_into_table(db, "changed_values", fields);
1033
+
1034
+ fields.remove("update_type");
1035
+ fields.remove("attrib_type");
1036
+
1037
+ if (isSchemaSrc)
1038
+ db.executeSQL( (String("UPDATE ") + tableName + " SET " + key + "=? WHERE object=?").c_str(), val, obj );
1039
+ else
1040
+ db_insert_into_table(db, tableName, fields);
1041
+ }
1042
+ }
1043
+
1044
+ db.endTransaction();
1045
+ }
1046
+
1047
+ void rho_connectclient_create_object(const char* szModel, unsigned long hash)
1048
+ {
1049
+ Hashtable<String, String>& hashObject = *((Hashtable<String, String>*)hash);
1050
+ String src_name = szModel;
1051
+
1052
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition, schema, sync_type from sources WHERE name=?", szModel);
1053
+ if ( res.isEnd())
1054
+ {
1055
+ //TODO: report error - unknown source
1056
+ return;
1057
+ }
1058
+
1059
+ String update_type = "create";
1060
+ int nSrcID = res.getIntByIdx(0);
1061
+ String obj = hashObject.containsKey("object") ? hashObject.get("object") : rhom_generate_id();
1062
+
1063
+ String db_partition = res.getStringByIdx(1);
1064
+ bool isSchemaSrc = res.getStringByIdx(2).length() > 0;
1065
+ bool isSyncSrc = res.getStringByIdx(3).compare("none") != 0;
1066
+ String tableName = isSchemaSrc ? src_name : "object_values";
1067
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
1068
+
1069
+ hashObject.put("source_id", convertToStringA(nSrcID));
1070
+ hashObject.put("object", obj);
1071
+
1072
+ db.startTransaction();
1073
+
1074
+ if ( isSyncSrc )
1075
+ {
1076
+ Hashtable<String,String> fields;
1077
+ fields.put("source_id", convertToStringA(nSrcID));
1078
+ fields.put("object", obj);
1079
+ fields.put("attrib", "object");
1080
+ fields.put("update_type", "create");
1081
+
1082
+ db_insert_into_table(db, "changed_values", fields );
1083
+ }
1084
+
1085
+ if ( isSchemaSrc )
1086
+ db_insert_into_table(db, tableName, hashObject, "source_id");
1087
+ else
1088
+ {
1089
+ for ( Hashtable<String,String>::iterator it = hashObject.begin(); it != hashObject.end(); ++it )
1090
+ {
1091
+ String key = it->first;
1092
+ String val = it->second;
1093
+
1094
+ if ( rhom_method_name_isreserved(key) )
1095
+ continue;
1096
+
1097
+ Hashtable<String,String> fields;
1098
+ fields.put("source_id", convertToStringA(nSrcID));
1099
+ fields.put("object", obj);
1100
+ fields.put("attrib", key);
1101
+ fields.put("value", val);
1102
+
1103
+ db_insert_into_table(db, tableName, fields);
1104
+ }
1105
+ }
1106
+
1107
+ db.endTransaction();
1108
+ }
1109
+
1110
+ int rho_connectclient_is_changed(const char* szModel)
1111
+ {
1112
+ String src_name = szModel;
1113
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition from sources WHERE name=?", szModel);
1114
+ if ( res.isEnd())
1115
+ {
1116
+ //TODO: report error - unknown source
1117
+ return 0;
1118
+ }
1119
+
1120
+ int nSrcID = res.getIntByIdx(0);
1121
+ String db_partition = res.getStringByIdx(1);
1122
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
1123
+
1124
+ IDBResult resChanged = db.executeSQL("SELECT object FROM changed_values WHERE source_id=? LIMIT 1 OFFSET 0", nSrcID);
1125
+
1126
+ return resChanged.isEnd() ? 0 : 1;
1127
+ }
1128
+
1129
+ void rho_connectclient_set_synctype(const char* szModel, RHOM_SYNC_TYPE sync_type)
1130
+ {
1131
+ IDBResult res = rhom_executeSQL("SELECT source_id, partition from sources WHERE name=?", szModel);
1132
+ if ( res.isEnd())
1133
+ {
1134
+ //TODO: report error - unknown source
1135
+ return;
1136
+ }
1137
+
1138
+ int nSrcID = res.getIntByIdx(0);
1139
+ String db_partition = res.getStringByIdx(1);
1140
+ db::CDBAdapter& db = db::CDBAdapter::getDB(db_partition.c_str());
1141
+
1142
+ db.executeSQL("UPDATE sources SET sync_type=? WHERE name=?", getSyncTypeName(sync_type), szModel );
1143
+ }
1144
+
1145
+ void parseServerErrors( CJSONEntry oEntry, unsigned long& errors_obj, unsigned long& errors_attrs )
1146
+ {
1147
+ if (!errors_obj)
1148
+ errors_obj = rho_connectclient_strarray_create();
1149
+
1150
+ CJSONStructIterator oIter(oEntry);
1151
+ for( ; !oIter.isEnd(); oIter.next() )
1152
+ {
1153
+ CJSONEntry oObjEntry = oIter.getCurValue();
1154
+
1155
+ String strObject = oIter.getCurKey();
1156
+ int nObj = rho_connectclient_strarray_find(errors_obj, strObject.c_str() );
1157
+ if ( nObj < 0 )
1158
+ nObj = rho_connectclient_strarray_add(errors_obj, strObject.c_str() );
1159
+
1160
+ if (oObjEntry.hasName("attributes"))
1161
+ {
1162
+ CJSONEntry oAttrEntry = oObjEntry.getEntry("attributes");
1163
+ CJSONStructIterator oAttrIter(oAttrEntry);
1164
+ for( ; !oAttrIter.isEnd(); oAttrIter.next() )
1165
+ {
1166
+ String strAttr = oAttrIter.getCurKey();
1167
+ if (!errors_attrs)
1168
+ errors_attrs = rho_connectclient_strhasharray_create();
1169
+
1170
+ VectorPtr<Hashtable<String, String>* >& arAttrs = *((VectorPtr<Hashtable<String, String>* >*)errors_attrs);
1171
+ if ( nObj < (int)arAttrs.size() )
1172
+ arAttrs[nObj]->put(strAttr, oAttrIter.getCurString());
1173
+ else
1174
+ {
1175
+ unsigned long hashAttrs = rho_connectclient_hash_create();
1176
+ rho_connectclient_hash_put(hashAttrs, strAttr.c_str(), oAttrIter.getCurString().c_str());
1177
+ arAttrs.addElement( (Hashtable<String, String>*)hashAttrs );
1178
+ }
1179
+ }
1180
+ }
1181
+ }
1182
+ }
1183
+
1184
+ void parseServerErrorMessage( CJSONEntry oEntry, unsigned long& errors_obj )
1185
+ {
1186
+ if (!errors_obj)
1187
+ errors_obj = rho_connectclient_hash_create();
1188
+
1189
+ CJSONStructIterator oIter(oEntry);
1190
+ for( ; !oIter.isEnd(); oIter.next() )
1191
+ {
1192
+ CJSONEntry oObjEntry = oIter.getCurValue();
1193
+
1194
+ if (oObjEntry.hasName("message"))
1195
+ {
1196
+ CJSONEntry oMsgEntry = oObjEntry.getEntry("message");
1197
+ rho_connectclient_hash_put(errors_obj, oIter.getCurKey().c_str(), oMsgEntry.getString());
1198
+ }
1199
+ }
1200
+
1201
+ }
1202
+
1203
+
1204
+ void rho_connectclient_parsenotify(const char* msg, RHO_CONNECT_NOTIFY* pNotify)
1205
+ {
1206
+ // for the case it has been called in single-threaded mode,
1207
+ // so notification message may be NULL
1208
+ if (NULL == msg)
1209
+ return;
1210
+
1211
+ CJSONEntry oMsg(msg);
1212
+ if ( oMsg.hasName("total_count") )
1213
+ convertFromStringA( oMsg.getString("total_count"), pNotify->total_count );
1214
+ if ( oMsg.hasName("processed_count"))
1215
+ convertFromStringA( oMsg.getString("processed_count"), pNotify->processed_count );
1216
+ if ( oMsg.hasName("cumulative_count"))
1217
+ convertFromStringA( oMsg.getString("cumulative_count"), pNotify->cumulative_count );
1218
+ if ( oMsg.hasName("source_id"))
1219
+ convertFromStringA( oMsg.getString("source_id"), pNotify->source_id );
1220
+ if ( oMsg.hasName("error_code") )
1221
+ convertFromStringA( oMsg.getString("error_code"), pNotify->error_code );
1222
+ if ( oMsg.hasName("source_name") )
1223
+ pNotify->source_name = strdup(oMsg.getString("source_name"));
1224
+ if ( oMsg.hasName("sync_type") )
1225
+ pNotify->sync_type = strdup(oMsg.getString("sync_type"));
1226
+ if ( oMsg.hasName("bulk_status") )
1227
+ pNotify->bulk_status = strdup(oMsg.getString("bulk_status"));
1228
+ if ( oMsg.hasName("partition") )
1229
+ pNotify->partition = strdup(oMsg.getString("partition"));
1230
+ if ( oMsg.hasName("status") )
1231
+ pNotify->status = strdup(oMsg.getString("status"));
1232
+ if ( oMsg.hasName("error_message") )
1233
+ pNotify->error_message = strdup(oMsg.getString("error_message"));
1234
+
1235
+ if ( oMsg.hasName("server_errors") )
1236
+ {
1237
+ CJSONEntry oSrvErrors = oMsg.getEntry("server_errors");
1238
+ if ( oSrvErrors.hasName("create-error") )
1239
+ parseServerErrorMessage(oSrvErrors.getEntry("create-error"), pNotify->create_errors_messages);
1240
+ if ( oSrvErrors.hasName("update-error") )
1241
+ {
1242
+ parseServerErrors( oSrvErrors.getEntry("update-error"), pNotify->update_errors_obj, pNotify->update_errors_attrs );
1243
+ parseServerErrorMessage(oSrvErrors.getEntry("update-error"), pNotify->update_errors_messages);
1244
+ }
1245
+ if ( oSrvErrors.hasName("update-rollback") )
1246
+ {
1247
+ parseServerErrors( oSrvErrors.getEntry("update-rollback"), pNotify->update_rollback_obj, pNotify->update_rollback_attrs );
1248
+ }
1249
+ if ( oSrvErrors.hasName("delete-error") )
1250
+ {
1251
+ parseServerErrors( oSrvErrors.getEntry("delete-error"), pNotify->delete_errors_obj, pNotify->delete_errors_attrs );
1252
+ parseServerErrorMessage(oSrvErrors.getEntry("delete-error"), pNotify->delete_errors_messages);
1253
+ }
1254
+ }
1255
+ }
1256
+
1257
+ void rho_connectclient_free_syncnotify(RHO_CONNECT_NOTIFY* pNotify)
1258
+ {
1259
+ if (!pNotify)
1260
+ return;
1261
+
1262
+ if ( pNotify->source_name != null )
1263
+ free(pNotify->source_name);
1264
+
1265
+ if ( pNotify->sync_type != null )
1266
+ free(pNotify->sync_type);
1267
+
1268
+ if ( pNotify->bulk_status != null )
1269
+ free(pNotify->bulk_status);
1270
+
1271
+ if ( pNotify->partition != null )
1272
+ free(pNotify->partition);
1273
+
1274
+ if ( pNotify->status != null )
1275
+ free(pNotify->status);
1276
+
1277
+ if ( pNotify->error_message != null )
1278
+ free(pNotify->error_message);
1279
+
1280
+ if ( pNotify->callback_params != null )
1281
+ free(pNotify->callback_params);
1282
+
1283
+ if ( pNotify->create_errors_messages != null )
1284
+ rho_connectclient_hash_delete(pNotify->create_errors_messages);
1285
+
1286
+ if ( pNotify->update_errors_obj != null )
1287
+ rho_connectclient_strarray_delete(pNotify->update_errors_obj);
1288
+
1289
+ if ( pNotify->update_errors_attrs != null )
1290
+ rho_connectclient_strhasharray_delete(pNotify->update_errors_attrs);
1291
+
1292
+ if ( pNotify->update_errors_messages != null )
1293
+ rho_connectclient_hash_delete(pNotify->update_errors_messages);
1294
+
1295
+ if ( pNotify->update_rollback_obj != null )
1296
+ rho_connectclient_strarray_delete(pNotify->update_rollback_obj);
1297
+
1298
+ if ( pNotify->update_rollback_attrs != null )
1299
+ rho_connectclient_strhasharray_delete(pNotify->update_rollback_attrs);
1300
+
1301
+ if ( pNotify->delete_errors_obj != null )
1302
+ rho_connectclient_strarray_delete(pNotify->delete_errors_obj);
1303
+
1304
+ if ( pNotify->delete_errors_attrs != null )
1305
+ rho_connectclient_strhasharray_delete(pNotify->delete_errors_attrs);
1306
+
1307
+ if ( pNotify->delete_errors_messages != null )
1308
+ rho_connectclient_hash_delete(pNotify->delete_errors_messages);
1309
+
1310
+ memset( pNotify, 0, sizeof(RHO_CONNECT_NOTIFY) );
1311
+ }
1312
+
1313
+ void rho_connectclient_parse_objectnotify(const char* msg, RHO_CONNECT_OBJECT_NOTIFY* pNotify)
1314
+ {
1315
+ //TODO: parse json and make tests
1316
+ /* {
1317
+ CTokenizer oTokenizer( msg, "&" );
1318
+ while (oTokenizer.hasMoreTokens())
1319
+ {
1320
+ String tok = oTokenizer.nextToken();
1321
+ if (tok.length() == 0)
1322
+ continue;
1323
+
1324
+ CTokenizer oValueTok( tok, "=" );
1325
+ String name = net::URI::urlDecode(oValueTok.nextToken());
1326
+
1327
+ if ( String_startsWith(name, "deleted[][object]"))
1328
+ pNotify->deleted_count++;
1329
+ else if ( String_startsWith(name, "updated[][object]"))
1330
+ pNotify->updated_count++;
1331
+ else if ( String_startsWith(name, "created[][object]"))
1332
+ pNotify->created_count++;
1333
+ }
1334
+ }
1335
+
1336
+ if ( pNotify->deleted_count > 0 )
1337
+ {
1338
+ pNotify->deleted_source_ids = new int[pNotify->deleted_count];
1339
+ pNotify->deleted_objects = new char*[pNotify->deleted_count];
1340
+ }
1341
+
1342
+ if ( pNotify->updated_count > 0 )
1343
+ {
1344
+ pNotify->updated_source_ids = new int[pNotify->updated_count];
1345
+ pNotify->updated_objects = new char*[pNotify->updated_count];
1346
+ }
1347
+
1348
+ if ( pNotify->created_count > 0 )
1349
+ {
1350
+ pNotify->created_source_ids = new int[pNotify->created_count];
1351
+ pNotify->created_objects = new char*[pNotify->created_count];
1352
+ }
1353
+
1354
+ {
1355
+ CTokenizer oTokenizer( msg, "&" );
1356
+ int nDeleted = 0, nUpdated = 0, nCreated = 0;
1357
+ while (oTokenizer.hasMoreTokens())
1358
+ {
1359
+ String tok = oTokenizer.nextToken();
1360
+ if (tok.length() == 0)
1361
+ continue;
1362
+
1363
+ CTokenizer oValueTok( tok, "=" );
1364
+ String name = net::URI::urlDecode(oValueTok.nextToken());
1365
+ String value = net::URI::urlDecode(oValueTok.nextToken());
1366
+
1367
+ if ( String_startsWith(name, "deleted[][object]"))
1368
+ {
1369
+ pNotify->deleted_objects[nDeleted] = strdup(value.c_str());
1370
+ nDeleted++;
1371
+ }else if (String_startsWith(name, "deleted[][source_id]"))
1372
+ convertFromStringA( value.c_str(), pNotify->deleted_source_ids[nDeleted] );
1373
+ else if ( String_startsWith(name, "updated[][object]"))
1374
+ {
1375
+ pNotify->updated_objects[nUpdated] = strdup(value.c_str());
1376
+ nUpdated++;
1377
+ }else if (String_startsWith(name, "updated[][source_id]"))
1378
+ convertFromStringA( value.c_str(), pNotify->updated_source_ids[nUpdated] );
1379
+ else if ( String_startsWith(name, "created[][object]"))
1380
+ {
1381
+ pNotify->created_objects[nCreated] = strdup(value.c_str());
1382
+ nCreated++;
1383
+ }else if (String_startsWith(name, "created[][source_id]"))
1384
+ convertFromStringA( value.c_str(), pNotify->created_source_ids[nCreated] );
1385
+ }
1386
+ }*/
1387
+ }
1388
+
1389
+ void rho_connectclient_free_sync_objectnotify(RHO_CONNECT_OBJECT_NOTIFY* pNotify)
1390
+ {
1391
+ if (!pNotify)
1392
+ return;
1393
+
1394
+ if ( pNotify->deleted_source_ids != null )
1395
+ free(pNotify->deleted_source_ids);
1396
+
1397
+ if ( pNotify->updated_source_ids != null )
1398
+ free(pNotify->updated_source_ids);
1399
+
1400
+ if ( pNotify->created_source_ids != null )
1401
+ free(pNotify->created_source_ids);
1402
+
1403
+ if ( pNotify->deleted_objects != null )
1404
+ {
1405
+ for(int i = 0; i < pNotify->deleted_count; i++)
1406
+ free(pNotify->deleted_objects[i]);
1407
+
1408
+ free(pNotify->deleted_objects);
1409
+ }
1410
+
1411
+ if ( pNotify->updated_objects != null )
1412
+ {
1413
+ for(int i = 0; i < pNotify->updated_count; i++)
1414
+ free(pNotify->updated_objects[i]);
1415
+
1416
+ free(pNotify->updated_objects);
1417
+ }
1418
+
1419
+ if ( pNotify->created_objects != null )
1420
+ {
1421
+ for(int i = 0; i < pNotify->created_count; i++)
1422
+ free(pNotify->created_objects[i]);
1423
+
1424
+ free(pNotify->created_objects);
1425
+ }
1426
+
1427
+ memset( pNotify, 0, sizeof(RHO_CONNECT_OBJECT_NOTIFY) );
1428
+ }
1429
+
1430
+ unsigned long rho_connectclient_strarray_create()
1431
+ {
1432
+ return (unsigned long)(new rho::Vector<rho::String>());
1433
+ }
1434
+
1435
+ int rho_connectclient_strarray_add(unsigned long ar, const char* szStr)
1436
+ {
1437
+ rho::Vector<rho::String>& arThis = *((rho::Vector<rho::String>*)ar);
1438
+ arThis.addElement(szStr);
1439
+
1440
+ return arThis.size()-1;
1441
+ }
1442
+
1443
+ void rho_connectclient_strarray_delete(unsigned long ar)
1444
+ {
1445
+ if (ar)
1446
+ delete ((rho::Vector<rho::String>*)ar);
1447
+ }
1448
+
1449
+ int rho_connectclient_strarray_find(unsigned long ar, const char* szStr)
1450
+ {
1451
+ rho::Vector<rho::String>& arThis = *((rho::Vector<rho::String>*)ar);
1452
+ for (int i = 0; i < (int)arThis.size(); i++)
1453
+ {
1454
+ if (arThis[i].compare(szStr) == 0)
1455
+ return i;
1456
+ }
1457
+
1458
+ return -1;
1459
+ }
1460
+
1461
+ unsigned long rho_connectclient_strhasharray_create()
1462
+ {
1463
+ return (unsigned long)(new VectorPtr<Hashtable<String, String>* >());
1464
+ }
1465
+
1466
+ void rho_connectclient_strhasharray_add(unsigned long ar, unsigned long hash)
1467
+ {
1468
+ VectorPtr<Hashtable<String, String>* >& arThis = *((VectorPtr<Hashtable<String, String>* >*)ar);
1469
+ arThis.addElement( (Hashtable<String, String>*)hash );
1470
+ }
1471
+
1472
+ void rho_connectclient_strhasharray_delete(unsigned long ar)
1473
+ {
1474
+ if (ar)
1475
+ delete ((VectorPtr<Hashtable<String, String>* >*)ar);
1476
+ }
1477
+
1478
+ int rho_connectclient_strhasharray_size(unsigned long ar)
1479
+ {
1480
+ VectorPtr<Hashtable<String, String>* >& arThis = *((VectorPtr<Hashtable<String, String>* >*)ar);
1481
+ return arThis.size();
1482
+ }
1483
+
1484
+ unsigned long rho_connectclient_strhasharray_get(unsigned long ar, int nIndex)
1485
+ {
1486
+ VectorPtr<Hashtable<String, String>* >& arThis = *((VectorPtr<Hashtable<String, String>* >*)ar);
1487
+ return (unsigned long) arThis.elementAt(nIndex);
1488
+ }
1489
+
1490
+ unsigned long rho_connectclient_hash_create()
1491
+ {
1492
+ return (unsigned long)(new rho::Hashtable<rho::String, rho::String>());
1493
+ }
1494
+
1495
+ void rho_connectclient_hash_put(unsigned long hash, const char* szKey, const char* szValue)
1496
+ {
1497
+ Hashtable<String, String>& hashThis = *((Hashtable<String, String>*)hash);
1498
+ hashThis.put(szKey, szValue);
1499
+ }
1500
+
1501
+ void rho_connectclient_hash_delete(unsigned long hash)
1502
+ {
1503
+ if (hash)
1504
+ delete ((rho::Hashtable<rho::String, rho::String>*)hash);
1505
+ }
1506
+
1507
+ const char* rho_connectclient_hash_get(unsigned long hash, const char* szKey)
1508
+ {
1509
+ if (!hash)
1510
+ return null;
1511
+
1512
+ Hashtable<String, String>& hashThis = *((Hashtable<String, String>*)hash);
1513
+
1514
+ if ( hashThis.containsKey(szKey) )
1515
+ return hashThis[szKey].c_str();
1516
+
1517
+ return null;
1518
+ }
1519
+
1520
+ int rho_connectclient_hash_equal(unsigned long hash1, unsigned long hash2)
1521
+ {
1522
+ Hashtable<String, String>& hashThis1 = *((Hashtable<String, String>*)hash1);
1523
+ Hashtable<String, String>& hashThis2 = *((Hashtable<String, String>*)hash2);
1524
+
1525
+ return hashThis1 == hashThis2 ? 1 : 0;
1526
+ }
1527
+
1528
+ int rho_connectclient_hash_size(unsigned long hash)
1529
+ {
1530
+ Hashtable<String, String>& hashThis = *((Hashtable<String, String>*)hash);
1531
+
1532
+ return hashThis.size();
1533
+ }
1534
+
1535
+ void rho_connectclient_hash_enumerate(unsigned long hash, int (*enum_func)(const char* szKey, const char* szValue, void* pThis), void* pThis )
1536
+ {
1537
+ Hashtable<String, String>& hashThis = *((Hashtable<String, String>*)hash);
1538
+
1539
+ for ( Hashtable<String,String>::iterator it = hashThis.begin(); it != hashThis.end(); ++it )
1540
+ {
1541
+ if ( !(*enum_func)(it->first.c_str(), it->second.c_str(), pThis) )
1542
+ return;
1543
+ }
1544
+ }
1545
+
1546
+ }
1547
+
1548
+ String rhom_generate_id()
1549
+ {
1550
+ static uint64 g_base_temp_id = 0;
1551
+ if ( g_base_temp_id == 0 )
1552
+ g_base_temp_id = CLocalTime().toULong();
1553
+
1554
+ g_base_temp_id ++;
1555
+ return convertToStringA(g_base_temp_id);
1556
+ }
1557
+
1558
+
1559
+ namespace rho {
1560
+ const _CRhoAppAdapter& RhoAppAdapter = _CRhoAppAdapter();
1561
+
1562
+ /*static*/ String _CRhoAppAdapter::getMessageText(const char* szName)
1563
+ {
1564
+ return String();
1565
+ }
1566
+
1567
+ /*static*/ String _CRhoAppAdapter::getErrorText(int nError)
1568
+ {
1569
+ return String(); //TODO?
1570
+ }
1571
+
1572
+ /*static*/ int _CRhoAppAdapter::getErrorFromResponse(NetResponse& resp)
1573
+ {
1574
+ if ( !resp.isResponseRecieved())
1575
+ return ERR_NETWORK;
1576
+
1577
+ if ( resp.isUnathorized() )
1578
+ return ERR_UNATHORIZED;
1579
+
1580
+ if ( !resp.isOK() )
1581
+ return ERR_REMOTESERVER;
1582
+
1583
+ return ERR_NONE;
1584
+ }
1585
+
1586
+ /*static*/ void _CRhoAppAdapter::loadServerSources(const String& strSources)
1587
+ {
1588
+
1589
+ }
1590
+
1591
+ /*static*/ void _CRhoAppAdapter::loadAllSyncSources()
1592
+ {
1593
+
1594
+ }
1595
+
1596
+ /*static*/ const char* _CRhoAppAdapter::getRhoDBVersion()
1597
+ {
1598
+ return "1.0";
1599
+ }
1600
+
1601
+ /*static*/ void _CRhoAppAdapter::resetDBOnSyncUserChanged()
1602
+ {
1603
+ rho_connectclient_database_full_reset(false);
1604
+ }
1605
+
1606
+ /*static*/ bool _CRhoAppAdapter::callCallbackOnSyncUserChanged()
1607
+ {
1608
+ return false;
1609
+ }
1610
+ }
1611
+
1612
+ extern "C"
1613
+ {
1614
+ extern "C" void alert_show_popup(const char* message)
1615
+ {
1616
+
1617
+ }
1618
+
1619
+ const char* rho_ruby_getMessageText(const char* szName)
1620
+ {
1621
+ return szName;
1622
+ }
1623
+
1624
+ const char* rho_ruby_getErrorText(int nError)
1625
+ {
1626
+ return "";
1627
+ }
1628
+
1629
+ void rho_net_impl_network_indicator(int active)
1630
+ {
1631
+ // [UIApplication sharedApplication].networkActivityIndicatorVisible = active ? YES : NO;
1632
+ }
1633
+
1634
+ void alert_show_status(const char* szTitle, const char* szMessage, const char* szHide)
1635
+ {
1636
+ }
1637
+
1638
+ const char* get_app_build_config_item(const char* key)
1639
+ {
1640
+ return 0;
1641
+ }
1642
+
1643
+ const char* rho_webview_execute_js(const char* js, int index){ return "";}
1644
+ const char* rho_webview_execute_js_sync(const char* js, int index){ return "";}
1645
+
1646
+ int rho_ruby_is_started(){return 0;}
1647
+ int rho_webview_active_tab(){return 0;}
1648
+ }
1649
+
1650
+ namespace rho{
1651
+ namespace sync{
1652
+
1653
+ CClientRegister::CClientRegister(){}
1654
+ CClientRegister::~CClientRegister(){}
1655
+ void CClientRegister::SetSslVerifyPeer(boolean b){}
1656
+ bool CClientRegister::GetSslVerifyPeer(){return true;}
1657
+
1658
+ CClientRegister* CClientRegister::Get(){ if (!m_pInstance){ m_pInstance = new CClientRegister();} return m_pInstance;}
1659
+
1660
+ void CClientRegister::Stop(){}
1661
+ void CClientRegister::run(){}
1662
+
1663
+
1664
+ void CClientRegister::setRhoconnectCredentials(const String& user, const String& pass, const String& session){}
1665
+ void CClientRegister::dropRhoconnectCredentials(const String& session,const String& clientID){}
1666
+
1667
+
1668
+
1669
+
1670
+ CClientRegister* CClientRegister::m_pInstance = 0;
1671
+
1672
+ }
1673
+ }