rhoconnect-client 5.5.0

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