rhodes 2.3.2 → 2.4.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (623) hide show
  1. data/CHANGELOG +18 -0
  2. data/CREDITS +38 -0
  3. data/README.md +2 -2
  4. data/Rakefile +60 -2
  5. data/bin/set-rhodes-sdk.bat +1 -0
  6. data/doc/application.txt +11 -0
  7. data/doc/build.txt +156 -39
  8. data/doc/configuration.txt +1 -10
  9. data/doc/connect-to-web-services.txt +6 -6
  10. data/doc/device-caps.txt +48 -5
  11. data/doc/extensions.txt +8 -1
  12. data/doc/rhom.txt +16 -0
  13. data/doc/synchronization.txt +56 -14
  14. data/doc/ui.txt +23 -2
  15. data/installer/instant-rhodes.nsi +6 -6
  16. data/lib/extensions/barcode/ext/barcode/platform/iphone/Barcode.xcodeproj/project.pbxproj +4 -2
  17. data/lib/extensions/barcode/ext/barcode/platform/wm/Rakefile +1 -1
  18. data/lib/extensions/digest-md5/ext/Rakefile +3 -3
  19. data/lib/extensions/digest-md5/ext/build +0 -1
  20. data/lib/extensions/digest-sha1/ext/Rakefile +1 -1
  21. data/lib/extensions/digest-sha1/ext/build +0 -1
  22. data/lib/extensions/digest/ext/Rakefile +3 -3
  23. data/lib/extensions/digest/ext/build +0 -1
  24. data/lib/extensions/fcntl/ext/Rakefile +1 -1
  25. data/lib/extensions/mspec/mspec/guards/guard.rb +4 -0
  26. data/lib/extensions/mspec/mspec/helpers/environment.rb +4 -0
  27. data/lib/extensions/nfc/ext.yml +2 -0
  28. data/lib/extensions/nfc/ext/build +12 -0
  29. data/lib/extensions/nfc/ext/build.bat +8 -0
  30. data/lib/extensions/nfc/ext/nfc/platform/android/AndroidManifest.xml +25 -0
  31. data/lib/extensions/nfc/ext/nfc/platform/android/Rakefile +94 -0
  32. data/lib/extensions/nfc/ext/nfc/platform/android/ext_build.files +4 -0
  33. data/lib/extensions/nfc/ext/nfc/platform/android/jni/src/nfc.cpp +404 -0
  34. data/lib/extensions/nfc/ext/nfc/platform/android/src/com/nfc/Nfc.java +138 -0
  35. data/lib/extensions/nfc/ext/nfc/platform/android/src/com/nfc/NfcMessage.java +34 -0
  36. data/lib/extensions/nfc/ext/nfc/platform/android/src/com/nfc/NfcMessagePack.java +33 -0
  37. data/lib/extensions/nfc/ext/nfc/platform/android/src/com/nfc/NfcRecord.java +149 -0
  38. data/lib/extensions/nfc/ext/nfc/shared/ruby/nfc.i +22 -0
  39. data/lib/extensions/nfc/ext/nfc/shared/ruby/nfc_wrap.c +2034 -0
  40. data/lib/extensions/nfc/nfc.rb +120 -0
  41. data/lib/extensions/rholang/{lang_ca.rb → rholang/lang_ca.rb} +0 -0
  42. data/lib/extensions/rholang/{lang_cf.rb → rholang/lang_cf.rb} +0 -0
  43. data/lib/extensions/rholang/{lang_chef.rb → rholang/lang_chef.rb} +0 -0
  44. data/lib/extensions/rholang/{lang_cs.rb → rholang/lang_cs.rb} +0 -0
  45. data/lib/extensions/rholang/{lang_da.rb → rholang/lang_da.rb} +0 -0
  46. data/lib/extensions/rholang/{lang_de.rb → rholang/lang_de.rb} +0 -0
  47. data/lib/extensions/rholang/{lang_es.rb → rholang/lang_es.rb} +0 -0
  48. data/lib/extensions/rholang/{lang_es_ar.rb → rholang/lang_es_ar.rb} +0 -0
  49. data/lib/extensions/rholang/{lang_fi.rb → rholang/lang_fi.rb} +0 -0
  50. data/lib/extensions/rholang/{lang_fr.rb → rholang/lang_fr.rb} +0 -0
  51. data/lib/extensions/rholang/{lang_it.rb → rholang/lang_it.rb} +0 -0
  52. data/lib/extensions/rholang/{lang_ko.rb → rholang/lang_ko.rb} +0 -0
  53. data/lib/extensions/rholang/{lang_nl.rb → rholang/lang_nl.rb} +0 -0
  54. data/lib/extensions/rholang/{lang_no.rb → rholang/lang_no.rb} +0 -0
  55. data/lib/extensions/rholang/{lang_pt.rb → rholang/lang_pt.rb} +0 -0
  56. data/lib/extensions/rholang/{lang_pt_br.rb → rholang/lang_pt_br.rb} +0 -0
  57. data/lib/extensions/rholang/{lang_ru.rb → rholang/lang_ru.rb} +0 -0
  58. data/lib/extensions/rholang/{lang_se.rb → rholang/lang_se.rb} +0 -0
  59. data/lib/extensions/rholang/{lang_sr.rb → rholang/lang_sr.rb} +0 -0
  60. data/lib/extensions/rholang/{rhoerror_ru.rb → rholang/rhoerror_ru.rb} +0 -0
  61. data/lib/extensions/rholang/{rhomsg_ru.rb → rholang/rhomsg_ru.rb} +0 -0
  62. data/lib/framework/date/format.rb +2 -0
  63. data/lib/framework/dateOrig.rb +17 -8
  64. data/lib/framework/rational18.rb +532 -0
  65. data/lib/framework/res/back_btn.wp7.png +0 -0
  66. data/lib/framework/res/blue_pushpin.wp7.png +0 -0
  67. data/lib/framework/res/blue_pushpin_small.wp7.png +0 -0
  68. data/lib/framework/res/callout.wp7.png +0 -0
  69. data/lib/framework/res/callout_link.wp7.png +0 -0
  70. data/lib/framework/res/esri.wp7.png +0 -0
  71. data/lib/framework/res/forward_btn.wp7.png +0 -0
  72. data/lib/framework/res/home_btn.wp7.png +0 -0
  73. data/lib/framework/res/options_btn.wp7.png +0 -0
  74. data/lib/framework/res/refresh_btn.wp7.png +0 -0
  75. data/lib/framework/rho/render.rb +8 -1
  76. data/lib/framework/rho/rho.rb +30 -7
  77. data/lib/framework/rho/rhoapplication.rb +9 -4
  78. data/lib/framework/rho/rhofsconnector.rb +5 -1
  79. data/lib/framework/rho/rhotabbar.rb +8 -0
  80. data/lib/framework/rho/rhotoolbar.rb +1 -1
  81. data/lib/framework/rho/rhoviewhelpers.rb +18 -1
  82. data/lib/framework/rhodes.rb +1 -1
  83. data/lib/framework/rhoframework.rb +46 -1
  84. data/lib/framework/rholang/localization_simplified.rb +17 -16
  85. data/lib/framework/rhom/rhom_db_adapter.rb +2 -2
  86. data/lib/framework/rhom/rhom_object_factory.rb +115 -12
  87. data/lib/framework/rhosystem.rb +135 -0
  88. data/lib/framework/version.rb +1 -1
  89. data/lib/rhodes.rb +1 -1
  90. data/lib/test/apps/rhoconfig.txt +23 -23
  91. data/platform/android/Rhodes/AndroidManifest.full.xml +101 -0
  92. data/platform/android/Rhodes/AndroidManifest.xml +10 -15
  93. data/platform/android/Rhodes/default.properties +11 -0
  94. data/platform/android/Rhodes/gen/com/rhomobile/rhodes/R.java +59 -53
  95. data/platform/android/Rhodes/jni/include/rhodes.h +1 -0
  96. data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_RhodesApplication.h +21 -0
  97. data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_alert_PopupActivity.h +21 -0
  98. data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_file_RhoFileApi.h +10 -2
  99. data/platform/android/Rhodes/jni/src/alert.cpp +2 -1
  100. data/platform/android/Rhodes/jni/src/datetimepicker.cpp +2 -0
  101. data/platform/android/Rhodes/jni/src/fileapi.cpp +671 -84
  102. data/platform/android/Rhodes/jni/src/nativebar.cpp +18 -0
  103. data/platform/android/Rhodes/jni/src/rhodes.cpp +92 -1
  104. data/platform/android/Rhodes/res/values/styles.xml +7 -0
  105. data/platform/android/Rhodes/src/com/rhomobile/rhodes/BaseActivity.java +35 -2
  106. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Capabilities.java +12 -13
  107. data/platform/android/Rhodes/src/com/rhomobile/rhodes/LocalFileProvider.java +130 -0
  108. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeBar.java +6 -0
  109. data/platform/android/Rhodes/src/com/rhomobile/rhodes/PushReceiver.java +5 -1
  110. data/platform/android/Rhodes/src/com/rhomobile/rhodes/PushService.java +6 -2
  111. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhoMenu.java +7 -36
  112. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesActivity.java +43 -20
  113. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesApplication.java +2 -0
  114. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesService.java +63 -28
  115. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Utils.java +2 -2
  116. data/platform/android/Rhodes/src/com/rhomobile/rhodes/WebView.java +6 -2
  117. data/platform/android/Rhodes/src/com/rhomobile/rhodes/alert/Alert.java +19 -282
  118. data/platform/android/Rhodes/src/com/rhomobile/rhodes/alert/PopupActivity.java +354 -0
  119. data/platform/android/Rhodes/src/com/rhomobile/rhodes/datetime/DateTimePickerScreen.java +4 -0
  120. data/platform/android/Rhodes/src/com/rhomobile/rhodes/event/EventStore.java +1 -2
  121. data/platform/android/Rhodes/src/com/rhomobile/rhodes/file/RhoFileApi.java +71 -5
  122. data/platform/android/Rhodes/src/com/rhomobile/rhodes/geolocation/GeoLocationImpl.java +107 -37
  123. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +10 -7
  124. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +156 -56
  125. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/MapView.java +0 -1
  126. data/platform/android/Rhodes/src/com/rhomobile/rhodes/phonebook/ContactAccessorNew.java +40 -32
  127. data/platform/android/Rhodes/src/com/rhomobile/rhodes/signature/SignatureView.java +1 -0
  128. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/ExternalHttpHandler.java +14 -6
  129. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/LocalFileHandler.java +46 -0
  130. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java +4 -24
  131. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/UriHandler.java +3 -1
  132. data/platform/android/build/RhodesSRC_build.files +28 -25
  133. data/platform/android/build/android.rake +230 -54
  134. data/platform/android/build/androidcommon.rb +1 -1
  135. data/platform/android/build/librhocommon_build.files +1 -0
  136. data/platform/bb/Hsqldb/BlackBerry_App_Descriptor.xml +20 -0
  137. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBResult.java +1 -5
  138. data/platform/bb/Hsqldb/src/com/rho/db/HsqlDBStorage.java +6 -1
  139. data/platform/bb/Hsqldb/src/org/hsqldb/rowio/RowOutputBase.java +1 -1
  140. data/platform/bb/Hsqldb/src/org/hsqldb/rowio/RowOutputBinary.java +1 -1
  141. data/platform/bb/RubyVM/BlackBerry_App_Descriptor.xml +20 -0
  142. data/platform/bb/RubyVM/src/com/rho/IRhoRubyHelper.java +2 -0
  143. data/platform/bb/RubyVM/src/com/rho/RhoLogOutputSink.java +0 -1
  144. data/platform/bb/RubyVM/src/com/rho/RhoLogger.java +12 -10
  145. data/platform/bb/RubyVM/src/com/rho/RhoThread.java +16 -0
  146. data/platform/bb/RubyVM/src/com/rho/RhoTimer.java +89 -0
  147. data/platform/bb/RubyVM/src/com/rho/RhodesApp.java +20 -13
  148. data/platform/bb/RubyVM/src/com/rho/SplashScreen.java +1 -2
  149. data/platform/bb/RubyVM/src/com/rho/ThreadQueue.java +2 -2
  150. data/platform/bb/RubyVM/src/com/rho/TimeInterval.java +5 -0
  151. data/platform/bb/RubyVM/src/com/rho/db/DBAdapter.java +54 -48
  152. data/platform/bb/RubyVM/src/com/rho/db/IDBResult.java +0 -1
  153. data/platform/bb/RubyVM/src/com/rho/db/IDBStorage.java +1 -0
  154. data/platform/bb/RubyVM/src/com/rho/net/AsyncHttp.java +1 -1
  155. data/platform/bb/RubyVM/src/com/rho/sync/ClientRegister.java +1 -1
  156. data/platform/bb/RubyVM/src/com/rho/sync/JSONStructIterator.java +1 -1
  157. data/platform/bb/RubyVM/src/com/rho/sync/SyncEngine.java +16 -8
  158. data/platform/bb/RubyVM/src/com/rho/sync/SyncNotify.java +2 -2
  159. data/platform/bb/RubyVM/src/com/rho/sync/SyncSource.java +52 -29
  160. data/platform/bb/RubyVM/src/com/rho/sync/SyncThread.java +1 -3
  161. data/platform/bb/build/RubyVM_build.files +1 -0
  162. data/platform/bb/build/bb.rake +29 -9
  163. data/platform/bb/rhodes/BlackBerry_App_Descriptor.xml +23 -0
  164. data/platform/bb/rhodes/platform/5.0/com/rho/RhodesApplicationPlatform.java +1 -1
  165. data/platform/bb/rhodes/platform/5.0/com/rho/db/SqliteCopyResult.java +0 -4
  166. data/platform/bb/rhodes/platform/5.0/com/rho/db/SqliteResult.java +13 -20
  167. data/platform/bb/rhodes/platform/5.0/com/rho/db/SqliteStorage.java +183 -157
  168. data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +22 -0
  169. data/platform/bb/rhodes/src/com/rho/RhodesApplicationPlatform.java +1 -1
  170. data/platform/bb/rhodes/src/com/rho/db/SqliteCopyResult.java +0 -4
  171. data/platform/bb/rhodes/src/com/rho/db/SqliteResult.java +13 -20
  172. data/platform/bb/rhodes/src/com/rho/db/SqliteStorage.java +183 -157
  173. data/platform/bb/rhodes/src/com/rho/rubyext/System.java +46 -1
  174. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +8 -1
  175. data/platform/bb/rhodes/src/rhomobile/camera/CameraFilesListener.java +13 -3
  176. data/platform/iphone/Classes/AppManager/AppManager.h +5 -1
  177. data/platform/iphone/Classes/AppManager/AppManager.m +170 -7
  178. data/platform/iphone/Classes/DateTimePicker.m +14 -1
  179. data/platform/iphone/Classes/DateTimePickerDelegate.h +2 -0
  180. data/platform/iphone/Classes/DateTimePickerDelegate.m +36 -2
  181. data/platform/iphone/Classes/NativeBar.h +1 -0
  182. data/platform/iphone/Classes/NativeBar.m +15 -3
  183. data/platform/iphone/Classes/Phonebook/phonebook.m +8 -9
  184. data/platform/iphone/Classes/Rhodes.m +50 -6
  185. data/platform/iphone/Classes/SimpleMainView.m +7 -6
  186. data/platform/iphone/Classes/SplitView/RightViewController.h +3 -1
  187. data/platform/iphone/Classes/SplitView/RightViewController.m +14 -1
  188. data/platform/iphone/Classes/TabbedMainView.h +4 -0
  189. data/platform/iphone/Classes/TabbedMainView.m +43 -26
  190. data/platform/iphone/Info.plist +1 -1
  191. data/platform/iphone/RhoLib/RhoLib.xcodeproj/project.pbxproj +4 -0
  192. data/platform/iphone/curl/curl.xcodeproj/project.pbxproj +3 -3
  193. data/platform/iphone/rbuild/iphone.rake +168 -119
  194. data/platform/iphone/rhoextlib/rhoextlib.xcodeproj/project.pbxproj +4 -2
  195. data/platform/iphone/rhorubylib/rhorubylib.xcodeproj/project.pbxproj +3 -3
  196. data/platform/iphone/rhorunner.xcodeproj/project.pbxproj +2 -2
  197. data/platform/iphone/rhosynclib/rhosynclib.xcodeproj/project.pbxproj +3 -3
  198. data/platform/shared/SyncClient/SyncClient.cpp +20 -8
  199. data/platform/shared/SyncClient/SyncClient.h +2 -1
  200. data/platform/shared/common/RhoDefs.h +4 -0
  201. data/platform/shared/common/RhoPort.h +22 -0
  202. data/platform/shared/common/RhoStd.h +5 -0
  203. data/platform/shared/common/RhoTime.cpp +73 -0
  204. data/platform/shared/common/RhoTime.h +26 -53
  205. data/platform/shared/common/RhodesApp.cpp +29 -28
  206. data/platform/shared/common/RhodesApp.h +4 -1
  207. data/platform/shared/common/StringConverter.h +37 -10
  208. data/platform/shared/common/app_build_capabilities.h +2 -0
  209. data/platform/shared/common/rhoparams.cpp +25 -12
  210. data/platform/shared/common/rhoparams.h +10 -8
  211. data/platform/shared/db/DBAdapter.cpp +0 -22
  212. data/platform/shared/json/RJSONTokener.c +15 -23
  213. data/platform/shared/net/AsyncHttp.cpp +9 -8
  214. data/platform/shared/net/HttpServer.cpp +61 -19
  215. data/platform/shared/net/HttpServer.h +2 -0
  216. data/platform/shared/ruby/ext/datetimepicker/datetimepicker.i +3 -0
  217. data/platform/shared/ruby/ext/datetimepicker/datetimepicker_wrap.c +151 -402
  218. data/platform/shared/ruby/ext/nativebar/nativebar.i +3 -0
  219. data/platform/shared/ruby/ext/nativebar/nativebar_wrap.c +154 -403
  220. data/platform/shared/ruby/ext/rho/rhoruby.c +4 -0
  221. data/platform/shared/ruby/ext/rho/rhoruby.h +2 -0
  222. data/platform/shared/ruby/ext/system/system.i +8 -0
  223. data/platform/shared/ruby/ext/system/system_wrap.c +80 -5
  224. data/platform/shared/ruby/file.c +6 -4
  225. data/platform/shared/ruby/gc.c +1 -1
  226. data/platform/shared/ruby/linux/ruby/config.h +7 -2
  227. data/platform/shared/ruby/missing/acosh.c +3 -3
  228. data/platform/shared/ruby/wince/_time.h +1 -1
  229. data/platform/shared/ruby/wince/stdlib.c +1 -1
  230. data/platform/shared/ruby/wince/string_wce.c +2 -2
  231. data/platform/shared/ruby/wince/sys/timeb.c +1 -0
  232. data/platform/shared/ruby/wince/time_wce.c +8 -0
  233. data/platform/shared/ruby/wince/wince.c +7 -7
  234. data/platform/shared/ruby/wince/wince.h +22 -0
  235. data/platform/shared/rubyext/System.cpp +19 -1
  236. data/platform/shared/sqlite/sqlite3.c +18993 -8129
  237. data/platform/shared/sqlite/sqlite3.h +953 -358
  238. data/platform/shared/sqlite/sqlite3ext.h +42 -0
  239. data/platform/shared/sync/SyncEngine.cpp +10 -0
  240. data/platform/shared/sync/SyncSource.cpp +41 -19
  241. data/platform/shared/sync/SyncSource.h +1 -1
  242. data/platform/shared/tcmalloc/rhomem.h +7 -2
  243. data/platform/shared/tcmalloc/windows/port.h +2 -0
  244. data/platform/shared/unzip/unzip.cpp +1 -0
  245. data/platform/shared/xruby/src/com/xruby/compiler/parser/RubyParser.java +11 -1
  246. data/platform/wm/RhoLib/RhoLib.vcproj +182 -24
  247. data/platform/wm/build/wm.rake +16 -3
  248. data/platform/wm/rhodes.sln +106 -113
  249. data/platform/wm/rhodes/Alert.cpp +6 -7
  250. data/platform/wm/rhodes/AppManager.cpp +8 -17
  251. data/platform/wm/rhodes/DateTimePicker.cpp +3 -0
  252. data/platform/wm/rhodes/DateTimePicker.h +2 -0
  253. data/platform/wm/rhodes/MainWindow.cpp +36 -16
  254. data/platform/wm/rhodes/MainWindow.h +6 -3
  255. data/platform/wm/rhodes/OutlookApp.cpp +3 -3
  256. data/platform/wm/rhodes/Rhodes.cpp +46 -27
  257. data/platform/wm/rhodes/Rhodes.rc +16 -3
  258. data/platform/wm/rhodes/RingtoneManager.cpp +7 -7
  259. data/platform/wm/rhodes/RingtoneManager.h +1 -1
  260. data/platform/wm/rhodes/Utils.cpp +2 -1
  261. data/platform/wm/rhodes/bluetooth/Bluetooth.cpp +1 -13
  262. data/platform/wm/rhodes/bluetooth/Bluetooth.h +1 -2
  263. data/platform/wm/rhodes/camera/Camera.cpp +6 -12
  264. data/platform/wm/rhodes/phonebook/phonebook.cpp +11 -11
  265. data/platform/wm/rhodes/phonebook/phonebook.h +1 -1
  266. data/platform/wm/rhodes/resource.h +3 -1
  267. data/platform/wm/rhodes/rho/net/NetRequestImpl.cpp +7 -5
  268. data/platform/wm/rhodes/rho/rubyext/GeoLocationImpl.cpp +6 -6
  269. data/platform/wm/rhodes/rho/rubyext/GeoLocationImpl.h +1 -1
  270. data/platform/wm/rhodes/rho/rubyext/NativeToolbar.cpp +6 -1
  271. data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +84 -19
  272. data/platform/wm/rhodes/rho/rubyext/calendar.cpp +2 -2
  273. data/platform/wm/rhodes/rhodes.vcproj +316 -73
  274. data/platform/wm/rhodes/signature/Signature.cpp +336 -6
  275. data/platform/wm/rhodes/signature/Signature.h +55 -0
  276. data/platform/wm/rhodes/stdafx.h +7 -4
  277. data/platform/wm/rubylib/rubylib.vcproj +261 -91
  278. data/platform/wm/sqlite3/sqlite3.vcproj +223 -69
  279. data/platform/wm/syncengine/syncengine.vcproj +220 -66
  280. data/platform/wm/tcmalloc/tcmalloc.vcproj +197 -43
  281. data/platform/wp7/IronRuby/Languages/Ruby/Ruby/Builtins/ConsoleStream.cs +107 -0
  282. data/platform/wp7/IronRuby/Languages/Ruby/Ruby/Runtime/Loader.cs +1037 -0
  283. data/platform/wp7/IronRuby/Languages/Ruby/Ruby/Runtime/RubyUtils.cs +1476 -0
  284. data/platform/wp7/RhoAppRunner/Program.cs +55 -0
  285. data/platform/wp7/RhoAppRunner/Properties/AssemblyInfo.cs +36 -0
  286. data/platform/wp7/RhoAppRunner/RhoAppRunner.csproj +69 -0
  287. data/platform/wp7/RhoRubyExtGen/GenerateInitializers.cmd +7 -0
  288. data/platform/wp7/RhoRubyExtGen/Properties/AssemblyInfo.cs +36 -0
  289. data/platform/wp7/RhoRubyExtGen/RhoAsyncHttp.cs +38 -0
  290. data/platform/wp7/RhoRubyExtGen/RhoDatabase.cs +93 -0
  291. data/platform/wp7/RhoRubyExtGen/RhoJSON.cs +37 -0
  292. data/platform/wp7/RhoRubyExtGen/RhoNativeBar.cs +106 -0
  293. data/platform/wp7/RhoRubyExtGen/RhoRubyExtGen.csproj +75 -0
  294. data/platform/wp7/RhoRubyExtGen/RhoSyncEngine.cs +123 -0
  295. data/platform/wp7/RhoRubyExtGen/RhoWebView.cs +42 -0
  296. data/platform/wp7/RhoRubyLib/Initializers.Generated.cs +309 -0
  297. data/platform/wp7/RhoRubyLib/Properties/AssemblyInfo.cs +36 -0
  298. data/platform/wp7/RhoRubyLib/RhoAppAdapter.cs +96 -0
  299. data/platform/wp7/RhoRubyLib/RhoRuby.cs +296 -0
  300. data/platform/wp7/RhoRubyLib/RhoRubyLib.csproj +155 -0
  301. data/platform/wp7/RhoRubyLib/WP_PlatformAdaptationLayer.cs +107 -0
  302. data/platform/wp7/RhoRubyLib/common/IInputStream.cs +21 -0
  303. data/platform/wp7/RhoRubyLib/common/Mutex.cs +30 -0
  304. data/platform/wp7/RhoRubyLib/common/RhoConf.cs +389 -0
  305. data/platform/wp7/RhoRubyLib/common/RhoEmptyProfiler.cs +27 -0
  306. data/platform/wp7/RhoRubyLib/common/RhoFile.cs +332 -0
  307. data/platform/wp7/RhoRubyLib/common/RhoFilePath.cs +89 -0
  308. data/platform/wp7/RhoRubyLib/common/RhoParamArray.cs +33 -0
  309. data/platform/wp7/RhoRubyLib/common/RhoParams.cs +66 -0
  310. data/platform/wp7/RhoRubyLib/common/RhoProfiler.cs +145 -0
  311. data/platform/wp7/RhoRubyLib/common/RhoResourceMap.cs +68 -0
  312. data/platform/wp7/RhoRubyLib/common/RhoStd.cs +205 -0
  313. data/platform/wp7/RhoRubyLib/common/RhoThread.cs +114 -0
  314. data/platform/wp7/RhoRubyLib/common/RhodesApp.cs +504 -0
  315. data/platform/wp7/RhoRubyLib/common/ThreadQueue.cs +199 -0
  316. data/platform/wp7/RhoRubyLib/common/TimeInterval.cs +56 -0
  317. data/platform/wp7/RhoRubyLib/common/Tokenizer.cs +52 -0
  318. data/platform/wp7/RhoRubyLib/db/DBAdapter.cs +1129 -0
  319. data/platform/wp7/RhoRubyLib/db/DBAttrManager.cs +92 -0
  320. data/platform/wp7/RhoRubyLib/db/DBException.cs +35 -0
  321. data/platform/wp7/RhoRubyLib/db/IDBCallback.cs +10 -0
  322. data/platform/wp7/RhoRubyLib/db/IDBResult.cs +33 -0
  323. data/platform/wp7/RhoRubyLib/db/IDBStorage.cs +32 -0
  324. data/platform/wp7/RhoRubyLib/db/SqliteCopyResult.cs +79 -0
  325. data/platform/wp7/RhoRubyLib/db/SqliteResult.cs +267 -0
  326. data/platform/wp7/RhoRubyLib/db/SqliteStorage.cs +319 -0
  327. data/platform/wp7/RhoRubyLib/json/JSONArrayIterator.cs +63 -0
  328. data/platform/wp7/RhoRubyLib/json/JSONEntry.cs +96 -0
  329. data/platform/wp7/RhoRubyLib/json/JSONStructIterator.cs +77 -0
  330. data/platform/wp7/RhoRubyLib/json/JsonParser.cs +483 -0
  331. data/platform/wp7/RhoRubyLib/json/RJSONTokener.cs +406 -0
  332. data/platform/wp7/RhoRubyLib/logging/IRhoLogSink.cs +12 -0
  333. data/platform/wp7/RhoRubyLib/logging/RhoLogConf.cs +161 -0
  334. data/platform/wp7/RhoRubyLib/logging/RhoLogFileSink.cs +174 -0
  335. data/platform/wp7/RhoRubyLib/logging/RhoLogger.cs +320 -0
  336. data/platform/wp7/RhoRubyLib/net/AsyncHttp.cs +362 -0
  337. data/platform/wp7/RhoRubyLib/net/HttpServer.cs +466 -0
  338. data/platform/wp7/RhoRubyLib/net/NetRequest.cs +717 -0
  339. data/platform/wp7/RhoRubyLib/net/NetResponse.cs +64 -0
  340. data/platform/wp7/RhoRubyLib/net/URI.cs +187 -0
  341. data/platform/wp7/RhoRubyLib/rubyext/RhoAsyncHttp.cs +43 -0
  342. data/platform/wp7/RhoRubyLib/rubyext/RhoDatabase.cs +177 -0
  343. data/platform/wp7/RhoRubyLib/rubyext/RhoJSON.cs +39 -0
  344. data/platform/wp7/RhoRubyLib/rubyext/RhoKernelOps.cs +19 -0
  345. data/platform/wp7/RhoRubyLib/rubyext/RhoNativeBar.cs +117 -0
  346. data/platform/wp7/RhoRubyLib/rubyext/RhoSyncEngine.cs +199 -0
  347. data/platform/wp7/RhoRubyLib/rubyext/RhoWebView.cs +49 -0
  348. data/platform/wp7/RhoRubyLib/sync/ClientRegister.cs +142 -0
  349. data/platform/wp7/RhoRubyLib/sync/ISyncProtocol.cs +23 -0
  350. data/platform/wp7/RhoRubyLib/sync/ISyncStatusListener.cs +10 -0
  351. data/platform/wp7/RhoRubyLib/sync/SyncEngine.cs +1051 -0
  352. data/platform/wp7/RhoRubyLib/sync/SyncNotify.cs +651 -0
  353. data/platform/wp7/RhoRubyLib/sync/SyncProtocol_3.cs +79 -0
  354. data/platform/wp7/RhoRubyLib/sync/SyncSource.cs +1105 -0
  355. data/platform/wp7/RhoRubyLib/sync/SyncThread.cs +301 -0
  356. data/platform/wp7/WPApplication.sln +50 -0
  357. data/platform/wp7/WPApplication/App.xaml +19 -0
  358. data/platform/wp7/WPApplication/App.xaml.cs +211 -0
  359. data/platform/wp7/WPApplication/ApplicationIcon.png +0 -0
  360. data/platform/wp7/WPApplication/Background.png +0 -0
  361. data/platform/wp7/WPApplication/MainPage.xaml +44 -0
  362. data/platform/wp7/WPApplication/MainPage.xaml.cs +132 -0
  363. data/platform/wp7/WPApplication/Properties/AppManifest.xml +6 -0
  364. data/platform/wp7/WPApplication/Properties/AssemblyInfo.cs +35 -0
  365. data/platform/wp7/WPApplication/Properties/WMAppManifest.xml +32 -0
  366. data/platform/wp7/WPApplication/SplashScreenImage.jpg +0 -0
  367. data/platform/wp7/WPApplication/WPApplication.csproj +201 -0
  368. data/platform/wp7/WPApplication/WP_PlatformAdaptationLayer.cs +88 -0
  369. data/platform/wp7/WPApplication/app_manifest.txt +1 -0
  370. data/platform/wp7/WPApplication/readme.htm +40 -0
  371. data/platform/wp7/WPApplication/readme2.htm +37 -0
  372. data/platform/wp7/WPApplication/rho/apps/app/Model1/edit.bb.erb +29 -0
  373. data/platform/wp7/WPApplication/rho/apps/app/Model1/edit.erb +32 -0
  374. data/platform/wp7/WPApplication/rho/apps/app/Model1/index.bb.erb +21 -0
  375. data/platform/wp7/WPApplication/rho/apps/app/Model1/index.erb +26 -0
  376. data/platform/wp7/WPApplication/rho/apps/app/Model1/model1.rb +10 -0
  377. data/platform/wp7/WPApplication/rho/apps/app/Model1/model1_controller.rb +58 -0
  378. data/platform/wp7/WPApplication/rho/apps/app/Model1/new.bb.erb +29 -0
  379. data/platform/wp7/WPApplication/rho/apps/app/Model1/new.erb +31 -0
  380. data/platform/wp7/WPApplication/rho/apps/app/Model1/show.bb.erb +26 -0
  381. data/platform/wp7/WPApplication/rho/apps/app/Model1/show.erb +28 -0
  382. data/platform/wp7/WPApplication/rho/apps/app/Settings/controller.rb +75 -0
  383. data/platform/wp7/WPApplication/rho/apps/app/Settings/home.bb.erb +17 -0
  384. data/platform/wp7/WPApplication/rho/apps/app/Settings/home.erb +20 -0
  385. data/platform/wp7/WPApplication/rho/apps/app/Settings/index.bb.erb +32 -0
  386. data/platform/wp7/WPApplication/rho/apps/app/Settings/index.erb +30 -0
  387. data/platform/wp7/WPApplication/rho/apps/app/Settings/login.bb.erb +35 -0
  388. data/platform/wp7/WPApplication/rho/apps/app/Settings/login.erb +27 -0
  389. data/platform/wp7/WPApplication/rho/apps/app/Settings/reset.bb.erb +15 -0
  390. data/platform/wp7/WPApplication/rho/apps/app/Settings/reset.erb +17 -0
  391. data/platform/wp7/WPApplication/rho/apps/app/Settings/wait.bb.erb +3 -0
  392. data/platform/wp7/WPApplication/rho/apps/app/Settings/wait.erb +5 -0
  393. data/platform/wp7/WPApplication/rho/apps/app/application.rb +16 -0
  394. data/platform/wp7/WPApplication/rho/apps/app/helpers/application_helper.rb +126 -0
  395. data/platform/wp7/WPApplication/rho/apps/app/helpers/browser_helper.rb +18 -0
  396. data/platform/wp7/WPApplication/rho/apps/app/index.bb.erb +26 -0
  397. data/platform/wp7/WPApplication/rho/apps/app/index.erb +26 -0
  398. data/platform/wp7/WPApplication/rho/apps/app/layout.erb +45 -0
  399. data/platform/wp7/WPApplication/rho/apps/app/loading.html +11 -0
  400. data/platform/wp7/WPApplication/rho/apps/app_manifest.txt +1 -0
  401. data/platform/wp7/WPApplication/rho/apps/public/css/android.css +330 -0
  402. data/platform/wp7/WPApplication/rho/apps/public/css/blackberry.css +115 -0
  403. data/platform/wp7/WPApplication/rho/apps/public/css/iphone.css +410 -0
  404. data/platform/wp7/WPApplication/rho/apps/public/css/windows_mobile.css +222 -0
  405. data/platform/wp7/WPApplication/rho/apps/public/images/IUI_LICENSE.txt +21 -0
  406. data/platform/wp7/WPApplication/rho/apps/public/images/android/btn_check_off.png +0 -0
  407. data/platform/wp7/WPApplication/rho/apps/public/images/android/btn_check_on.png +0 -0
  408. data/platform/wp7/WPApplication/rho/apps/public/images/android/btn_radio_off.png +0 -0
  409. data/platform/wp7/WPApplication/rho/apps/public/images/android/btn_radio_on.png +0 -0
  410. data/platform/wp7/WPApplication/rho/apps/public/images/android/disclosure.png +0 -0
  411. data/platform/wp7/WPApplication/rho/apps/public/images/android/ic_menu_more.png +0 -0
  412. data/platform/wp7/WPApplication/rho/apps/public/images/backButton.png +0 -0
  413. data/platform/wp7/WPApplication/rho/apps/public/images/blueButton.png +0 -0
  414. data/platform/wp7/WPApplication/rho/apps/public/images/cancel.png +0 -0
  415. data/platform/wp7/WPApplication/rho/apps/public/images/grayButton.png +0 -0
  416. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/disclosure.png +0 -0
  417. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/disclosure_detail.png +0 -0
  418. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/backButton.png +0 -0
  419. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/blueButton.png +0 -0
  420. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/cancel.png +0 -0
  421. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/chevron.png +0 -0
  422. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/grayButton.png +0 -0
  423. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/listArrowSel.png +0 -0
  424. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/listGroup.png +0 -0
  425. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/loading.gif +0 -0
  426. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/on_off.png +0 -0
  427. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/pinstripes.png +0 -0
  428. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/selection.png +0 -0
  429. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/thumb.png +0 -0
  430. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/toggle.png +0 -0
  431. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/toggleOn.png +0 -0
  432. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/toolButton.png +0 -0
  433. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/toolbar.png +0 -0
  434. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/jqtouch/whiteButton.png +0 -0
  435. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/radiobutton.png +0 -0
  436. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/select.png +0 -0
  437. data/platform/wp7/WPApplication/rho/apps/public/images/iphone/switch.png +0 -0
  438. data/platform/wp7/WPApplication/rho/apps/public/images/iui-logo-touch-icon.png +0 -0
  439. data/platform/wp7/WPApplication/rho/apps/public/images/listArrow.png +0 -0
  440. data/platform/wp7/WPApplication/rho/apps/public/images/listArrowDown.png +0 -0
  441. data/platform/wp7/WPApplication/rho/apps/public/images/listArrowSel.png +0 -0
  442. data/platform/wp7/WPApplication/rho/apps/public/images/listGroup.png +0 -0
  443. data/platform/wp7/WPApplication/rho/apps/public/images/loading.gif +0 -0
  444. data/platform/wp7/WPApplication/rho/apps/public/images/pinstripes.png +0 -0
  445. data/platform/wp7/WPApplication/rho/apps/public/images/right_button.png +0 -0
  446. data/platform/wp7/WPApplication/rho/apps/public/images/selection.png +0 -0
  447. data/platform/wp7/WPApplication/rho/apps/public/images/thumb.png +0 -0
  448. data/platform/wp7/WPApplication/rho/apps/public/images/toggle.png +0 -0
  449. data/platform/wp7/WPApplication/rho/apps/public/images/toggleOn.png +0 -0
  450. data/platform/wp7/WPApplication/rho/apps/public/images/toolButton.png +0 -0
  451. data/platform/wp7/WPApplication/rho/apps/public/images/toolButton_new.png +0 -0
  452. data/platform/wp7/WPApplication/rho/apps/public/images/toolbar.png +0 -0
  453. data/platform/wp7/WPApplication/rho/apps/public/images/whiteButton.png +0 -0
  454. data/platform/wp7/WPApplication/rho/apps/public/jqtouch/jqtouch-iphone.css +9 -0
  455. data/platform/wp7/WPApplication/rho/apps/public/jqtouch/jqtouch.css +374 -0
  456. data/platform/wp7/WPApplication/rho/apps/public/jqtouch/jqtouch.js +742 -0
  457. data/platform/wp7/WPApplication/rho/apps/public/jqtouch/jqtouch.transitions.js +60 -0
  458. data/platform/wp7/WPApplication/rho/apps/public/jqtouch/jquery.1.3.2.min.js +19 -0
  459. data/platform/wp7/WPApplication/rho/apps/public/js/application.js +1 -0
  460. data/platform/wp7/WPApplication/rho/apps/public/js/rho.js +4 -0
  461. data/platform/wp7/WPApplication/rho/apps/public/js/rhogeolocation-wm.js +59 -0
  462. data/platform/wp7/WPApplication/rho/apps/public/js/rhogeolocation.js +11 -0
  463. data/platform/wp7/WPApplication/rho/apps/rhoconfig.txt +32 -0
  464. data/platform/wp7/WPApplication/rhoconfig.txt +32 -0
  465. data/platform/wp7/WPApplication/windows_mobile.css +222 -0
  466. data/platform/wp7/build/wp.rake +261 -0
  467. data/platform/wp7/rhodes.sln +79 -0
  468. data/platform/wp7/rhodes/App.xaml +19 -0
  469. data/platform/wp7/rhodes/App.xaml.cs +144 -0
  470. data/platform/wp7/rhodes/Background.png +0 -0
  471. data/platform/wp7/rhodes/MainPage.xaml +44 -0
  472. data/platform/wp7/rhodes/MainPage.xaml.cs +98 -0
  473. data/platform/wp7/rhodes/Properties/AppManifest.xml +6 -0
  474. data/platform/wp7/rhodes/Properties/AssemblyInfo.cs +35 -0
  475. data/platform/wp7/rhodes/Properties/WMAppManifest.xml +31 -0
  476. data/platform/wp7/rhodes/Rhodes.csproj +127 -0
  477. data/platform/wp7/rhodes/SplashScreenImage.jpg +0 -0
  478. data/platform/wp7/rhodes/icon.png +0 -0
  479. data/platform/wp7/sqlite3/Properties/AssemblyInfo.cs +35 -0
  480. data/platform/wp7/sqlite3/SQLiteClient.cs +550 -0
  481. data/platform/wp7/sqlite3/SqliteWrapper/BtreeInt_h.cs +774 -0
  482. data/platform/wp7/sqlite3/SqliteWrapper/Btree_h.cs +280 -0
  483. data/platform/wp7/sqlite3/SqliteWrapper/ClassDiagram1.cd +1306 -0
  484. data/platform/wp7/sqlite3/SqliteWrapper/Delagates.cs +365 -0
  485. data/platform/wp7/sqlite3/SqliteWrapper/Hash_h.cs +133 -0
  486. data/platform/wp7/sqlite3/SqliteWrapper/VdbeInt_h.cs +620 -0
  487. data/platform/wp7/sqlite3/SqliteWrapper/Vdbe_h.cs +302 -0
  488. data/platform/wp7/sqlite3/SqliteWrapper/_Custom.cs +449 -0
  489. data/platform/wp7/sqlite3/SqliteWrapper/alter_c.cs +872 -0
  490. data/platform/wp7/sqlite3/SqliteWrapper/analyze_c.cs +757 -0
  491. data/platform/wp7/sqlite3/SqliteWrapper/attach_c.cs +628 -0
  492. data/platform/wp7/sqlite3/SqliteWrapper/auth_c.cs +268 -0
  493. data/platform/wp7/sqlite3/SqliteWrapper/backup_c.cs +737 -0
  494. data/platform/wp7/sqlite3/SqliteWrapper/bitvec_c.cs +509 -0
  495. data/platform/wp7/sqlite3/SqliteWrapper/btmutex_c.cs +379 -0
  496. data/platform/wp7/sqlite3/SqliteWrapper/btree_c.cs +9138 -0
  497. data/platform/wp7/sqlite3/SqliteWrapper/build_c.cs +4189 -0
  498. data/platform/wp7/sqlite3/SqliteWrapper/callback_c.cs +548 -0
  499. data/platform/wp7/sqlite3/SqliteWrapper/complete_c.cs +342 -0
  500. data/platform/wp7/sqlite3/SqliteWrapper/ctime_cs.cs +408 -0
  501. data/platform/wp7/sqlite3/SqliteWrapper/date_c.cs +1317 -0
  502. data/platform/wp7/sqlite3/SqliteWrapper/delete_c.cs +726 -0
  503. data/platform/wp7/sqlite3/SqliteWrapper/expr_c.cs +4406 -0
  504. data/platform/wp7/sqlite3/SqliteWrapper/fault_c.cs +115 -0
  505. data/platform/wp7/sqlite3/SqliteWrapper/fkey_c.cs +1330 -0
  506. data/platform/wp7/sqlite3/SqliteWrapper/func_c.cs +2025 -0
  507. data/platform/wp7/sqlite3/SqliteWrapper/global_c.cs +228 -0
  508. data/platform/wp7/sqlite3/SqliteWrapper/hash_c.cs +351 -0
  509. data/platform/wp7/sqlite3/SqliteWrapper/hwtime_c.cs +101 -0
  510. data/platform/wp7/sqlite3/SqliteWrapper/insert_c.cs +2122 -0
  511. data/platform/wp7/sqlite3/SqliteWrapper/journal_c.cs +247 -0
  512. data/platform/wp7/sqlite3/SqliteWrapper/keywordhash_h.cs +302 -0
  513. data/platform/wp7/sqlite3/SqliteWrapper/legacy_c.cs +223 -0
  514. data/platform/wp7/sqlite3/SqliteWrapper/loadext_c.cs +683 -0
  515. data/platform/wp7/sqlite3/SqliteWrapper/main_c.cs +2716 -0
  516. data/platform/wp7/sqlite3/SqliteWrapper/malloc_c.cs +977 -0
  517. data/platform/wp7/sqlite3/SqliteWrapper/mem_Pool.cs +394 -0
  518. data/platform/wp7/sqlite3/SqliteWrapper/memjournal_c.cs +315 -0
  519. data/platform/wp7/sqlite3/SqliteWrapper/mutex_c.cs +182 -0
  520. data/platform/wp7/sqlite3/SqliteWrapper/mutex_h.cs +91 -0
  521. data/platform/wp7/sqlite3/SqliteWrapper/mutex_noop_c.cs +202 -0
  522. data/platform/wp7/sqlite3/SqliteWrapper/mutex_w32.cs +344 -0
  523. data/platform/wp7/sqlite3/SqliteWrapper/notify_c.cs +347 -0
  524. data/platform/wp7/sqlite3/SqliteWrapper/opcodes_c.cs +171 -0
  525. data/platform/wp7/sqlite3/SqliteWrapper/opcodes_h.cs +346 -0
  526. data/platform/wp7/sqlite3/SqliteWrapper/os_c.cs +367 -0
  527. data/platform/wp7/sqlite3/SqliteWrapper/os_common_h.cs +174 -0
  528. data/platform/wp7/sqlite3/SqliteWrapper/os_h.cs +295 -0
  529. data/platform/wp7/sqlite3/SqliteWrapper/os_win_c.cs +1255 -0
  530. data/platform/wp7/sqlite3/SqliteWrapper/pager_c.cs +6078 -0
  531. data/platform/wp7/sqlite3/SqliteWrapper/pager_h.cs +188 -0
  532. data/platform/wp7/sqlite3/SqliteWrapper/parse_c.cs +4045 -0
  533. data/platform/wp7/sqlite3/SqliteWrapper/parse_h.cs +331 -0
  534. data/platform/wp7/sqlite3/SqliteWrapper/pcache1_c.cs +969 -0
  535. data/platform/wp7/sqlite3/SqliteWrapper/pcache_c.cs +712 -0
  536. data/platform/wp7/sqlite3/SqliteWrapper/pcache_h.cs +213 -0
  537. data/platform/wp7/sqlite3/SqliteWrapper/pragma_c.cs +1767 -0
  538. data/platform/wp7/sqlite3/SqliteWrapper/prepare_c.cs +1015 -0
  539. data/platform/wp7/sqlite3/SqliteWrapper/printf_c.cs +1300 -0
  540. data/platform/wp7/sqlite3/SqliteWrapper/random_c.cs +201 -0
  541. data/platform/wp7/sqlite3/SqliteWrapper/resolve_c.cs +1396 -0
  542. data/platform/wp7/sqlite3/SqliteWrapper/rowset_c.cs +519 -0
  543. data/platform/wp7/sqlite3/SqliteWrapper/select_c.cs +4878 -0
  544. data/platform/wp7/sqlite3/SqliteWrapper/sqlite3_h.cs +6253 -0
  545. data/platform/wp7/sqlite3/SqliteWrapper/sqlite3ext_h.cs +397 -0
  546. data/platform/wp7/sqlite3/SqliteWrapper/sqliteInt_h.cs +4075 -0
  547. data/platform/wp7/sqlite3/SqliteWrapper/sqliteLimit_h.cs +214 -0
  548. data/platform/wp7/sqlite3/SqliteWrapper/sqliteicu_h.cs +39 -0
  549. data/platform/wp7/sqlite3/SqliteWrapper/status_c.cs +155 -0
  550. data/platform/wp7/sqlite3/SqliteWrapper/table_c.cs +222 -0
  551. data/platform/wp7/sqlite3/SqliteWrapper/tokenize_c.cs +673 -0
  552. data/platform/wp7/sqlite3/SqliteWrapper/trigger_c.cs +1219 -0
  553. data/platform/wp7/sqlite3/SqliteWrapper/update_c.cs +766 -0
  554. data/platform/wp7/sqlite3/SqliteWrapper/utf_c.cs +612 -0
  555. data/platform/wp7/sqlite3/SqliteWrapper/util_c.cs +1476 -0
  556. data/platform/wp7/sqlite3/SqliteWrapper/vacuum_c.cs +382 -0
  557. data/platform/wp7/sqlite3/SqliteWrapper/vdbe_c.cs +6566 -0
  558. data/platform/wp7/sqlite3/SqliteWrapper/vdbeapi_c.cs +1557 -0
  559. data/platform/wp7/sqlite3/SqliteWrapper/vdbeaux_c.cs +4019 -0
  560. data/platform/wp7/sqlite3/SqliteWrapper/vdbeblob_c.cs +396 -0
  561. data/platform/wp7/sqlite3/SqliteWrapper/vdbemem_c.cs +1480 -0
  562. data/platform/wp7/sqlite3/SqliteWrapper/vdbetrace_c.cs +181 -0
  563. data/platform/wp7/sqlite3/SqliteWrapper/vtab_c.cs +957 -0
  564. data/platform/wp7/sqlite3/SqliteWrapper/walker_c.cs +174 -0
  565. data/platform/wp7/sqlite3/SqliteWrapper/where_c.cs +4651 -0
  566. data/platform/wp7/sqlite3/sqlite3.csproj +155 -0
  567. data/rakefile.rb +60 -2
  568. data/res/build-tools/7za.exe +0 -0
  569. data/res/build-tools/RhoAppRunner.exe +0 -0
  570. data/res/build-tools/xruby-0.3.3.jar +0 -0
  571. data/res/generators/rhogen.rb +9 -1
  572. data/res/generators/templates/application/app/Settings/reset.erb +1 -1
  573. data/res/generators/templates/application/app/layout.erb +17 -10
  574. data/res/generators/templates/application/build.yml +5 -3
  575. data/res/generators/templates/application/public/jqtouch/changes.txt +20 -0
  576. data/res/generators/templates/application/public/jqtouch/jqtouch.js +12 -4
  577. data/res/generators/templates/application/public/jqtouch/jquery.1.3.2.min.js +1 -1
  578. data/res/generators/templates/application/public/js/wp7.js +7 -0
  579. data/res/generators/templates/model/controller.rb +5 -6
  580. data/rhobuild.yml.example +1 -0
  581. data/rhodes.gemspec +2 -1
  582. data/spec/framework_spec/app/spec/core/dir/close_spec.rb +1 -1
  583. data/spec/framework_spec/app/spec/core/dir/shared/pwd.rb +13 -11
  584. data/spec/framework_spec/app/spec/core/env/shared/store.rb +12 -10
  585. data/spec/framework_spec/app/spec/core/env/update_spec.rb +1 -0
  586. data/spec/framework_spec/app/spec/core/file/expand_path_spec.rb +3 -2
  587. data/spec/framework_spec/app/spec/core/file/fixtures/file_types.rb +7 -1
  588. data/spec/framework_spec/app/spec/core/file/flock_spec.rb +8 -1
  589. data/spec/framework_spec/app/spec/core/file/ftype_spec.rb +5 -3
  590. data/spec/framework_spec/app/spec/core/file/lchmod_spec.rb +1 -1
  591. data/spec/framework_spec/app/spec/core/file/setgid_spec.rb +1 -1
  592. data/spec/framework_spec/app/spec/core/file/setuid_spec.rb +1 -1
  593. data/spec/framework_spec/app/spec/core/file/stat/ftype_spec.rb +6 -4
  594. data/spec/framework_spec/app/spec/core/file/truncate_spec.rb +5 -1
  595. data/spec/framework_spec/app/spec/core/float/to_s_spec.rb +1 -1
  596. data/spec/framework_spec/app/spec/core/process/gid_spec.rb +5 -3
  597. data/spec/framework_spec/app/spec/core/process/groups_spec.rb +11 -9
  598. data/spec/framework_spec/app/spec/core/process/uid_spec.rb +5 -3
  599. data/spec/framework_spec/app/spec/language/execution_spec.rb +10 -6
  600. data/spec/framework_spec/app/spec/shared/file/directory.rb +6 -1
  601. data/spec/framework_spec/app/spec/shared/file/executable.rb +7 -1
  602. data/spec/framework_spec/app/spec/shared/file/file.rb +6 -1
  603. data/spec/framework_spec/app/spec/shared/file/readable.rb +13 -4
  604. data/spec/framework_spec/app/spec/shared/file/writable.rb +6 -1
  605. data/spec/phone_spec/app/spec/rho_controller_spec.rb +11 -0
  606. data/spec/phone_spec/app/spec/rho_spec.rb +11 -0
  607. data/spec/phone_spec/app/spec/rhom_object_spec.rb +102 -6
  608. data/spec/phone_spec/app/spec/string/end_with_spec.rb +4 -1
  609. data/spec/phone_spec/app/spec/string/slice_spec.rb +5 -1
  610. data/spec/phone_spec/app/spec/string/start_with_spec.rb +4 -0
  611. data/spec/phone_spec/app/spec/syncengine_spec.rb +73 -6
  612. data/spec/phone_spec/app/spec_runner.rb +7 -3
  613. metadata +380 -41
  614. data/Manifest.txt +0 -5819
  615. data/platform/bb/Hsqldb/Hsqldb.cso +0 -5
  616. data/platform/bb/Hsqldb/Hsqldb.jdp +0 -197
  617. data/platform/bb/RhoBundle/RhoBundle.cso +0 -5
  618. data/platform/bb/RhoBundle/RhoBundle.jdp +0 -42
  619. data/platform/bb/RubyVM/RubyVM.cso +0 -5
  620. data/platform/bb/RubyVM/RubyVM.jdp +0 -467
  621. data/platform/bb/rhodes/rhodes.csl +0 -3
  622. data/platform/bb/rhodes/rhodes.cso +0 -5
  623. data/platform/bb/rhodes/rhodes.jdp +0 -104
@@ -0,0 +1,115 @@
1
+ using System;
2
+ using System.Diagnostics;
3
+
4
+ namespace Community.CsharpSqlite
5
+ {
6
+ public partial class Sqlite3
7
+ {
8
+ /*
9
+ ** 2008 Jan 22
10
+ **
11
+ ** The author disclaims copyright to this source code. In place of
12
+ ** a legal notice, here is a blessing:
13
+ **
14
+ ** May you do good and not evil.
15
+ ** May you find forgiveness for yourself and forgive others.
16
+ ** May you share freely, never taking more than you give.
17
+ *************************************************************************
18
+ **
19
+ ** This file contains code to support the concept of "benign"
20
+ ** malloc failures (when the xMalloc() or xRealloc() method of the
21
+ ** sqlite3_mem_methods structure fails to allocate a block of memory
22
+ ** and returns 0).
23
+ **
24
+ ** Most malloc failures are non-benign. After they occur, SQLite
25
+ ** abandons the current operation and returns an error code (usually
26
+ ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
27
+ ** fatal. For example, if a malloc fails while resizing a hash table, this
28
+ ** is completely recoverable simply by not carrying out the resize. The
29
+ ** hash table will continue to function normally. So a malloc failure
30
+ ** during a hash table resize is a benign fault.
31
+ *************************************************************************
32
+ ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
33
+ ** C#-SQLite is an independent reimplementation of the SQLite software library
34
+ **
35
+ ** SQLITE_SOURCE_ID: 2009-12-07 16:39:13 1ed88e9d01e9eda5cbc622e7614277f29bcc551c
36
+ **
37
+ ** $Header$
38
+ *************************************************************************
39
+ */
40
+ //#include "sqliteInt.h"
41
+
42
+ #if !SQLITE_OMIT_BUILTIN_TEST
43
+ /*
44
+ ** Global variables.
45
+ */
46
+ //typedef struct BenignMallocHooks BenignMallocHooks;
47
+ public struct BenignMallocHooks//
48
+ {
49
+ public void_function xBenignBegin;//void (*xBenignBegin)(void);
50
+ public void_function xBenignEnd; //void (*xBenignEnd)(void);
51
+ public BenignMallocHooks( void_function xBenignBegin, void_function xBenignEnd )
52
+ {
53
+ this.xBenignBegin = xBenignBegin;
54
+ this.xBenignEnd = xBenignEnd;
55
+ }
56
+ }
57
+ static BenignMallocHooks sqlite3Hooks = new BenignMallocHooks( null, null );
58
+
59
+ /* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks
60
+ ** structure. If writable static data is unsupported on the target,
61
+ ** we have to locate the state vector at run-time. In the more common
62
+ ** case where writable static data is supported, wsdHooks can refer directly
63
+ ** to the "sqlite3Hooks" state vector declared above.
64
+ */
65
+ #if SQLITE_OMIT_WSD
66
+ //# define wsdHooksInit \
67
+ BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks)
68
+ //# define wsdHooks x[0]
69
+ #else
70
+ //# define wsdHooksInit
71
+ static void wsdHooksInit() { }
72
+ //# define wsdHooks sqlite3Hooks
73
+ static BenignMallocHooks wsdHooks = sqlite3Hooks;
74
+ #endif
75
+
76
+
77
+
78
+ /*
79
+ ** Register hooks to call when sqlite3BeginBenignMalloc() and
80
+ ** sqlite3EndBenignMalloc() are called, respectively.
81
+ */
82
+ static void sqlite3BenignMallocHooks(
83
+ void_function xBenignBegin, //void (*xBenignBegin)(void),
84
+ void_function xBenignEnd //void (*xBenignEnd)(void)
85
+ )
86
+ {
87
+ wsdHooksInit();
88
+ wsdHooks.xBenignBegin = xBenignBegin;
89
+ wsdHooks.xBenignEnd = xBenignEnd;
90
+ }
91
+
92
+ /*
93
+ ** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
94
+ ** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
95
+ ** indicates that subsequent malloc failures are non-benign.
96
+ */
97
+ static void sqlite3BeginBenignMalloc()
98
+ {
99
+ wsdHooksInit();
100
+ if ( wsdHooks.xBenignBegin != null )
101
+ {
102
+ wsdHooks.xBenignBegin();
103
+ }
104
+ }
105
+ static void sqlite3EndBenignMalloc()
106
+ {
107
+ wsdHooksInit();
108
+ if ( wsdHooks.xBenignEnd != null )
109
+ {
110
+ wsdHooks.xBenignEnd();
111
+ }
112
+ }
113
+ #endif //* SQLITE_OMIT_BUILTIN_TEST */
114
+ }
115
+ }
@@ -0,0 +1,1330 @@
1
+ using System;
2
+ using System.Diagnostics;
3
+ using System.Text;
4
+
5
+ using Bitmask = System.UInt64;
6
+ using u8 = System.Byte;
7
+ using u32 = System.UInt32;
8
+
9
+ namespace Community.CsharpSqlite
10
+ {
11
+ public partial class Sqlite3
12
+ {
13
+ /*
14
+ **
15
+ ** The author disclaims copyright to this source code. In place of
16
+ ** a legal notice, here is a blessing:
17
+ **
18
+ ** May you do good and not evil.
19
+ ** May you find forgiveness for yourself and forgive others.
20
+ ** May you share freely, never taking more than you give.
21
+ **
22
+ *************************************************************************
23
+ ** This file contains code used by the compiler to add foreign key
24
+ ** support to compiled SQL statements.
25
+ */
26
+ //#include "sqliteInt.h"
27
+
28
+ #if !SQLITE_OMIT_FOREIGN_KEY
29
+ #if !SQLITE_OMIT_TRIGGER
30
+
31
+ /*
32
+ ** Deferred and Immediate FKs
33
+ ** --------------------------
34
+ **
35
+ ** Foreign keys in SQLite come in two flavours: deferred and immediate.
36
+ ** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
37
+ ** is returned and the current statement transaction rolled back. If a
38
+ ** deferred foreign key constraint is violated, no action is taken
39
+ ** immediately. However if the application attempts to commit the
40
+ ** transaction before fixing the constraint violation, the attempt fails.
41
+ **
42
+ ** Deferred constraints are implemented using a simple counter associated
43
+ ** with the database handle. The counter is set to zero each time a
44
+ ** database transaction is opened. Each time a statement is executed
45
+ ** that causes a foreign key violation, the counter is incremented. Each
46
+ ** time a statement is executed that removes an existing violation from
47
+ ** the database, the counter is decremented. When the transaction is
48
+ ** committed, the commit fails if the current value of the counter is
49
+ ** greater than zero. This scheme has two big drawbacks:
50
+ **
51
+ ** * When a commit fails due to a deferred foreign key constraint,
52
+ ** there is no way to tell which foreign constraint is not satisfied,
53
+ ** or which row it is not satisfied for.
54
+ **
55
+ ** * If the database contains foreign key violations when the
56
+ ** transaction is opened, this may cause the mechanism to malfunction.
57
+ **
58
+ ** Despite these problems, this approach is adopted as it seems simpler
59
+ ** than the alternatives.
60
+ **
61
+ ** INSERT operations:
62
+ **
63
+ ** I.1) For each FK for which the table is the child table, search
64
+ ** the parent table for a match. If none is found increment the
65
+ ** constraint counter.
66
+ **
67
+ ** I.2) For each FK for which the table is the parent table,
68
+ ** search the child table for rows that correspond to the new
69
+ ** row in the parent table. Decrement the counter for each row
70
+ ** found (as the constraint is now satisfied).
71
+ **
72
+ ** DELETE operations:
73
+ **
74
+ ** D.1) For each FK for which the table is the child table,
75
+ ** search the parent table for a row that corresponds to the
76
+ ** deleted row in the child table. If such a row is not found,
77
+ ** decrement the counter.
78
+ **
79
+ ** D.2) For each FK for which the table is the parent table, search
80
+ ** the child table for rows that correspond to the deleted row
81
+ ** in the parent table. For each found increment the counter.
82
+ **
83
+ ** UPDATE operations:
84
+ **
85
+ ** An UPDATE command requires that all 4 steps above are taken, but only
86
+ ** for FK constraints for which the affected columns are actually
87
+ ** modified (values must be compared at runtime).
88
+ **
89
+ ** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2.
90
+ ** This simplifies the implementation a bit.
91
+ **
92
+ ** For the purposes of immediate FK constraints, the OR REPLACE conflict
93
+ ** resolution is considered to delete rows before the new row is inserted.
94
+ ** If a delete caused by OR REPLACE violates an FK constraint, an exception
95
+ ** is thrown, even if the FK constraint would be satisfied after the new
96
+ ** row is inserted.
97
+ **
98
+ ** Immediate constraints are usually handled similarly. The only difference
99
+ ** is that the counter used is stored as part of each individual statement
100
+ ** object (struct Vdbe). If, after the statement has run, its immediate
101
+ ** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
102
+ ** and the statement transaction is rolled back. An exception is an INSERT
103
+ ** statement that inserts a single row only (no triggers). In this case,
104
+ ** instead of using a counter, an exception is thrown immediately if the
105
+ ** INSERT violates a foreign key constraint. This is necessary as such
106
+ ** an INSERT does not open a statement transaction.
107
+ **
108
+ ** TODO: How should dropping a table be handled? How should renaming a
109
+ ** table be handled?
110
+ **
111
+ **
112
+ ** Query API Notes
113
+ ** ---------------
114
+ **
115
+ ** Before coding an UPDATE or DELETE row operation, the code-generator
116
+ ** for those two operations needs to know whether or not the operation
117
+ ** requires any FK processing and, if so, which columns of the original
118
+ ** row are required by the FK processing VDBE code (i.e. if FKs were
119
+ ** implemented using triggers, which of the old.* columns would be
120
+ ** accessed). No information is required by the code-generator before
121
+ ** coding an INSERT operation. The functions used by the UPDATE/DELETE
122
+ ** generation code to query for this information are:
123
+ **
124
+ ** sqlite3FkRequired() - Test to see if FK processing is required.
125
+ ** sqlite3FkOldmask() - Query for the set of required old.* columns.
126
+ **
127
+ **
128
+ ** Externally accessible module functions
129
+ ** --------------------------------------
130
+ **
131
+ ** sqlite3FkCheck() - Check for foreign key violations.
132
+ ** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions.
133
+ ** sqlite3FkDelete() - Delete an FKey structure.
134
+ */
135
+
136
+ /*
137
+ ** VDBE Calling Convention
138
+ ** -----------------------
139
+ **
140
+ ** Example:
141
+ **
142
+ ** For the following INSERT statement:
143
+ **
144
+ ** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c);
145
+ ** INSERT INTO t1 VALUES(1, 2, 3.1);
146
+ **
147
+ ** Register (x): 2 (type integer)
148
+ ** Register (x+1): 1 (type integer)
149
+ ** Register (x+2): NULL (type NULL)
150
+ ** Register (x+3): 3.1 (type real)
151
+ */
152
+
153
+ /*
154
+ ** A foreign key constraint requires that the key columns in the parent
155
+ ** table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
156
+ ** Given that pParent is the parent table for foreign key constraint pFKey,
157
+ ** search the schema a unique index on the parent key columns.
158
+ **
159
+ ** If successful, zero is returned. If the parent key is an INTEGER PRIMARY
160
+ ** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
161
+ ** is set to point to the unique index.
162
+ **
163
+ ** If the parent key consists of a single column (the foreign key constraint
164
+ ** is not a composite foreign key), output variable *paiCol is set to NULL.
165
+ ** Otherwise, it is set to point to an allocated array of size N, where
166
+ ** N is the number of columns in the parent key. The first element of the
167
+ ** array is the index of the child table column that is mapped by the FK
168
+ ** constraint to the parent table column stored in the left-most column
169
+ ** of index *ppIdx. The second element of the array is the index of the
170
+ ** child table column that corresponds to the second left-most column of
171
+ ** *ppIdx, and so on.
172
+ **
173
+ ** If the required index cannot be found, either because:
174
+ **
175
+ ** 1) The named parent key columns do not exist, or
176
+ **
177
+ ** 2) The named parent key columns do exist, but are not subject to a
178
+ ** UNIQUE or PRIMARY KEY constraint, or
179
+ **
180
+ ** 3) No parent key columns were provided explicitly as part of the
181
+ ** foreign key definition, and the parent table does not have a
182
+ ** PRIMARY KEY, or
183
+ **
184
+ ** 4) No parent key columns were provided explicitly as part of the
185
+ ** foreign key definition, and the PRIMARY KEY of the parent table
186
+ ** consists of a a different number of columns to the child key in
187
+ ** the child table.
188
+ **
189
+ ** then non-zero is returned, and a "foreign key mismatch" error loaded
190
+ ** into pParse. If an OOM error occurs, non-zero is returned and the
191
+ ** pParse.db.mallocFailed flag is set.
192
+ */
193
+ static int locateFkeyIndex(
194
+ Parse pParse, /* Parse context to store any error in */
195
+ Table pParent, /* Parent table of FK constraint pFKey */
196
+ FKey pFKey, /* Foreign key to find index for */
197
+ ref Index ppIdx, /* OUT: Unique index on parent table */
198
+ ref int[] paiCol /* OUT: Map of index columns in pFKey */
199
+ )
200
+ {
201
+ Index pIdx = null; /* Value to return via *ppIdx */
202
+ int[] aiCol = null; /* Value to return via *paiCol */
203
+ int nCol = pFKey.nCol; /* Number of columns in parent key */
204
+ string zKey = pFKey.aCol[0].zCol; /* Name of left-most parent key column */
205
+
206
+ /* The caller is responsible for zeroing output parameters. */
207
+ Debug.Assert( ppIdx == null ); //assert( ppIdx && *ppIdx==0 );
208
+ Debug.Assert( paiCol == null ); //assert( !paiCol || *paiCol==0 );
209
+ Debug.Assert( pParse != null );
210
+
211
+ /* If this is a non-composite (single column) foreign key, check if it
212
+ ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx
213
+ ** and *paiCol set to zero and return early.
214
+ **
215
+ ** Otherwise, for a composite foreign key (more than one column), allocate
216
+ ** space for the aiCol array (returned via output parameter *paiCol).
217
+ ** Non-composite foreign keys do not require the aiCol array.
218
+ */
219
+ if ( nCol == 1 )
220
+ {
221
+ /* The FK maps to the IPK if any of the following are true:
222
+ **
223
+ ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly
224
+ ** mapped to the primary key of table pParent, or
225
+ ** 2) The FK is explicitly mapped to a column declared as INTEGER
226
+ ** PRIMARY KEY.
227
+ */
228
+ if ( pParent.iPKey >= 0 )
229
+ {
230
+ if ( null == zKey ) return 0;
231
+ if ( 0 == sqlite3StrICmp( pParent.aCol[pParent.iPKey].zName, zKey ) ) return 0;
232
+ }
233
+ }
234
+ else //if( paiCol ){
235
+ {
236
+ Debug.Assert( nCol > 1 );
237
+ aiCol = new int[nCol];// (int*)sqlite3DbMallocRaw( pParse.db, nCol * sizeof( int ) );
238
+ //if( !aiCol ) return 1;
239
+ paiCol = aiCol;
240
+ }
241
+
242
+ for ( pIdx = pParent.pIndex; pIdx != null; pIdx = pIdx.pNext )
243
+ {
244
+ if ( pIdx.nColumn == nCol && pIdx.onError != OE_None )
245
+ {
246
+ /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
247
+ ** of columns. If each indexed column corresponds to a foreign key
248
+ ** column of pFKey, then this index is a winner. */
249
+
250
+ if ( zKey == null )
251
+ {
252
+ /* If zKey is NULL, then this foreign key is implicitly mapped to
253
+ ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be
254
+ ** identified by the test (Index.autoIndex==2). */
255
+ if ( pIdx.autoIndex == 2 )
256
+ {
257
+ if ( aiCol != null )
258
+ {
259
+ int i;
260
+ for ( i = 0; i < nCol; i++ ) aiCol[i] = pFKey.aCol[i].iFrom;
261
+ }
262
+ break;
263
+ }
264
+ }
265
+ else
266
+ {
267
+ /* If zKey is non-NULL, then this foreign key was declared to
268
+ ** map to an explicit list of columns in table pParent. Check if this
269
+ ** index matches those columns. Also, check that the index uses
270
+ ** the default collation sequences for each column. */
271
+ int i, j;
272
+ for ( i = 0; i < nCol; i++ )
273
+ {
274
+ int iCol = pIdx.aiColumn[i]; /* Index of column in parent tbl */
275
+ string zDfltColl; /* Def. collation for column */
276
+ string zIdxCol; /* Name of indexed column */
277
+
278
+ /* If the index uses a collation sequence that is different from
279
+ ** the default collation sequence for the column, this index is
280
+ ** unusable. Bail out early in this case. */
281
+ zDfltColl = pParent.aCol[iCol].zColl;
282
+ if ( String.IsNullOrEmpty( zDfltColl ) )
283
+ {
284
+ zDfltColl = "BINARY";
285
+ }
286
+ if ( sqlite3StrICmp( pIdx.azColl[i], zDfltColl ) != 0 ) break;
287
+
288
+ zIdxCol = pParent.aCol[iCol].zName;
289
+ for ( j = 0; j < nCol; j++ )
290
+ {
291
+ if ( sqlite3StrICmp( pFKey.aCol[j].zCol, zIdxCol ) == 0 )
292
+ {
293
+ if ( aiCol != null ) aiCol[i] = pFKey.aCol[j].iFrom;
294
+ break;
295
+ }
296
+ }
297
+ if ( j == nCol ) break;
298
+ }
299
+ if ( i == nCol ) break; /* pIdx is usable */
300
+ }
301
+ }
302
+ }
303
+
304
+ if ( null == pIdx )
305
+ {
306
+ if ( 0 == pParse.disableTriggers )
307
+ {
308
+ sqlite3ErrorMsg( pParse, "foreign key mismatch" );
309
+ }
310
+ sqlite3DbFree( pParse.db, ref aiCol );
311
+ return 1;
312
+ }
313
+
314
+ ppIdx = pIdx;
315
+ return 0;
316
+ }
317
+
318
+ /*
319
+ ** This function is called when a row is inserted into or deleted from the
320
+ ** child table of foreign key constraint pFKey. If an SQL UPDATE is executed
321
+ ** on the child table of pFKey, this function is invoked twice for each row
322
+ ** affected - once to "delete" the old row, and then again to "insert" the
323
+ ** new row.
324
+ **
325
+ ** Each time it is called, this function generates VDBE code to locate the
326
+ ** row in the parent table that corresponds to the row being inserted into
327
+ ** or deleted from the child table. If the parent row can be found, no
328
+ ** special action is taken. Otherwise, if the parent row can *not* be
329
+ ** found in the parent table:
330
+ **
331
+ ** Operation | FK type | Action taken
332
+ ** --------------------------------------------------------------------------
333
+ ** INSERT immediate Increment the "immediate constraint counter".
334
+ **
335
+ ** DELETE immediate Decrement the "immediate constraint counter".
336
+ **
337
+ ** INSERT deferred Increment the "deferred constraint counter".
338
+ **
339
+ ** DELETE deferred Decrement the "deferred constraint counter".
340
+ **
341
+ ** These operations are identified in the comment at the top of this file
342
+ ** (fkey.c) as "I.1" and "D.1".
343
+ */
344
+ static void fkLookupParent(
345
+ Parse pParse, /* Parse context */
346
+ int iDb, /* Index of database housing pTab */
347
+ Table pTab, /* Parent table of FK pFKey */
348
+ Index pIdx, /* Unique index on parent key columns in pTab */
349
+ FKey pFKey, /* Foreign key constraint */
350
+ int[] aiCol, /* Map from parent key columns to child table columns */
351
+ int regData, /* Address of array containing child table row */
352
+ int nIncr, /* Increment constraint counter by this */
353
+ int isIgnore /* If true, pretend pTab contains all NULL values */
354
+ )
355
+ {
356
+ int i; /* Iterator variable */
357
+ Vdbe v = sqlite3GetVdbe( pParse ); /* Vdbe to add code to */
358
+ int iCur = pParse.nTab - 1; /* Cursor number to use */
359
+ int iOk = sqlite3VdbeMakeLabel( v ); /* jump here if parent key found */
360
+
361
+ /* If nIncr is less than zero, then check at runtime if there are any
362
+ ** outstanding constraints to resolve. If there are not, there is no need
363
+ ** to check if deleting this row resolves any outstanding violations.
364
+ **
365
+ ** Check if any of the key columns in the child table row are NULL. If
366
+ ** any are, then the constraint is considered satisfied. No need to
367
+ ** search for a matching row in the parent table. */
368
+ if ( nIncr < 0 )
369
+ {
370
+ sqlite3VdbeAddOp2( v, OP_FkIfZero, pFKey.isDeferred, iOk );
371
+ }
372
+ for ( i = 0; i < pFKey.nCol; i++ )
373
+ {
374
+ int iReg = aiCol[i] + regData + 1;
375
+ sqlite3VdbeAddOp2( v, OP_IsNull, iReg, iOk );
376
+ }
377
+
378
+ if ( isIgnore == 0 )
379
+ {
380
+ if ( pIdx == null )
381
+ {
382
+ /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
383
+ ** column of the parent table (table pTab). */
384
+ int iMustBeInt; /* Address of MustBeInt instruction */
385
+ int regTemp = sqlite3GetTempReg( pParse );
386
+
387
+ /* Invoke MustBeInt to coerce the child key value to an integer (i.e.
388
+ ** apply the affinity of the parent key). If this fails, then there
389
+ ** is no matching parent key. Before using MustBeInt, make a copy of
390
+ ** the value. Otherwise, the value inserted into the child key column
391
+ ** will have INTEGER affinity applied to it, which may not be correct. */
392
+ sqlite3VdbeAddOp2( v, OP_SCopy, aiCol[0] + 1 + regData, regTemp );
393
+ iMustBeInt = sqlite3VdbeAddOp2( v, OP_MustBeInt, regTemp, 0 );
394
+
395
+ /* If the parent table is the same as the child table, and we are about
396
+ ** to increment the constraint-counter (i.e. this is an INSERT operation),
397
+ ** then check if the row being inserted matches itself. If so, do not
398
+ ** increment the constraint-counter. */
399
+ if ( pTab == pFKey.pFrom && nIncr == 1 )
400
+ {
401
+ sqlite3VdbeAddOp3( v, OP_Eq, regData, iOk, regTemp );
402
+ }
403
+
404
+ sqlite3OpenTable( pParse, iCur, iDb, pTab, OP_OpenRead );
405
+ sqlite3VdbeAddOp3( v, OP_NotExists, iCur, 0, regTemp );
406
+ sqlite3VdbeAddOp2( v, OP_Goto, 0, iOk );
407
+ sqlite3VdbeJumpHere( v, sqlite3VdbeCurrentAddr( v ) - 2 );
408
+ sqlite3VdbeJumpHere( v, iMustBeInt );
409
+ sqlite3ReleaseTempReg( pParse, regTemp );
410
+ }
411
+ else
412
+ {
413
+ int nCol = pFKey.nCol;
414
+ int regTemp = sqlite3GetTempRange( pParse, nCol );
415
+ int regRec = sqlite3GetTempReg( pParse );
416
+ KeyInfo pKey = sqlite3IndexKeyinfo( pParse, pIdx );
417
+
418
+ sqlite3VdbeAddOp3( v, OP_OpenRead, iCur, pIdx.tnum, iDb );
419
+ sqlite3VdbeChangeP4( v, -1, pKey, P4_KEYINFO_HANDOFF );
420
+ for ( i = 0; i < nCol; i++ )
421
+ {
422
+ sqlite3VdbeAddOp2( v, OP_SCopy, aiCol[i] + 1 + regData, regTemp + i );
423
+ }
424
+
425
+ /* If the parent table is the same as the child table, and we are about
426
+ ** to increment the constraint-counter (i.e. this is an INSERT operation),
427
+ ** then check if the row being inserted matches itself. If so, do not
428
+ ** increment the constraint-counter. */
429
+ if ( pTab == pFKey.pFrom && nIncr == 1 )
430
+ {
431
+ int iJump = sqlite3VdbeCurrentAddr( v ) + nCol + 1;
432
+ for ( i = 0; i < nCol; i++ )
433
+ {
434
+ int iChild = aiCol[i] + 1 + regData;
435
+ int iParent = pIdx.aiColumn[i] + 1 + regData;
436
+ sqlite3VdbeAddOp3( v, OP_Ne, iChild, iJump, iParent );
437
+ }
438
+ sqlite3VdbeAddOp2( v, OP_Goto, 0, iOk );
439
+ }
440
+
441
+ sqlite3VdbeAddOp3( v, OP_MakeRecord, regTemp, nCol, regRec );
442
+ sqlite3VdbeChangeP4( v, -1, sqlite3IndexAffinityStr( v, pIdx ), 0 );
443
+ sqlite3VdbeAddOp4Int( v, OP_Found, iCur, iOk, regRec, 0 );
444
+
445
+ sqlite3ReleaseTempReg( pParse, regRec );
446
+ sqlite3ReleaseTempRange( pParse, regTemp, nCol );
447
+ }
448
+ }
449
+
450
+ if ( 0==pFKey.isDeferred && null==pParse.pToplevel && 0==pParse.isMultiWrite )
451
+ {
452
+ /* Special case: If this is an INSERT statement that will insert exactly
453
+ ** one row into the table, raise a constraint immediately instead of
454
+ ** incrementing a counter. This is necessary as the VM code is being
455
+ ** generated for will not open a statement transaction. */
456
+ Debug.Assert( nIncr == 1 );
457
+ sqlite3HaltConstraint(
458
+ pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
459
+ );
460
+ }
461
+ else
462
+ {
463
+ if ( nIncr > 0 && pFKey.isDeferred == 0 )
464
+ {
465
+ sqlite3ParseToplevel( pParse ).mayAbort = 1;
466
+ }
467
+ sqlite3VdbeAddOp2( v, OP_FkCounter, pFKey.isDeferred, nIncr );
468
+ }
469
+
470
+ sqlite3VdbeResolveLabel( v, iOk );
471
+ sqlite3VdbeAddOp1( v, OP_Close, iCur );
472
+ }
473
+
474
+ /*
475
+ ** This function is called to generate code executed when a row is deleted
476
+ ** from the parent table of foreign key constraint pFKey and, if pFKey is
477
+ ** deferred, when a row is inserted into the same table. When generating
478
+ ** code for an SQL UPDATE operation, this function may be called twice -
479
+ ** once to "delete" the old row and once to "insert" the new row.
480
+ **
481
+ ** The code generated by this function scans through the rows in the child
482
+ ** table that correspond to the parent table row being deleted or inserted.
483
+ ** For each child row found, one of the following actions is taken:
484
+ **
485
+ ** Operation | FK type | Action taken
486
+ ** --------------------------------------------------------------------------
487
+ ** DELETE immediate Increment the "immediate constraint counter".
488
+ ** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
489
+ ** throw a "foreign key constraint failed" exception.
490
+ **
491
+ ** INSERT immediate Decrement the "immediate constraint counter".
492
+ **
493
+ ** DELETE deferred Increment the "deferred constraint counter".
494
+ ** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
495
+ ** throw a "foreign key constraint failed" exception.
496
+ **
497
+ ** INSERT deferred Decrement the "deferred constraint counter".
498
+ **
499
+ ** These operations are identified in the comment at the top of this file
500
+ ** (fkey.c) as "I.2" and "D.2".
501
+ */
502
+ static void fkScanChildren(
503
+ Parse pParse, /* Parse context */
504
+ SrcList pSrc, /* SrcList containing the table to scan */
505
+ Table pTab,
506
+ Index pIdx, /* Foreign key index */
507
+ FKey pFKey, /* Foreign key relationship */
508
+ int[] aiCol, /* Map from pIdx cols to child table cols */
509
+ int regData, /* Referenced table data starts here */
510
+ int nIncr /* Amount to increment deferred counter by */
511
+ )
512
+ {
513
+ sqlite3 db = pParse.db; /* Database handle */
514
+ int i; /* Iterator variable */
515
+ Expr pWhere = null; /* WHERE clause to scan with */
516
+ NameContext sNameContext; /* Context used to resolve WHERE clause */
517
+ WhereInfo pWInfo; /* Context used by sqlite3WhereXXX() */
518
+ int iFkIfZero = 0; /* Address of OP_FkIfZero */
519
+ Vdbe v = sqlite3GetVdbe( pParse );
520
+
521
+ Debug.Assert( null==pIdx || pIdx.pTable == pTab );
522
+
523
+ if ( nIncr < 0 )
524
+ {
525
+ iFkIfZero = sqlite3VdbeAddOp2( v, OP_FkIfZero, pFKey.isDeferred, 0 );
526
+ }
527
+
528
+ /* Create an Expr object representing an SQL expression like:
529
+ **
530
+ ** <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
531
+ **
532
+ ** The collation sequence used for the comparison should be that of
533
+ ** the parent key columns. The affinity of the parent key column should
534
+ ** be applied to each child key value before the comparison takes place.
535
+ */
536
+ for ( i = 0; i < pFKey.nCol; i++ )
537
+ {
538
+ Expr pLeft; /* Value from parent table row */
539
+ Expr pRight; /* Column ref to child table */
540
+ Expr pEq; /* Expression (pLeft = pRight) */
541
+ int iCol; /* Index of column in child table */
542
+ string zCol; /* Name of column in child table */
543
+
544
+ pLeft = sqlite3Expr( db, TK_REGISTER, null );
545
+ if ( pLeft != null )
546
+ {
547
+ /* Set the collation sequence and affinity of the LHS of each TK_EQ
548
+ ** expression to the parent key column defaults. */
549
+ if ( pIdx != null )
550
+ {
551
+ Column pCol;
552
+ iCol = pIdx.aiColumn[i];
553
+ pCol = pIdx.pTable.aCol[iCol];
554
+ pLeft.iTable = regData + iCol + 1;
555
+ pLeft.affinity = pCol.affinity;
556
+ pLeft.pColl = sqlite3LocateCollSeq( pParse, pCol.zColl );
557
+ }
558
+ else
559
+ {
560
+ pLeft.iTable = regData;
561
+ pLeft.affinity = SQLITE_AFF_INTEGER;
562
+ }
563
+ }
564
+ iCol = aiCol !=null? aiCol[i] : pFKey.aCol[0].iFrom;
565
+ Debug.Assert( iCol >= 0 );
566
+ zCol = pFKey.pFrom.aCol[iCol].zName;
567
+ pRight = sqlite3Expr( db, TK_ID, zCol );
568
+ pEq = sqlite3PExpr( pParse, TK_EQ, pLeft, pRight, 0 );
569
+ pWhere = sqlite3ExprAnd( db, pWhere, pEq );
570
+ }
571
+
572
+ /* If the child table is the same as the parent table, and this scan
573
+ ** is taking place as part of a DELETE operation (operation D.2), omit the
574
+ ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE
575
+ ** clause, where $rowid is the rowid of the row being deleted. */
576
+ if ( pTab == pFKey.pFrom && nIncr > 0 )
577
+ {
578
+ Expr pEq; /* Expression (pLeft = pRight) */
579
+ Expr pLeft; /* Value from parent table row */
580
+ Expr pRight; /* Column ref to child table */
581
+ pLeft = sqlite3Expr( db, TK_REGISTER, null );
582
+ pRight = sqlite3Expr( db, TK_COLUMN, null );
583
+ if ( pLeft != null && pRight != null )
584
+ {
585
+ pLeft.iTable = regData;
586
+ pLeft.affinity = SQLITE_AFF_INTEGER;
587
+ pRight.iTable = pSrc.a[0].iCursor;
588
+ pRight.iColumn = -1;
589
+ }
590
+ pEq = sqlite3PExpr( pParse, TK_NE, pLeft, pRight, 0 );
591
+ pWhere = sqlite3ExprAnd( db, pWhere, pEq );
592
+ }
593
+
594
+ /* Resolve the references in the WHERE clause. */
595
+ sNameContext = new NameContext();// memset( &sNameContext, 0, sizeof( NameContext ) );
596
+ sNameContext.pSrcList = pSrc;
597
+ sNameContext.pParse = pParse;
598
+ sqlite3ResolveExprNames( sNameContext, ref pWhere );
599
+
600
+ /* Create VDBE to loop through the entries in pSrc that match the WHERE
601
+ ** clause. If the constraint is not deferred, throw an exception for
602
+ ** each row found. Otherwise, for deferred constraints, increment the
603
+ ** deferred constraint counter by nIncr for each row selected. */
604
+ ExprList elDummy = null;
605
+ pWInfo = sqlite3WhereBegin( pParse, pSrc, pWhere, ref elDummy, 0 );
606
+ if ( nIncr > 0 && pFKey.isDeferred == 0 )
607
+ {
608
+ sqlite3ParseToplevel( pParse ).mayAbort = 1;
609
+ }
610
+ sqlite3VdbeAddOp2( v, OP_FkCounter, pFKey.isDeferred, nIncr );
611
+ if ( pWInfo != null )
612
+ {
613
+ sqlite3WhereEnd( pWInfo );
614
+ }
615
+
616
+ /* Clean up the WHERE clause constructed above. */
617
+ sqlite3ExprDelete( db, ref pWhere );
618
+ if ( iFkIfZero != 0 )
619
+ {
620
+ sqlite3VdbeJumpHere( v, iFkIfZero );
621
+ }
622
+ }
623
+
624
+ /*
625
+ ** This function returns a pointer to the head of a linked list of FK
626
+ ** constraints for which table pTab is the parent table. For example,
627
+ ** given the following schema:
628
+ **
629
+ ** CREATE TABLE t1(a PRIMARY KEY);
630
+ ** CREATE TABLE t2(b REFERENCES t1(a);
631
+ **
632
+ ** Calling this function with table "t1" as an argument returns a pointer
633
+ ** to the FKey structure representing the foreign key constraint on table
634
+ ** "t2". Calling this function with "t2" as the argument would return a
635
+ ** NULL pointer (as there are no FK constraints for which t2 is the parent
636
+ ** table).
637
+ */
638
+ static FKey sqlite3FkReferences( Table pTab )
639
+ {
640
+ int nName = sqlite3Strlen30( pTab.zName );
641
+ return (FKey)sqlite3HashFind( pTab.pSchema.fkeyHash, pTab.zName, nName );
642
+ }
643
+
644
+ /*
645
+ ** The second argument is a Trigger structure allocated by the
646
+ ** fkActionTrigger() routine. This function deletes the Trigger structure
647
+ ** and all of its sub-components.
648
+ **
649
+ ** The Trigger structure or any of its sub-components may be allocated from
650
+ ** the lookaside buffer belonging to database handle dbMem.
651
+ */
652
+ static void fkTriggerDelete( sqlite3 dbMem, Trigger p )
653
+ {
654
+ if ( p !=null)
655
+ {
656
+ TriggerStep pStep = p.step_list;
657
+ sqlite3ExprDelete( dbMem, ref pStep.pWhere );
658
+ sqlite3ExprListDelete( dbMem, ref pStep.pExprList );
659
+ sqlite3SelectDelete( dbMem, ref pStep.pSelect );
660
+ sqlite3ExprDelete( dbMem, ref p.pWhen );
661
+ sqlite3DbFree( dbMem, ref p );
662
+ }
663
+ }
664
+
665
+ /*
666
+ ** This function is called to generate code that runs when table pTab is
667
+ ** being dropped from the database. The SrcList passed as the second argument
668
+ ** to this function contains a single entry guaranteed to resolve to
669
+ ** table pTab.
670
+ **
671
+ ** Normally, no code is required. However, if either
672
+ **
673
+ ** (a) The table is the parent table of a FK constraint, or
674
+ ** (b) The table is the child table of a deferred FK constraint and it is
675
+ ** determined at runtime that there are outstanding deferred FK
676
+ ** constraint violations in the database,
677
+ **
678
+ ** then the equivalent of "DELETE FROM <tbl>" is executed before dropping
679
+ ** the table from the database. Triggers are disabled while running this
680
+ ** DELETE, but foreign key actions are not.
681
+ */
682
+ static void sqlite3FkDropTable( Parse pParse, SrcList pName, Table pTab )
683
+ {
684
+ sqlite3 db = pParse.db;
685
+ if ( ( db.flags & SQLITE_ForeignKeys )!=0 && !IsVirtual( pTab ) && null==pTab.pSelect )
686
+ {
687
+ int iSkip = 0;
688
+ Vdbe v = sqlite3GetVdbe( pParse );
689
+
690
+ Debug.Assert( v!=null ); /* VDBE has already been allocated */
691
+ if ( sqlite3FkReferences( pTab ) ==null )
692
+ {
693
+ /* Search for a deferred foreign key constraint for which this table
694
+ ** is the child table. If one cannot be found, return without
695
+ ** generating any VDBE code. If one can be found, then jump over
696
+ ** the entire DELETE if there are no outstanding deferred constraints
697
+ ** when this statement is run. */
698
+ FKey p;
699
+ for ( p = pTab.pFKey; p!=null; p = p.pNextFrom )
700
+ {
701
+ if ( p.isDeferred !=0) break;
702
+ }
703
+ if ( null==p ) return;
704
+ iSkip = sqlite3VdbeMakeLabel( v );
705
+ sqlite3VdbeAddOp2( v, OP_FkIfZero, 1, iSkip );
706
+ }
707
+
708
+ pParse.disableTriggers = 1;
709
+ sqlite3DeleteFrom( pParse, sqlite3SrcListDup( db, pName, 0 ), null );
710
+ pParse.disableTriggers = 0;
711
+
712
+ /* If the DELETE has generated immediate foreign key constraint
713
+ ** violations, halt the VDBE and return an error at this point, before
714
+ ** any modifications to the schema are made. This is because statement
715
+ ** transactions are not able to rollback schema changes. */
716
+ sqlite3VdbeAddOp2( v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr( v ) + 2 );
717
+ sqlite3HaltConstraint(
718
+ pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
719
+ );
720
+
721
+ if ( iSkip!=0 )
722
+ {
723
+ sqlite3VdbeResolveLabel( v, iSkip );
724
+ }
725
+ }
726
+ }
727
+
728
+ /*
729
+ ** This function is called when inserting, deleting or updating a row of
730
+ ** table pTab to generate VDBE code to perform foreign key constraint
731
+ ** processing for the operation.
732
+ **
733
+ ** For a DELETE operation, parameter regOld is passed the index of the
734
+ ** first register in an array of (pTab.nCol+1) registers containing the
735
+ ** rowid of the row being deleted, followed by each of the column values
736
+ ** of the row being deleted, from left to right. Parameter regNew is passed
737
+ ** zero in this case.
738
+ **
739
+ ** For an INSERT operation, regOld is passed zero and regNew is passed the
740
+ ** first register of an array of (pTab.nCol+1) registers containing the new
741
+ ** row data.
742
+ **
743
+ ** For an UPDATE operation, this function is called twice. Once before
744
+ ** the original record is deleted from the table using the calling convention
745
+ ** described for DELETE. Then again after the original record is deleted
746
+ ** but before the new record is inserted using the INSERT convention.
747
+ */
748
+ static void sqlite3FkCheck(
749
+ Parse pParse, /* Parse context */
750
+ Table pTab, /* Row is being deleted from this table */
751
+ int regOld, /* Previous row data is stored here */
752
+ int regNew /* New row data is stored here */
753
+ )
754
+ {
755
+ sqlite3 db = pParse.db; /* Database handle */
756
+ Vdbe v; /* VM to write code to */
757
+ FKey pFKey; /* Used to iterate through FKs */
758
+ int iDb; /* Index of database containing pTab */
759
+ string zDb; /* Name of database containing pTab */
760
+ int isIgnoreErrors = pParse.disableTriggers;
761
+
762
+ /* Exactly one of regOld and regNew should be non-zero. */
763
+ Debug.Assert( ( regOld == 0 ) != ( regNew == 0 ) );
764
+
765
+ /* If foreign-keys are disabled, this function is a no-op. */
766
+ if ( ( db.flags & SQLITE_ForeignKeys ) == 0 ) return;
767
+
768
+ v = sqlite3GetVdbe( pParse );
769
+ iDb = sqlite3SchemaToIndex( db, pTab.pSchema );
770
+ zDb = db.aDb[iDb].zName;
771
+
772
+ /* Loop through all the foreign key constraints for which pTab is the
773
+ ** child table (the table that the foreign key definition is part of). */
774
+ for ( pFKey = pTab.pFKey; pFKey != null; pFKey = pFKey.pNextFrom )
775
+ {
776
+ Table pTo; /* Parent table of foreign key pFKey */
777
+ Index pIdx = null; /* Index on key columns in pTo */
778
+ int[] aiFree = null;
779
+ int[] aiCol;
780
+ int iCol;
781
+ int i;
782
+ int isIgnore = 0;
783
+
784
+ /* Find the parent table of this foreign key. Also find a unique index
785
+ ** on the parent key columns in the parent table. If either of these
786
+ ** schema items cannot be located, set an error in pParse and return
787
+ ** early. */
788
+ if ( pParse.disableTriggers!=0 )
789
+ {
790
+ pTo = sqlite3FindTable( db, pFKey.zTo, zDb );
791
+ }
792
+ else
793
+ {
794
+ pTo = sqlite3LocateTable( pParse, 0, pFKey.zTo, zDb );
795
+ }
796
+ if ( null==pTo || locateFkeyIndex( pParse, pTo, pFKey, ref pIdx, ref aiFree ) !=0)
797
+ {
798
+ if ( 0==isIgnoreErrors /* || db.mallocFailed */) return;
799
+ continue;
800
+ }
801
+ Debug.Assert( pFKey.nCol == 1 || ( aiFree != null && pIdx != null ) );
802
+
803
+ if ( aiFree !=null)
804
+ {
805
+ aiCol = aiFree;
806
+ }
807
+ else
808
+ {
809
+ iCol = pFKey.aCol[0].iFrom;
810
+ aiCol = new int[1]; aiCol[0] = iCol;
811
+ }
812
+ for ( i = 0; i < pFKey.nCol; i++ )
813
+ {
814
+ if ( aiCol[i] == pTab.iPKey )
815
+ {
816
+ aiCol[i] = -1;
817
+ }
818
+ #if !SQLITE_OMIT_AUTHORIZATION
819
+ /* Request permission to read the parent key columns. If the
820
+ ** authorization callback returns SQLITE_IGNORE, behave as if any
821
+ ** values read from the parent table are NULL. */
822
+ if( db.xAuth ){
823
+ int rcauth;
824
+ char *zCol = pTo.aCol[pIdx ? pIdx.aiColumn[i] : pTo.iPKey].zName;
825
+ rcauth = sqlite3AuthReadCol(pParse, pTo.zName, zCol, iDb);
826
+ isIgnore = (rcauth==SQLITE_IGNORE);
827
+ }
828
+ #endif
829
+ }
830
+
831
+ /* Take a shared-cache advisory read-lock on the parent table. Allocate
832
+ ** a cursor to use to search the unique index on the parent key columns
833
+ ** in the parent table. */
834
+ sqlite3TableLock( pParse, iDb, pTo.tnum, 0, pTo.zName );
835
+ pParse.nTab++;
836
+
837
+ if ( regOld != 0 )
838
+ {
839
+ /* A row is being removed from the child table. Search for the parent.
840
+ ** If the parent does not exist, removing the child row resolves an
841
+ ** outstanding foreign key constraint violation. */
842
+ fkLookupParent( pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, isIgnore );
843
+ }
844
+ if ( regNew != 0 )
845
+ {
846
+ /* A row is being added to the child table. If a parent row cannot
847
+ ** be found, adding the child row has violated the FK constraint. */
848
+ fkLookupParent( pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, isIgnore );
849
+ }
850
+
851
+ sqlite3DbFree( db, ref aiFree );
852
+ }
853
+
854
+ /* Loop through all the foreign key constraints that refer to this table */
855
+ for ( pFKey = sqlite3FkReferences( pTab ); pFKey!=null; pFKey = pFKey.pNextTo )
856
+ {
857
+ Index pIdx = null; /* Foreign key index for pFKey */
858
+ SrcList pSrc;
859
+ int[] aiCol = null;
860
+
861
+ if ( 0==pFKey.isDeferred && null==pParse.pToplevel && 0==pParse.isMultiWrite )
862
+ {
863
+ Debug.Assert( regOld == 0 && regNew != 0 );
864
+ /* Inserting a single row into a parent table cannot cause an immediate
865
+ ** foreign key violation. So do nothing in this case. */
866
+ continue;
867
+ }
868
+
869
+ if ( locateFkeyIndex( pParse, pTab, pFKey, ref pIdx, ref aiCol )!=0 )
870
+ {
871
+ if ( 0==isIgnoreErrors /*|| db.mallocFailed */) return;
872
+ continue;
873
+ }
874
+ Debug.Assert( aiCol!=null || pFKey.nCol == 1 );
875
+
876
+ /* Create a SrcList structure containing a single table (the table
877
+ ** the foreign key that refers to this table is attached to). This
878
+ ** is required for the sqlite3WhereXXX() interface. */
879
+ pSrc = sqlite3SrcListAppend( db, 0, null, null );
880
+ if ( pSrc != null )
881
+ {
882
+ SrcList_item pItem = pSrc.a[0];
883
+ pItem.pTab = pFKey.pFrom;
884
+ pItem.zName = pFKey.pFrom.zName;
885
+ pItem.pTab.nRef++;
886
+ pItem.iCursor = pParse.nTab++;
887
+
888
+ if ( regNew != 0 )
889
+ {
890
+ fkScanChildren( pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1 );
891
+ }
892
+ if ( regOld != 0 )
893
+ {
894
+ /* If there is a RESTRICT action configured for the current operation
895
+ ** on the parent table of this FK, then throw an exception
896
+ ** immediately if the FK constraint is violated, even if this is a
897
+ ** deferred trigger. That's what RESTRICT means. To defer checking
898
+ ** the constraint, the FK should specify NO ACTION (represented
899
+ ** using OE_None). NO ACTION is the default. */
900
+ fkScanChildren( pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1 );
901
+ }
902
+ pItem.zName = null;
903
+ sqlite3SrcListDelete( db, ref pSrc );
904
+ }
905
+ sqlite3DbFree( db, ref aiCol );
906
+ }
907
+ }
908
+
909
+ //#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))
910
+ static uint COLUMN_MASK( int x ) { return ( ( x ) > 31 ) ? 0xffffffff : ( (u32)1 << ( x ) ); }
911
+
912
+ /*
913
+ ** This function is called before generating code to update or delete a
914
+ ** row contained in table pTab.
915
+ */
916
+ static u32 sqlite3FkOldmask(
917
+ Parse pParse, /* Parse context */
918
+ Table pTab /* Table being modified */
919
+ )
920
+ {
921
+ u32 mask = 0;
922
+ if (( pParse.db.flags & SQLITE_ForeignKeys )!=0)
923
+ {
924
+ FKey p;
925
+ int i;
926
+ for ( p = pTab.pFKey; p!=null; p = p.pNextFrom )
927
+ {
928
+ for ( i = 0; i < p.nCol; i++ ) mask |= COLUMN_MASK( p.aCol[i].iFrom );
929
+ }
930
+ for ( p = sqlite3FkReferences( pTab ); p != null; p = p.pNextTo )
931
+ {
932
+ Index pIdx = null;
933
+ int[] iDummy = null;
934
+ locateFkeyIndex( pParse, pTab, p, ref pIdx, ref iDummy );
935
+ if ( pIdx != null )
936
+ {
937
+ for ( i = 0; i < pIdx.nColumn; i++ ) mask |= COLUMN_MASK( pIdx.aiColumn[i] );
938
+ }
939
+ }
940
+ }
941
+ return mask;
942
+ }
943
+
944
+ /*
945
+ ** This function is called before generating code to update or delete a
946
+ ** row contained in table pTab. If the operation is a DELETE, then
947
+ ** parameter aChange is passed a NULL value. For an UPDATE, aChange points
948
+ ** to an array of size N, where N is the number of columns in table pTab.
949
+ ** If the i'th column is not modified by the UPDATE, then the corresponding
950
+ ** entry in the aChange[] array is set to -1. If the column is modified,
951
+ ** the value is 0 or greater. Parameter chngRowid is set to true if the
952
+ ** UPDATE statement modifies the rowid fields of the table.
953
+ **
954
+ ** If any foreign key processing will be required, this function returns
955
+ ** true. If there is no foreign key related processing, this function
956
+ ** returns false.
957
+ */
958
+ static int sqlite3FkRequired(
959
+ Parse pParse, /* Parse context */
960
+ Table pTab, /* Table being modified */
961
+ int[] aChange, /* Non-NULL for UPDATE operations */
962
+ int chngRowid /* True for UPDATE that affects rowid */
963
+ )
964
+ {
965
+ if (( pParse.db.flags & SQLITE_ForeignKeys )!=0)
966
+ {
967
+ if ( null==aChange )
968
+ {
969
+ /* A DELETE operation. Foreign key processing is required if the
970
+ ** table in question is either the child or parent table for any
971
+ ** foreign key constraint. */
972
+ return ( sqlite3FkReferences( pTab )!=null || pTab.pFKey !=null)?1:0;
973
+ }
974
+ else
975
+ {
976
+ /* This is an UPDATE. Foreign key processing is only required if the
977
+ ** operation modifies one or more child or parent key columns. */
978
+ int i;
979
+ FKey p;
980
+
981
+ /* Check if any child key columns are being modified. */
982
+ for ( p = pTab.pFKey; p!=null; p = p.pNextFrom )
983
+ {
984
+ for ( i = 0; i < p.nCol; i++ )
985
+ {
986
+ int iChildKey = p.aCol[i].iFrom;
987
+ if ( aChange[iChildKey] >= 0 ) return 1;
988
+ if ( iChildKey == pTab.iPKey && chngRowid!=0 ) return 1;
989
+ }
990
+ }
991
+
992
+ /* Check if any parent key columns are being modified. */
993
+ for ( p = sqlite3FkReferences( pTab ); p != null; p = p.pNextTo )
994
+ {
995
+ for ( i = 0; i < p.nCol; i++ )
996
+ {
997
+ string zKey = p.aCol[i].zCol;
998
+ int iKey;
999
+ for ( iKey = 0; iKey < pTab.nCol; iKey++ )
1000
+ {
1001
+ Column pCol = pTab.aCol[iKey];
1002
+ if ( ( !String.IsNullOrEmpty(zKey )? 0==sqlite3StrICmp( pCol.zName, zKey ): pCol.isPrimKey !=0) )
1003
+ {
1004
+ if ( aChange[iKey] >= 0 ) return 1;
1005
+ if ( iKey == pTab.iPKey && chngRowid!=0 ) return 1;
1006
+ }
1007
+ }
1008
+ }
1009
+ }
1010
+ }
1011
+ }
1012
+ return 0;
1013
+ }
1014
+
1015
+ /*
1016
+ ** This function is called when an UPDATE or DELETE operation is being
1017
+ ** compiled on table pTab, which is the parent table of foreign-key pFKey.
1018
+ ** If the current operation is an UPDATE, then the pChanges parameter is
1019
+ ** passed a pointer to the list of columns being modified. If it is a
1020
+ ** DELETE, pChanges is passed a NULL pointer.
1021
+ **
1022
+ ** It returns a pointer to a Trigger structure containing a trigger
1023
+ ** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
1024
+ ** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
1025
+ ** returned (these actions require no special handling by the triggers
1026
+ ** sub-system, code for them is created by fkScanChildren()).
1027
+ **
1028
+ ** For example, if pFKey is the foreign key and pTab is table "p" in
1029
+ ** the following schema:
1030
+ **
1031
+ ** CREATE TABLE p(pk PRIMARY KEY);
1032
+ ** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE);
1033
+ **
1034
+ ** then the returned trigger structure is equivalent to:
1035
+ **
1036
+ ** CREATE TRIGGER ... DELETE ON p BEGIN
1037
+ ** DELETE FROM c WHERE ck = old.pk;
1038
+ ** END;
1039
+ **
1040
+ ** The returned pointer is cached as part of the foreign key object. It
1041
+ ** is eventually freed along with the rest of the foreign key object by
1042
+ ** sqlite3FkDelete().
1043
+ */
1044
+ static Trigger fkActionTrigger(
1045
+ Parse pParse, /* Parse context */
1046
+ Table pTab, /* Table being updated or deleted from */
1047
+ FKey pFKey, /* Foreign key to get action for */
1048
+ ExprList pChanges /* Change-list for UPDATE, NULL for DELETE */
1049
+ )
1050
+ {
1051
+ sqlite3 db = pParse.db; /* Database handle */
1052
+ int action; /* One of OE_None, OE_Cascade etc. */
1053
+ Trigger pTrigger; /* Trigger definition to return */
1054
+ int iAction = ( pChanges != null )?1:0; /* 1 for UPDATE, 0 for DELETE */
1055
+
1056
+ action = pFKey.aAction[iAction];
1057
+ pTrigger = pFKey.apTrigger[iAction];
1058
+
1059
+ if ( action != OE_None && null==pTrigger )
1060
+ {
1061
+ u8 enableLookaside; /* Copy of db.lookaside.bEnabled */
1062
+ string zFrom; /* Name of child table */
1063
+ int nFrom; /* Length in bytes of zFrom */
1064
+ Index pIdx = null; /* Parent key index for this FK */
1065
+ int[] aiCol = null; /* child table cols . parent key cols */
1066
+ TriggerStep pStep = null; /* First (only) step of trigger program */
1067
+ Expr pWhere = null; /* WHERE clause of trigger step */
1068
+ ExprList pList = null; /* Changes list if ON UPDATE CASCADE */
1069
+ Select pSelect = null; /* If RESTRICT, "SELECT RAISE(...)" */
1070
+ int i; /* Iterator variable */
1071
+ Expr pWhen = null; /* WHEN clause for the trigger */
1072
+
1073
+ if ( locateFkeyIndex( pParse, pTab, pFKey, ref pIdx, ref aiCol )!=0 ) return null;
1074
+ Debug.Assert( aiCol!=null || pFKey.nCol == 1 );
1075
+
1076
+ for ( i = 0; i < pFKey.nCol; i++ )
1077
+ {
1078
+ Token tOld = new Token( "old", 3 ); /* Literal "old" token */
1079
+ Token tNew = new Token( "new", 3 ); /* Literal "new" token */
1080
+ Token tFromCol = new Token(); /* Name of column in child table */
1081
+ Token tToCol = new Token(); /* Name of column in parent table */
1082
+ int iFromCol; /* Idx of column in child table */
1083
+ Expr pEq; /* tFromCol = OLD.tToCol */
1084
+
1085
+ iFromCol = aiCol!=null ? aiCol[i] : pFKey.aCol[0].iFrom;
1086
+ Debug.Assert( iFromCol >= 0 );
1087
+ tToCol.z = pIdx != null ? pTab.aCol[pIdx.aiColumn[i]].zName : "oid";
1088
+ tFromCol.z = pFKey.pFrom.aCol[iFromCol].zName;
1089
+
1090
+ tToCol.n = sqlite3Strlen30( tToCol.z );
1091
+ tFromCol.n = sqlite3Strlen30( tFromCol.z );
1092
+
1093
+ /* Create the expression "OLD.zToCol = zFromCol". It is important
1094
+ ** that the "OLD.zToCol" term is on the LHS of the = operator, so
1095
+ ** that the affinity and collation sequence associated with the
1096
+ ** parent table are used for the comparison. */
1097
+ pEq = sqlite3PExpr( pParse, TK_EQ,
1098
+ sqlite3PExpr( pParse, TK_DOT,
1099
+ sqlite3PExpr( pParse, TK_ID, null, null, tOld ),
1100
+ sqlite3PExpr( pParse, TK_ID, null, null, tToCol )
1101
+ , 0 ),
1102
+ sqlite3PExpr( pParse, TK_ID, null, null, tFromCol )
1103
+ , 0 );
1104
+ pWhere = sqlite3ExprAnd( db, pWhere, pEq );
1105
+
1106
+ /* For ON UPDATE, construct the next term of the WHEN clause.
1107
+ ** The final WHEN clause will be like this:
1108
+ **
1109
+ ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
1110
+ */
1111
+ if ( pChanges != null )
1112
+ {
1113
+ pEq = sqlite3PExpr( pParse, TK_IS,
1114
+ sqlite3PExpr( pParse, TK_DOT,
1115
+ sqlite3PExpr( pParse, TK_ID, null, null, tOld ),
1116
+ sqlite3PExpr( pParse, TK_ID, null, null, tToCol ),
1117
+ 0 ),
1118
+ sqlite3PExpr( pParse, TK_DOT,
1119
+ sqlite3PExpr( pParse, TK_ID, null, null, tNew ),
1120
+ sqlite3PExpr( pParse, TK_ID, null, null, tToCol ),
1121
+ 0 ),
1122
+ 0 );
1123
+ pWhen = sqlite3ExprAnd( db, pWhen, pEq );
1124
+ }
1125
+
1126
+ if ( action != OE_Restrict && ( action != OE_Cascade || pChanges!=null ) )
1127
+ {
1128
+ Expr pNew;
1129
+ if ( action == OE_Cascade )
1130
+ {
1131
+ pNew = sqlite3PExpr( pParse, TK_DOT,
1132
+ sqlite3PExpr( pParse, TK_ID, null, null, tNew ),
1133
+ sqlite3PExpr( pParse, TK_ID, null, null, tToCol )
1134
+ , 0 );
1135
+ }
1136
+ else if ( action == OE_SetDflt )
1137
+ {
1138
+ Expr pDflt = pFKey.pFrom.aCol[iFromCol].pDflt;
1139
+ if ( pDflt !=null)
1140
+ {
1141
+ pNew = sqlite3ExprDup( db, pDflt, 0 );
1142
+ }
1143
+ else
1144
+ {
1145
+ pNew = sqlite3PExpr( pParse, TK_NULL, 0, 0, 0 );
1146
+ }
1147
+ }
1148
+ else
1149
+ {
1150
+ pNew = sqlite3PExpr( pParse, TK_NULL, 0, 0, 0 );
1151
+ }
1152
+ pList = sqlite3ExprListAppend( pParse, pList, pNew );
1153
+ sqlite3ExprListSetName( pParse, pList, tFromCol, 0 );
1154
+ }
1155
+ }
1156
+ sqlite3DbFree( db, ref aiCol );
1157
+
1158
+ zFrom = pFKey.pFrom.zName;
1159
+ nFrom = sqlite3Strlen30( zFrom );
1160
+
1161
+ if ( action == OE_Restrict )
1162
+ {
1163
+ Token tFrom = new Token();
1164
+ Expr pRaise;
1165
+
1166
+ tFrom.z = zFrom;
1167
+ tFrom.n = nFrom;
1168
+ pRaise = sqlite3Expr( db, TK_RAISE, "foreign key constraint failed" );
1169
+ if ( pRaise != null )
1170
+ {
1171
+ pRaise.affinity = (char)OE_Abort;
1172
+ }
1173
+ pSelect = sqlite3SelectNew( pParse,
1174
+ sqlite3ExprListAppend( pParse, 0, pRaise ),
1175
+ sqlite3SrcListAppend( db, 0, tFrom, null ),
1176
+ pWhere,
1177
+ null, null, null, 0, null, null
1178
+ );
1179
+ pWhere = null;
1180
+ }
1181
+
1182
+ /* In the current implementation, pTab.dbMem==0 for all tables except
1183
+ ** for temporary tables used to describe subqueries. And temporary
1184
+ ** tables do not have foreign key constraints. Hence, pTab.dbMem
1185
+ ** should always be 0 there.
1186
+ */
1187
+ enableLookaside = db.lookaside.bEnabled;
1188
+ db.lookaside.bEnabled = 0;
1189
+
1190
+ pTrigger = new Trigger();
1191
+ //(Trigger*)sqlite3DbMallocZero( db,
1192
+ // sizeof( Trigger ) + /* struct Trigger */
1193
+ // sizeof( TriggerStep ) + /* Single step in trigger program */
1194
+ // nFrom + 1 /* Space for pStep.target.z */
1195
+ // );
1196
+ //if ( pTrigger )
1197
+ {
1198
+
1199
+ pStep = pTrigger.step_list = new TriggerStep() ;// = (TriggerStep)pTrigger[1];
1200
+ //pStep.target.z = pStep[1];
1201
+ pStep.target.n = nFrom;
1202
+ pStep.target.z = zFrom;// memcpy( (char*)pStep.target.z, zFrom, nFrom );
1203
+
1204
+ pStep.pWhere = sqlite3ExprDup( db, pWhere, EXPRDUP_REDUCE );
1205
+ pStep.pExprList = sqlite3ExprListDup( db, pList, EXPRDUP_REDUCE );
1206
+ pStep.pSelect = sqlite3SelectDup( db, pSelect, EXPRDUP_REDUCE );
1207
+ if ( pWhen!=null )
1208
+ {
1209
+ pWhen = sqlite3PExpr( pParse, TK_NOT, pWhen, 0, 0 );
1210
+ pTrigger.pWhen = sqlite3ExprDup( db, pWhen, EXPRDUP_REDUCE );
1211
+ }
1212
+ }
1213
+
1214
+ /* Re-enable the lookaside buffer, if it was disabled earlier. */
1215
+ db.lookaside.bEnabled = enableLookaside;
1216
+
1217
+ sqlite3ExprDelete( db, ref pWhere );
1218
+ sqlite3ExprDelete( db, ref pWhen );
1219
+ sqlite3ExprListDelete( db, ref pList );
1220
+ sqlite3SelectDelete( db, ref pSelect );
1221
+ //if ( db.mallocFailed == 1 )
1222
+ //{
1223
+ // fkTriggerDelete( db, pTrigger );
1224
+ // return 0;
1225
+ //}
1226
+
1227
+ switch ( action )
1228
+ {
1229
+ case OE_Restrict:
1230
+ pStep.op = TK_SELECT;
1231
+ break;
1232
+ case OE_Cascade:
1233
+ if ( null == pChanges )
1234
+ {
1235
+ pStep.op = TK_DELETE;
1236
+ break;
1237
+ }
1238
+ goto default;
1239
+ default:
1240
+ pStep.op = TK_UPDATE;
1241
+ break;
1242
+ }
1243
+ pStep.pTrig = pTrigger;
1244
+ pTrigger.pSchema = pTab.pSchema;
1245
+ pTrigger.pTabSchema = pTab.pSchema;
1246
+ pFKey.apTrigger[iAction] = pTrigger;
1247
+ pTrigger.op = (byte)( pChanges!=null ? TK_UPDATE : TK_DELETE );
1248
+ }
1249
+
1250
+ return pTrigger;
1251
+ }
1252
+
1253
+ /*
1254
+ ** This function is called when deleting or updating a row to implement
1255
+ ** any required CASCADE, SET NULL or SET DEFAULT actions.
1256
+ */
1257
+ static void sqlite3FkActions(
1258
+ Parse pParse, /* Parse context */
1259
+ Table pTab, /* Table being updated or deleted from */
1260
+ ExprList pChanges, /* Change-list for UPDATE, NULL for DELETE */
1261
+ int regOld /* Address of array containing old row */
1262
+ )
1263
+ {
1264
+ /* If foreign-key support is enabled, iterate through all FKs that
1265
+ ** refer to table pTab. If there is an action a6ssociated with the FK
1266
+ ** for this operation (either update or delete), invoke the associated
1267
+ ** trigger sub-program. */
1268
+ if (( pParse.db.flags & SQLITE_ForeignKeys )!=0)
1269
+ {
1270
+ FKey pFKey; /* Iterator variable */
1271
+ for ( pFKey = sqlite3FkReferences( pTab ); pFKey != null; pFKey = pFKey.pNextTo )
1272
+ {
1273
+ Trigger pAction = fkActionTrigger( pParse, pTab, pFKey, pChanges );
1274
+ if ( pAction != null )
1275
+ {
1276
+ sqlite3CodeRowTriggerDirect( pParse, pAction, pTab, regOld, OE_Abort, 0 );
1277
+ }
1278
+ }
1279
+ }
1280
+ }
1281
+
1282
+ #endif //* ifndef SQLITE_OMIT_TRIGGER */
1283
+
1284
+ /*
1285
+ ** Free all memory associated with foreign key definitions attached to
1286
+ ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
1287
+ ** hash table.
1288
+ */
1289
+ static void sqlite3FkDelete( Table pTab )
1290
+ {
1291
+ FKey pFKey; /* Iterator variable */
1292
+ FKey pNext; /* Copy of pFKey.pNextFrom */
1293
+
1294
+ for ( pFKey = pTab.pFKey; pFKey != null; pFKey = pNext )
1295
+ {
1296
+
1297
+ /* Remove the FK from the fkeyHash hash table. */
1298
+ if ( pFKey.pPrevTo != null )
1299
+ {
1300
+ pFKey.pPrevTo.pNextTo = pFKey.pNextTo;
1301
+ }
1302
+ else
1303
+ {
1304
+ FKey data = pFKey.pNextTo;
1305
+ string z = ( data != null ? pFKey.pNextTo.zTo : pFKey.zTo );
1306
+ sqlite3HashInsert( ref pTab.pSchema.fkeyHash, z, sqlite3Strlen30( z ), data );
1307
+ }
1308
+ if ( pFKey.pNextTo != null )
1309
+ {
1310
+ pFKey.pNextTo.pPrevTo = pFKey.pPrevTo;
1311
+ }
1312
+
1313
+ /* Delete any triggers created to implement actions for this FK. */
1314
+ #if !SQLITE_OMIT_TRIGGER
1315
+ fkTriggerDelete( pTab.dbMem, pFKey.apTrigger[0] );
1316
+ fkTriggerDelete( pTab.dbMem, pFKey.apTrigger[1] );
1317
+ #endif
1318
+
1319
+ /* EV: R-30323-21917 Each foreign key constraint in SQLite is
1320
+ ** classified as either immediate or deferred.
1321
+ */
1322
+ Debug.Assert( pFKey.isDeferred == 0 || pFKey.isDeferred == 1 );
1323
+
1324
+ pNext = pFKey.pNextFrom;
1325
+ sqlite3DbFree( pTab.dbMem, ref pFKey );
1326
+ }
1327
+ }
1328
+ #endif //* ifndef SQLITE_OMIT_FOREIGN_KEY */
1329
+ }
1330
+ }