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,4019 @@
1
+ using System;
2
+ using System.Diagnostics;
3
+ using System.Text;
4
+
5
+ using FILE = System.IO.TextWriter;
6
+ using i32 = System.Int32;
7
+ using i64 = System.Int64;
8
+ using u8 = System.Byte;
9
+ using u16 = System.UInt16;
10
+ using u32 = System.UInt32;
11
+ using u64 = System.UInt64;
12
+
13
+ using Pgno = System.UInt32;
14
+
15
+ #if !SQLITE_MAX_VARIABLE_NUMBER
16
+ using ynVar = System.Int16;
17
+ #else
18
+ using ynVar = System.Int32;
19
+ #endif
20
+
21
+ namespace Community.CsharpSqlite
22
+ {
23
+ using Op = Sqlite3.VdbeOp;
24
+ using sqlite3_stmt = Sqlite3.Vdbe;
25
+ using sqlite3_value = Sqlite3.Mem;
26
+
27
+ public partial class Sqlite3
28
+ {
29
+ /*
30
+ ** 2003 September 6
31
+ **
32
+ ** The author disclaims copyright to this source code. In place of
33
+ ** a legal notice, here is a blessing:
34
+ **
35
+ ** May you do good and not evil.
36
+ ** May you find forgiveness for yourself and forgive others.
37
+ ** May you share freely, never taking more than you give.
38
+ **
39
+ *************************************************************************
40
+ ** This file contains code used for creating, destroying, and populating
41
+ ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
42
+ ** to version 2.8.7, all this code was combined into the vdbe.c source file.
43
+ ** But that file was getting too big so this subroutines were split out.
44
+ *************************************************************************
45
+ ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
46
+ ** C#-SQLite is an independent reimplementation of the SQLite software library
47
+ **
48
+ ** SQLITE_SOURCE_ID: 2010-03-09 19:31:43 4ae453ea7be69018d8c16eb8dabe05617397dc4d
49
+ **
50
+ ** $Header$
51
+ *************************************************************************
52
+ */
53
+ //#include "sqliteInt.h"
54
+ //#include "vdbeInt.h"
55
+
56
+
57
+
58
+ /*
59
+ ** When debugging the code generator in a symbolic debugger, one can
60
+ ** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed
61
+ ** as they are added to the instruction stream.
62
+ */
63
+ #if SQLITE_DEBUG
64
+ static bool sqlite3VdbeAddopTrace = false;
65
+ #endif
66
+
67
+
68
+ /*
69
+ ** Create a new virtual database engine.
70
+ */
71
+ static Vdbe sqlite3VdbeCreate( sqlite3 db )
72
+ {
73
+ Vdbe p;
74
+ p = new Vdbe();// sqlite3DbMallocZero(db, Vdbe).Length;
75
+ if ( p == null ) return null;
76
+ p.db = db;
77
+ if ( db.pVdbe != null )
78
+ {
79
+ db.pVdbe.pPrev = p;
80
+ }
81
+ p.pNext = db.pVdbe;
82
+ p.pPrev = null;
83
+ db.pVdbe = p;
84
+ p.magic = VDBE_MAGIC_INIT;
85
+ return p;
86
+ }
87
+
88
+ /*
89
+ ** Remember the SQL string for a prepared statement.
90
+ */
91
+ static void sqlite3VdbeSetSql( Vdbe p, string z, int n, int isPrepareV2 )
92
+ {
93
+ Debug.Assert( isPrepareV2 == 1 || isPrepareV2 == 0 );
94
+ if ( p == null ) return;
95
+ #if SQLITE_OMIT_TRACE
96
+ if( 0==isPrepareV2 ) return;
97
+ #endif
98
+ Debug.Assert( p.zSql == "" );
99
+ p.zSql = z.Substring( 0, n );// sqlite3DbStrNDup(p.db, z, n);
100
+ p.isPrepareV2 = isPrepareV2 != 0;
101
+ }
102
+
103
+ /*
104
+ ** Return the SQL associated with a prepared statement
105
+ */
106
+ static string sqlite3_sql( sqlite3_stmt pStmt )
107
+ {
108
+ Vdbe p = (Vdbe)pStmt;
109
+ return ( p!=null && p.isPrepareV2 ? p.zSql : "" );
110
+ }
111
+
112
+ /*
113
+ ** Swap all content between two VDBE structures.
114
+ */
115
+ static void sqlite3VdbeSwap( Vdbe pA, Vdbe pB )
116
+ {
117
+ Vdbe tmp = new Vdbe(); Vdbe pTmp = new Vdbe();
118
+ string zTmp;
119
+ pA.CopyTo( tmp );
120
+ pB.CopyTo( pA );
121
+ tmp.CopyTo( pB );
122
+ pTmp = pA.pNext;
123
+ pA.pNext = pB.pNext;
124
+ pB.pNext = pTmp;
125
+ pTmp = pA.pPrev;
126
+ pA.pPrev = pB.pPrev;
127
+ pB.pPrev = pTmp;
128
+ zTmp = pA.zSql;
129
+ pA.zSql = pB.zSql;
130
+ pB.zSql = zTmp;
131
+ pB.isPrepareV2 = pA.isPrepareV2;
132
+ }
133
+
134
+ #if SQLITE_DEBUG
135
+ /*
136
+ ** Turn tracing on or off
137
+ */
138
+ static void sqlite3VdbeTrace( Vdbe p, FILE trace )
139
+ {
140
+ p.trace = trace;
141
+ }
142
+ #endif
143
+
144
+ /*
145
+ ** Resize the Vdbe.aOp array so that it is at least one op larger than
146
+ ** it was.
147
+ **
148
+ ** If an out-of-memory error occurs while resizing the array, return
149
+ ** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain
150
+ ** unchanged (this is so that any opcodes already allocated can be
151
+ ** correctly deallocated along with the rest of the Vdbe).
152
+ */
153
+ static int growOpArray( Vdbe p )
154
+ {
155
+ //VdbeOp pNew;
156
+ int nNew = ( p.nOpAlloc != 0 ? p.nOpAlloc * 2 : 1024 / 4 );//(int)(1024/sizeof(Op)));
157
+ // pNew = sqlite3DbRealloc( p.db, p.aOp, nNew * sizeof( Op ) );
158
+ //if (pNew != null)
159
+ //{
160
+ // p.nOpAlloc = sqlite3DbMallocSize(p.db, pNew)/sizeof(Op);
161
+ // p.aOp = pNew;
162
+ //}
163
+ p.nOpAlloc = nNew;
164
+ if ( p.aOp == null ) p.aOp = new VdbeOp[nNew]; else Array.Resize( ref p.aOp, nNew );
165
+ return ( p.aOp != null ? SQLITE_OK : SQLITE_NOMEM ); // return (pNew ? SQLITE_OK : SQLITE_NOMEM);
166
+ }
167
+
168
+ /*
169
+ ** Add a new instruction to the list of instructions current in the
170
+ ** VDBE. Return the address of the new instruction.
171
+ **
172
+ ** Parameters:
173
+ **
174
+ ** p Pointer to the VDBE
175
+ **
176
+ ** op The opcode for this instruction
177
+ **
178
+ ** p1, p2, p3 Operands
179
+ **
180
+ ** Use the sqlite3VdbeResolveLabel() function to fix an address and
181
+ ** the sqlite3VdbeChangeP4() function to change the value of the P4
182
+ ** operand.
183
+ */
184
+ static int sqlite3VdbeAddOp3( Vdbe p, int op, int p1, int p2, int p3 )
185
+ {
186
+ int i;
187
+ VdbeOp pOp;
188
+
189
+ i = p.nOp;
190
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
191
+ Debug.Assert( op > 0 && op < 0xff );
192
+ if ( p.nOpAlloc <= i )
193
+ {
194
+ if ( growOpArray( p ) != 0 )
195
+ {
196
+ return 1;
197
+ }
198
+ }
199
+ p.nOp++;
200
+ if ( p.aOp[i] == null ) p.aOp[i] = new VdbeOp();
201
+ pOp = p.aOp[i];
202
+ pOp.opcode = (u8)op;
203
+ pOp.p5 = 0;
204
+ pOp.p1 = p1;
205
+ pOp.p2 = p2;
206
+ pOp.p3 = p3;
207
+ pOp.p4.p = null;
208
+ pOp.p4type = P4_NOTUSED;
209
+ p.expired = false;
210
+ //sqlite3VdbePrintOp(null, i, p.aOp[i]);
211
+ #if SQLITE_DEBUG
212
+ pOp.zComment = null;
213
+ if ( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp( null, i, p.aOp[i] );
214
+ #endif
215
+ #if VDBE_PROFILE
216
+ pOp.cycles = 0;
217
+ pOp.cnt = 0;
218
+ #endif
219
+ return i;
220
+ }
221
+ static int sqlite3VdbeAddOp0( Vdbe p, int op )
222
+ {
223
+ return sqlite3VdbeAddOp3( p, op, 0, 0, 0 );
224
+ }
225
+ static int sqlite3VdbeAddOp1( Vdbe p, int op, int p1 )
226
+ {
227
+ return sqlite3VdbeAddOp3( p, op, p1, 0, 0 );
228
+ }
229
+ static int sqlite3VdbeAddOp2( Vdbe p, int op, int p1, bool b2 )
230
+ {
231
+ return sqlite3VdbeAddOp2( p, op, p1, (int)( b2 ? 1 : 0 ) );
232
+ }
233
+
234
+ static int sqlite3VdbeAddOp2( Vdbe p, int op, int p1, int p2 )
235
+ {
236
+ return sqlite3VdbeAddOp3( p, op, p1, p2, 0 );
237
+ }
238
+
239
+
240
+ /*
241
+ ** Add an opcode that includes the p4 value as a pointer.
242
+ */
243
+ //P4_INT32
244
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, i32 pP4, int p4type )
245
+ {
246
+ union_p4 _p4 = new union_p4(); _p4.i = pP4;
247
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
248
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
249
+ return addr;
250
+ }
251
+
252
+ //char
253
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, char pP4, int p4type )
254
+ {
255
+ union_p4 _p4 = new union_p4(); _p4.z = pP4.ToString();
256
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
257
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
258
+ return addr;
259
+ }
260
+
261
+ //String
262
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, string pP4, int p4type )
263
+ {
264
+ // Debug.Assert( pP4 != null );
265
+ union_p4 _p4 = new union_p4(); _p4.z = pP4;
266
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
267
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
268
+ return addr;
269
+ }
270
+
271
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, byte[] pP4, int p4type )
272
+ {
273
+ Debug.Assert( op == OP_Null || pP4 != null );
274
+ union_p4 _p4 = new union_p4(); _p4.z = Encoding.UTF8.GetString( pP4, 0, pP4.Length );
275
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
276
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
277
+ return addr;
278
+ }
279
+
280
+ //P4_INTARRAY
281
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, int[] pP4, int p4type )
282
+ {
283
+ Debug.Assert( pP4 != null );
284
+ union_p4 _p4 = new union_p4(); _p4.ai = pP4;
285
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
286
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
287
+ return addr;
288
+ }
289
+ //P4_INT64
290
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, i64 pP4, int p4type )
291
+ {
292
+ union_p4 _p4 = new union_p4(); _p4.pI64 = pP4;
293
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
294
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
295
+ return addr;
296
+ }
297
+
298
+ //DOUBLE (REAL)
299
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, double pP4, int p4type )
300
+ {
301
+ union_p4 _p4 = new union_p4(); _p4.pReal = pP4;
302
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
303
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
304
+ return addr;
305
+ }
306
+
307
+ //FUNCDEF
308
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, FuncDef pP4, int p4type )
309
+ {
310
+ union_p4 _p4 = new union_p4(); _p4.pFunc = pP4;
311
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
312
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
313
+ return addr;
314
+ }
315
+
316
+ //CollSeq
317
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, CollSeq pP4, int p4type )
318
+ {
319
+ union_p4 _p4 = new union_p4(); _p4.pColl = pP4;
320
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
321
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
322
+ return addr;
323
+ }
324
+
325
+ //KeyInfo
326
+ static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, KeyInfo pP4, int p4type )
327
+ {
328
+ union_p4 _p4 = new union_p4(); _p4.pKeyInfo = pP4;
329
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
330
+ sqlite3VdbeChangeP4( p, addr, _p4, p4type );
331
+ return addr;
332
+ }
333
+
334
+ // static int sqlite3VdbeAddOp4(
335
+ // Vdbe p, /* Add the opcode to this VM */
336
+ // int op, /* The new opcode */
337
+ // int p1, /* The P1 operand */
338
+ // int p2, /* The P2 operand */
339
+ // int p3, /* The P3 operand */
340
+ // union_p4 _p4, /* The P4 operand */
341
+ // int p4type /* P4 operand type */
342
+ //)
343
+ // {
344
+ // int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
345
+ // sqlite3VdbeChangeP4(p, addr, _p4, p4type);
346
+ // return addr;
347
+ // }
348
+
349
+ /*
350
+ ** Add an opcode that includes the p4 value as an integer.
351
+ */
352
+ static int sqlite3VdbeAddOp4Int(
353
+ Vdbe p, /* Add the opcode to this VM */
354
+ int op, /* The new opcode */
355
+ int p1, /* The P1 operand */
356
+ int p2, /* The P2 operand */
357
+ int p3, /* The P3 operand */
358
+ int p4 /* The P4 operand as an integer */
359
+ )
360
+ {
361
+ union_p4 _p4 = new union_p4(); _p4.i = p4;
362
+ int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 );
363
+ sqlite3VdbeChangeP4( p, addr, _p4, P4_INT32 );
364
+ return addr;
365
+ }
366
+ /*
367
+ ** Create a new symbolic label for an instruction that has yet to be
368
+ ** coded. The symbolic label is really just a negative number. The
369
+ ** label can be used as the P2 value of an operation. Later, when
370
+ ** the label is resolved to a specific address, the VDBE will scan
371
+ ** through its operation list and change all values of P2 which match
372
+ ** the label into the resolved address.
373
+ **
374
+ ** The VDBE knows that a P2 value is a label because labels are
375
+ ** always negative and P2 values are suppose to be non-negative.
376
+ ** Hence, a negative P2 value is a label that has yet to be resolved.
377
+ **
378
+ ** Zero is returned if a malloc() fails.
379
+ */
380
+ static int sqlite3VdbeMakeLabel( Vdbe p )
381
+ {
382
+ int i;
383
+ i = p.nLabel++;
384
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
385
+ if ( i >= p.nLabelAlloc )
386
+ {
387
+ int n = p.nLabelAlloc == 0 ? 15 : p.nLabelAlloc * 2 + 5;
388
+ if (p.aLabel == null) p.aLabel = sqlite3Malloc(p.aLabel, n);
389
+ else Array.Resize(ref p.aLabel, n);
390
+ //p.aLabel = sqlite3DbReallocOrFree(p.db, p.aLabel,
391
+ // n*sizeof(p.aLabel[0]));
392
+ p.nLabelAlloc = p.aLabel.Length;//sqlite3DbMallocSize(p.db, p.aLabel)/sizeof(p.aLabel[0]);
393
+ }
394
+ if ( p.aLabel != null )
395
+ {
396
+ p.aLabel[i] = -1;
397
+ }
398
+ return -1 - i;
399
+ }
400
+
401
+ /*
402
+ ** Resolve label "x" to be the address of the next instruction to
403
+ ** be inserted. The parameter "x" must have been obtained from
404
+ ** a prior call to sqlite3VdbeMakeLabel().
405
+ */
406
+ static void sqlite3VdbeResolveLabel( Vdbe p, int x )
407
+ {
408
+ int j = -1 - x;
409
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
410
+ Debug.Assert( j >= 0 && j < p.nLabel );
411
+ if ( p.aLabel != null )
412
+ {
413
+ p.aLabel[j] = p.nOp;
414
+ }
415
+ }
416
+
417
+ /*
418
+ ** Mark the VDBE as one that can only be run one time.
419
+ */
420
+ static void sqlite3VdbeRunOnlyOnce(Vdbe p)
421
+ {
422
+ p.runOnlyOnce = 1;
423
+ }
424
+
425
+ #if SQLITE_DEBUG //* sqlite3AssertMayAbort() logic */
426
+
427
+ /*
428
+ ** The following type and function are used to iterate through all opcodes
429
+ ** in a Vdbe main program and each of the sub-programs (triggers) it may
430
+ ** invoke directly or indirectly. It should be used as follows:
431
+ **
432
+ ** Op *pOp;
433
+ ** VdbeOpIter sIter;
434
+ **
435
+ ** memset(&sIter, 0, sizeof(sIter));
436
+ ** sIter.v = v; // v is of type Vdbe*
437
+ ** while( (pOp = opIterNext(&sIter)) ){
438
+ ** // Do something with pOp
439
+ ** }
440
+ ** sqlite3DbFree(v->db, sIter.apSub);
441
+ **
442
+ */
443
+ //typedef struct VdbeOpIter VdbeOpIter;
444
+ public class VdbeOpIter
445
+ {
446
+ public Vdbe v; /* Vdbe to iterate through the opcodes of */
447
+ public SubProgram[] apSub; /* Array of subprograms */
448
+ public int nSub; /* Number of entries in apSub */
449
+ public int iAddr; /* Address of next instruction to return */
450
+ public int iSub; /* 0 = main program, 1 = first sub-program etc. */
451
+ };
452
+
453
+ static Op opIterNext( VdbeOpIter p )
454
+ {
455
+ Vdbe v = p.v;
456
+ Op pRet = null;
457
+ Op[] aOp;
458
+ int nOp;
459
+
460
+ if ( p.iSub <= p.nSub )
461
+ {
462
+
463
+ if ( p.iSub == 0 )
464
+ {
465
+ aOp = v.aOp;
466
+ nOp = v.nOp;
467
+ }
468
+ else
469
+ {
470
+ aOp = p.apSub[p.iSub - 1].aOp;
471
+ nOp = p.apSub[p.iSub - 1].nOp;
472
+ }
473
+ Debug.Assert( p.iAddr < nOp );
474
+
475
+ pRet = aOp[p.iAddr];
476
+ p.iAddr++;
477
+ if ( p.iAddr == nOp )
478
+ {
479
+ p.iSub++;
480
+ p.iAddr = 0;
481
+ }
482
+
483
+ if ( pRet.p4type == P4_SUBPROGRAM )
484
+ {
485
+ //int nByte = p.nSub + 1 ) * sizeof( SubProgram* );
486
+ int j;
487
+ for ( j = 0; j < p.nSub; j++ )
488
+ {
489
+ if ( p.apSub[j] == pRet.p4.pProgram ) break;
490
+ }
491
+ if ( j == p.nSub )
492
+ {
493
+ Array.Resize( ref p.apSub, p.nSub + 1 );/// sqlite3DbReallocOrFree( v.db, p.apSub, nByte );
494
+ //if( null==p.apSub ){
495
+ // pRet = null;
496
+ //}else{
497
+ p.apSub[p.nSub++] = pRet.p4.pProgram;
498
+ //}
499
+ }
500
+ }
501
+ }
502
+
503
+ return pRet;
504
+ }
505
+
506
+ /*
507
+ ** Check if the program stored in the VM associated with pParse may
508
+ ** throw an ABORT exception (causing the statement, but not entire transaction
509
+ ** to be rolled back). This condition is true if the main program or any
510
+ ** sub-programs contains any of the following:
511
+ **
512
+ ** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
513
+ ** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
514
+ ** * OP_Destroy
515
+ ** * OP_VUpdate
516
+ ** * OP_VRename
517
+ ** * OP_FkCounter with P2==0 (immediate foreign key constraint)
518
+ **
519
+ ** Then check that the value of Parse.mayAbort is true if an
520
+ ** ABORT may be thrown, or false otherwise. Return true if it does
521
+ ** match, or false otherwise. This function is intended to be used as
522
+ ** part of an assert statement in the compiler. Similar to:
523
+ **
524
+ ** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) );
525
+ */
526
+ static int sqlite3VdbeAssertMayAbort( Vdbe v, int mayAbort )
527
+ {
528
+ int hasAbort = 0;
529
+ Op pOp;
530
+ VdbeOpIter sIter;
531
+ sIter = new VdbeOpIter();// memset( &sIter, 0, sizeof( sIter ) );
532
+ sIter.v = v;
533
+
534
+ while ( ( pOp = opIterNext( sIter ) ) != null )
535
+ {
536
+ int opcode = pOp.opcode;
537
+ if ( opcode == OP_Destroy || opcode == OP_VUpdate || opcode == OP_VRename
538
+ #if !SQLITE_OMIT_FOREIGN_KEY
539
+ || ( opcode == OP_FkCounter && pOp.p1 == 0 && pOp.p2 == 1 )
540
+ #endif
541
+ || ( ( opcode == OP_Halt || opcode == OP_HaltIfNull )
542
+ && ( pOp.p1 == SQLITE_CONSTRAINT && pOp.p2 == OE_Abort ) )
543
+ )
544
+ {
545
+ hasAbort = 1;
546
+ break;
547
+ }
548
+ }
549
+ sIter.apSub = null;// sqlite3DbFree( v.db, sIter.apSub );
550
+
551
+ /* Return true if hasAbort==mayAbort. Or if a malloc failure occured.
552
+ ** If malloc failed, then the while() loop above may not have iterated
553
+ ** through all opcodes and hasAbort may be set incorrectly. Return
554
+ ** true for this case to prevent the assert() in the callers frame
555
+ ** from failing. */
556
+ return ( hasAbort == mayAbort ) ? 1 : 0;//v.db.mallocFailed !=0|| hasAbort==mayAbort );
557
+ }
558
+ #endif //* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
559
+
560
+ /*
561
+ ** Loop through the program looking for P2 values that are negative
562
+ ** on jump instructions. Each such value is a label. Resolve the
563
+ ** label by setting the P2 value to its correct non-zero value.
564
+ **
565
+ ** This routine is called once after all opcodes have been inserted.
566
+ **
567
+ ** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument
568
+ ** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by
569
+ ** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array.
570
+ **
571
+ ** The Op.opflags field is set on all opcodes.
572
+ */
573
+ static void resolveP2Values( Vdbe p, ref int pMaxFuncArgs )
574
+ {
575
+ int i;
576
+ int nMaxArgs = pMaxFuncArgs;
577
+ Op pOp;
578
+ int[] aLabel = p.aLabel;
579
+ p.readOnly = true;
580
+ for ( i = 0; i < p.nOp; i++ )// for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++)
581
+ {
582
+ pOp = p.aOp[i];
583
+ u8 opcode = pOp.opcode;
584
+
585
+ pOp.opflags = (u8)sqlite3OpcodeProperty[opcode];
586
+ if ( opcode == OP_Function || opcode == OP_AggStep )
587
+ {
588
+ if ( pOp.p5 > nMaxArgs ) nMaxArgs = pOp.p5;
589
+ }
590
+ else if ( opcode == OP_Transaction && pOp.p2 != 0 )
591
+ {
592
+ p.readOnly = false;
593
+ #if ! SQLITE_OMIT_VIRTUALTABLE
594
+ }else if( opcode==OP_VUpdate ){
595
+ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
596
+ }else if( opcode==OP_VFilter ){
597
+ int n;
598
+ Debug.Assert( i < p.nOp - 3 );
599
+ Debug.Assert( pOp[-1].opcode==OP_Integer );
600
+ n = pOp[-1].p1;
601
+ if( n>nMaxArgs ) nMaxArgs = n;
602
+ #endif
603
+ }
604
+
605
+ if ( ( pOp.opflags & OPFLG_JUMP ) != 0 && pOp.p2 < 0 )
606
+ {
607
+ Debug.Assert( -1 - pOp.p2 < p.nLabel );
608
+ pOp.p2 = aLabel[-1 - pOp.p2];
609
+ }
610
+ }
611
+ sqlite3DbFree( p.db, ref p.aLabel );
612
+
613
+ pMaxFuncArgs = nMaxArgs;
614
+ }
615
+
616
+ /*
617
+ ** Return the address of the next instruction to be inserted.
618
+ */
619
+ static int sqlite3VdbeCurrentAddr( Vdbe p )
620
+ {
621
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
622
+ return p.nOp;
623
+ }
624
+
625
+ /*
626
+ ** This function returns a pointer to the array of opcodes associated with
627
+ ** the Vdbe passed as the first argument. It is the callers responsibility
628
+ ** to arrange for the returned array to be eventually freed using the
629
+ ** vdbeFreeOpArray() function.
630
+ **
631
+ ** Before returning, *pnOp is set to the number of entries in the returned
632
+ ** array. Also, *pnMaxArg is set to the larger of its current value and
633
+ ** the number of entries in the Vdbe.apArg[] array required to execute the
634
+ ** returned program.
635
+ */
636
+ static VdbeOp[] sqlite3VdbeTakeOpArray( Vdbe p, ref int pnOp, ref int pnMaxArg )
637
+ {
638
+ VdbeOp[] aOp = p.aOp;
639
+ Debug.Assert( aOp != null );// && 0==p.db.mallocFailed );
640
+
641
+ /* Check that sqlite3VdbeUsesBtree() was not called on this VM */
642
+ Debug.Assert( p.aMutex == null || p.aMutex.nMutex == 0 );
643
+
644
+ resolveP2Values( p, ref pnMaxArg );
645
+ pnOp = p.nOp;
646
+ p.aOp = null;
647
+ return aOp;
648
+ }
649
+
650
+ /*
651
+ ** Add a whole list of operations to the operation stack. Return the
652
+ ** address of the first operation added.
653
+ */
654
+ static int sqlite3VdbeAddOpList( Vdbe p, int nOp, VdbeOpList[] aOp )
655
+ {
656
+ int addr;
657
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
658
+ if ( p.nOp + nOp > p.nOpAlloc && growOpArray( p ) != 0 )
659
+ {
660
+ return 0;
661
+ }
662
+ addr = p.nOp;
663
+ if ( ALWAYS( nOp > 0 ) )
664
+ {
665
+ int i;
666
+ VdbeOpList pIn;
667
+ for ( i = 0; i < nOp; i++ )
668
+ {
669
+ pIn = aOp[i];
670
+ int p2 = pIn.p2;
671
+ if ( p.aOp[i + addr] == null ) p.aOp[i + addr] = new VdbeOp();
672
+ VdbeOp pOut = p.aOp[i + addr];
673
+ pOut.opcode = pIn.opcode;
674
+ pOut.p1 = pIn.p1;
675
+ if ( p2 < 0 && ( sqlite3OpcodeProperty[pOut.opcode] & OPFLG_JUMP ) != 0 )
676
+ {
677
+ pOut.p2 = addr + ( -1 - p2 );// ADDR(p2);
678
+ }
679
+ else
680
+ {
681
+ pOut.p2 = p2;
682
+ }
683
+ pOut.p3 = pIn.p3;
684
+ pOut.p4type = P4_NOTUSED;
685
+ pOut.p4.p = null;
686
+ pOut.p5 = 0;
687
+ #if SQLITE_DEBUG
688
+ pOut.zComment = null;
689
+ if ( sqlite3VdbeAddopTrace )
690
+ {
691
+ sqlite3VdbePrintOp( null, i + addr, p.aOp[i + addr] );
692
+ }
693
+ #endif
694
+ }
695
+ p.nOp += nOp;
696
+ }
697
+ return addr;
698
+ }
699
+
700
+ /*
701
+ ** Change the value of the P1 operand for a specific instruction.
702
+ ** This routine is useful when a large program is loaded from a
703
+ ** static array using sqlite3VdbeAddOpList but we want to make a
704
+ ** few minor changes to the program.
705
+ */
706
+ static void sqlite3VdbeChangeP1( Vdbe p, int addr, int val )
707
+ {
708
+ Debug.Assert( p != null );
709
+ Debug.Assert( addr >= 0 );
710
+ if ( p.nOp > addr )
711
+ {
712
+ p.aOp[addr].p1 = val;
713
+ }
714
+ }
715
+
716
+ /*
717
+ ** Change the value of the P2 operand for a specific instruction.
718
+ ** This routine is useful for setting a jump destination.
719
+ */
720
+ static void sqlite3VdbeChangeP2( Vdbe p, int addr, int val )
721
+ {
722
+ Debug.Assert( p != null );
723
+ Debug.Assert( addr >= 0 );
724
+ if ( p.nOp > addr )
725
+ {
726
+ p.aOp[addr].p2 = val;
727
+ }
728
+ }
729
+
730
+ /*
731
+ ** Change the value of the P3 operand for a specific instruction.
732
+ */
733
+ static void sqlite3VdbeChangeP3( Vdbe p, int addr, int val )
734
+ {
735
+ Debug.Assert( p != null );
736
+ Debug.Assert( addr >= 0 );
737
+ if ( p.nOp > addr )
738
+ {
739
+ p.aOp[addr].p3 = val;
740
+ }
741
+ }
742
+
743
+ /*
744
+ ** Change the value of the P5 operand for the most recently
745
+ ** added operation.
746
+ */
747
+ static void sqlite3VdbeChangeP5( Vdbe p, u8 val )
748
+ {
749
+ Debug.Assert( p != null );
750
+ if ( p.aOp != null )
751
+ {
752
+ Debug.Assert( p.nOp > 0 );
753
+ p.aOp[p.nOp - 1].p5 = val;
754
+ }
755
+ }
756
+
757
+ /*
758
+ ** Change the P2 operand of instruction addr so that it points to
759
+ ** the address of the next instruction to be coded.
760
+ */
761
+ static void sqlite3VdbeJumpHere( Vdbe p, int addr )
762
+ {
763
+ sqlite3VdbeChangeP2( p, addr, p.nOp );
764
+ }
765
+
766
+
767
+ /*
768
+ ** If the input FuncDef structure is ephemeral, then free it. If
769
+ ** the FuncDef is not ephermal, then do nothing.
770
+ */
771
+ static void freeEphemeralFunction( sqlite3 db, FuncDef pDef )
772
+ {
773
+ if ( ALWAYS( pDef ) && ( pDef.flags & SQLITE_FUNC_EPHEM ) != 0 )
774
+ {
775
+ pDef = null;
776
+ sqlite3DbFree( db, ref pDef );
777
+ }
778
+ }
779
+
780
+ /*
781
+ ** Delete a P4 value if necessary.
782
+ */
783
+ static void freeP4( sqlite3 db, int p4type, object p4 )
784
+ {
785
+ if ( p4 != null )
786
+ {
787
+ switch ( p4type )
788
+ {
789
+ case P4_REAL:
790
+ case P4_INT64:
791
+ case P4_MPRINTF:
792
+ case P4_DYNAMIC:
793
+ case P4_KEYINFO:
794
+ case P4_INTARRAY:
795
+ case P4_KEYINFO_HANDOFF:
796
+ {
797
+ sqlite3DbFree( db, ref p4 );
798
+ break;
799
+ }
800
+ case P4_VDBEFUNC:
801
+ {
802
+ VdbeFunc pVdbeFunc = (VdbeFunc)p4;
803
+ freeEphemeralFunction( db, pVdbeFunc.pFunc );
804
+ sqlite3VdbeDeleteAuxData( pVdbeFunc, 0 );
805
+ sqlite3DbFree( db, ref pVdbeFunc );
806
+ break;
807
+ }
808
+ case P4_FUNCDEF:
809
+ {
810
+ freeEphemeralFunction( db, (FuncDef)p4 );
811
+ break;
812
+ }
813
+ case P4_MEM:
814
+ {
815
+ p4 = null;// sqlite3ValueFree(ref (sqlite3_value)p4);
816
+ break;
817
+ }
818
+ case P4_VTAB:
819
+ {
820
+ sqlite3VtabUnlock( (VTable)p4 );
821
+ break;
822
+ }
823
+ case P4_SUBPROGRAM:
824
+ {
825
+ sqlite3VdbeProgramDelete( db, (SubProgram)p4, 1 );
826
+ break;
827
+ }
828
+ }
829
+ }
830
+ }
831
+
832
+ /*
833
+ ** Free the space allocated for aOp and any p4 values allocated for the
834
+ ** opcodes contained within. If aOp is not NULL it is assumed to contain
835
+ ** nOp entries.
836
+ */
837
+ static void vdbeFreeOpArray( sqlite3 db, ref Op[] aOp, int nOp )
838
+ {
839
+ if ( aOp != null )
840
+ {
841
+ //Op pOp;
842
+ // for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
843
+ // freeP4(db, pOp.p4type, pOp.p4.p);
844
+ //#if SQLITE_DEBUG
845
+ // sqlite3DbFree(db, ref pOp.zComment);
846
+ //#endif
847
+ // }
848
+ // }
849
+ // sqlite3DbFree(db, aOp);
850
+ aOp = null;
851
+ }
852
+ }
853
+
854
+ /*
855
+ ** Decrement the ref-count on the SubProgram structure passed as the
856
+ ** second argument. If the ref-count reaches zero, free the structure.
857
+ **
858
+ ** The array of VDBE opcodes stored as SubProgram.aOp is freed if
859
+ ** either the ref-count reaches zero or parameter freeop is non-zero.
860
+ **
861
+ ** Since the array of opcodes pointed to by SubProgram.aOp may directly
862
+ ** or indirectly contain a reference to the SubProgram structure itself.
863
+ ** By passing a non-zero freeop parameter, the caller may ensure that all
864
+ ** SubProgram structures and their aOp arrays are freed, even when there
865
+ ** are such circular references.
866
+ */
867
+ static void sqlite3VdbeProgramDelete( sqlite3 db, SubProgram p, int freeop )
868
+ {
869
+ if ( p != null )
870
+ {
871
+ Debug.Assert( p.nRef > 0 );
872
+ if ( freeop != 0 || p.nRef == 1 )
873
+ {
874
+ Op[] aOp = p.aOp;
875
+ p.aOp = null;
876
+ vdbeFreeOpArray( db, ref aOp, p.nOp );
877
+ p.nOp = 0;
878
+ }
879
+ p.nRef--;
880
+ if ( p.nRef == 0 )
881
+ {
882
+ p = null; sqlite3DbFree( db, ref p );
883
+ }
884
+ }
885
+ }
886
+ /*
887
+ ** Change N opcodes starting at addr to No-ops.
888
+ */
889
+ static void sqlite3VdbeChangeToNoop( Vdbe p, int addr, int N )
890
+ {
891
+ if ( p.aOp != null )
892
+ {
893
+ sqlite3 db = p.db;
894
+ while ( N-- > 0 )
895
+ {
896
+ VdbeOp pOp = p.aOp[addr + N];
897
+ freeP4( db, pOp.p4type, pOp.p4.p );
898
+ pOp = p.aOp[addr + N] = new VdbeOp();//memset(pOp, 0, sizeof(pOp[0]));
899
+ pOp.opcode = OP_Noop;
900
+ //pOp++;
901
+ }
902
+ }
903
+ }
904
+
905
+ /*
906
+ ** Change the value of the P4 operand for a specific instruction.
907
+ ** This routine is useful when a large program is loaded from a
908
+ ** static array using sqlite3VdbeAddOpList but we want to make a
909
+ ** few minor changes to the program.
910
+ **
911
+ ** If n>=0 then the P4 operand is dynamic, meaning that a copy of
912
+ ** the string is made into memory obtained from sqlite3Malloc().
913
+ ** A value of n==0 means copy bytes of zP4 up to and including the
914
+ ** first null byte. If n>0 then copy n+1 bytes of zP4.
915
+ **
916
+ ** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
917
+ ** A copy is made of the KeyInfo structure into memory obtained from
918
+ ** sqlite3Malloc, to be freed when the Vdbe is finalized.
919
+ ** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
920
+ ** stored in memory that the caller has obtained from sqlite3Malloc. The
921
+ ** caller should not free the allocation, it will be freed when the Vdbe is
922
+ ** finalized.
923
+ **
924
+ ** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
925
+ ** to a string or structure that is guaranteed to exist for the lifetime of
926
+ ** the Vdbe. In these cases we can just copy the pointer.
927
+ **
928
+ ** If addr<0 then change P4 on the most recently inserted instruction.
929
+ */
930
+
931
+ //P4_COLLSEQ
932
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, CollSeq pColl, int n )
933
+ {
934
+ union_p4 _p4 = new union_p4(); _p4.pColl = pColl;
935
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
936
+ }
937
+ //P4_FUNCDEF
938
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, FuncDef pFunc, int n )
939
+ {
940
+ union_p4 _p4 = new union_p4(); _p4.pFunc = pFunc;
941
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
942
+ }
943
+ //P4_INT32
944
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, int i32n, int n )
945
+ {
946
+ union_p4 _p4 = new union_p4(); _p4.i = i32n;
947
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
948
+ }
949
+
950
+ //P4_KEYINFO
951
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, KeyInfo pKeyInfo, int n )
952
+ {
953
+ union_p4 _p4 = new union_p4(); _p4.pKeyInfo = pKeyInfo;
954
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
955
+ }
956
+ //CHAR
957
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, char c, int n )
958
+ {
959
+ union_p4 _p4 = new union_p4(); _p4.z = c.ToString();
960
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
961
+ }
962
+
963
+ //MEM
964
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, Mem m, int n )
965
+ {
966
+ union_p4 _p4 = new union_p4(); _p4.pMem = m;
967
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
968
+ }
969
+
970
+ //STRING
971
+
972
+ //STRING + Type
973
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, string z, dxDel P4_Type )
974
+ {
975
+ union_p4 _p4 = new union_p4();
976
+ _p4.z = z;
977
+ sqlite3VdbeChangeP4( p, addr, _p4, P4_DYNAMIC );
978
+ }
979
+
980
+ //SUBPROGRAM
981
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, SubProgram pProgram, int n )
982
+ {
983
+ union_p4 _p4 = new union_p4();
984
+ _p4.pProgram = pProgram;
985
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
986
+ }
987
+
988
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, string z, int n )
989
+ {
990
+ union_p4 _p4 = new union_p4();
991
+ if ( n > 0 && n <= z.Length ) _p4.z = z.Substring( 0, n );
992
+ else _p4.z = z;
993
+ sqlite3VdbeChangeP4( p, addr, _p4, n );
994
+ }
995
+
996
+ static void sqlite3VdbeChangeP4( Vdbe p, int addr, union_p4 _p4, int n )
997
+ {
998
+ Op pOp;
999
+ sqlite3 db;
1000
+ Debug.Assert( p != null );
1001
+ db = p.db;
1002
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
1003
+ if ( p.aOp == null /*|| db.mallocFailed != 0 */)
1004
+ {
1005
+ if ( n != P4_KEYINFO && n != P4_VTAB )
1006
+ {
1007
+ freeP4( db, n, _p4 );
1008
+ }
1009
+ return;
1010
+ }
1011
+ Debug.Assert( p.nOp > 0 );
1012
+ Debug.Assert( addr < p.nOp );
1013
+ if ( addr < 0 )
1014
+ {
1015
+ addr = p.nOp - 1;
1016
+ }
1017
+ pOp = p.aOp[addr];
1018
+ freeP4( db, pOp.p4type, pOp.p4.p );
1019
+ pOp.p4.p = null;
1020
+ if ( n == P4_INT32 )
1021
+ {
1022
+ /* Note: this cast is safe, because the origin data point was an int
1023
+ ** that was cast to a (const char *). */
1024
+ pOp.p4.i = _p4.i; // SQLITE_PTR_TO_INT(zP4);
1025
+ pOp.p4type = P4_INT32;
1026
+ }
1027
+ else if ( n == P4_INT64 )
1028
+ {
1029
+ pOp.p4.pI64 = _p4.pI64;
1030
+ pOp.p4type = n;
1031
+ }
1032
+ else if ( n == P4_REAL )
1033
+ {
1034
+ pOp.p4.pReal = _p4.pReal;
1035
+ pOp.p4type = n;
1036
+ }
1037
+ else if ( _p4 == null )
1038
+ {
1039
+ pOp.p4.p = null;
1040
+ pOp.p4type = P4_NOTUSED;
1041
+ }
1042
+ else if ( n == P4_KEYINFO )
1043
+ {
1044
+ KeyInfo pKeyInfo;
1045
+ int nField, nByte;
1046
+
1047
+ nField = _p4.pKeyInfo.nField;
1048
+ //nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo.aColl[0]) + nField;
1049
+ pKeyInfo = new KeyInfo();//sqlite3Malloc( nByte );
1050
+ pOp.p4.pKeyInfo = pKeyInfo;
1051
+ if ( pKeyInfo != null )
1052
+ {
1053
+ //u8 *aSortOrder;
1054
+ //memcpy(pKeyInfo, zP4, nByte);
1055
+ //aSortOrder = pKeyInfo.aSortOrder;
1056
+ //if( aSortOrder ){
1057
+ // pKeyInfo.aSortOrder = (unsigned char*)&pKeyInfo.aColl[nField];
1058
+ // memcpy(pKeyInfo.aSortOrder, aSortOrder, nField);
1059
+ //}
1060
+ pKeyInfo = _p4.pKeyInfo.Copy();
1061
+ pOp.p4type = P4_KEYINFO;
1062
+ }
1063
+ else
1064
+ {
1065
+ //p.db.mallocFailed = 1;
1066
+ pOp.p4type = P4_NOTUSED;
1067
+ }
1068
+ pOp.p4.pKeyInfo = _p4.pKeyInfo;
1069
+ pOp.p4type = P4_KEYINFO;
1070
+ }
1071
+ else if ( n == P4_KEYINFO_HANDOFF || n == P4_KEYINFO_STATIC )
1072
+ {
1073
+ pOp.p4.pKeyInfo = _p4.pKeyInfo;
1074
+ pOp.p4type = P4_KEYINFO;
1075
+ }
1076
+ else if ( n == P4_FUNCDEF )
1077
+ {
1078
+ pOp.p4.pFunc = _p4.pFunc;
1079
+ pOp.p4type = P4_FUNCDEF;
1080
+ }
1081
+ else if ( n == P4_COLLSEQ )
1082
+ {
1083
+ pOp.p4.pColl = _p4.pColl;
1084
+ pOp.p4type = P4_COLLSEQ;
1085
+ }
1086
+ else if ( n == P4_DYNAMIC || n == P4_STATIC )
1087
+ {
1088
+ pOp.p4.z = _p4.z;
1089
+ pOp.p4type = P4_DYNAMIC;
1090
+ }
1091
+ else if ( n == P4_MEM )
1092
+ {
1093
+ pOp.p4.pMem = _p4.pMem;
1094
+ pOp.p4type = P4_MEM;
1095
+ }
1096
+ else if ( n == P4_INTARRAY )
1097
+ {
1098
+ pOp.p4.ai = _p4.ai;
1099
+ pOp.p4type = P4_INTARRAY;
1100
+ }
1101
+ else if ( n == P4_SUBPROGRAM )
1102
+ {
1103
+ pOp.p4.pProgram = _p4.pProgram;
1104
+ pOp.p4type = P4_SUBPROGRAM;
1105
+ }
1106
+ else if ( n == P4_VTAB )
1107
+ {
1108
+ pOp.p4.pVtab = _p4.pVtab;
1109
+ pOp.p4type = P4_VTAB;
1110
+ sqlite3VtabLock( _p4.pVtab );
1111
+ Debug.Assert( ( _p4.pVtab ).db == p.db );
1112
+ }
1113
+ else if ( n < 0 )
1114
+ {
1115
+ pOp.p4.p = _p4.p;
1116
+ pOp.p4type = n;
1117
+ }
1118
+ else
1119
+ {
1120
+ //if (n == 0) n = n = sqlite3Strlen30(zP4);
1121
+ pOp.p4.z = _p4.z;// sqlite3DbStrNDup(p.db, zP4, n);
1122
+ pOp.p4type = P4_DYNAMIC;
1123
+ }
1124
+ }
1125
+
1126
+ #if !NDEBUG
1127
+ /*
1128
+ ** Change the comment on the the most recently coded instruction. Or
1129
+ ** insert a No-op and add the comment to that new instruction. This
1130
+ ** makes the code easier to read during debugging. None of this happens
1131
+ ** in a production build.
1132
+ */
1133
+ static void sqlite3VdbeComment( Vdbe p, string zFormat, params object[] ap )
1134
+ {
1135
+ // va_list ap;
1136
+ if ( null == p ) return;
1137
+ Debug.Assert( p.nOp > 0 || p.aOp == null );
1138
+ Debug.Assert( p.aOp == null || p.aOp[p.nOp - 1].zComment == null /* || p.db.mallocFailed != 0 */);
1139
+ if ( p.nOp != 0 )
1140
+ {
1141
+ string pz;// = p.aOp[p.nOp-1].zComment;
1142
+ va_start( ap, zFormat );
1143
+ //sqlite3DbFree(db, ref pz);
1144
+ pz = sqlite3VMPrintf( p.db, zFormat, ap );
1145
+ p.aOp[p.nOp - 1].zComment = pz;
1146
+ va_end( ap );
1147
+ }
1148
+ }
1149
+ static void sqlite3VdbeNoopComment( Vdbe p, string zFormat, params object[] ap )
1150
+ {
1151
+ //va_list ap;
1152
+ if ( null == p ) return;
1153
+ sqlite3VdbeAddOp0( p, OP_Noop );
1154
+ Debug.Assert( p.nOp > 0 || p.aOp == null );
1155
+ Debug.Assert( p.aOp == null || p.aOp[p.nOp - 1].zComment == null /* || p.db.mallocFailed != 0 */);
1156
+ if ( p.nOp != 0 )
1157
+ {
1158
+ string pz; // = p.aOp[p.nOp - 1].zComment;
1159
+ va_start( ap, zFormat );
1160
+ //sqlite3DbFree(db,ref pz);
1161
+ pz = sqlite3VMPrintf( p.db, zFormat, ap );
1162
+ p.aOp[p.nOp - 1].zComment = pz;
1163
+ va_end( ap );
1164
+ }
1165
+ }
1166
+ #else
1167
+ #endif //* NDEBUG */
1168
+
1169
+
1170
+ /*
1171
+ ** Return the opcode for a given address. If the address is -1, then
1172
+ ** return the most recently inserted opcode.
1173
+ **
1174
+ ** If a memory allocation error has occurred prior to the calling of this
1175
+ ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
1176
+ ** is readable and writable, but it has no effect. The return of a dummy
1177
+ ** opcode allows the call to continue functioning after a OOM fault without
1178
+ ** having to check to see if the return from this routine is a valid pointer.
1179
+ **
1180
+ ** About the #if SQLITE_OMIT_TRACE: Normally, this routine is never called
1181
+ ** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE,
1182
+ ** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as
1183
+ ** a new VDBE is created. So we are free to set addr to p->nOp-1 without
1184
+ ** having to double-check to make sure that the result is non-negative. But
1185
+ ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to
1186
+ ** check the value of p->nOp-1 before continuing.
1187
+ */
1188
+ static VdbeOp sqlite3VdbeGetOp( Vdbe p, int addr )
1189
+ {
1190
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
1191
+ if ( addr < 0 )
1192
+ {
1193
+ #if SQLITE_OMIT_TRACE
1194
+ VdbeOp dummy = new VdbeOp();
1195
+ if( p.nOp==0 ) return dummy;
1196
+ #endif
1197
+ addr = p.nOp - 1;
1198
+ }
1199
+ Debug.Assert( ( addr >= 0 && addr < p.nOp ) /* || p.db.mallocFailed != 0 */);
1200
+ //if ( p.db.mallocFailed != 0 )
1201
+ //{
1202
+ // return dummy;
1203
+ //}
1204
+ //else
1205
+ {
1206
+ return p.aOp[addr];
1207
+ }
1208
+ }
1209
+
1210
+ #if !SQLITE_OMIT_EXPLAIN || !NDEBUG || VDBE_PROFILE || SQLITE_DEBUG
1211
+ /*
1212
+ ** Compute a string that describes the P4 parameter for an opcode.
1213
+ ** Use zTemp for any required temporary buffer space.
1214
+ */
1215
+ static string displayP4( Op pOp, string zBuffer, int nTemp )
1216
+ {
1217
+ StringBuilder zTemp = new StringBuilder( 100 );
1218
+ Debug.Assert( nTemp >= 20 );
1219
+ switch ( pOp.p4type )
1220
+ {
1221
+ case P4_KEYINFO_STATIC:
1222
+ case P4_KEYINFO:
1223
+ {
1224
+ int i, j;
1225
+ KeyInfo pKeyInfo = pOp.p4.pKeyInfo;
1226
+ sqlite3_snprintf( nTemp, ref zTemp, "keyinfo(%d", pKeyInfo.nField );
1227
+ i = sqlite3Strlen30( zTemp );
1228
+ for ( j = 0; j < pKeyInfo.nField; j++ )
1229
+ {
1230
+ CollSeq pColl = pKeyInfo.aColl[j];
1231
+ if ( pColl != null )
1232
+ {
1233
+ int n = sqlite3Strlen30( pColl.zName );
1234
+ if ( i + n > nTemp )
1235
+ {
1236
+ zTemp.Append( ",..." ); // memcpy( &zTemp[i], ",...", 4 );
1237
+ break;
1238
+ }
1239
+ zTemp.Append( "," );// zTemp[i++] = ',';
1240
+ if ( pKeyInfo.aSortOrder != null && pKeyInfo.aSortOrder[j] != 0 )
1241
+ {
1242
+ zTemp.Append( "-" );// zTemp[i++] = '-';
1243
+ }
1244
+ zTemp.Append( pColl.zName );// memcpy( &zTemp[i], pColl.zName, n + 1 );
1245
+ i += n;
1246
+ }
1247
+ else if ( i + 4 < nTemp )
1248
+ {
1249
+ zTemp.Append( ",nil" );// memcpy( &zTemp[i], ",nil", 4 );
1250
+ i += 4;
1251
+ }
1252
+ }
1253
+ zTemp.Append( ")" );// zTemp[i++] = ')';
1254
+ //zTemp[i] = 0;
1255
+ Debug.Assert( i < nTemp );
1256
+ break;
1257
+ }
1258
+ case P4_COLLSEQ:
1259
+ {
1260
+ CollSeq pColl = pOp.p4.pColl;
1261
+ sqlite3_snprintf( nTemp, ref zTemp, "collseq(%.20s)", ( pColl != null ? pColl.zName : "null" ) );
1262
+ break;
1263
+ }
1264
+ case P4_FUNCDEF:
1265
+ {
1266
+ FuncDef pDef = pOp.p4.pFunc;
1267
+ sqlite3_snprintf( nTemp, ref zTemp, "%s(%d)", pDef.zName, pDef.nArg );
1268
+ break;
1269
+ }
1270
+ case P4_INT64:
1271
+ {
1272
+ sqlite3_snprintf( nTemp, ref zTemp, "%lld", pOp.p4.pI64 );
1273
+ break;
1274
+ }
1275
+ case P4_INT32:
1276
+ {
1277
+ sqlite3_snprintf( nTemp, ref zTemp, "%d", pOp.p4.i );
1278
+ break;
1279
+ }
1280
+ case P4_REAL:
1281
+ {
1282
+ sqlite3_snprintf( nTemp, ref zTemp, "%.16g", pOp.p4.pReal );
1283
+ break;
1284
+ }
1285
+ case P4_MEM:
1286
+ {
1287
+ Mem pMem = pOp.p4.pMem;
1288
+ Debug.Assert( ( pMem.flags & MEM_Null ) == 0 );
1289
+ if ( ( pMem.flags & MEM_Str ) != 0 )
1290
+ {
1291
+ zTemp.Append( pMem.z );
1292
+ }
1293
+ else if ( ( pMem.flags & MEM_Int ) != 0 )
1294
+ {
1295
+ sqlite3_snprintf( nTemp, ref zTemp, "%lld", pMem.u.i );
1296
+ }
1297
+ else if ( ( pMem.flags & MEM_Real ) != 0 )
1298
+ {
1299
+ sqlite3_snprintf( nTemp, ref zTemp, "%.16g", pMem.r );
1300
+ }
1301
+ else
1302
+ {
1303
+ Debug.Assert( ( pMem.flags & MEM_Blob ) != 0 );
1304
+ zTemp = new StringBuilder( "(blob)" );
1305
+ }
1306
+ break;
1307
+ }
1308
+ #if ! SQLITE_OMIT_VIRTUALTABLE
1309
+ case P4_VTAB: {
1310
+ sqlite3_vtab pVtab = pOp.p4.pVtab.pVtab;
1311
+ sqlite3_snprintf(nTemp, ref zTemp, "vtab:%p:%p", pVtab, pVtab.pModule);
1312
+ break;
1313
+ }
1314
+ #endif
1315
+ case P4_INTARRAY:
1316
+ {
1317
+ sqlite3_snprintf( nTemp, ref zTemp, "intarray" );
1318
+ break;
1319
+ }
1320
+ case P4_SUBPROGRAM:
1321
+ {
1322
+ sqlite3_snprintf( nTemp, ref zTemp, "program" );
1323
+ break;
1324
+ }
1325
+ default:
1326
+ {
1327
+ if ( pOp.p4.z != null ) zTemp.Append( pOp.p4.z );
1328
+ //if ( zTemp == null )
1329
+ //{
1330
+ // zTemp = "";
1331
+ //}
1332
+ break;
1333
+ }
1334
+ }
1335
+ Debug.Assert( zTemp != null );
1336
+ return zTemp.ToString();
1337
+ }
1338
+ #endif
1339
+
1340
+ /*
1341
+ ** Declare to the Vdbe that the BTree object at db.aDb[i] is used.
1342
+ */
1343
+ static void sqlite3VdbeUsesBtree( Vdbe p, int i )
1344
+ {
1345
+ int mask;
1346
+ Debug.Assert( i >= 0 && i < p.db.nDb && i < sizeof( u32 ) * 8 );
1347
+ Debug.Assert( i < sizeof( int ) * 8 );
1348
+ mask = (int)( (u32)1 ) << i;
1349
+ if ( ( p.btreeMask & mask ) == 0 )
1350
+ {
1351
+ p.btreeMask |= mask;
1352
+ sqlite3BtreeMutexArrayInsert( p.aMutex, p.db.aDb[i].pBt );
1353
+ }
1354
+ }
1355
+
1356
+
1357
+ #if VDBE_PROFILE || SQLITE_DEBUG
1358
+ /*
1359
+ ** Print a single opcode. This routine is used for debugging only.
1360
+ */
1361
+ static void sqlite3VdbePrintOp( FILE pOut, int pc, Op pOp )
1362
+ {
1363
+ string zP4;
1364
+ string zPtr = null;
1365
+ string zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
1366
+ if ( pOut == null ) pOut = System.Console.Out;
1367
+ zP4 = displayP4( pOp, zPtr, 50 );
1368
+ string zOut = "";
1369
+ sqlite3_snprintf( 999, ref zOut, zFormat1, pc,
1370
+ sqlite3OpcodeName( pOp.opcode ), pOp.p1, pOp.p2, pOp.p3, zP4, pOp.p5,
1371
+ #if SQLITE_DEBUG
1372
+ pOp.zComment != null ? pOp.zComment : ""
1373
+ #else
1374
+ ""
1375
+ #endif
1376
+ );
1377
+ pOut.Write( zOut );
1378
+ //fflush(pOut);
1379
+ }
1380
+ #endif
1381
+
1382
+ /*
1383
+ ** Release an array of N Mem elements
1384
+ */
1385
+ static void releaseMemArray( Mem[] p, int N )
1386
+ {
1387
+ releaseMemArray( p, 0, N );
1388
+ }
1389
+ static void releaseMemArray( Mem[] p, int starting, int N )
1390
+ {
1391
+ if ( p != null && p.Length > starting && p[starting] != null && N != 0 )
1392
+ {
1393
+ Mem pEnd;
1394
+ sqlite3 db = p[starting].db;
1395
+ //u8 malloc_failed = db.mallocFailed;
1396
+ for ( int i = starting; i < N; i++ )//pEnd = p[N] ; p < pEnd ; p++ )
1397
+ {
1398
+ pEnd = p[i];
1399
+ Debug.Assert( //( p[1] ) == pEnd ||
1400
+ N == 1 || p[starting].db == p[starting + 1].db );
1401
+
1402
+ /* This block is really an inlined version of sqlite3VdbeMemRelease()
1403
+ ** that takes advantage of the fact that the memory cell value is
1404
+ ** being set to NULL after releasing any dynamic resources.
1405
+ **
1406
+ ** The justification for duplicating code is that according to
1407
+ ** callgrind, this causes a certain test case to hit the CPU 4.7
1408
+ ** percent less (x86 linux, gcc version 4.1.2, -O6) than if
1409
+ ** sqlite3MemRelease() were called from here. With -O2, this jumps
1410
+ ** to 6.6 percent. The test case is inserting 1000 rows into a table
1411
+ ** with no indexes using a single prepared INSERT statement, bind()
1412
+ ** and reset(). Inserts are grouped into a transaction.
1413
+ */
1414
+ if ( pEnd != null )
1415
+ {
1416
+ if ( ( pEnd.flags & ( MEM_Agg | MEM_Dyn | MEM_Frame | MEM_RowSet ) ) != 0 )
1417
+ {
1418
+ sqlite3VdbeMemRelease( pEnd );
1419
+ }
1420
+ //else if ( pEnd.zMalloc != null )
1421
+ //{
1422
+ // sqlite3DbFree( db, ref pEnd.zMalloc );
1423
+ // pEnd.zMalloc = 0;
1424
+ //}
1425
+ pEnd.z = null;
1426
+ pEnd.n = 0;
1427
+ pEnd.flags = MEM_Null;
1428
+ sqlite3_free( ref pEnd._Mem );
1429
+ sqlite3_free( ref pEnd.zBLOB);
1430
+ }
1431
+ }
1432
+ // db.mallocFailed = malloc_failed;
1433
+ }
1434
+ }
1435
+
1436
+ /*
1437
+ ** Delete a VdbeFrame object and its contents. VdbeFrame objects are
1438
+ ** allocated by the OP_Program opcode in sqlite3VdbeExec().
1439
+ */
1440
+ static void sqlite3VdbeFrameDelete( VdbeFrame p )
1441
+ {
1442
+ int i;
1443
+ //Mem[] aMem = VdbeFrameMem(p);
1444
+ VdbeCursor[] apCsr = p.aChildCsr;// (VdbeCursor)aMem[p.nChildMem];
1445
+ for ( i = 0; i < p.nChildCsr; i++ )
1446
+ {
1447
+ sqlite3VdbeFreeCursor( p.v, apCsr[i] );
1448
+ }
1449
+ releaseMemArray(p.aChildMem, p.nChildMem);
1450
+ p = null;// sqlite3DbFree( p.v.db, p );
1451
+ }
1452
+
1453
+ #if ! SQLITE_OMIT_EXPLAIN
1454
+ /*
1455
+ ** Give a listing of the program in the virtual machine.
1456
+ **
1457
+ ** The interface is the same as sqlite3VdbeExec(). But instead of
1458
+ ** running the code, it invokes the callback once for each instruction.
1459
+ ** This feature is used to implement "EXPLAIN".
1460
+ **
1461
+ ** When p.explain==1, each instruction is listed. When
1462
+ ** p.explain==2, only OP_Explain instructions are listed and these
1463
+ ** are shown in a different format. p.explain==2 is used to implement
1464
+ ** EXPLAIN QUERY PLAN.
1465
+ **
1466
+ ** When p->explain==1, first the main program is listed, then each of
1467
+ ** the trigger subprograms are listed one by one.
1468
+ */
1469
+ static int sqlite3VdbeList(
1470
+ Vdbe p /* The VDBE */
1471
+ )
1472
+ {
1473
+ int nRow; /* Stop when row count reaches this */
1474
+ int nSub = 0; /* Number of sub-vdbes seen so far */
1475
+ SubProgram[] apSub = null; /* Array of sub-vdbes */
1476
+ Mem pSub = null; /* Memory cell hold array of subprogs */
1477
+ sqlite3 db = p.db; /* The database connection */
1478
+ int i; /* Loop counter */
1479
+ int rc = SQLITE_OK; /* Return code */
1480
+ if ( p.pResultSet == null ) p.pResultSet = new Mem[0];//Mem* pMem = p.pResultSet = p.aMem[1]; /* First Mem of result set */
1481
+ Mem pMem;
1482
+ Debug.Assert( p.explain != 0 );
1483
+ Debug.Assert( p.magic == VDBE_MAGIC_RUN );
1484
+ Debug.Assert( p.rc == SQLITE_OK || p.rc == SQLITE_BUSY || p.rc == SQLITE_NOMEM );
1485
+ /* Even though this opcode does not use dynamic strings for
1486
+ ** the result, result columns may become dynamic if the user calls
1487
+ ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
1488
+ */
1489
+ releaseMemArray( p.pResultSet, 8 );
1490
+
1491
+ //if ( p.rc == SQLITE_NOMEM )
1492
+ //{
1493
+ // /* This happens if a malloc() inside a call to sqlite3_column_text() or
1494
+ // ** sqlite3_column_text16() failed. */
1495
+ // db.mallocFailed = 1;
1496
+ // return SQLITE_ERROR;
1497
+ //}
1498
+
1499
+ /* When the number of output rows reaches nRow, that means the
1500
+ ** listing has finished and sqlite3_step() should return SQLITE_DONE.
1501
+ ** nRow is the sum of the number of rows in the main program, plus
1502
+ ** the sum of the number of rows in all trigger subprograms encountered
1503
+ ** so far. The nRow value will increase as new trigger subprograms are
1504
+ ** encountered, but p->pc will eventually catch up to nRow.
1505
+ */
1506
+ nRow = p.nOp;
1507
+ int i_pMem;
1508
+ if ( p.explain == 1 )
1509
+ {
1510
+ /* The first 8 memory cells are used for the result set. So we will
1511
+ ** commandeer the 9th cell to use as storage for an array of pointers
1512
+ ** to trigger subprograms. The VDBE is guaranteed to have at least 9
1513
+ ** cells. */
1514
+ Debug.Assert( p.nMem > 9 );
1515
+ pSub = p.aMem[9];
1516
+ if ( ( pSub.flags & MEM_Blob ) != 0 )
1517
+ {
1518
+ /* On the first call to sqlite3_step(), pSub will hold a NULL. It is
1519
+ ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
1520
+ apSub = p.aMem[9]._SubProgram; // apSub = (SubProgram**)pSub->z;
1521
+ nSub = apSub.Length;// pSub->n / sizeof( Vdbe* );
1522
+ }
1523
+ for ( i = 0; i < nSub; i++ )
1524
+ {
1525
+ nRow += apSub[i].nOp;
1526
+ }
1527
+ }
1528
+
1529
+ i_pMem = 0; if ( i_pMem >= p.pResultSet.Length ) Array.Resize( ref p.pResultSet, 8 + p.pResultSet.Length );
1530
+ {
1531
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1532
+ }
1533
+ pMem = p.pResultSet[i_pMem++];
1534
+ do
1535
+ {
1536
+ i = p.pc++;
1537
+ } while ( i < nRow && p.explain == 2 && p.aOp[i].opcode != OP_Explain );
1538
+ if ( i >= nRow )
1539
+ {
1540
+ p.rc = SQLITE_OK;
1541
+ rc = SQLITE_DONE;
1542
+ }
1543
+ else if ( db.u1.isInterrupted )
1544
+ {
1545
+ p.rc = SQLITE_INTERRUPT;
1546
+ rc = SQLITE_ERROR;
1547
+ sqlite3SetString( ref p.zErrMsg, db, sqlite3ErrStr( p.rc ) );
1548
+ }
1549
+ else
1550
+ {
1551
+ string z;
1552
+ Op pOp;
1553
+ if ( i < p.nOp )
1554
+ {
1555
+ /* The output line number is small enough that we are still in the
1556
+ ** main program. */
1557
+ pOp = p.aOp[i];
1558
+ }
1559
+ else
1560
+ {
1561
+ /* We are currently listing subprograms. Figure out which one and
1562
+ ** pick up the appropriate opcode. */
1563
+ int j;
1564
+ i -= p.nOp;
1565
+ for ( j = 0; i >= apSub[j].nOp; j++ )
1566
+ {
1567
+ i -= apSub[j].nOp;
1568
+ }
1569
+ pOp = apSub[j].aOp[i];
1570
+ }
1571
+ if ( p.explain == 1 )
1572
+ {
1573
+ pMem.flags = MEM_Int;
1574
+ pMem.type = SQLITE_INTEGER;
1575
+ pMem.u.i = i; /* Program counter */
1576
+ if ( p.pResultSet[i_pMem] == null )
1577
+ {
1578
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1579
+ }
1580
+ pMem = p.pResultSet[i_pMem++]; //pMem++;
1581
+
1582
+ /* When an OP_Program opcode is encounter (the only opcode that has
1583
+ ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
1584
+ ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
1585
+ ** has not already been seen.
1586
+ */
1587
+ pMem.flags = MEM_Static | MEM_Str | MEM_Term;
1588
+ pMem.z = sqlite3OpcodeName( pOp.opcode ); /* Opcode */
1589
+ Debug.Assert( pMem.z != null );
1590
+ pMem.n = sqlite3Strlen30( pMem.z );
1591
+ pMem.type = SQLITE_TEXT;
1592
+ pMem.enc = SQLITE_UTF8;
1593
+ if ( p.pResultSet[i_pMem] == null )
1594
+ {
1595
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1596
+ }
1597
+ pMem = p.pResultSet[i_pMem++]; //pMem++;
1598
+ if ( pOp.p4type == P4_SUBPROGRAM )
1599
+ {
1600
+ //Debugger.Break(); // TODO
1601
+ //int nByte = 0;//(nSub+1)*sizeof(SubProgram*);
1602
+ int j;
1603
+ for ( j = 0; j < nSub; j++ )
1604
+ {
1605
+ if ( apSub[j] == pOp.p4.pProgram ) break;
1606
+ }
1607
+ if ( j == nSub )
1608
+ {// && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, 1) ){
1609
+ Array.Resize( ref apSub, nSub + 1 );
1610
+ pSub._SubProgram = apSub;// (SubProgram)pSub.z;
1611
+ apSub[nSub++] = pOp.p4.pProgram;
1612
+ pSub.flags |= MEM_Blob;
1613
+ pSub.n = 0;//nSub*sizeof(SubProgram*);
1614
+ }
1615
+ }
1616
+ }
1617
+
1618
+ pMem.flags = MEM_Int;
1619
+ pMem.u.i = pOp.p1; /* P1 */
1620
+ pMem.type = SQLITE_INTEGER;
1621
+ if ( p.pResultSet[i_pMem] == null )
1622
+ {
1623
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1624
+ }
1625
+ pMem = p.pResultSet[i_pMem++]; //pMem++;
1626
+
1627
+ pMem.flags = MEM_Int;
1628
+ pMem.u.i = pOp.p2; /* P2 */
1629
+ pMem.type = SQLITE_INTEGER;
1630
+ if ( p.pResultSet[i_pMem] == null )
1631
+ {
1632
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1633
+ }
1634
+ pMem = p.pResultSet[i_pMem++]; //pMem++;
1635
+
1636
+ if ( p.explain == 1 )
1637
+ {
1638
+ pMem.flags = MEM_Int;
1639
+ pMem.u.i = pOp.p3; /* P3 */
1640
+ pMem.type = SQLITE_INTEGER;
1641
+ if ( p.pResultSet[i_pMem] == null )
1642
+ {
1643
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1644
+ }
1645
+ pMem = p.pResultSet[i_pMem++]; //pMem++;
1646
+ }
1647
+
1648
+ //if ( sqlite3VdbeMemGrow( pMem, 32, 0 ) != 0 )
1649
+ //{ /* P4 */
1650
+ // Debug.Assert( p.db.mallocFailed != 0 );
1651
+ // return SQLITE_ERROR;
1652
+ //}
1653
+ pMem.flags = MEM_Dyn | MEM_Str | MEM_Term;
1654
+ z = displayP4( pOp, pMem.z, 32 );
1655
+ if ( z != pMem.z )
1656
+ {
1657
+ sqlite3VdbeMemSetStr( pMem, z, -1, SQLITE_UTF8, null );
1658
+ }
1659
+ else
1660
+ {
1661
+ Debug.Assert( pMem.z != null );
1662
+ pMem.n = sqlite3Strlen30( pMem.z );
1663
+ pMem.enc = SQLITE_UTF8;
1664
+ }
1665
+ pMem.type = SQLITE_TEXT;
1666
+ if ( p.pResultSet[i_pMem] == null )
1667
+ {
1668
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1669
+ }
1670
+ pMem = p.pResultSet[i_pMem++]; //pMem++;
1671
+
1672
+ if ( p.explain == 1 )
1673
+ {
1674
+ //if ( sqlite3VdbeMemGrow( pMem, 4, 0 ) != 0 )
1675
+ //{
1676
+ // Debug.Assert( p.db.mallocFailed != 0 );
1677
+ // return SQLITE_ERROR;
1678
+ //}
1679
+ pMem.flags = MEM_Dyn | MEM_Str | MEM_Term;
1680
+ pMem.n = 2;
1681
+ pMem.z = pOp.p5.ToString( "x2" ); //sqlite3_snprintf( 3, pMem.z, "%.2x", pOp.p5 ); /* P5 */
1682
+ pMem.type = SQLITE_TEXT;
1683
+ pMem.enc = SQLITE_UTF8;
1684
+ if ( p.pResultSet[i_pMem] == null )
1685
+ {
1686
+ p.pResultSet[i_pMem] = sqlite3Malloc( p.pResultSet[i_pMem] );
1687
+ }
1688
+ pMem = p.pResultSet[i_pMem++]; // pMem++;
1689
+
1690
+ #if SQLITE_DEBUG
1691
+ if ( pOp.zComment != null )
1692
+ {
1693
+ pMem.flags = MEM_Str | MEM_Term;
1694
+ pMem.z = pOp.zComment;
1695
+ pMem.n = pMem.z == null ? 0 : sqlite3Strlen30( pMem.z );
1696
+ pMem.enc = SQLITE_UTF8;
1697
+ pMem.type = SQLITE_TEXT;
1698
+ }
1699
+ else
1700
+ #endif
1701
+ {
1702
+ pMem.flags = MEM_Null; /* Comment */
1703
+ pMem.type = SQLITE_NULL;
1704
+ }
1705
+ }
1706
+
1707
+ p.nResColumn = (u16)( 8 - 5 * ( p.explain - 1 ) );
1708
+ p.rc = SQLITE_OK;
1709
+ rc = SQLITE_ROW;
1710
+ }
1711
+ return rc;
1712
+ }
1713
+ #endif // * SQLITE_OMIT_EXPLAIN */
1714
+
1715
+ #if SQLITE_DEBUG
1716
+ /*
1717
+ ** Print the SQL that was used to generate a VDBE program.
1718
+ */
1719
+ static void sqlite3VdbePrintSql( Vdbe p )
1720
+ {
1721
+ int nOp = p.nOp;
1722
+ VdbeOp pOp;
1723
+ if ( nOp < 1 ) return;
1724
+ pOp = p.aOp[0];
1725
+ if ( pOp.opcode == OP_Trace && pOp.p4.z != null )
1726
+ {
1727
+ string z = pOp.p4.z;
1728
+ z = z.Trim();// while ( sqlite3Isspace( *(u8*)z ) ) z++;
1729
+ Console.Write( "SQL: [%s]\n", z );
1730
+ }
1731
+ }
1732
+ #endif
1733
+
1734
+ #if !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE
1735
+ /*
1736
+ ** Print an IOTRACE message showing SQL content.
1737
+ */
1738
+ static void sqlite3VdbeIOTraceSql( Vdbe p )
1739
+ {
1740
+ int nOp = p.nOp;
1741
+ VdbeOp pOp;
1742
+ if ( SQLite3IoTrace == false ) return;
1743
+ if ( nOp < 1 ) return;
1744
+ pOp = p.aOp[0];
1745
+ if ( pOp.opcode == OP_Trace && pOp.p4.z != null )
1746
+ {
1747
+ int i, j;
1748
+ string z = "";//char z[1000];
1749
+ sqlite3_snprintf( 1000, ref z, "%s", pOp.p4.z );
1750
+ //for(i=0; sqlite3Isspace(z[i]); i++){}
1751
+ //for(j=0; z[i]; i++){
1752
+ //if( sqlite3Isspace(z[i]) ){
1753
+ //if( z[i-1]!=' ' ){
1754
+ //z[j++] = ' ';
1755
+ //}
1756
+ //}else{
1757
+ //z[j++] = z[i];
1758
+ //}
1759
+ //}
1760
+ //z[j] = 0;
1761
+ //z = z.Trim( z );
1762
+ sqlite3IoTrace( "SQL %s\n", z.Trim() );
1763
+ }
1764
+ }
1765
+ #endif // * !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
1766
+
1767
+ /*
1768
+ ** Allocate space from a fixed size buffer and return a pointer to
1769
+ ** that space. If insufficient space is available, return NULL.
1770
+ **
1771
+ ** The pBuf parameter is the initial value of a pointer which will
1772
+ ** receive the new memory. pBuf is normally NULL. If pBuf is not
1773
+ ** NULL, it means that memory space has already been allocated and that
1774
+ ** this routine should not allocate any new memory. When pBuf is not
1775
+ ** NULL simply return pBuf. Only allocate new memory space when pBuf
1776
+ ** is NULL.
1777
+ **
1778
+ ** nByte is the number of bytes of space needed.
1779
+ **
1780
+ ** *ppFrom points to available space and pEnd points to the end of the
1781
+ ** available space. When space is allocated, *ppFrom is advanced past
1782
+ ** the end of the allocated space.
1783
+ **
1784
+ ** *pnByte is a counter of the number of bytes of space that have failed
1785
+ ** to allocate. If there is insufficient space in *ppFrom to satisfy the
1786
+ ** request, then increment *pnByte by the amount of the request.
1787
+ */
1788
+ //static void* allocSpace(
1789
+ // void* pBuf, /* Where return pointer will be stored */
1790
+ // int nByte, /* Number of bytes to allocate */
1791
+ // u8** ppFrom, /* IN/OUT: Allocate from *ppFrom */
1792
+ // u8* pEnd, /* Pointer to 1 byte past the end of *ppFrom buffer */
1793
+ // int* pnByte /* If allocation cannot be made, increment *pnByte */
1794
+ //)
1795
+ //{
1796
+ // assert(EIGHT_BYTE_ALIGNMENT(*ppFrom));
1797
+ // if (pBuf) return pBuf;
1798
+ // nByte = ROUND8(nByte);
1799
+ // if (&(*ppFrom)[nByte] <= pEnd)
1800
+ // {
1801
+ // pBuf = (void*)*ppFrom;
1802
+ // *ppFrom += nByte;
1803
+ // }
1804
+ // else
1805
+ // {
1806
+ // *pnByte += nByte;
1807
+ // }
1808
+ // return pBuf;
1809
+ //}
1810
+
1811
+ /*
1812
+ ** Prepare a virtual machine for execution. This involves things such
1813
+ ** as allocating stack space and initializing the program counter.
1814
+ ** After the VDBE has be prepped, it can be executed by one or more
1815
+ ** calls to sqlite3VdbeExec().
1816
+ **
1817
+ ** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
1818
+ ** VDBE_MAGIC_RUN.
1819
+ **
1820
+ ** This function may be called more than once on a single virtual machine.
1821
+ ** The first call is made while compiling the SQL statement. Subsequent
1822
+ ** calls are made as part of the process of resetting a statement to be
1823
+ ** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor
1824
+ ** and isExplain parameters are only passed correct values the first time
1825
+ ** the function is called. On subsequent calls, from sqlite3_reset(), nVar
1826
+ ** is passed -1 and nMem, nCursor and isExplain are all passed zero.
1827
+ */
1828
+ static void sqlite3VdbeMakeReady(
1829
+ Vdbe p, /* The VDBE */
1830
+ int nVar, /* Number of '?' see in the SQL statement */
1831
+ int nMem, /* Number of memory cells to allocate */
1832
+ int nCursor, /* Number of cursors to allocate */
1833
+ int nArg, /* Maximum number of args in SubPrograms */
1834
+ int isExplain, /* True if the EXPLAIN keywords is present */
1835
+ int usesStmtJournal /* True to set Vdbe.usesStmtJournal */
1836
+ )
1837
+ {
1838
+ int n;
1839
+ sqlite3 db = p.db;
1840
+
1841
+ Debug.Assert( p != null );
1842
+ Debug.Assert( p.magic == VDBE_MAGIC_INIT );
1843
+
1844
+ /* There should be at least one opcode.
1845
+ */
1846
+ Debug.Assert( p.nOp > 0 );
1847
+
1848
+ /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
1849
+ p.magic = VDBE_MAGIC_RUN;
1850
+
1851
+ /* For each cursor required, also allocate a memory cell. Memory
1852
+ ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
1853
+ ** the vdbe program. Instead they are used to allocate space for
1854
+ ** VdbeCursor/BtCursor structures. The blob of memory associated with
1855
+ ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
1856
+ ** stores the blob of memory associated with cursor 1, etc.
1857
+ **
1858
+ ** See also: allocateCursor().
1859
+ */
1860
+ nMem += nCursor;
1861
+
1862
+ /* Allocate space for memory registers, SQL variables, VDBE cursors and
1863
+ ** an array to marshal SQL function arguments in. This is only done the
1864
+ ** first time this function is called for a given VDBE, not when it is
1865
+ ** being called from sqlite3_reset() to reset the virtual machine.
1866
+ */
1867
+ if ( nVar >= 0 /* && ALWAYS(db->mallocFailed==0) */ )
1868
+ {
1869
+ //u8* zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for alloation */
1870
+ //u8* zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past available mem */
1871
+ int nByte; /* How much extra memory needed */
1872
+ resolveP2Values( p, ref nArg );
1873
+ p.usesStmtJournal = usesStmtJournal != 0;
1874
+ if ( isExplain != 0 && nMem < 10 )
1875
+ {
1876
+ nMem = 10;
1877
+ }
1878
+ //memset(zCsr, 0, zEnd-zCsr);
1879
+ //zCsr += ( zCsr - (u8*)0 ) & 7;
1880
+ //assert( EIGHT_BYTE_ALIGNMENT( zCsr ) );
1881
+ //
1882
+ // C# -- Replace allocation with individual Dims
1883
+ //
1884
+ /* Memory for registers, parameters, cursor, etc, is allocated in two
1885
+ ** passes. On the first pass, we try to reuse unused space at the
1886
+ ** end of the opcode array. If we are unable to satisfy all memory
1887
+ ** requirements by reusing the opcode array tail, then the second
1888
+ ** pass will fill in the rest using a fresh allocation.
1889
+ **
1890
+ ** This two-pass approach that reuses as much memory as possible from
1891
+ ** the leftover space at the end of the opcode array can significantly
1892
+ ** reduce the amount of memory held by a prepared statement.
1893
+ */
1894
+ //do
1895
+ //{
1896
+ // nByte = 0;
1897
+ // p->aMem = allocSpace(p->aMem, nMem * sizeof(Mem), &zCsr, zEnd, &nByte);
1898
+ // p->aVar = allocSpace(p->aVar, nVar * sizeof(Mem), &zCsr, zEnd, &nByte);
1899
+ // p->apArg = allocSpace(p->apArg, nArg * sizeof(Mem*), &zCsr, zEnd, &nByte);
1900
+ // p->azVar = allocSpace(p->azVar, nVar * sizeof(char*), &zCsr, zEnd, &nByte);
1901
+ // p->apCsr = allocSpace(p->apCsr, nCursor * sizeof(VdbeCursor*),
1902
+ // &zCsr, zEnd, &nByte);
1903
+ // if (nByte)
1904
+ // {
1905
+ // p->pFree = sqlite3DbMallocZero(db, nByte);
1906
+ // }
1907
+ // zCsr = p->pFree;
1908
+ // zEnd = &zCsr[nByte];
1909
+ //} while (nByte && !db->mallocFailed);
1910
+
1911
+
1912
+ // C# -- Replace allocation with individual Dims
1913
+ // aMem is 1 based, so allocate 1 extra cell under C#
1914
+ p.aMem = new Mem[nMem + 1];
1915
+ for ( n = 0; n <= nMem; n++ )
1916
+ {
1917
+ p.aMem[n] = sqlite3Malloc( p.aMem[n] );
1918
+ p.aMem[n].db = db;
1919
+ }
1920
+ //p.aMem--; /* aMem[] goes from 1..nMem */
1921
+ p.nMem = nMem; /* not from 0..nMem-1 */
1922
+ //
1923
+ p.aVar = new Mem[nVar == 0 ? 1 : nVar ];
1924
+ for ( n = 0; n < nVar; n++ )
1925
+ {
1926
+ p.aVar[n] = sqlite3Malloc(p.aVar[n] );
1927
+ }
1928
+ p.nVar = (ynVar)nVar;
1929
+ p.okVar = 0;
1930
+ //
1931
+ p.apArg = new Mem[nArg == 0 ? 1 : nArg];//p.apArg = (Mem**)p.aVar[nVar];
1932
+ //
1933
+
1934
+ p.azVar = new string[nArg == 0 ? 1 : nArg]; //p.azVar = (char**)p.apArg[nArg];
1935
+ for ( n = 0; n < nArg; n++ )
1936
+ { p.azVar[n] = ""; }
1937
+ //
1938
+ p.apCsr = new VdbeCursor[nCursor == 0 ? 1 : nCursor];//p.apCsr = (VdbeCursor**)p.azVar[nVar];
1939
+ p.apCsr[0] = new VdbeCursor();
1940
+ p.nCursor = (u16)nCursor;
1941
+ if ( p.aVar != null )
1942
+ {
1943
+ p.nVar = (ynVar)nVar;
1944
+ //
1945
+ for ( n = 0; n < nVar; n++ )
1946
+ {
1947
+ p.aVar[n].flags = MEM_Null;
1948
+ p.aVar[n].db = db;
1949
+ }
1950
+ }
1951
+ if ( p.aMem != null )
1952
+ {
1953
+ //p.aMem--; /* aMem[] goes from 1..nMem */
1954
+ p.nMem = nMem; /* not from 0..nMem-1 */
1955
+ for ( n = 0; n <= nMem; n++ )
1956
+ {
1957
+ p.aMem[n].flags = MEM_Null;
1958
+ p.aMem[n].n = 0;
1959
+ p.aMem[n].z = null;
1960
+ p.aMem[n].zBLOB = null;
1961
+ p.aMem[n].db = db;
1962
+ }
1963
+ }
1964
+ }
1965
+
1966
+ #if SQLITE_DEBUG
1967
+ for ( n = 1; n < p.nMem; n++ )
1968
+ {
1969
+ Debug.Assert( p.aMem[n].db == db );
1970
+ }
1971
+ #endif
1972
+
1973
+ p.pc = -1;
1974
+ p.rc = SQLITE_OK;
1975
+ p.errorAction = OE_Abort;
1976
+ p.explain |= isExplain;
1977
+ p.magic = VDBE_MAGIC_RUN;
1978
+ p.nChange = 0;
1979
+ p.cacheCtr = 1;
1980
+ p.minWriteFileFormat = 255;
1981
+ p.iStatement = 0;
1982
+ #if VDBE_PROFILE
1983
+ {
1984
+ int i;
1985
+ for ( i = 0 ; i < p.nOp ; i++ )
1986
+ {
1987
+ p.aOp[i].cnt = 0;
1988
+ p.aOp[i].cycles = 0;
1989
+ }
1990
+ }
1991
+ #endif
1992
+ }
1993
+
1994
+ /*
1995
+ ** Close a VDBE cursor and release all the resources that cursor
1996
+ ** happens to hold.
1997
+ */
1998
+ static void sqlite3VdbeFreeCursor( Vdbe p, VdbeCursor pCx )
1999
+ {
2000
+ if ( pCx == null )
2001
+ {
2002
+ return;
2003
+ }
2004
+
2005
+ if ( pCx.pBt != null )
2006
+ {
2007
+ sqlite3BtreeClose( ref pCx.pBt );
2008
+ /* The pCx.pCursor will be close automatically, if it exists, by
2009
+ ** the call above. */
2010
+ }
2011
+ else if ( pCx.pCursor != null )
2012
+ {
2013
+ sqlite3BtreeCloseCursor( pCx.pCursor );
2014
+ sqlite3MemFreeBtCursor( ref pCx.pCursor );
2015
+ }
2016
+ #if ! SQLITE_OMIT_VIRTUALTABLE
2017
+ if( pCx.pVtabCursor ){
2018
+ sqlite3_vtab_cursor pVtabCursor = pCx.pVtabCursor;
2019
+ const sqlite3_module pModule = pCx.pModule;
2020
+ p.inVtabMethod = 1;
2021
+ pModule.xClose(pVtabCursor);
2022
+ p.inVtabMethod = 0;
2023
+ }
2024
+ #endif
2025
+ }
2026
+ /*
2027
+ ** Copy the values stored in the VdbeFrame structure to its Vdbe. This
2028
+ ** is used, for example, when a trigger sub-program is halted to restore
2029
+ ** control to the main program.
2030
+ */
2031
+ static int sqlite3VdbeFrameRestore( VdbeFrame pFrame )
2032
+ {
2033
+ Vdbe v = pFrame.v;
2034
+ v.aOp = pFrame.aOp;
2035
+ v.nOp = pFrame.nOp;
2036
+ v.aMem = pFrame.aMem;
2037
+ v.nMem = pFrame.nMem;
2038
+ v.apCsr = pFrame.apCsr;
2039
+ v.nCursor = pFrame.nCursor;
2040
+ v.db.lastRowid = pFrame.lastRowid;
2041
+ v.nChange = pFrame.nChange;
2042
+ return pFrame.pc;
2043
+ }
2044
+
2045
+ /*
2046
+ ** Close all cursors.
2047
+ **
2048
+ ** Also release any dynamic memory held by the VM in the Vdbe.aMem memory
2049
+ ** cell array. This is necessary as the memory cell array may contain
2050
+ ** pointers to VdbeFrame objects, which may in turn contain pointers to
2051
+ ** open cursors.
2052
+ */
2053
+ static void closeAllCursors( Vdbe p )
2054
+ {
2055
+ if ( p.pFrame != null )
2056
+ {
2057
+ VdbeFrame pFrame = p.pFrame;
2058
+ for ( pFrame = p.pFrame; pFrame.pParent != null; pFrame = pFrame.pParent ) ;
2059
+ sqlite3VdbeFrameRestore( pFrame );
2060
+ }
2061
+ p.pFrame = null;
2062
+ p.nFrame = 0;
2063
+
2064
+ if ( p.apCsr != null )
2065
+ {
2066
+ int i;
2067
+ for ( i = 0; i < p.nCursor; i++ )
2068
+ {
2069
+ VdbeCursor pC = p.apCsr[i];
2070
+ if ( pC != null )
2071
+ {
2072
+ sqlite3VdbeFreeCursor( p, pC );
2073
+ p.apCsr[i] = null;
2074
+ }
2075
+ }
2076
+ }
2077
+ if ( p.aMem != null )
2078
+ {
2079
+ releaseMemArray( p.aMem, 1, p.nMem );
2080
+ }
2081
+ }
2082
+ /*
2083
+ ** Clean up the VM after execution.
2084
+ **
2085
+ ** This routine will automatically close any cursors, lists, and/or
2086
+ ** sorters that were left open. It also deletes the values of
2087
+ ** variables in the aVar[] array.
2088
+ */
2089
+ static void Cleanup( Vdbe p )
2090
+ {
2091
+ sqlite3 db = p.db;
2092
+ #if SQLITE_DEBUG
2093
+ /* Execute assert() statements to ensure that the Vdbe.apCsr[] and
2094
+ ** Vdbe.aMem[] arrays have already been cleaned up. */
2095
+ int i;
2096
+ //TODO for(i=0; i<p.nCursor; i++) Debug.Assert( p.apCsr==null || p.apCsr[i]==null );
2097
+ for ( i = 1; i <= p.nMem; i++ ) Debug.Assert( p.aMem != null || p.aMem[i].flags == MEM_Null );
2098
+ #endif
2099
+
2100
+ sqlite3DbFree( db, ref p.zErrMsg );
2101
+ p.pResultSet = null;
2102
+ }
2103
+
2104
+ /*
2105
+ ** Set the number of result columns that will be returned by this SQL
2106
+ ** statement. This is now set at compile time, rather than during
2107
+ ** execution of the vdbe program so that sqlite3_column_count() can
2108
+ ** be called on an SQL statement before sqlite3_step().
2109
+ */
2110
+ static void sqlite3VdbeSetNumCols( Vdbe p, int nResColumn )
2111
+ {
2112
+ Mem pColName;
2113
+ int n;
2114
+ sqlite3 db = p.db;
2115
+
2116
+ releaseMemArray( p.aColName, p.nResColumn * COLNAME_N );
2117
+ sqlite3DbFree( db, ref p.aColName );
2118
+ n = nResColumn * COLNAME_N;
2119
+ p.nResColumn = (u16)nResColumn;
2120
+ p.aColName = new Mem[n];// (Mem*)sqlite3DbMallocZero(db, Mem.Length * n);
2121
+ //if (p.aColName == 0) return;
2122
+ while ( n-- > 0 )
2123
+ {
2124
+ p.aColName[n] = sqlite3Malloc( p.aColName[n] );
2125
+ pColName = p.aColName[n];
2126
+ pColName.flags = MEM_Null;
2127
+ pColName.db = p.db;
2128
+ }
2129
+ }
2130
+
2131
+ /*
2132
+ ** Set the name of the idx'th column to be returned by the SQL statement.
2133
+ ** zName must be a pointer to a nul terminated string.
2134
+ **
2135
+ ** This call must be made after a call to sqlite3VdbeSetNumCols().
2136
+ **
2137
+ ** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC
2138
+ ** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed
2139
+ ** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed.
2140
+ */
2141
+
2142
+
2143
+ static int sqlite3VdbeSetColName(
2144
+ Vdbe p, /* Vdbe being configured */
2145
+ int idx, /* Index of column zName applies to */
2146
+ int var, /* One of the COLNAME_* constants */
2147
+ string zName, /* Pointer to buffer containing name */
2148
+ dxDel xDel /* Memory management strategy for zName */
2149
+ )
2150
+ {
2151
+ int rc;
2152
+ Mem pColName;
2153
+ Debug.Assert( idx < p.nResColumn );
2154
+ Debug.Assert( var < COLNAME_N );
2155
+ //if ( p.db.mallocFailed != 0 )
2156
+ //{
2157
+ // Debug.Assert( null == zName || xDel != SQLITE_DYNAMIC );
2158
+ // return SQLITE_NOMEM;
2159
+ //}
2160
+ Debug.Assert( p.aColName != null );
2161
+ pColName = p.aColName[idx + var * p.nResColumn];
2162
+ rc = sqlite3VdbeMemSetStr( pColName, zName, -1, SQLITE_UTF8, xDel );
2163
+ Debug.Assert( rc != 0 || null == zName || ( pColName.flags & MEM_Term ) != 0 );
2164
+ return rc;
2165
+ }
2166
+
2167
+ /*
2168
+ ** A read or write transaction may or may not be active on database handle
2169
+ ** db. If a transaction is active, commit it. If there is a
2170
+ ** write-transaction spanning more than one database file, this routine
2171
+ ** takes care of the master journal trickery.
2172
+ */
2173
+ static int vdbeCommit( sqlite3 db, Vdbe p )
2174
+ {
2175
+ int i;
2176
+ int nTrans = 0; /* Number of databases with an active write-transaction */
2177
+ int rc = SQLITE_OK;
2178
+ bool needXcommit = false;
2179
+
2180
+ #if SQLITE_OMIT_VIRTUALTABLE
2181
+ /* With this option, sqlite3VtabSync() is defined to be simply
2182
+ ** SQLITE_OK so p is not used.
2183
+ */
2184
+ UNUSED_PARAMETER( p );
2185
+ #endif
2186
+ /* Before doing anything else, call the xSync() callback for any
2187
+ ** virtual module tables written in this transaction. This has to
2188
+ ** be done before determining whether a master journal file is
2189
+ ** required, as an xSync() callback may add an attached database
2190
+ ** to the transaction.
2191
+ */
2192
+ rc = sqlite3VtabSync( db, p.zErrMsg );
2193
+ if ( rc != SQLITE_OK )
2194
+ {
2195
+ return rc;
2196
+ }
2197
+
2198
+ /* This loop determines (a) if the commit hook should be invoked and
2199
+ ** (b) how many database files have open write transactions, not
2200
+ ** including the temp database. (b) is important because if more than
2201
+ ** one database file has an open write transaction, a master journal
2202
+ ** file is required for an atomic commit.
2203
+ */
2204
+ for ( i = 0; i < db.nDb; i++ )
2205
+ {
2206
+ Btree pBt = db.aDb[i].pBt;
2207
+ if ( sqlite3BtreeIsInTrans( pBt ) )
2208
+ {
2209
+ needXcommit = true;
2210
+ if ( i != 1 ) nTrans++;
2211
+ }
2212
+ }
2213
+
2214
+ /* If there are any write-transactions at all, invoke the commit hook */
2215
+ if ( needXcommit && db.xCommitCallback != null )
2216
+ {
2217
+ rc = db.xCommitCallback( db.pCommitArg );
2218
+ if ( rc != 0 )
2219
+ {
2220
+ return SQLITE_CONSTRAINT;
2221
+ }
2222
+ }
2223
+
2224
+ /* The simple case - no more than one database file (not counting the
2225
+ ** TEMP database) has a transaction active. There is no need for the
2226
+ ** master-journal.
2227
+ **
2228
+ ** If the return value of sqlite3BtreeGetFilename() is a zero length
2229
+ ** string, it means the main database is :memory: or a temp file. In
2230
+ ** that case we do not support atomic multi-file commits, so use the
2231
+ ** simple case then too.
2232
+ */
2233
+ if ( 0 == sqlite3Strlen30( sqlite3BtreeGetFilename( db.aDb[0].pBt ) )
2234
+ || nTrans <= 1 )
2235
+ {
2236
+ for ( i = 0; rc == SQLITE_OK && i < db.nDb; i++ )
2237
+ {
2238
+ Btree pBt = db.aDb[i].pBt;
2239
+ if ( pBt != null )
2240
+ {
2241
+ rc = sqlite3BtreeCommitPhaseOne( pBt, null );
2242
+ }
2243
+ }
2244
+
2245
+ /* Do the commit only if all databases successfully complete phase 1.
2246
+ ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an
2247
+ ** IO error while deleting or truncating a journal file. It is unlikely,
2248
+ ** but could happen. In this case abandon processing and return the error.
2249
+ */
2250
+ for ( i = 0; rc == SQLITE_OK && i < db.nDb; i++ )
2251
+ {
2252
+ Btree pBt = db.aDb[i].pBt;
2253
+ if ( pBt != null )
2254
+ {
2255
+ rc = sqlite3BtreeCommitPhaseTwo( pBt );
2256
+ }
2257
+ }
2258
+ if ( rc == SQLITE_OK )
2259
+ {
2260
+ sqlite3VtabCommit( db );
2261
+ }
2262
+ }
2263
+
2264
+ /* The complex case - There is a multi-file write-transaction active.
2265
+ ** This requires a master journal file to ensure the transaction is
2266
+ ** committed atomicly.
2267
+ */
2268
+ #if ! SQLITE_OMIT_DISKIO
2269
+ else
2270
+ {
2271
+ sqlite3_vfs pVfs = db.pVfs;
2272
+ bool needSync = false;
2273
+ string zMaster = ""; /* File-name for the master journal */
2274
+ string zMainFile = sqlite3BtreeGetFilename( db.aDb[0].pBt );
2275
+ sqlite3_file pMaster = null;
2276
+ i64 offset = 0;
2277
+ int res = 0;
2278
+
2279
+ /* Select a master journal file name */
2280
+ do
2281
+ {
2282
+ i64 iRandom = 0;
2283
+ sqlite3DbFree( db, ref zMaster );
2284
+ sqlite3_randomness( sizeof( u32 ), ref iRandom );//random.Length
2285
+ zMaster = sqlite3MPrintf( db, "%s-mj%08X", zMainFile, iRandom & 0x7fffffff );
2286
+ //if (!zMaster)
2287
+ //{
2288
+ // return SQLITE_NOMEM;
2289
+ //}
2290
+ rc = sqlite3OsAccess( pVfs, zMaster, SQLITE_ACCESS_EXISTS, ref res );
2291
+ } while ( rc == SQLITE_OK && res == 1 );
2292
+ if ( rc == SQLITE_OK )
2293
+ {
2294
+ /* Open the master journal. */
2295
+ rc = sqlite3OsOpenMalloc( ref pVfs, zMaster, pMaster,
2296
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
2297
+ SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_MASTER_JOURNAL, ref rc
2298
+ );
2299
+ } if ( rc != SQLITE_OK )
2300
+ {
2301
+ sqlite3DbFree( db, ref zMaster );
2302
+ return rc;
2303
+ }
2304
+
2305
+ /* Write the name of each database file in the transaction into the new
2306
+ ** master journal file. If an error occurs at this point close
2307
+ ** and delete the master journal file. All the individual journal files
2308
+ ** still have 'null' as the master journal pointer, so they will roll
2309
+ ** back independently if a failure occurs.
2310
+ */
2311
+ for ( i = 0; i < db.nDb; i++ )
2312
+ {
2313
+ Btree pBt = db.aDb[i].pBt;
2314
+ if ( sqlite3BtreeIsInTrans( pBt ) )
2315
+ {
2316
+ string zFile = sqlite3BtreeGetJournalname( pBt );
2317
+ if ( String.IsNullOrEmpty( zFile ) )// zFile == 0 || zFile[0] == 0)
2318
+ {
2319
+ continue; /* Ignore TEMP and :memory: databases */
2320
+ }
2321
+ if ( !needSync && 0 == sqlite3BtreeSyncDisabled( pBt ) )
2322
+ {
2323
+ needSync = true;
2324
+ }
2325
+ rc = sqlite3OsWrite( pMaster, Encoding.UTF8.GetBytes( zFile ), sqlite3Strlen30( zFile ), offset );
2326
+ offset += sqlite3Strlen30( zFile );
2327
+ if ( rc != SQLITE_OK )
2328
+ {
2329
+ sqlite3OsCloseFree( pMaster );
2330
+ sqlite3OsDelete( pVfs, zMaster, 0 );
2331
+ sqlite3DbFree( db, ref zMaster );
2332
+ return rc;
2333
+ }
2334
+ }
2335
+ }
2336
+
2337
+ /* Sync the master journal file. If the IOCAP_SEQUENTIAL device
2338
+ ** flag is set this is not required.
2339
+ */
2340
+ if ( needSync
2341
+ && 0 == ( sqlite3OsDeviceCharacteristics( pMaster ) & SQLITE_IOCAP_SEQUENTIAL )
2342
+ && SQLITE_OK != ( rc = sqlite3OsSync( pMaster, SQLITE_SYNC_NORMAL ) )
2343
+ )
2344
+ {
2345
+ sqlite3OsCloseFree( pMaster );
2346
+ sqlite3OsDelete( pVfs, zMaster, 0 );
2347
+ sqlite3DbFree( db, ref zMaster );
2348
+ return rc;
2349
+ }
2350
+
2351
+ /* Sync all the db files involved in the transaction. The same call
2352
+ ** sets the master journal pointer in each individual journal. If
2353
+ ** an error occurs here, do not delete the master journal file.
2354
+ **
2355
+ ** If the error occurs during the first call to
2356
+ ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the
2357
+ ** master journal file will be orphaned. But we cannot delete it,
2358
+ ** in case the master journal file name was written into the journal
2359
+ ** file before the failure occurred.
2360
+ */
2361
+ for ( i = 0; rc == SQLITE_OK && i < db.nDb; i++ )
2362
+ {
2363
+ Btree pBt = db.aDb[i].pBt;
2364
+ if ( pBt != null )
2365
+ {
2366
+ rc = sqlite3BtreeCommitPhaseOne( pBt, zMaster );
2367
+ }
2368
+ }
2369
+ sqlite3OsCloseFree( pMaster );
2370
+ if ( rc != SQLITE_OK )
2371
+ {
2372
+ sqlite3DbFree( db, ref zMaster );
2373
+ return rc;
2374
+ }
2375
+
2376
+ /* Delete the master journal file. This commits the transaction. After
2377
+ ** doing this the directory is synced again before any individual
2378
+ ** transaction files are deleted.
2379
+ */
2380
+ rc = sqlite3OsDelete( pVfs, zMaster, 1 );
2381
+ sqlite3DbFree( db, ref zMaster );
2382
+ if ( rc != 0 )
2383
+ {
2384
+ return rc;
2385
+ }
2386
+
2387
+ /* All files and directories have already been synced, so the following
2388
+ ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and
2389
+ ** deleting or truncating journals. If something goes wrong while
2390
+ ** this is happening we don't really care. The integrity of the
2391
+ ** transaction is already guaranteed, but some stray 'cold' journals
2392
+ ** may be lying around. Returning an error code won't help matters.
2393
+ */
2394
+ #if SQLITE_TEST
2395
+ disable_simulated_io_errors();
2396
+ #endif
2397
+ sqlite3BeginBenignMalloc();
2398
+ for ( i = 0; i < db.nDb; i++ )
2399
+ {
2400
+ Btree pBt = db.aDb[i].pBt;
2401
+ if ( pBt != null )
2402
+ {
2403
+ sqlite3BtreeCommitPhaseTwo( pBt );
2404
+ }
2405
+ }
2406
+ sqlite3EndBenignMalloc();
2407
+ #if SQLITE_TEST
2408
+ enable_simulated_io_errors();
2409
+ #endif
2410
+ sqlite3VtabCommit( db );
2411
+ }
2412
+ #endif
2413
+
2414
+ return rc;
2415
+ }
2416
+
2417
+ /*
2418
+ ** This routine checks that the sqlite3.activeVdbeCnt count variable
2419
+ ** matches the number of vdbe's in the list sqlite3.pVdbe that are
2420
+ ** currently active. An Debug.Assertion fails if the two counts do not match.
2421
+ ** This is an internal self-check only - it is not an essential processing
2422
+ ** step.
2423
+ **
2424
+ ** This is a no-op if NDEBUG is defined.
2425
+ */
2426
+ #if !NDEBUG
2427
+ static void checkActiveVdbeCnt( sqlite3 db )
2428
+ {
2429
+ Vdbe p;
2430
+ int cnt = 0;
2431
+ int nWrite = 0;
2432
+ p = db.pVdbe;
2433
+ while ( p != null )
2434
+ {
2435
+ if ( p.magic == VDBE_MAGIC_RUN && p.pc >= 0 )
2436
+ {
2437
+ cnt++;
2438
+ if ( p.readOnly == false ) nWrite++;
2439
+ }
2440
+ p = p.pNext;
2441
+ }
2442
+ Debug.Assert( cnt == db.activeVdbeCnt );
2443
+ Debug.Assert( nWrite == db.writeVdbeCnt );
2444
+ }
2445
+ #else
2446
+ //#define checkActiveVdbeCnt(x)
2447
+ static void checkActiveVdbeCnt( sqlite3 db ){}
2448
+ #endif
2449
+
2450
+ /*
2451
+ ** For every Btree that in database connection db which
2452
+ ** has been modified, "trip" or invalidate each cursor in
2453
+ ** that Btree might have been modified so that the cursor
2454
+ ** can never be used again. This happens when a rollback
2455
+ *** occurs. We have to trip all the other cursors, even
2456
+ ** cursor from other VMs in different database connections,
2457
+ ** so that none of them try to use the data at which they
2458
+ ** were pointing and which now may have been changed due
2459
+ ** to the rollback.
2460
+ **
2461
+ ** Remember that a rollback can delete tables complete and
2462
+ ** reorder rootpages. So it is not sufficient just to save
2463
+ ** the state of the cursor. We have to invalidate the cursor
2464
+ ** so that it is never used again.
2465
+ */
2466
+ static void invalidateCursorsOnModifiedBtrees( sqlite3 db )
2467
+ {
2468
+ int i;
2469
+ for ( i = 0; i < db.nDb; i++ )
2470
+ {
2471
+ Btree p = db.aDb[i].pBt;
2472
+ if ( p != null && sqlite3BtreeIsInTrans( p ) )
2473
+ {
2474
+ sqlite3BtreeTripAllCursors( p, SQLITE_ABORT );
2475
+ }
2476
+ }
2477
+ }
2478
+
2479
+ /*
2480
+ ** If the Vdbe passed as the first argument opened a statement-transaction,
2481
+ ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
2482
+ ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
2483
+ ** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the
2484
+ ** statement transaction is commtted.
2485
+ **
2486
+ ** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
2487
+ ** Otherwise SQLITE_OK.
2488
+ */
2489
+ static int sqlite3VdbeCloseStatement( Vdbe p, int eOp )
2490
+ {
2491
+ sqlite3 db = p.db;
2492
+ int rc = SQLITE_OK;
2493
+ /* If p->iStatement is greater than zero, then this Vdbe opened a
2494
+ ** statement transaction that should be closed here. The only exception
2495
+ ** is that an IO error may have occured, causing an emergency rollback.
2496
+ ** In this case (db->nStatement==0), and there is nothing to do.
2497
+ */
2498
+ if ( db.nStatement != 0 && p.iStatement != 0 )
2499
+ {
2500
+ int i;
2501
+ int iSavepoint = p.iStatement - 1;
2502
+
2503
+ Debug.Assert( eOp == SAVEPOINT_ROLLBACK || eOp == SAVEPOINT_RELEASE );
2504
+ Debug.Assert( db.nStatement > 0 );
2505
+ Debug.Assert( p.iStatement == ( db.nStatement + db.nSavepoint ) );
2506
+
2507
+ for ( i = 0; i < db.nDb; i++ )
2508
+ {
2509
+ int rc2 = SQLITE_OK;
2510
+ Btree pBt = db.aDb[i].pBt;
2511
+ if ( pBt != null )
2512
+ {
2513
+ if ( eOp == SAVEPOINT_ROLLBACK )
2514
+ {
2515
+ rc2 = sqlite3BtreeSavepoint( pBt, SAVEPOINT_ROLLBACK, iSavepoint );
2516
+ }
2517
+ if ( rc2 == SQLITE_OK )
2518
+ {
2519
+ rc2 = sqlite3BtreeSavepoint( pBt, SAVEPOINT_RELEASE, iSavepoint );
2520
+ }
2521
+ if ( rc == SQLITE_OK )
2522
+ {
2523
+ rc = rc2;
2524
+ }
2525
+ }
2526
+ }
2527
+ db.nStatement--;
2528
+ p.iStatement = 0;
2529
+
2530
+ /* If the statement transaction is being rolled back, also restore the
2531
+ ** database handles deferred constraint counter to the value it had when
2532
+ ** the statement transaction was opened. */
2533
+ if ( eOp == SAVEPOINT_ROLLBACK )
2534
+ {
2535
+ db.nDeferredCons = p.nStmtDefCons;
2536
+ }
2537
+ }
2538
+ return rc;
2539
+ }
2540
+
2541
+ /*
2542
+ ** If SQLite is compiled to support shared-cache mode and to be threadsafe,
2543
+ ** this routine obtains the mutex associated with each BtShared structure
2544
+ ** that may be accessed by the VM passed as an argument. In doing so it
2545
+ ** sets the BtShared.db member of each of the BtShared structures, ensuring
2546
+ ** that the correct busy-handler callback is invoked if required.
2547
+ **
2548
+ ** If SQLite is not threadsafe but does support shared-cache mode, then
2549
+ ** sqlite3BtreeEnterAll() is invoked to set the BtShared.db variables
2550
+ ** of all of BtShared structures accessible via the database handle
2551
+ ** associated with the VM. Of course only a subset of these structures
2552
+ ** will be accessed by the VM, and we could use Vdbe.btreeMask to figure
2553
+ ** that subset out, but there is no advantage to doing so.
2554
+ **
2555
+ ** If SQLite is not threadsafe and does not support shared-cache mode, this
2556
+ ** function is a no-op.
2557
+ */
2558
+ #if !SQLITE_OMIT_SHARED_CACHE
2559
+ static void sqlite3VdbeMutexArrayEnter(Vdbe p){
2560
+ #if SQLITE_THREADSAFE
2561
+ sqlite3BtreeMutexArrayEnter(&p->aMutex);
2562
+ #else
2563
+ sqlite3BtreeEnterAll(p.db);
2564
+ #endif
2565
+ }
2566
+ #endif
2567
+
2568
+ /*
2569
+ ** This function is called when a transaction opened by the database
2570
+ ** handle associated with the VM passed as an argument is about to be
2571
+ ** committed. If there are outstanding deferred foreign key constraint
2572
+ ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
2573
+ **
2574
+ ** If there are outstanding FK violations and this function returns
2575
+ ** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
2576
+ ** an error message to it. Then return SQLITE_ERROR.
2577
+ */
2578
+ #if !SQLITE_OMIT_FOREIGN_KEY
2579
+ static int sqlite3VdbeCheckFk( Vdbe p, int deferred )
2580
+ {
2581
+ sqlite3 db = p.db;
2582
+ if ( ( deferred != 0 && db.nDeferredCons > 0 ) || ( 0 == deferred && p.nFkConstraint > 0 ) )
2583
+ {
2584
+ p.rc = SQLITE_CONSTRAINT;
2585
+ p.errorAction = OE_Abort;
2586
+ sqlite3SetString( ref p.zErrMsg, db, "foreign key constraint failed" );
2587
+ return SQLITE_ERROR;
2588
+ }
2589
+ return SQLITE_OK;
2590
+ }
2591
+ #endif
2592
+
2593
+ /*
2594
+ ** This routine is called the when a VDBE tries to halt. If the VDBE
2595
+ ** has made changes and is in autocommit mode, then commit those
2596
+ ** changes. If a rollback is needed, then do the rollback.
2597
+ **
2598
+ ** This routine is the only way to move the state of a VM from
2599
+ ** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to
2600
+ ** call this on a VM that is in the SQLITE_MAGIC_HALT state.
2601
+ **
2602
+ ** Return an error code. If the commit could not complete because of
2603
+ ** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
2604
+ ** means the close did not happen and needs to be repeated.
2605
+ */
2606
+ static int sqlite3VdbeHalt( Vdbe p )
2607
+ {
2608
+ int rc; /* Used to store transient return codes */
2609
+ sqlite3 db = p.db;
2610
+
2611
+ /* This function contains the logic that determines if a statement or
2612
+ ** transaction will be committed or rolled back as a result of the
2613
+ ** execution of this virtual machine.
2614
+ **
2615
+ ** If any of the following errors occur:
2616
+ **
2617
+ ** SQLITE_NOMEM
2618
+ ** SQLITE_IOERR
2619
+ ** SQLITE_FULL
2620
+ ** SQLITE_INTERRUPT
2621
+ **
2622
+ ** Then the internal cache might have been left in an inconsistent
2623
+ ** state. We need to rollback the statement transaction, if there is
2624
+ ** one, or the complete transaction if there is no statement transaction.
2625
+ */
2626
+
2627
+ //if ( p.db.mallocFailed != 0 )
2628
+ //{
2629
+ // p.rc = SQLITE_NOMEM;
2630
+ //}
2631
+ closeAllCursors( p );
2632
+ if ( p.magic != VDBE_MAGIC_RUN )
2633
+ {
2634
+ return SQLITE_OK;
2635
+ }
2636
+ checkActiveVdbeCnt( db );
2637
+
2638
+ /* No commit or rollback needed if the program never started */
2639
+ if ( p.pc >= 0 )
2640
+ {
2641
+ int mrc; /* Primary error code from p.rc */
2642
+ int eStatementOp = 0;
2643
+ bool isSpecialError = false; /* Set to true if a 'special' error */
2644
+
2645
+ /* Lock all btrees used by the statement */
2646
+ sqlite3VdbeMutexArrayEnter( p );
2647
+ /* Check for one of the special errors */
2648
+ mrc = p.rc & 0xff;
2649
+ Debug.Assert( p.rc != SQLITE_IOERR_BLOCKED ); /* This error no longer exists */
2650
+ isSpecialError = mrc == SQLITE_NOMEM || mrc == SQLITE_IOERR
2651
+ || mrc == SQLITE_INTERRUPT || mrc == SQLITE_FULL;
2652
+ if ( isSpecialError )
2653
+ {
2654
+ /* If the query was read-only, we need do no rollback at all. Otherwise,
2655
+ ** proceed with the special handling.
2656
+ */
2657
+ if ( !p.readOnly || mrc != SQLITE_INTERRUPT )
2658
+ {
2659
+ if ( ( mrc == SQLITE_NOMEM || mrc == SQLITE_FULL ) && p.usesStmtJournal )
2660
+ {
2661
+ eStatementOp = SAVEPOINT_ROLLBACK;
2662
+ }
2663
+ else
2664
+ {
2665
+ /* We are forced to roll back the active transaction. Before doing
2666
+ ** so, abort any other statements this handle currently has active.
2667
+ */
2668
+ invalidateCursorsOnModifiedBtrees( db );
2669
+ sqlite3RollbackAll( db );
2670
+ sqlite3CloseSavepoints( db );
2671
+ db.autoCommit = 1;
2672
+ }
2673
+ }
2674
+ }
2675
+
2676
+ /* Check for immediate foreign key violations. */
2677
+ if ( p.rc == SQLITE_OK )
2678
+ {
2679
+ sqlite3VdbeCheckFk( p, 0 );
2680
+ }
2681
+
2682
+ /* If the auto-commit flag is set and this is the only active writer
2683
+ ** VM, then we do either a commit or rollback of the current transaction.
2684
+ **
2685
+ ** Note: This block also runs if one of the special errors handled
2686
+ ** above has occurred.
2687
+ */
2688
+ if ( !sqlite3VtabInSync( db )
2689
+ && db.autoCommit != 0
2690
+ && db.writeVdbeCnt == ( ( p.readOnly == false ) ? 1 : 0 )
2691
+ )
2692
+ {
2693
+ if ( p.rc == SQLITE_OK || ( p.errorAction == OE_Fail && !isSpecialError ) )
2694
+ {
2695
+ if ( sqlite3VdbeCheckFk( p, 1 ) != 0 )
2696
+ {
2697
+ sqlite3BtreeMutexArrayLeave( p.aMutex );
2698
+ return SQLITE_ERROR;
2699
+ }
2700
+ /* The auto-commit flag is true, the vdbe program was successful
2701
+ ** or hit an 'OR FAIL' constraint and there are no deferred foreign
2702
+ ** key constraints to hold up the transaction. This means a commit
2703
+ ** is required. */
2704
+ rc = vdbeCommit( db, p );
2705
+ if ( rc == SQLITE_BUSY )
2706
+ {
2707
+ sqlite3BtreeMutexArrayLeave( p.aMutex );
2708
+ return SQLITE_BUSY;
2709
+ }
2710
+ else if ( rc != SQLITE_OK )
2711
+ {
2712
+ p.rc = rc;
2713
+ sqlite3RollbackAll( db );
2714
+ }
2715
+ else
2716
+ {
2717
+ db.nDeferredCons = 0;
2718
+ sqlite3CommitInternalChanges( db );
2719
+ }
2720
+ }
2721
+ else
2722
+ {
2723
+ sqlite3RollbackAll( db );
2724
+ }
2725
+ db.nStatement = 0;
2726
+ }
2727
+ else if ( eStatementOp == 0 )
2728
+ {
2729
+ if ( p.rc == SQLITE_OK || p.errorAction == OE_Fail )
2730
+ {
2731
+ eStatementOp = SAVEPOINT_RELEASE;
2732
+ }
2733
+ else if ( p.errorAction == OE_Abort )
2734
+ {
2735
+ eStatementOp = SAVEPOINT_ROLLBACK;
2736
+ }
2737
+ else
2738
+ {
2739
+ invalidateCursorsOnModifiedBtrees( db );
2740
+ sqlite3RollbackAll( db );
2741
+ sqlite3CloseSavepoints( db );
2742
+ db.autoCommit = 1;
2743
+ }
2744
+ }
2745
+
2746
+ /* If eStatementOp is non-zero, then a statement transaction needs to
2747
+ ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to
2748
+ ** do so. If this operation returns an error, and the current statement
2749
+ ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the
2750
+ ** current statement error code.
2751
+ **
2752
+ ** Note that sqlite3VdbeCloseStatement() can only fail if eStatementOp
2753
+ ** is SAVEPOINT_ROLLBACK. But if p->rc==SQLITE_OK then eStatementOp
2754
+ ** must be SAVEPOINT_RELEASE. Hence the NEVER(p->rc==SQLITE_OK) in
2755
+ ** the following code.
2756
+ */
2757
+ if (eStatementOp != 0)
2758
+ {
2759
+ rc = sqlite3VdbeCloseStatement( p, eStatementOp );
2760
+ if ( rc != 0 && (NEVER( p.rc == SQLITE_OK) || p.rc == SQLITE_CONSTRAINT ) )
2761
+ {
2762
+ p.rc = rc;
2763
+ sqlite3DbFree( db, ref p.zErrMsg );
2764
+ p.zErrMsg = null;
2765
+ }
2766
+ }
2767
+
2768
+ /* If this was an INSERT, UPDATE or DELETE and no statement transaction
2769
+ ** has been rolled back, update the database connection change-counter.
2770
+ */
2771
+ if ( p.changeCntOn )
2772
+ {
2773
+ if ( eStatementOp != SAVEPOINT_ROLLBACK )
2774
+ {
2775
+ sqlite3VdbeSetChanges( db, p.nChange );
2776
+ }
2777
+ else
2778
+ {
2779
+ sqlite3VdbeSetChanges( db, 0 );
2780
+ }
2781
+ p.nChange = 0;
2782
+ }
2783
+
2784
+ /* Rollback or commit any schema changes that occurred. */
2785
+ if ( p.rc != SQLITE_OK && ( db.flags & SQLITE_InternChanges ) != 0 )
2786
+ {
2787
+ sqlite3ResetInternalSchema( db, 0 );
2788
+ db.flags = ( db.flags | SQLITE_InternChanges );
2789
+ }
2790
+
2791
+ /* Release the locks */
2792
+ sqlite3BtreeMutexArrayLeave( p.aMutex );
2793
+ }
2794
+
2795
+ /* We have successfully halted and closed the VM. Record this fact. */
2796
+ if ( p.pc >= 0 )
2797
+ {
2798
+ db.activeVdbeCnt--;
2799
+ if ( !p.readOnly )
2800
+ {
2801
+ db.writeVdbeCnt--;
2802
+ }
2803
+ Debug.Assert( db.activeVdbeCnt >= db.writeVdbeCnt );
2804
+ }
2805
+ p.magic = VDBE_MAGIC_HALT;
2806
+ checkActiveVdbeCnt( db );
2807
+ //if ( p.db.mallocFailed != 0 )
2808
+ //{
2809
+ // p.rc = SQLITE_NOMEM;
2810
+ //}
2811
+ /* If the auto-commit flag is set to true, then any locks that were held
2812
+ ** by connection db have now been released. Call sqlite3ConnectionUnlocked()
2813
+ ** to invoke any required unlock-notify callbacks.
2814
+ */
2815
+ if ( db.autoCommit != 0 )
2816
+ {
2817
+ sqlite3ConnectionUnlocked( db );
2818
+ }
2819
+
2820
+ Debug.Assert( db.activeVdbeCnt > 0 || db.autoCommit == 0 || db.nStatement == 0 );
2821
+ return SQLITE_OK;
2822
+ }
2823
+
2824
+
2825
+ /*
2826
+ ** Each VDBE holds the result of the most recent sqlite3_step() call
2827
+ ** in p.rc. This routine sets that result back to SQLITE_OK.
2828
+ */
2829
+ static void sqlite3VdbeResetStepResult( Vdbe p )
2830
+ {
2831
+ p.rc = SQLITE_OK;
2832
+ }
2833
+
2834
+ /*
2835
+ ** Clean up a VDBE after execution but do not delete the VDBE just yet.
2836
+ ** Write any error messages into pzErrMsg. Return the result code.
2837
+ **
2838
+ ** After this routine is run, the VDBE should be ready to be executed
2839
+ ** again.
2840
+ **
2841
+ ** To look at it another way, this routine resets the state of the
2842
+ ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
2843
+ ** VDBE_MAGIC_INIT.
2844
+ */
2845
+ static int sqlite3VdbeReset( Vdbe p )
2846
+ {
2847
+ sqlite3 db;
2848
+ db = p.db;
2849
+
2850
+ /* If the VM did not run to completion or if it encountered an
2851
+ ** error, then it might not have been halted properly. So halt
2852
+ ** it now.
2853
+ */
2854
+ sqlite3VdbeHalt( p );
2855
+
2856
+ /* If the VDBE has be run even partially, then transfer the error code
2857
+ ** and error message from the VDBE into the main database structure. But
2858
+ ** if the VDBE has just been set to run but has not actually executed any
2859
+ ** instructions yet, leave the main database error information unchanged.
2860
+ */
2861
+ if ( p.pc >= 0 )
2862
+ {
2863
+ //if ( p.zErrMsg != 0 ) // Always exists under C#
2864
+ {
2865
+ sqlite3BeginBenignMalloc();
2866
+ sqlite3ValueSetStr( db.pErr, -1, p.zErrMsg == null ? "" : p.zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT );
2867
+ sqlite3EndBenignMalloc();
2868
+ db.errCode = p.rc;
2869
+ sqlite3DbFree( db, ref p.zErrMsg );
2870
+ p.zErrMsg = "";
2871
+ }
2872
+ //else if ( p.rc != 0 )
2873
+ //{
2874
+ // sqlite3Error( db, p.rc, 0 );
2875
+ //}
2876
+ //else
2877
+ //{
2878
+ // sqlite3Error( db, SQLITE_OK, 0 );
2879
+ //}
2880
+ if (p.runOnlyOnce != 0) p.expired = true;
2881
+ }
2882
+ else if ( p.rc != 0 && p.expired )
2883
+ {
2884
+ /* The expired flag was set on the VDBE before the first call
2885
+ ** to sqlite3_step(). For consistency (since sqlite3_step() was
2886
+ ** called), set the database error in this case as well.
2887
+ */
2888
+ sqlite3Error( db, p.rc, 0 );
2889
+ sqlite3ValueSetStr( db.pErr, -1, p.zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT );
2890
+ sqlite3DbFree( db, ref p.zErrMsg );
2891
+ p.zErrMsg = "";
2892
+ }
2893
+
2894
+ /* Reclaim all memory used by the VDBE
2895
+ */
2896
+ Cleanup( p );
2897
+
2898
+ /* Save profiling information from this VDBE run.
2899
+ */
2900
+ #if VDBE_PROFILE && TODO
2901
+ {
2902
+ FILE *out = fopen("vdbe_profile.out", "a");
2903
+ if( out ){
2904
+ int i;
2905
+ fprintf(out, "---- ");
2906
+ for(i=0; i<p.nOp; i++){
2907
+ fprintf(out, "%02x", p.aOp[i].opcode);
2908
+ }
2909
+ fprintf(out, "\n");
2910
+ for(i=0; i<p.nOp; i++){
2911
+ fprintf(out, "%6d %10lld %8lld ",
2912
+ p.aOp[i].cnt,
2913
+ p.aOp[i].cycles,
2914
+ p.aOp[i].cnt>0 ? p.aOp[i].cycles/p.aOp[i].cnt : 0
2915
+ );
2916
+ sqlite3VdbePrintOp(out, i, p.aOp[i]);
2917
+ }
2918
+ fclose(out);
2919
+ }
2920
+ }
2921
+ #endif
2922
+ p.magic = VDBE_MAGIC_INIT;
2923
+ return p.rc & db.errMask;
2924
+ }
2925
+
2926
+ /*
2927
+ ** Clean up and delete a VDBE after execution. Return an integer which is
2928
+ ** the result code. Write any error message text into pzErrMsg.
2929
+ */
2930
+ static int sqlite3VdbeFinalize( Vdbe p )
2931
+ {
2932
+ int rc = SQLITE_OK;
2933
+ if ( p.magic == VDBE_MAGIC_RUN || p.magic == VDBE_MAGIC_HALT )
2934
+ {
2935
+ rc = sqlite3VdbeReset( p );
2936
+ Debug.Assert( ( rc & p.db.errMask ) == rc );
2937
+ }
2938
+ sqlite3VdbeDelete( ref p );
2939
+ return rc;
2940
+ }
2941
+
2942
+ /*
2943
+ ** Call the destructor for each auxdata entry in pVdbeFunc for which
2944
+ ** the corresponding bit in mask is clear. Auxdata entries beyond 31
2945
+ ** are always destroyed. To destroy all auxdata entries, call this
2946
+ ** routine with mask==0.
2947
+ */
2948
+ static void sqlite3VdbeDeleteAuxData( VdbeFunc pVdbeFunc, int mask )
2949
+ {
2950
+ int i;
2951
+ for ( i = 0; i < pVdbeFunc.nAux; i++ )
2952
+ {
2953
+ AuxData pAux = pVdbeFunc.apAux[i];
2954
+ if ( ( i > 31 || ( mask & ( ( (u32)1 ) << i ) ) == 0 && pAux.pAux != null ) )
2955
+ {
2956
+ if ( pAux.xDelete != null )
2957
+ {
2958
+ pAux.xDelete( ref pAux.pAux );
2959
+ }
2960
+ pAux.pAux = null;
2961
+ }
2962
+ }
2963
+ }
2964
+
2965
+ /*
2966
+ ** Delete an entire VDBE.
2967
+ */
2968
+ static void sqlite3VdbeDelete( ref Vdbe p )
2969
+ {
2970
+ sqlite3 db;
2971
+ if ( NEVER( p == null ) ) return;
2972
+ Cleanup( p );
2973
+ db = p.db;
2974
+ if ( p.pPrev != null )
2975
+ {
2976
+ p.pPrev.pNext = p.pNext;
2977
+ }
2978
+ else
2979
+ {
2980
+ Debug.Assert( db.pVdbe == p );
2981
+ db.pVdbe = p.pNext;
2982
+ }
2983
+ if ( p.pNext != null )
2984
+ {
2985
+ p.pNext.pPrev = p.pPrev;
2986
+ }
2987
+ releaseMemArray( p.aVar, p.nVar );
2988
+ releaseMemArray( p.aColName, p.nResColumn * COLNAME_N );
2989
+ vdbeFreeOpArray( db, ref p.aOp, p.nOp );
2990
+ sqlite3DbFree( db, ref p.aLabel );
2991
+ sqlite3DbFree( db, ref p.aColName );
2992
+ sqlite3DbFree( db, ref p.zSql );
2993
+ p.magic = VDBE_MAGIC_DEAD;
2994
+ sqlite3DbFree( db, ref p.pFree );
2995
+ p.db = null;
2996
+ if (p.aMem != null) releaseMemArray(p.aMem, p.aMem.Length);
2997
+ if (p.apArg != null) releaseMemArray(p.apArg, p.apArg.Length);
2998
+ sqlite3DbFree( db, ref p );
2999
+ }
3000
+
3001
+ /*
3002
+ ** Make sure the cursor p is ready to read or write the row to which it
3003
+ ** was last positioned. Return an error code if an OOM fault or I/O error
3004
+ ** prevents us from positioning the cursor to its correct position.
3005
+ **
3006
+ ** If a MoveTo operation is pending on the given cursor, then do that
3007
+ ** MoveTo now. If no move is pending, check to see if the row has been
3008
+ ** deleted out from under the cursor and if it has, mark the row as
3009
+ ** a NULL row.
3010
+ **
3011
+ ** If the cursor is already pointing to the correct row and that row has
3012
+ ** not been deleted out from under the cursor, then this routine is a no-op.
3013
+ */
3014
+ static int sqlite3VdbeCursorMoveto( VdbeCursor p )
3015
+ {
3016
+ if ( p.deferredMoveto )
3017
+ {
3018
+ int res = 0; int rc;
3019
+ #if SQLITE_TEST
3020
+ //extern int sqlite3_search_count;
3021
+ #endif
3022
+ Debug.Assert( p.isTable );
3023
+ rc = sqlite3BtreeMovetoUnpacked( p.pCursor, null, p.movetoTarget, 0, ref res );
3024
+ if ( rc != 0 ) return rc;
3025
+ p.lastRowid = p.movetoTarget;
3026
+ p.rowidIsValid = ALWAYS( res == 0 ) ? true : false;
3027
+ if ( NEVER( res < 0 ) )
3028
+ {
3029
+ rc = sqlite3BtreeNext( p.pCursor, ref res );
3030
+ if ( rc != 0 ) return rc;
3031
+ }
3032
+ #if SQLITE_TEST
3033
+ sqlite3_search_count.iValue++;
3034
+ #endif
3035
+ p.deferredMoveto = false;
3036
+ p.cacheStatus = CACHE_STALE;
3037
+ }
3038
+ else if ( ALWAYS( p.pCursor != null ) )
3039
+ {
3040
+ int hasMoved = 0;
3041
+ int rc = sqlite3BtreeCursorHasMoved( p.pCursor, ref hasMoved );
3042
+ if ( rc != 0 ) return rc;
3043
+ if ( hasMoved != 0 )
3044
+ {
3045
+ p.cacheStatus = CACHE_STALE;
3046
+ p.nullRow = true;
3047
+ }
3048
+ }
3049
+ return SQLITE_OK;
3050
+ }
3051
+
3052
+ /*
3053
+ ** The following functions:
3054
+ **
3055
+ ** sqlite3VdbeSerialType()
3056
+ ** sqlite3VdbeSerialTypeLen()
3057
+ ** sqlite3VdbeSerialLen()
3058
+ ** sqlite3VdbeSerialPut()
3059
+ ** sqlite3VdbeSerialGet()
3060
+ **
3061
+ ** encapsulate the code that serializes values for storage in SQLite
3062
+ ** data and index records. Each serialized value consists of a
3063
+ ** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
3064
+ ** integer, stored as a varint.
3065
+ **
3066
+ ** In an SQLite index record, the serial type is stored directly before
3067
+ ** the blob of data that it corresponds to. In a table record, all serial
3068
+ ** types are stored at the start of the record, and the blobs of data at
3069
+ ** the end. Hence these functions allow the caller to handle the
3070
+ ** serial-type and data blob seperately.
3071
+ **
3072
+ ** The following table describes the various storage classes for data:
3073
+ **
3074
+ ** serial type bytes of data type
3075
+ ** -------------- --------------- ---------------
3076
+ ** 0 0 NULL
3077
+ ** 1 1 signed integer
3078
+ ** 2 2 signed integer
3079
+ ** 3 3 signed integer
3080
+ ** 4 4 signed integer
3081
+ ** 5 6 signed integer
3082
+ ** 6 8 signed integer
3083
+ ** 7 8 IEEE float
3084
+ ** 8 0 Integer constant 0
3085
+ ** 9 0 Integer constant 1
3086
+ ** 10,11 reserved for expansion
3087
+ ** N>=12 and even (N-12)/2 BLOB
3088
+ ** N>=13 and odd (N-13)/2 text
3089
+ **
3090
+ ** The 8 and 9 types were added in 3.3.0, file format 4. Prior versions
3091
+ ** of SQLite will not understand those serial types.
3092
+ */
3093
+
3094
+ /*
3095
+ ** Return the serial-type for the value stored in pMem.
3096
+ */
3097
+ static u32 sqlite3VdbeSerialType( Mem pMem, int file_format )
3098
+ {
3099
+ int flags = pMem.flags;
3100
+ int n;
3101
+
3102
+ if ( ( flags & MEM_Null ) != 0 )
3103
+ {
3104
+ return 0;
3105
+ }
3106
+ if ( ( flags & MEM_Int ) != 0 )
3107
+ {
3108
+ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
3109
+ const i64 MAX_6BYTE = ( ( ( (i64)0x00008000 ) << 32 ) - 1 );
3110
+ i64 i = pMem.u.i;
3111
+ u64 u;
3112
+ if ( file_format >= 4 && ( i & 1 ) == i )
3113
+ {
3114
+ return 8 + (u32)i;
3115
+ }
3116
+ u = (ulong)( i < 0 ? -i : i );
3117
+ if ( u <= 127 ) return 1;
3118
+ if ( u <= 32767 ) return 2;
3119
+ if ( u <= 8388607 ) return 3;
3120
+ if ( u <= 2147483647 ) return 4;
3121
+ if ( u <= MAX_6BYTE ) return 5;
3122
+ return 6;
3123
+ }
3124
+ if ( ( flags & MEM_Real ) != 0 )
3125
+ {
3126
+ return 7;
3127
+ }
3128
+ Debug.Assert( /* pMem.db.mallocFailed != 0 || */ ( flags & ( MEM_Str | MEM_Blob ) ) != 0 );
3129
+ n = pMem.n;
3130
+ if ( ( flags & MEM_Zero ) != 0 )
3131
+ {
3132
+ n += pMem.u.nZero;
3133
+ }
3134
+ else if ( ( flags & MEM_Blob ) != 0 )
3135
+ {
3136
+ n = pMem.zBLOB != null ? pMem.zBLOB.Length : pMem.z != null ? pMem.z.Length : 0;
3137
+ }
3138
+ else
3139
+ {
3140
+ if ( pMem.z != null ) n = Encoding.UTF8.GetByteCount( pMem.n < pMem.z.Length ? pMem.z.Substring( 0, pMem.n ) : pMem.z );
3141
+ else n = pMem.zBLOB.Length;
3142
+ pMem.n = n;
3143
+ }
3144
+
3145
+ Debug.Assert( n >= 0 );
3146
+ return (u32)( ( n * 2 ) + 12 + ( ( ( flags & MEM_Str ) != 0 ) ? 1 : 0 ) );
3147
+ }
3148
+
3149
+ /*
3150
+ ** Return the length of the data corresponding to the supplied serial-type.
3151
+ */
3152
+ static u32 sqlite3VdbeSerialTypeLen( u32 serial_type )
3153
+ {
3154
+ if ( serial_type >= 12 )
3155
+ {
3156
+ return (u32)( ( serial_type - 12 ) / 2 );
3157
+ }
3158
+ else
3159
+ {
3160
+ u32[] aSize = new u32[] { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
3161
+ return aSize[serial_type];
3162
+ }
3163
+ }
3164
+
3165
+ /*
3166
+ ** If we are on an architecture with mixed-endian floating
3167
+ ** points (ex: ARM7) then swap the lower 4 bytes with the
3168
+ ** upper 4 bytes. Return the result.
3169
+ **
3170
+ ** For most architectures, this is a no-op.
3171
+ **
3172
+ ** (later): It is reported to me that the mixed-endian problem
3173
+ ** on ARM7 is an issue with GCC, not with the ARM7 chip. It seems
3174
+ ** that early versions of GCC stored the two words of a 64-bit
3175
+ ** float in the wrong order. And that error has been propagated
3176
+ ** ever since. The blame is not necessarily with GCC, though.
3177
+ ** GCC might have just copying the problem from a prior compiler.
3178
+ ** I am also told that newer versions of GCC that follow a different
3179
+ ** ABI get the byte order right.
3180
+ **
3181
+ ** Developers using SQLite on an ARM7 should compile and run their
3182
+ ** application using -DSQLITE_DEBUG=1 at least once. With DEBUG
3183
+ ** enabled, some Debug.Asserts below will ensure that the byte order of
3184
+ ** floating point values is correct.
3185
+ **
3186
+ ** (2007-08-30) Frank van Vugt has studied this problem closely
3187
+ ** and has send his findings to the SQLite developers. Frank
3188
+ ** writes that some Linux kernels offer floating point hardware
3189
+ ** emulation that uses only 32-bit mantissas instead of a full
3190
+ ** 48-bits as required by the IEEE standard. (This is the
3191
+ ** CONFIG_FPE_FASTFPE option.) On such systems, floating point
3192
+ ** byte swapping becomes very complicated. To avoid problems,
3193
+ ** the necessary byte swapping is carried out using a 64-bit integer
3194
+ ** rather than a 64-bit float. Frank assures us that the code here
3195
+ ** works for him. We, the developers, have no way to independently
3196
+ ** verify this, but Frank seems to know what he is talking about
3197
+ ** so we trust him.
3198
+ */
3199
+ #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
3200
+ //static u64 floatSwap(u64 in){
3201
+ // union {
3202
+ // u64 r;
3203
+ // u32 i[2];
3204
+ // } u;
3205
+ // u32 t;
3206
+
3207
+ // u.r = in;
3208
+ // t = u.i[0];
3209
+ // u.i[0] = u.i[1];
3210
+ // u.i[1] = t;
3211
+ // return u.r;
3212
+ //}
3213
+ //# define swapMixedEndianFloat(X) X = floatSwap(X)
3214
+ #else
3215
+ //# define swapMixedEndianFloat(X)
3216
+ #endif
3217
+
3218
+ /*
3219
+ ** Write the serialized data blob for the value stored in pMem into
3220
+ ** buf. It is assumed that the caller has allocated sufficient space.
3221
+ ** Return the number of bytes written.
3222
+ **
3223
+ ** nBuf is the amount of space left in buf[]. nBuf must always be
3224
+ ** large enough to hold the entire field. Except, if the field is
3225
+ ** a blob with a zero-filled tail, then buf[] might be just the right
3226
+ ** size to hold everything except for the zero-filled tail. If buf[]
3227
+ ** is only big enough to hold the non-zero prefix, then only write that
3228
+ ** prefix into buf[]. But if buf[] is large enough to hold both the
3229
+ ** prefix and the tail then write the prefix and set the tail to all
3230
+ ** zeros.
3231
+ **
3232
+ ** Return the number of bytes actually written into buf[]. The number
3233
+ ** of bytes in the zero-filled tail is included in the return value only
3234
+ ** if those bytes were zeroed in buf[].
3235
+ */
3236
+ static u32 sqlite3VdbeSerialPut( byte[] buf, int offset, int nBuf, Mem pMem, int file_format )
3237
+ {
3238
+ u32 serial_type = sqlite3VdbeSerialType( pMem, file_format );
3239
+ u32 len;
3240
+
3241
+ /* Integer and Real */
3242
+ if ( serial_type <= 7 && serial_type > 0 )
3243
+ {
3244
+ u64 v;
3245
+ u32 i;
3246
+ if ( serial_type == 7 )
3247
+ {
3248
+ //Debug.Assert( sizeof( v) == sizeof(pMem.r));
3249
+ v = (ulong)BitConverter.ToInt64(BitConverter.GetBytes(pMem.r), 0);/// memcpy( &v, pMem.r, v ).Length;
3250
+ #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
3251
+ swapMixedEndianFloat( v );
3252
+ #endif
3253
+ }
3254
+ else
3255
+ {
3256
+ v = (ulong)pMem.u.i;
3257
+ }
3258
+ len = i = sqlite3VdbeSerialTypeLen( serial_type );
3259
+ Debug.Assert( len <= (u32)nBuf );
3260
+ while ( i-- != 0 )
3261
+ {
3262
+ buf[offset + i] = (u8)( v & 0xFF );
3263
+ v >>= 8;
3264
+ }
3265
+ return len;
3266
+ }
3267
+
3268
+ /* String or blob */
3269
+ if ( serial_type >= 12 )
3270
+ {
3271
+ Debug.Assert( pMem.n + ( ( pMem.flags & MEM_Zero ) != 0 ? pMem.u.nZero : 0 ) == (int)sqlite3VdbeSerialTypeLen( serial_type ) );
3272
+ Debug.Assert( pMem.n <= nBuf );
3273
+ if ( ( len = (u32)pMem.n ) != 0 )
3274
+ if ( pMem.zBLOB == null && String.IsNullOrEmpty( pMem.z ) )
3275
+ { }
3276
+ else if ( ( pMem.flags & MEM_Blob ) != 0 || pMem.z == null )
3277
+ Buffer.BlockCopy( pMem.zBLOB, 0, buf, offset, (int)len );//memcpy( buf, pMem.z, len );
3278
+ else
3279
+ Buffer.BlockCopy( Encoding.UTF8.GetBytes( pMem.z ), 0, buf, offset, (int)len );//memcpy( buf, pMem.z, len );
3280
+ if ( ( pMem.flags & MEM_Zero ) != 0 )
3281
+ {
3282
+ len += (u32)pMem.u.nZero;
3283
+ Debug.Assert( nBuf >= 0 );
3284
+ if ( len > (u32)nBuf )
3285
+ {
3286
+ len = (u32)nBuf;
3287
+ }
3288
+ Array.Clear( buf, offset + pMem.n, (int)( len - pMem.n ) );// memset( &buf[pMem.n], 0, len - pMem.n );
3289
+ }
3290
+ return len;
3291
+ }
3292
+
3293
+ /* NULL or constants 0 or 1 */
3294
+ return 0;
3295
+ }
3296
+
3297
+ /*
3298
+ ** Deserialize the data blob pointed to by buf as serial type serial_type
3299
+ ** and store the result in pMem. Return the number of bytes read.
3300
+ */
3301
+ static u32 sqlite3VdbeSerialGet(
3302
+ byte[] buf, /* Buffer to deserialize from */
3303
+ int offset, /* Offset into Buffer */
3304
+ u32 serial_type, /* Serial type to deserialize */
3305
+ Mem pMem /* Memory cell to write value into */
3306
+ )
3307
+ {
3308
+ switch ( serial_type )
3309
+ {
3310
+ case 10: /* Reserved for future use */
3311
+ case 11: /* Reserved for future use */
3312
+ case 0:
3313
+ { /* NULL */
3314
+ pMem.flags = MEM_Null;
3315
+ pMem.n = 0;
3316
+ pMem.z = null;
3317
+ pMem.zBLOB = null;
3318
+ break;
3319
+ }
3320
+ case 1:
3321
+ { /* 1-byte signed integer */
3322
+ pMem.u.i = (sbyte)buf[offset + 0];
3323
+ pMem.flags = MEM_Int;
3324
+ return 1;
3325
+ }
3326
+ case 2:
3327
+ { /* 2-byte signed integer */
3328
+ pMem.u.i = (int)( ( ( (sbyte)buf[offset + 0] ) << 8 ) | buf[offset + 1] );
3329
+ pMem.flags = MEM_Int;
3330
+ return 2;
3331
+ }
3332
+ case 3:
3333
+ { /* 3-byte signed integer */
3334
+ pMem.u.i = (int)( ( ( (sbyte)buf[offset + 0] ) << 16 ) | ( buf[offset + 1] << 8 ) | buf[offset + 2] );
3335
+ pMem.flags = MEM_Int;
3336
+ return 3;
3337
+ }
3338
+ case 4:
3339
+ { /* 4-byte signed integer */
3340
+ pMem.u.i = (int)( ( (sbyte)buf[offset + 0] << 24 ) | ( buf[offset + 1] << 16 ) | ( buf[offset + 2] << 8 ) | buf[offset + 3] );
3341
+ pMem.flags = MEM_Int;
3342
+ return 4;
3343
+ }
3344
+ case 5:
3345
+ { /* 6-byte signed integer */
3346
+ u64 x = (ulong)( ( ( (sbyte)buf[offset + 0] ) << 8 ) | buf[offset + 1] );
3347
+ u32 y = (u32)( ( buf[offset + 2] << 24 ) | ( buf[offset + 3] << 16 ) | ( buf[offset + 4] << 8 ) | buf[offset + 5] );
3348
+ x = ( x << 32 ) | y;
3349
+ pMem.u.i = (i64)x;
3350
+ pMem.flags = MEM_Int;
3351
+ return 6;
3352
+ }
3353
+ case 6: /* 8-byte signed integer */
3354
+ case 7:
3355
+ { /* IEEE floating point */
3356
+ u64 x;
3357
+ u32 y;
3358
+ #if !NDEBUG && !SQLITE_OMIT_FLOATING_POINT
3359
+ /* Verify that integers and floating point values use the same
3360
+ ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
3361
+ ** defined that 64-bit floating point values really are mixed
3362
+ ** endian.
3363
+ */
3364
+ const u64 t1 = ( (u64)0x3ff00000 ) << 32;
3365
+ const double r1 = 1.0;
3366
+ u64 t2 = t1;
3367
+ #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
3368
+ swapMixedEndianFloat(t2);
3369
+ #endif
3370
+ Debug.Assert( sizeof( double ) == sizeof( u64 ) && memcmp( BitConverter.GetBytes( r1 ), BitConverter.GetBytes( t2 ), sizeof( double ) ) == 0 );//Debug.Assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, t2, sizeof(r1))==0 );
3371
+ #endif
3372
+
3373
+ x = (u64)( ( buf[offset + 0] << 24 ) | ( buf[offset + 1] << 16 ) | ( buf[offset + 2] << 8 ) | buf[offset + 3] );
3374
+ y = (u32)( ( buf[offset + 4] << 24 ) | ( buf[offset + 5] << 16 ) | ( buf[offset + 6] << 8 ) | buf[offset + 7] );
3375
+ x = ( x << 32 ) | y;
3376
+ if ( serial_type == 6 )
3377
+ {
3378
+ pMem.u.i = (i64)x;
3379
+ pMem.flags = MEM_Int;
3380
+ }
3381
+ else
3382
+ {
3383
+ Debug.Assert( sizeof( i64 ) == 8 && sizeof( double ) == 8 );
3384
+ #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
3385
+ swapMixedEndianFloat(x);
3386
+ #endif
3387
+ pMem.r = BitConverter.ToDouble(BitConverter.GetBytes((long)x), 0);// memcpy(pMem.r, x, sizeof(x))
3388
+ pMem.flags = (u16)( sqlite3IsNaN( pMem.r ) ? MEM_Null : MEM_Real );
3389
+ }
3390
+ return 8;
3391
+ }
3392
+ case 8: /* Integer 0 */
3393
+ case 9:
3394
+ { /* Integer 1 */
3395
+ pMem.u.i = serial_type - 8;
3396
+ pMem.flags = MEM_Int;
3397
+ return 0;
3398
+ }
3399
+ default:
3400
+ {
3401
+ u32 len = ( serial_type - 12 ) / 2;
3402
+ pMem.n = (int)len;
3403
+ pMem.xDel = null;
3404
+ if ( ( serial_type & 0x01 ) != 0 )
3405
+ {
3406
+ pMem.flags = MEM_Str | MEM_Ephem;
3407
+ pMem.z = Encoding.UTF8.GetString( buf, offset, (int)len );//memcpy( buf, pMem.z, len );
3408
+ pMem.n = pMem.z.Length;
3409
+ pMem.zBLOB = null;
3410
+ }
3411
+ else
3412
+ {
3413
+ pMem.z = null;
3414
+ pMem.zBLOB = sqlite3Malloc((int)len);
3415
+ pMem.flags = MEM_Blob | MEM_Ephem;
3416
+ Buffer.BlockCopy( buf, offset, pMem.zBLOB, 0, (int)len );//memcpy( buf, pMem.z, len );
3417
+ }
3418
+ return len;
3419
+ }
3420
+ }
3421
+ return 0;
3422
+ }
3423
+
3424
+ static int sqlite3VdbeSerialGet(
3425
+ byte[] buf, /* Buffer to deserialize from */
3426
+ u32 serial_type, /* Serial type to deserialize */
3427
+ Mem pMem /* Memory cell to write value into */
3428
+ )
3429
+ {
3430
+ switch ( serial_type )
3431
+ {
3432
+ case 10: /* Reserved for future use */
3433
+ case 11: /* Reserved for future use */
3434
+ case 0:
3435
+ { /* NULL */
3436
+ pMem.flags = MEM_Null;
3437
+ break;
3438
+ }
3439
+ case 1:
3440
+ { /* 1-byte signed integer */
3441
+ pMem.u.i = (sbyte)buf[0];
3442
+ pMem.flags = MEM_Int;
3443
+ return 1;
3444
+ }
3445
+ case 2:
3446
+ { /* 2-byte signed integer */
3447
+ pMem.u.i = (int)( ( ( buf[0] ) << 8 ) | buf[1] );
3448
+ pMem.flags = MEM_Int;
3449
+ return 2;
3450
+ }
3451
+ case 3:
3452
+ { /* 3-byte signed integer */
3453
+ pMem.u.i = (int)( ( ( buf[0] ) << 16 ) | ( buf[1] << 8 ) | buf[2] );
3454
+ pMem.flags = MEM_Int;
3455
+ return 3;
3456
+ }
3457
+ case 4:
3458
+ { /* 4-byte signed integer */
3459
+ pMem.u.i = (int)( ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] );
3460
+ pMem.flags = MEM_Int;
3461
+ return 4;
3462
+ }
3463
+ case 5:
3464
+ { /* 6-byte signed integer */
3465
+ u64 x = (ulong)( ( ( buf[0] ) << 8 ) | buf[1] );
3466
+ u32 y = (u32)( ( buf[2] << 24 ) | ( buf[3] << 16 ) | ( buf[4] << 8 ) | buf[5] );
3467
+ x = ( x << 32 ) | y;
3468
+ pMem.u.i = (i64)x;
3469
+ pMem.flags = MEM_Int;
3470
+ return 6;
3471
+ }
3472
+ case 6: /* 8-byte signed integer */
3473
+ case 7:
3474
+ { /* IEEE floating point */
3475
+ u64 x;
3476
+ u32 y;
3477
+ #if !NDEBUG && !SQLITE_OMIT_FLOATING_POINT
3478
+ /* Verify that integers and floating point values use the same
3479
+ ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
3480
+ ** defined that 64-bit floating point values really are mixed
3481
+ ** endian.
3482
+ */
3483
+ const u64 t1 = ( (u64)0x3ff00000 ) << 32;
3484
+ const double r1 = 1.0;
3485
+ u64 t2 = t1;
3486
+ #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
3487
+ swapMixedEndianFloat(t2);
3488
+ #endif
3489
+ Debug.Assert( sizeof( double ) == sizeof( u64 ) && memcmp( BitConverter.GetBytes( r1 ), BitConverter.GetBytes( t2 ), sizeof( double ) ) == 0 );//Debug.Assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, t2, sizeof(r1))==0 );
3490
+ #endif
3491
+
3492
+ x = (u64)( ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] );
3493
+ y = (u32)( ( buf[4] << 24 ) | ( buf[5] << 16 ) | ( buf[6] << 8 ) | buf[7] );
3494
+ x = ( x << 32 ) | y;
3495
+ if ( serial_type == 6 )
3496
+ {
3497
+ pMem.u.i = (i64)x;
3498
+ pMem.flags = MEM_Int;
3499
+ }
3500
+ else
3501
+ {
3502
+ Debug.Assert( sizeof( i64 ) == 8 && sizeof( double ) == 8 );
3503
+ #if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
3504
+ swapMixedEndianFloat(x);
3505
+ #endif
3506
+ pMem.r = BitConverter.ToDouble(BitConverter.GetBytes((long)x), 0);// memcpy(pMem.r, x, sizeof(x))
3507
+ pMem.flags = MEM_Real;
3508
+ }
3509
+ return 8;
3510
+ }
3511
+ case 8: /* Integer 0 */
3512
+ case 9:
3513
+ { /* Integer 1 */
3514
+ pMem.u.i = serial_type - 8;
3515
+ pMem.flags = MEM_Int;
3516
+ return 0;
3517
+ }
3518
+ default:
3519
+ {
3520
+ int len = (int)( ( serial_type - 12 ) / 2 );
3521
+ pMem.xDel = null;
3522
+ if ( ( serial_type & 0x01 ) != 0 )
3523
+ {
3524
+ pMem.flags = MEM_Str | MEM_Ephem;
3525
+ pMem.z = Encoding.UTF8.GetString( buf, 0, len );//memcpy( buf, pMem.z, len );
3526
+ pMem.n = pMem.z.Length;// len;
3527
+ pMem.zBLOB = null;
3528
+ }
3529
+ else
3530
+ {
3531
+ pMem.flags = MEM_Blob | MEM_Ephem;
3532
+ pMem.zBLOB = sqlite3Malloc(len);
3533
+ buf.CopyTo( pMem.zBLOB, 0 );
3534
+ pMem.n = len;// len;
3535
+ pMem.z = null;
3536
+ }
3537
+ return len;
3538
+ }
3539
+ }
3540
+ return 0;
3541
+ }
3542
+
3543
+ /*
3544
+ ** Given the nKey-byte encoding of a record in pKey[], parse the
3545
+ ** record into a UnpackedRecord structure. Return a pointer to
3546
+ ** that structure.
3547
+ **
3548
+ ** The calling function might provide szSpace bytes of memory
3549
+ ** space at pSpace. This space can be used to hold the returned
3550
+ ** VDbeParsedRecord structure if it is large enough. If it is
3551
+ ** not big enough, space is obtained from sqlite3Malloc().
3552
+ **
3553
+ ** The returned structure should be closed by a call to
3554
+ ** sqlite3VdbeDeleteUnpackedRecord().
3555
+ */
3556
+ static UnpackedRecord sqlite3VdbeRecordUnpack(
3557
+ KeyInfo pKeyInfo, /* Information about the record format */
3558
+ int nKey, /* Size of the binary record */
3559
+ byte[] pKey, /* The binary record */
3560
+ UnpackedRecord pSpace, // char *pSpace, /* Unaligned space available to hold the object */
3561
+ int szSpace /* Size of pSpace[] in bytes */
3562
+ )
3563
+ {
3564
+ byte[] aKey = pKey;
3565
+ UnpackedRecord p; /* The unpacked record that we will return */
3566
+ int nByte; /* Memory space needed to hold p, in bytes */
3567
+ int d;
3568
+ u32 idx;
3569
+ int u; /* Unsigned loop counter */
3570
+ int szHdr = 0;
3571
+ Mem pMem;
3572
+ int nOff; /* Increase pSpace by this much to 8-byte align it */
3573
+
3574
+ /*
3575
+ ** We want to shift the pointer pSpace up such that it is 8-byte aligned.
3576
+ ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift
3577
+ ** it by. If pSpace is already 8-byte aligned, nOff should be zero.
3578
+ */
3579
+ //nOff = ( 8 - ( SQLITE_PTR_TO_INT( pSpace ) & 7 ) ) & 7;
3580
+ //pSpace += nOff;
3581
+ //szSpace -= nOff;
3582
+ //nByte = ROUND8( sizeof( UnpackedRecord ) ) + sizeof( Mem ) * ( pKeyInfo->nField + 1 );
3583
+ //if ( nByte > szSpace)
3584
+ //{
3585
+ // p = new UnpackedRecord();//sqlite3DbMallocRaw(pKeyInfo.db, nByte);
3586
+ // if ( p == null ) return null;
3587
+ // p.flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY;
3588
+ //}
3589
+ //else
3590
+ {
3591
+ p = pSpace;//(UnpackedRecord*)pSpace;
3592
+ p.flags = UNPACKED_NEED_DESTROY;
3593
+ }
3594
+ p.pKeyInfo = pKeyInfo;
3595
+ p.nField = (u16)( pKeyInfo.nField + 1 );
3596
+ //p->aMem = pMem = (Mem*)&( (char*)p )[ROUND8( sizeof( UnpackedRecord ) )];
3597
+ //assert( EIGHT_BYTE_ALIGNMENT( pMem ) );
3598
+ p.aMem = new Mem[p.nField + 1];
3599
+ idx = (u32)getVarint32( aKey, 0, ref szHdr );// GetVarint( aKey, szHdr );
3600
+ d = (int)szHdr;
3601
+ u = 0;
3602
+ while ( idx < (int)szHdr && u < p.nField && d <= nKey )
3603
+ {
3604
+ p.aMem[u] = sqlite3Malloc(p.aMem[u]);
3605
+ pMem = p.aMem[u];
3606
+ u32 serial_type = 0;
3607
+
3608
+ idx += (u32)getVarint32( aKey, idx, ref serial_type );// GetVarint( aKey + idx, serial_type );
3609
+ pMem.enc = pKeyInfo.enc;
3610
+ pMem.db = pKeyInfo.db;
3611
+ pMem.flags = 0;
3612
+ //pMem.zMalloc = null;
3613
+ d += (int)sqlite3VdbeSerialGet( aKey, d, serial_type, pMem );
3614
+ //pMem++;
3615
+ u++;
3616
+ }
3617
+ Debug.Assert( u <= pKeyInfo.nField + 1 );
3618
+ p.nField = (u16)u;
3619
+ return p;// (void*)p;
3620
+ }
3621
+
3622
+ /*
3623
+ ** This routine destroys a UnpackedRecord object.
3624
+ */
3625
+ static void sqlite3VdbeDeleteUnpackedRecord( UnpackedRecord p )
3626
+ {
3627
+ int i;
3628
+ Mem pMem;
3629
+ Debug.Assert( p != null );
3630
+ Debug.Assert( ( p.flags & UNPACKED_NEED_DESTROY ) != 0 );
3631
+ //for ( i = 0, pMem = p->aMem ; i < p->nField ; i++, pMem++ )
3632
+ //{
3633
+ // /* The unpacked record is always constructed by the
3634
+ // ** sqlite3VdbeUnpackRecord() function above, which makes all
3635
+ // ** strings and blobs static. And none of the elements are
3636
+ // ** ever transformed, so there is never anything to delete.
3637
+ // */
3638
+ // if ( NEVER( pMem->zMalloc ) ) sqlite3VdbeMemRelease( pMem );
3639
+ //}
3640
+ if ( ( p.flags & UNPACKED_NEED_FREE ) != 0 )
3641
+ {
3642
+ sqlite3DbFree( p.pKeyInfo.db, ref p.aMem );
3643
+ p = null;
3644
+ }
3645
+ }
3646
+
3647
+ /*
3648
+ ** This function compares the two table rows or index records
3649
+ ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
3650
+ ** or positive integer if key1 is less than, equal to or
3651
+ ** greater than key2. The {nKey1, pKey1} key must be a blob
3652
+ ** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
3653
+ ** key must be a parsed key such as obtained from
3654
+ ** sqlite3VdbeParseRecord.
3655
+ **
3656
+ ** Key1 and Key2 do not have to contain the same number of fields.
3657
+ ** The key with fewer fields is usually compares less than the
3658
+ ** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set
3659
+ ** and the common prefixes are equal, then key1 is less than key2.
3660
+ ** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are
3661
+ ** equal, then the keys are considered to be equal and
3662
+ ** the parts beyond the common prefix are ignored.
3663
+ **
3664
+ ** If the UNPACKED_IGNORE_ROWID flag is set, then the last byte of
3665
+ ** the header of pKey1 is ignored. It is assumed that pKey1 is
3666
+ ** an index key, and thus ends with a rowid value. The last byte
3667
+ ** of the header will therefore be the serial type of the rowid:
3668
+ ** one of 1, 2, 3, 4, 5, 6, 8, or 9 - the integer serial types.
3669
+ ** The serial type of the final rowid will always be a single byte.
3670
+ ** By ignoring this last byte of the header, we force the comparison
3671
+ ** to ignore the rowid at the end of key1.
3672
+ */
3673
+
3674
+ static Mem mem1 = new Mem();
3675
+ // ALTERNATE FORM for C#
3676
+ static int sqlite3VdbeRecordCompare(
3677
+ int nKey1, byte[] pKey1, /* Left key */
3678
+ UnpackedRecord pPKey2 /* Right key */
3679
+ )
3680
+ {
3681
+ return sqlite3VdbeRecordCompare( nKey1, pKey1, 0, pPKey2 );
3682
+ }
3683
+
3684
+ static int sqlite3VdbeRecordCompare(
3685
+ int nKey1, byte[] pKey1, /* Left key */
3686
+ int offset,
3687
+ UnpackedRecord pPKey2 /* Right key */
3688
+ )
3689
+ {
3690
+ int d1; /* Offset into aKey[] of next data element */
3691
+ u32 idx1; /* Offset into aKey[] of next header element */
3692
+ u32 szHdr1; /* Number of bytes in header */
3693
+ int i = 0;
3694
+ int nField;
3695
+ int rc = 0;
3696
+
3697
+ //byte[] aKey1 = new byte[pKey1.Length - offset];
3698
+ //Buffer.BlockCopy( pKey1, offset, aKey1, 0, aKey1.Length );
3699
+ KeyInfo pKeyInfo;
3700
+
3701
+ pKeyInfo = pPKey2.pKeyInfo;
3702
+ mem1.enc = pKeyInfo.enc;
3703
+ mem1.db = pKeyInfo.db;
3704
+ /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */
3705
+ // VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
3706
+
3707
+ /* Compilers may complain that mem1.u.i is potentially uninitialized.
3708
+ ** We could initialize it, as shown here, to silence those complaints.
3709
+ ** But in fact, mem1.u.i will never actually be used initialized, and doing
3710
+ ** the unnecessary initialization has a measurable negative performance
3711
+ ** impact, since this routine is a very high runner. And so, we choose
3712
+ ** to ignore the compiler warnings and leave this variable uninitialized.
3713
+ */
3714
+ /* mem1.u.i = 0; // not needed, here to silence compiler warning */
3715
+
3716
+ idx1 = (u32)((szHdr1 = pKey1[offset]) <= 0x7f ? 1 : getVarint32(pKey1, offset, ref szHdr1));// GetVarint( aKey1, szHdr1 );
3717
+ d1 = (int)szHdr1;
3718
+ if ( ( pPKey2.flags & UNPACKED_IGNORE_ROWID ) != 0 )
3719
+ {
3720
+ szHdr1--;
3721
+ }
3722
+ nField = pKeyInfo.nField;
3723
+ while ( idx1 < szHdr1 && i < pPKey2.nField )
3724
+ {
3725
+ u32 serial_type1;
3726
+
3727
+ /* Read the serial types for the next element in each key. */
3728
+ idx1 += (u32)((serial_type1 = pKey1[offset + idx1]) <= 0x7f ? 1 : getVarint32(pKey1,(uint)( offset+idx1), ref serial_type1)); //GetVarint( aKey1 + idx1, serial_type1 );
3729
+ if ( d1 >= nKey1 && sqlite3VdbeSerialTypeLen( serial_type1 ) > 0 ) break;
3730
+
3731
+ /* Extract the values to be compared.
3732
+ */
3733
+ d1 += (int)sqlite3VdbeSerialGet(pKey1,offset+ d1, serial_type1, mem1);//sqlite3VdbeSerialGet( aKey1, d1, serial_type1, mem1 );
3734
+
3735
+ /* Do the comparison
3736
+ */
3737
+ rc = sqlite3MemCompare( mem1, pPKey2.aMem[i], i < nField ? pKeyInfo.aColl[i] : null );
3738
+ if ( rc != 0 )
3739
+ {
3740
+ //Debug.Assert( mem1.zMalloc==null ); /* See comment below */
3741
+
3742
+ /* Invert the result if we are using DESC sort order. */
3743
+ if ( pKeyInfo.aSortOrder != null && i < nField && pKeyInfo.aSortOrder[i] != 0 )
3744
+ {
3745
+ rc = -rc;
3746
+ }
3747
+
3748
+ /* If the PREFIX_SEARCH flag is set and all fields except the final
3749
+ ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
3750
+ ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
3751
+ ** This is used by the OP_IsUnique opcode.
3752
+ */
3753
+ if ( ( pPKey2.flags & UNPACKED_PREFIX_SEARCH ) != 0 && i == ( pPKey2.nField - 1 ) )
3754
+ {
3755
+ Debug.Assert( idx1 == szHdr1 && rc != 0 );
3756
+ Debug.Assert( ( mem1.flags & MEM_Int ) != 0 );
3757
+ pPKey2.flags = (ushort)( pPKey2.flags & ~UNPACKED_PREFIX_SEARCH );
3758
+ pPKey2.rowid = mem1.u.i;
3759
+ }
3760
+
3761
+ return rc;
3762
+ }
3763
+ i++;
3764
+ }
3765
+
3766
+ /* No memory allocation is ever used on mem1. Prove this using
3767
+ ** the following assert(). If the assert() fails, it indicates a
3768
+ ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
3769
+ */
3770
+ //Debug.Assert( mem1.zMalloc==null );
3771
+
3772
+ /* rc==0 here means that one of the keys ran out of fields and
3773
+ ** all the fields up to that point were equal. If the UNPACKED_INCRKEY
3774
+ ** flag is set, then break the tie by treating key2 as larger.
3775
+ ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
3776
+ ** are considered to be equal. Otherwise, the longer key is the
3777
+ ** larger. As it happens, the pPKey2 will always be the longer
3778
+ ** if there is a difference.
3779
+ */
3780
+ Debug.Assert( rc == 0 );
3781
+ if ( ( pPKey2.flags & UNPACKED_INCRKEY ) != 0 )
3782
+ {
3783
+ rc = -1;
3784
+ }
3785
+ else if ( ( pPKey2.flags & UNPACKED_PREFIX_MATCH ) != 0 )
3786
+ {
3787
+ /* Leave rc==0 */
3788
+ }
3789
+ else if ( idx1 < szHdr1 )
3790
+ {
3791
+ rc = 1;
3792
+ }
3793
+ return rc;
3794
+ }
3795
+
3796
+ /*
3797
+ ** pCur points at an index entry created using the OP_MakeRecord opcode.
3798
+ ** Read the rowid (the last field in the record) and store it in *rowid.
3799
+ ** Return SQLITE_OK if everything works, or an error code otherwise.
3800
+ **
3801
+ ** pCur might be pointing to text obtained from a corrupt database file.
3802
+ ** So the content cannot be trusted. Do appropriate checks on the content.
3803
+ */
3804
+ static int sqlite3VdbeIdxRowid( sqlite3 db, BtCursor pCur, ref i64 rowid )
3805
+ {
3806
+ i64 nCellKey = 0;
3807
+ int rc;
3808
+ u32 szHdr = 0; /* Size of the header */
3809
+ u32 typeRowid = 0; /* Serial type of the rowid */
3810
+ u32 lenRowid; /* Size of the rowid */
3811
+ Mem m = null;
3812
+ Mem v = null;
3813
+ v = sqlite3Malloc( v);
3814
+ UNUSED_PARAMETER(db);
3815
+
3816
+ /* Get the size of the index entry. Only indices entries of less
3817
+ ** than 2GiB are support - anything large must be database corruption.
3818
+ ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
3819
+ ** this code can safely assume that nCellKey is 32-bits
3820
+ */
3821
+ Debug.Assert( sqlite3BtreeCursorIsValid( pCur ) );
3822
+ rc = sqlite3BtreeKeySize( pCur, ref nCellKey );
3823
+ Debug.Assert( rc == SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
3824
+ Debug.Assert( ( (u32)nCellKey & SQLITE_MAX_U32 ) == (u64)nCellKey );
3825
+
3826
+ /* Read in the complete content of the index entry */
3827
+ m = sqlite3Malloc( m );
3828
+ // memset(&m, 0, sizeof(m));
3829
+ rc = sqlite3VdbeMemFromBtree( pCur, 0, (int)nCellKey, true, m );
3830
+ if ( rc != 0 )
3831
+ {
3832
+ return rc;
3833
+ }
3834
+
3835
+ /* The index entry must begin with a header size */
3836
+ getVarint32( m.zBLOB, 0, ref szHdr );
3837
+ testcase( szHdr == 3 );
3838
+ testcase( szHdr == m.n );
3839
+ if ( unlikely( szHdr < 3 || (int)szHdr > m.n ) )
3840
+ {
3841
+ goto idx_rowid_corruption;
3842
+ }
3843
+
3844
+ /* The last field of the index should be an integer - the ROWID.
3845
+ ** Verify that the last entry really is an integer. */
3846
+ getVarint32( m.zBLOB, szHdr - 1, ref typeRowid );
3847
+ testcase( typeRowid == 1 );
3848
+ testcase( typeRowid == 2 );
3849
+ testcase( typeRowid == 3 );
3850
+ testcase( typeRowid == 4 );
3851
+ testcase( typeRowid == 5 );
3852
+ testcase( typeRowid == 6 );
3853
+ testcase( typeRowid == 8 );
3854
+ testcase( typeRowid == 9 );
3855
+ if ( unlikely( typeRowid < 1 || typeRowid > 9 || typeRowid == 7 ) )
3856
+ {
3857
+ goto idx_rowid_corruption;
3858
+ }
3859
+ lenRowid = (u32)sqlite3VdbeSerialTypeLen( typeRowid );
3860
+ testcase( (u32)m.n == szHdr + lenRowid );
3861
+ if ( unlikely( (u32)m.n < szHdr + lenRowid ) )
3862
+ {
3863
+ goto idx_rowid_corruption;
3864
+ }
3865
+
3866
+ /* Fetch the integer off the end of the index record */
3867
+ sqlite3VdbeSerialGet( m.zBLOB, (int)( m.n - lenRowid ), typeRowid, v );
3868
+ rowid = v.u.i;
3869
+ sqlite3VdbeMemRelease( m );
3870
+ return SQLITE_OK;
3871
+
3872
+ /* Jump here if database corruption is detected after m has been
3873
+ ** allocated. Free the m object and return SQLITE_CORRUPT. */
3874
+ idx_rowid_corruption:
3875
+ //testcase( m.zMalloc != 0 );
3876
+ sqlite3VdbeMemRelease( m );
3877
+ return SQLITE_CORRUPT_BKPT();
3878
+ }
3879
+
3880
+ /*
3881
+ ** Compare the key of the index entry that cursor pC is pointing to against
3882
+ ** the key string in pUnpacked. Write into *pRes a number
3883
+ ** that is negative, zero, or positive if pC is less than, equal to,
3884
+ ** or greater than pUnpacked. Return SQLITE_OK on success.
3885
+ **
3886
+ ** pUnpacked is either created without a rowid or is truncated so that it
3887
+ ** omits the rowid at the end. The rowid at the end of the index entry
3888
+ ** is ignored as well. Hence, this routine only compares the prefixes
3889
+ ** of the keys prior to the final rowid, not the entire key.
3890
+ */
3891
+ static int sqlite3VdbeIdxKeyCompare(
3892
+ VdbeCursor pC, /* The cursor to compare against */
3893
+ UnpackedRecord pUnpacked, /* Unpacked version of key to compare against */
3894
+ ref int res /* Write the comparison result here */
3895
+ )
3896
+ {
3897
+ i64 nCellKey = 0;
3898
+ int rc;
3899
+ BtCursor pCur = pC.pCursor;
3900
+ Mem m = null;
3901
+
3902
+ Debug.Assert( sqlite3BtreeCursorIsValid( pCur ) );
3903
+ rc = sqlite3BtreeKeySize( pCur, ref nCellKey );
3904
+ Debug.Assert( rc == SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
3905
+ /* nCellKey will always be between 0 and 0xffffffff because of the say
3906
+ ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
3907
+ if ( nCellKey <= 0 || nCellKey > 0x7fffffff )
3908
+ {
3909
+ res = 0;
3910
+ return SQLITE_CORRUPT_BKPT();
3911
+ }
3912
+
3913
+ m = sqlite3Malloc( m );
3914
+ // memset(&m, 0, sizeof(m));
3915
+ rc = sqlite3VdbeMemFromBtree( pC.pCursor, 0, (int)nCellKey, true, m );
3916
+ if ( rc != 0 )
3917
+ {
3918
+ return rc;
3919
+ }
3920
+ Debug.Assert( ( pUnpacked.flags & UNPACKED_IGNORE_ROWID ) != 0 );
3921
+ res = sqlite3VdbeRecordCompare( m.n, m.zBLOB, pUnpacked );
3922
+ sqlite3VdbeMemRelease( m );
3923
+ return SQLITE_OK;
3924
+ }
3925
+
3926
+ /*
3927
+ ** This routine sets the value to be returned by subsequent calls to
3928
+ ** sqlite3_changes() on the database handle 'db'.
3929
+ */
3930
+ static void sqlite3VdbeSetChanges( sqlite3 db, int nChange )
3931
+ {
3932
+ Debug.Assert( sqlite3_mutex_held( db.mutex ) );
3933
+ db.nChange = nChange;
3934
+ db.nTotalChange += nChange;
3935
+ }
3936
+
3937
+ /*
3938
+ ** Set a flag in the vdbe to update the change counter when it is finalised
3939
+ ** or reset.
3940
+ */
3941
+ static void sqlite3VdbeCountChanges( Vdbe v )
3942
+ {
3943
+ v.changeCntOn = true;
3944
+ }
3945
+
3946
+ /*
3947
+ ** Mark every prepared statement associated with a database connection
3948
+ ** as expired.
3949
+ **
3950
+ ** An expired statement means that recompilation of the statement is
3951
+ ** recommend. Statements expire when things happen that make their
3952
+ ** programs obsolete. Removing user-defined functions or collating
3953
+ ** sequences, or changing an authorization function are the types of
3954
+ ** things that make prepared statements obsolete.
3955
+ */
3956
+ static void sqlite3ExpirePreparedStatements( sqlite3 db )
3957
+ {
3958
+ Vdbe p;
3959
+ for ( p = db.pVdbe; p != null; p = p.pNext )
3960
+ {
3961
+ p.expired = true;
3962
+ }
3963
+ }
3964
+
3965
+ /*
3966
+ ** Return the database associated with the Vdbe.
3967
+ */
3968
+ static sqlite3 sqlite3VdbeDb( Vdbe v )
3969
+ {
3970
+ return v.db;
3971
+ }
3972
+ /*
3973
+ ** Return a pointer to an sqlite3_value structure containing the value bound
3974
+ ** parameter iVar of VM v. Except, if the value is an SQL NULL, return
3975
+ ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
3976
+ ** constants) to the value before returning it.
3977
+ **
3978
+ ** The returned value must be freed by the caller using sqlite3ValueFree().
3979
+ */
3980
+ static sqlite3_value sqlite3VdbeGetValue( Vdbe v, int iVar, u8 aff )
3981
+ {
3982
+ Debug.Assert( iVar > 0 );
3983
+ if ( v != null )
3984
+ {
3985
+ Mem pMem = v.aVar[iVar - 1];
3986
+ if ( 0 == ( pMem.flags & MEM_Null ) )
3987
+ {
3988
+ sqlite3_value pRet = sqlite3ValueNew( v.db );
3989
+ if ( pRet != null )
3990
+ {
3991
+ sqlite3VdbeMemCopy( (Mem)pRet, pMem );
3992
+ sqlite3ValueApplyAffinity( pRet, (char)aff, SQLITE_UTF8 );
3993
+ sqlite3VdbeMemStoreType( (Mem)pRet );
3994
+ }
3995
+ return pRet;
3996
+ }
3997
+ }
3998
+ return null;
3999
+ }
4000
+
4001
+ /*
4002
+ ** Configure SQL variable iVar so that binding a new value to it signals
4003
+ ** to sqlite3_reoptimize() that re-preparing the statement may result
4004
+ ** in a better query plan.
4005
+ */
4006
+ static void sqlite3VdbeSetVarmask( Vdbe v, int iVar )
4007
+ {
4008
+ Debug.Assert( iVar > 0 );
4009
+ if ( iVar > 32 )
4010
+ {
4011
+ v.expmask = 0xffffffff;
4012
+ }
4013
+ else
4014
+ {
4015
+ v.expmask |= ( (u32)1 << ( iVar - 1 ) );
4016
+ }
4017
+ }
4018
+ }
4019
+ }