shoesgem 0.1424.0 → 0.1426.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (320) hide show
  1. data/README.rdoc +3 -0
  2. data/shoes/CHANGELOG.txt +21 -21
  3. data/shoes/COPYING.txt +30 -30
  4. data/shoes/VERSION.txt +1 -1
  5. data/shoes/freetype6.dll +0 -0
  6. data/shoes/lib/shoes/cache.rb +54 -54
  7. data/shoes/lib/shoes/data.rb +39 -39
  8. data/shoes/lib/shoes/help.rb +421 -421
  9. data/shoes/lib/shoes/image.rb +25 -25
  10. data/shoes/lib/shoes/inspect.rb +128 -128
  11. data/shoes/lib/shoes/log.rb +48 -48
  12. data/shoes/lib/shoes/minitar.rb +986 -986
  13. data/shoes/lib/shoes/override.rb +38 -38
  14. data/shoes/lib/shoes/pack.rb +503 -503
  15. data/shoes/lib/shoes/search.rb +46 -46
  16. data/shoes/lib/shoes/setup.rb +329 -329
  17. data/shoes/lib/shoes/shy.rb +131 -131
  18. data/shoes/lib/shoes/shybuilder.rb +44 -44
  19. data/shoes/lib/shoes.rb +522 -522
  20. data/shoes/libcairo-2.dll +0 -0
  21. data/shoes/libeay32.dll +0 -0
  22. data/shoes/libexpat-1.dll +0 -0
  23. data/shoes/libfontconfig-1.dll +0 -0
  24. data/shoes/libgio-2.0-0.dll +0 -0
  25. data/shoes/libglib-2.0-0.dll +0 -0
  26. data/shoes/libgmodule-2.0-0.dll +0 -0
  27. data/shoes/libgobject-2.0-0.dll +0 -0
  28. data/shoes/libgthread-2.0-0.dll +0 -0
  29. data/shoes/libiconv2.dll +0 -0
  30. data/shoes/libjpeg-8.dll +0 -0
  31. data/shoes/libpango-1.0-0.dll +0 -0
  32. data/shoes/libpangocairo-1.0-0.dll +0 -0
  33. data/shoes/libpangoft2-1.0-0.dll +0 -0
  34. data/shoes/libpangowin32-1.0-0.dll +0 -0
  35. data/shoes/libpng14-14.dll +0 -0
  36. data/shoes/libportaudio-2.dll +0 -0
  37. data/shoes/libshoes.dll +0 -0
  38. data/shoes/libssl32.dll +0 -0
  39. data/shoes/libungif4.dll +0 -0
  40. data/shoes/msvcrt-ruby191.dll +0 -0
  41. data/shoes/nsis/base.nsi +644 -0
  42. data/shoes/nsis/installer-1.bmp +0 -0
  43. data/shoes/nsis/installer-2.bmp +0 -0
  44. data/shoes/nsis/setup.ico +0 -0
  45. data/shoes/nsis/shoes.exe.manifest +17 -0
  46. data/shoes/nsis/shoes.ico +0 -0
  47. data/shoes/nsis/shoes.nsi +644 -0
  48. data/shoes/nsis/stub-inject.c +59 -0
  49. data/shoes/nsis/stub.c +271 -0
  50. data/shoes/nsis/stub32.h +14 -0
  51. data/shoes/nsis/stub32.rc +16 -0
  52. data/shoes/readline5.dll +0 -0
  53. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/fast_xs.so +0 -0
  54. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/blankslate.rb +63 -63
  55. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/builder.rb +216 -216
  56. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/elements.rb +510 -510
  57. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/htmlinfo.rb +691 -691
  58. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/inspect.rb +103 -103
  59. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/modules.rb +40 -40
  60. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/parse.rb +38 -38
  61. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/tag.rb +202 -202
  62. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/tags.rb +164 -164
  63. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/traverse.rb +838 -838
  64. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot/xchar.rb +94 -94
  65. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot.rb +26 -26
  66. data/shoes/ruby/gems/1.9.1/gems/hpricot-0.8.1/lib/hpricot_scan.so +0 -0
  67. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/add/core.rb +135 -135
  68. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/add/rails.rb +58 -58
  69. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/common.rb +354 -354
  70. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/ext/generator.so +0 -0
  71. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/ext/parser.so +0 -0
  72. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/ext.rb +13 -13
  73. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json/version.rb +9 -9
  74. data/shoes/ruby/gems/1.9.1/gems/json-shoes-1.1.3/lib/json.rb +8 -8
  75. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/constants.rb +49 -49
  76. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/database.rb +721 -721
  77. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/driver/dl/api.rb +152 -152
  78. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/driver/dl/driver.rb +307 -307
  79. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/driver/native/driver.rb +219 -219
  80. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/errors.rb +68 -68
  81. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/pragmas.rb +271 -271
  82. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/resultset.rb +180 -180
  83. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/statement.rb +231 -231
  84. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/translator.rb +109 -109
  85. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/value.rb +57 -57
  86. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3/version.rb +16 -16
  87. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3.rb +1 -1
  88. data/shoes/ruby/gems/1.9.1/gems/sqlite3-ruby-1.2.5-x86-mswin32/lib/sqlite3_api.so +0 -0
  89. data/shoes/ruby/gems/1.9.1/specifications/hpricot-0.8.1.gemspec +32 -32
  90. data/shoes/ruby/gems/1.9.1/specifications/json-shoes-1.1.3.gemspec +34 -34
  91. data/shoes/ruby/gems/1.9.1/specifications/sqlite3-ruby-1.2.5-x86-mswin32.gemspec +46 -46
  92. data/shoes/ruby/lib/ftsearch/analysis/analyzer.rb +16 -16
  93. data/shoes/ruby/lib/ftsearch/analysis/simple_identifier_analyzer.rb +23 -23
  94. data/shoes/ruby/lib/ftsearch/analysis/whitespace_analyzer.rb +22 -22
  95. data/shoes/ruby/lib/ftsearch/document_map_reader.rb +106 -106
  96. data/shoes/ruby/lib/ftsearch/document_map_writer.rb +46 -46
  97. data/shoes/ruby/lib/ftsearch/field_infos.rb +46 -46
  98. data/shoes/ruby/lib/ftsearch/fragment_writer.rb +114 -114
  99. data/shoes/ruby/lib/ftsearch/fulltext_reader.rb +52 -52
  100. data/shoes/ruby/lib/ftsearch/fulltext_writer.rb +75 -75
  101. data/shoes/ruby/lib/ftsearch/suffix_array_reader.rb +275 -275
  102. data/shoes/ruby/lib/ftsearch/suffix_array_writer.rb +99 -99
  103. data/shoes/ruby/lib/ftsearch/util.rb +21 -21
  104. data/shoes/ruby/lib/i386-mingw32/bigdecimal.so +0 -0
  105. data/shoes/ruby/lib/i386-mingw32/binject.so +0 -0
  106. data/shoes/ruby/lib/i386-mingw32/bloops.so +0 -0
  107. data/shoes/ruby/lib/i386-mingw32/continuation.so +0 -0
  108. data/shoes/ruby/lib/i386-mingw32/coverage.so +0 -0
  109. data/shoes/ruby/lib/i386-mingw32/curses.so +0 -0
  110. data/shoes/ruby/lib/i386-mingw32/digest/bubblebabble.so +0 -0
  111. data/shoes/ruby/lib/i386-mingw32/digest/md5.so +0 -0
  112. data/shoes/ruby/lib/i386-mingw32/digest/rmd160.so +0 -0
  113. data/shoes/ruby/lib/i386-mingw32/digest/sha1.so +0 -0
  114. data/shoes/ruby/lib/i386-mingw32/digest/sha2.so +0 -0
  115. data/shoes/ruby/lib/i386-mingw32/digest.so +0 -0
  116. data/shoes/ruby/lib/i386-mingw32/dl.so +0 -0
  117. data/shoes/ruby/lib/i386-mingw32/enc/big5.so +0 -0
  118. data/shoes/ruby/lib/i386-mingw32/enc/cp949.so +0 -0
  119. data/shoes/ruby/lib/i386-mingw32/enc/emacs_mule.so +0 -0
  120. data/shoes/ruby/lib/i386-mingw32/enc/encdb.so +0 -0
  121. data/shoes/ruby/lib/i386-mingw32/enc/euc_jp.so +0 -0
  122. data/shoes/ruby/lib/i386-mingw32/enc/euc_kr.so +0 -0
  123. data/shoes/ruby/lib/i386-mingw32/enc/euc_tw.so +0 -0
  124. data/shoes/ruby/lib/i386-mingw32/enc/gb18030.so +0 -0
  125. data/shoes/ruby/lib/i386-mingw32/enc/gb2312.so +0 -0
  126. data/shoes/ruby/lib/i386-mingw32/enc/gbk.so +0 -0
  127. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_1.so +0 -0
  128. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_10.so +0 -0
  129. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_11.so +0 -0
  130. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_13.so +0 -0
  131. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_14.so +0 -0
  132. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_15.so +0 -0
  133. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_16.so +0 -0
  134. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_2.so +0 -0
  135. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_3.so +0 -0
  136. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_4.so +0 -0
  137. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_5.so +0 -0
  138. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_6.so +0 -0
  139. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_7.so +0 -0
  140. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_8.so +0 -0
  141. data/shoes/ruby/lib/i386-mingw32/enc/iso_8859_9.so +0 -0
  142. data/shoes/ruby/lib/i386-mingw32/enc/koi8_r.so +0 -0
  143. data/shoes/ruby/lib/i386-mingw32/enc/koi8_u.so +0 -0
  144. data/shoes/ruby/lib/i386-mingw32/enc/shift_jis.so +0 -0
  145. data/shoes/ruby/lib/i386-mingw32/enc/trans/big5.so +0 -0
  146. data/shoes/ruby/lib/i386-mingw32/enc/trans/chinese.so +0 -0
  147. data/shoes/ruby/lib/i386-mingw32/enc/trans/escape.so +0 -0
  148. data/shoes/ruby/lib/i386-mingw32/enc/trans/gb18030.so +0 -0
  149. data/shoes/ruby/lib/i386-mingw32/enc/trans/gbk.so +0 -0
  150. data/shoes/ruby/lib/i386-mingw32/enc/trans/iso2022.so +0 -0
  151. data/shoes/ruby/lib/i386-mingw32/enc/trans/japanese.so +0 -0
  152. data/shoes/ruby/lib/i386-mingw32/enc/trans/japanese_euc.so +0 -0
  153. data/shoes/ruby/lib/i386-mingw32/enc/trans/japanese_sjis.so +0 -0
  154. data/shoes/ruby/lib/i386-mingw32/enc/trans/korean.so +0 -0
  155. data/shoes/ruby/lib/i386-mingw32/enc/trans/single_byte.so +0 -0
  156. data/shoes/ruby/lib/i386-mingw32/enc/trans/transdb.so +0 -0
  157. data/shoes/ruby/lib/i386-mingw32/enc/trans/utf_16_32.so +0 -0
  158. data/shoes/ruby/lib/i386-mingw32/enc/utf_16be.so +0 -0
  159. data/shoes/ruby/lib/i386-mingw32/enc/utf_16le.so +0 -0
  160. data/shoes/ruby/lib/i386-mingw32/enc/utf_32be.so +0 -0
  161. data/shoes/ruby/lib/i386-mingw32/enc/utf_32le.so +0 -0
  162. data/shoes/ruby/lib/i386-mingw32/enc/windows_1251.so +0 -0
  163. data/shoes/ruby/lib/i386-mingw32/etc.so +0 -0
  164. data/shoes/ruby/lib/i386-mingw32/fcntl.so +0 -0
  165. data/shoes/ruby/lib/i386-mingw32/fiber.so +0 -0
  166. data/shoes/ruby/lib/i386-mingw32/ftsearchrt.so +0 -0
  167. data/shoes/ruby/lib/i386-mingw32/gdbm.so +0 -0
  168. data/shoes/ruby/lib/i386-mingw32/iconv.so +0 -0
  169. data/shoes/ruby/lib/i386-mingw32/io/wait.so +0 -0
  170. data/shoes/ruby/lib/i386-mingw32/json/ext/generator.so +0 -0
  171. data/shoes/ruby/lib/i386-mingw32/json/ext/parser.so +0 -0
  172. data/shoes/ruby/lib/i386-mingw32/mathn/complex.so +0 -0
  173. data/shoes/ruby/lib/i386-mingw32/mathn/rational.so +0 -0
  174. data/shoes/ruby/lib/i386-mingw32/nkf.so +0 -0
  175. data/shoes/ruby/lib/i386-mingw32/openssl.so +0 -0
  176. data/shoes/ruby/lib/i386-mingw32/racc/cparse.so +0 -0
  177. data/shoes/ruby/lib/i386-mingw32/rbconfig.rb +2 -2
  178. data/shoes/ruby/lib/i386-mingw32/readline.so +0 -0
  179. data/shoes/ruby/lib/i386-mingw32/ripper.so +0 -0
  180. data/shoes/ruby/lib/i386-mingw32/sdbm.so +0 -0
  181. data/shoes/ruby/lib/i386-mingw32/socket.so +0 -0
  182. data/shoes/ruby/lib/i386-mingw32/stringio.so +0 -0
  183. data/shoes/ruby/lib/i386-mingw32/strscan.so +0 -0
  184. data/shoes/ruby/lib/i386-mingw32/syck.so +0 -0
  185. data/shoes/ruby/lib/i386-mingw32/win32ole.so +0 -0
  186. data/shoes/ruby/lib/i386-mingw32/zlib.so +0 -0
  187. data/shoes/ruby/lib/rbconfig/datadir.rb +24 -24
  188. data/shoes/ruby/lib/rubygems/builder.rb +88 -88
  189. data/shoes/ruby/lib/rubygems/command.rb +406 -406
  190. data/shoes/ruby/lib/rubygems/command_manager.rb +146 -146
  191. data/shoes/ruby/lib/rubygems/commands/build_command.rb +53 -53
  192. data/shoes/ruby/lib/rubygems/commands/cert_command.rb +86 -86
  193. data/shoes/ruby/lib/rubygems/commands/check_command.rb +75 -75
  194. data/shoes/ruby/lib/rubygems/commands/cleanup_command.rb +91 -91
  195. data/shoes/ruby/lib/rubygems/commands/contents_command.rb +74 -74
  196. data/shoes/ruby/lib/rubygems/commands/dependency_command.rb +188 -188
  197. data/shoes/ruby/lib/rubygems/commands/environment_command.rb +128 -128
  198. data/shoes/ruby/lib/rubygems/commands/fetch_command.rb +62 -62
  199. data/shoes/ruby/lib/rubygems/commands/generate_index_command.rb +57 -57
  200. data/shoes/ruby/lib/rubygems/commands/help_command.rb +172 -172
  201. data/shoes/ruby/lib/rubygems/commands/install_command.rb +148 -148
  202. data/shoes/ruby/lib/rubygems/commands/list_command.rb +35 -35
  203. data/shoes/ruby/lib/rubygems/commands/lock_command.rb +110 -110
  204. data/shoes/ruby/lib/rubygems/commands/mirror_command.rb +111 -111
  205. data/shoes/ruby/lib/rubygems/commands/outdated_command.rb +33 -33
  206. data/shoes/ruby/lib/rubygems/commands/pristine_command.rb +93 -93
  207. data/shoes/ruby/lib/rubygems/commands/query_command.rb +233 -233
  208. data/shoes/ruby/lib/rubygems/commands/rdoc_command.rb +82 -82
  209. data/shoes/ruby/lib/rubygems/commands/search_command.rb +37 -37
  210. data/shoes/ruby/lib/rubygems/commands/server_command.rb +48 -48
  211. data/shoes/ruby/lib/rubygems/commands/sources_command.rb +152 -152
  212. data/shoes/ruby/lib/rubygems/commands/specification_command.rb +77 -77
  213. data/shoes/ruby/lib/rubygems/commands/stale_command.rb +27 -27
  214. data/shoes/ruby/lib/rubygems/commands/uninstall_command.rb +73 -73
  215. data/shoes/ruby/lib/rubygems/commands/unpack_command.rb +95 -95
  216. data/shoes/ruby/lib/rubygems/commands/update_command.rb +181 -181
  217. data/shoes/ruby/lib/rubygems/commands/which_command.rb +87 -87
  218. data/shoes/ruby/lib/rubygems/config_file.rb +266 -266
  219. data/shoes/ruby/lib/rubygems/custom_require.rb +46 -46
  220. data/shoes/ruby/lib/rubygems/defaults.rb +89 -89
  221. data/shoes/ruby/lib/rubygems/dependency.rb +119 -119
  222. data/shoes/ruby/lib/rubygems/dependency_installer.rb +258 -258
  223. data/shoes/ruby/lib/rubygems/dependency_list.rb +165 -165
  224. data/shoes/ruby/lib/rubygems/digest/digest_adapter.rb +39 -39
  225. data/shoes/ruby/lib/rubygems/digest/md5.rb +23 -23
  226. data/shoes/ruby/lib/rubygems/digest/sha1.rb +16 -16
  227. data/shoes/ruby/lib/rubygems/digest/sha2.rb +17 -17
  228. data/shoes/ruby/lib/rubygems/doc_manager.rb +214 -214
  229. data/shoes/ruby/lib/rubygems/exceptions.rb +84 -84
  230. data/shoes/ruby/lib/rubygems/ext/builder.rb +56 -56
  231. data/shoes/ruby/lib/rubygems/ext/configure_builder.rb +24 -24
  232. data/shoes/ruby/lib/rubygems/ext/ext_conf_builder.rb +23 -23
  233. data/shoes/ruby/lib/rubygems/ext/rake_builder.rb +27 -27
  234. data/shoes/ruby/lib/rubygems/ext.rb +18 -18
  235. data/shoes/ruby/lib/rubygems/format.rb +87 -87
  236. data/shoes/ruby/lib/rubygems/gem_openssl.rb +83 -83
  237. data/shoes/ruby/lib/rubygems/gem_path_searcher.rb +100 -100
  238. data/shoes/ruby/lib/rubygems/gem_runner.rb +58 -58
  239. data/shoes/ruby/lib/rubygems/indexer.rb +370 -370
  240. data/shoes/ruby/lib/rubygems/install_update_options.rb +113 -113
  241. data/shoes/ruby/lib/rubygems/installer.rb +578 -578
  242. data/shoes/ruby/lib/rubygems/local_remote_options.rb +134 -134
  243. data/shoes/ruby/lib/rubygems/old_format.rb +148 -148
  244. data/shoes/ruby/lib/rubygems/package/f_sync_dir.rb +24 -24
  245. data/shoes/ruby/lib/rubygems/package/tar_header.rb +245 -245
  246. data/shoes/ruby/lib/rubygems/package/tar_input.rb +219 -219
  247. data/shoes/ruby/lib/rubygems/package/tar_output.rb +143 -143
  248. data/shoes/ruby/lib/rubygems/package/tar_reader/entry.rb +99 -99
  249. data/shoes/ruby/lib/rubygems/package/tar_reader.rb +86 -86
  250. data/shoes/ruby/lib/rubygems/package/tar_writer.rb +180 -180
  251. data/shoes/ruby/lib/rubygems/package.rb +95 -95
  252. data/shoes/ruby/lib/rubygems/platform.rb +178 -178
  253. data/shoes/ruby/lib/rubygems/remote_fetcher.rb +344 -344
  254. data/shoes/ruby/lib/rubygems/require_paths_builder.rb +14 -14
  255. data/shoes/ruby/lib/rubygems/requirement.rb +163 -163
  256. data/shoes/ruby/lib/rubygems/rubygems_version.rb +6 -6
  257. data/shoes/ruby/lib/rubygems/security.rb +786 -786
  258. data/shoes/ruby/lib/rubygems/server.rb +629 -629
  259. data/shoes/ruby/lib/rubygems/source_index.rb +559 -559
  260. data/shoes/ruby/lib/rubygems/source_info_cache.rb +393 -393
  261. data/shoes/ruby/lib/rubygems/source_info_cache_entry.rb +56 -56
  262. data/shoes/ruby/lib/rubygems/spec_fetcher.rb +249 -249
  263. data/shoes/ruby/lib/rubygems/specification.rb +1262 -1262
  264. data/shoes/ruby/lib/rubygems/test_utilities.rb +131 -131
  265. data/shoes/ruby/lib/rubygems/timer.rb +25 -25
  266. data/shoes/ruby/lib/rubygems/uninstaller.rb +242 -242
  267. data/shoes/ruby/lib/rubygems/user_interaction.rb +360 -360
  268. data/shoes/ruby/lib/rubygems/validator.rb +208 -208
  269. data/shoes/ruby/lib/rubygems/version.rb +167 -167
  270. data/shoes/ruby/lib/rubygems/version_option.rb +48 -48
  271. data/shoes/ruby/lib/rubygems.rb +888 -888
  272. data/shoes/ruby/lib/ubygems.rb +10 -10
  273. data/shoes/samples/class-book.rb +43 -43
  274. data/shoes/samples/class-book.yaml +387 -387
  275. data/shoes/samples/expert-definr.rb +23 -23
  276. data/shoes/samples/expert-funnies.rb +51 -51
  277. data/shoes/samples/expert-irb.rb +112 -112
  278. data/shoes/samples/expert-minesweeper.rb +267 -267
  279. data/shoes/samples/expert-othello.rb +319 -319
  280. data/shoes/samples/expert-pong.rb +62 -62
  281. data/shoes/samples/expert-tankspank.rb +385 -385
  282. data/shoes/samples/good-arc.rb +37 -37
  283. data/shoes/samples/good-clock.rb +51 -51
  284. data/shoes/samples/good-follow.rb +26 -26
  285. data/shoes/samples/good-reminder.rb +174 -174
  286. data/shoes/samples/good-vjot.rb +56 -56
  287. data/shoes/samples/simple-accordion.rb +75 -75
  288. data/shoes/samples/simple-anim-shapes.rb +17 -17
  289. data/shoes/samples/simple-anim-text.rb +13 -13
  290. data/shoes/samples/simple-arc.rb +23 -23
  291. data/shoes/samples/simple-bounce.rb +24 -24
  292. data/shoes/samples/simple-calc.rb +70 -70
  293. data/shoes/samples/simple-control-sizes.rb +24 -24
  294. data/shoes/samples/simple-curve.rb +26 -26
  295. data/shoes/samples/simple-dialogs.rb +29 -29
  296. data/shoes/samples/simple-downloader.rb +27 -27
  297. data/shoes/samples/simple-draw.rb +13 -13
  298. data/shoes/samples/simple-editor.rb +28 -28
  299. data/shoes/samples/simple-form.rb +28 -28
  300. data/shoes/samples/simple-mask.rb +21 -21
  301. data/shoes/samples/simple-menu.rb +31 -31
  302. data/shoes/samples/simple-menu1.rb +35 -35
  303. data/shoes/samples/simple-rubygems.rb +29 -29
  304. data/shoes/samples/simple-slide.rb +45 -45
  305. data/shoes/samples/simple-sphere.rb +28 -28
  306. data/shoes/samples/simple-timer.rb +13 -13
  307. data/shoes/samples/simple-video.rb +13 -13
  308. data/shoes/shoes.exe +0 -0
  309. data/shoes/sqlite3.dll +0 -0
  310. data/shoes/static/code_highlighter.js +188 -188
  311. data/shoes/static/code_highlighter_ruby.js +26 -26
  312. data/shoes/static/manual-en.txt +2783 -2783
  313. data/shoes/static/manual-ja.txt +2780 -2780
  314. data/shoes/static/manual.css +167 -167
  315. data/shoes/static/stubs/blank.run +375 -375
  316. data/shoes/static/stubs/sh-install +48 -48
  317. data/shoes/zlib.dll +0 -0
  318. data/shoes/zlib1.dll +0 -0
  319. metadata +15 -5
  320. data/shoes/static/Thumbs.db +0 -0
@@ -1,721 +1,721 @@
1
- require 'sqlite3/constants'
2
- require 'sqlite3/errors'
3
- require 'sqlite3/pragmas'
4
- require 'sqlite3/statement'
5
- require 'sqlite3/translator'
6
- require 'sqlite3/value'
7
-
8
- module SQLite3
9
-
10
- # The Database class encapsulates a single connection to a SQLite3 database.
11
- # Its usage is very straightforward:
12
- #
13
- # require 'sqlite3'
14
- #
15
- # SQLite3::Database.new( "data.db" ) do |db|
16
- # db.execute( "select * from table" ) do |row|
17
- # p row
18
- # end
19
- # end
20
- #
21
- # It wraps the lower-level methods provides by the selected driver, and
22
- # includes the Pragmas module for access to various pragma convenience
23
- # methods.
24
- #
25
- # The Database class provides type translation services as well, by which
26
- # the SQLite3 data types (which are all represented as strings) may be
27
- # converted into their corresponding types (as defined in the schemas
28
- # for their tables). This translation only occurs when querying data from
29
- # the database--insertions and updates are all still typeless.
30
- #
31
- # Furthermore, the Database class has been designed to work well with the
32
- # ArrayFields module from Ara Howard. If you require the ArrayFields
33
- # module before performing a query, and if you have not enabled results as
34
- # hashes, then the results will all be indexible by field name.
35
- class Database
36
- include Pragmas
37
-
38
- class <<self
39
-
40
- alias :open :new
41
-
42
- # Quotes the given string, making it safe to use in an SQL statement.
43
- # It replaces all instances of the single-quote character with two
44
- # single-quote characters. The modified string is returned.
45
- def quote( string )
46
- string.gsub( /'/, "''" )
47
- end
48
-
49
- end
50
-
51
- # The low-level opaque database handle that this object wraps.
52
- attr_reader :handle
53
-
54
- # A reference to the underlying SQLite3 driver used by this database.
55
- attr_reader :driver
56
-
57
- # A boolean that indicates whether rows in result sets should be returned
58
- # as hashes or not. By default, rows are returned as arrays.
59
- attr_accessor :results_as_hash
60
-
61
- # A boolean indicating whether or not type translation is enabled for this
62
- # database.
63
- attr_accessor :type_translation
64
-
65
- # Create a new Database object that opens the given file. If utf16
66
- # is +true+, the filename is interpreted as a UTF-16 encoded string.
67
- #
68
- # By default, the new database will return result rows as arrays
69
- # (#results_as_hash) and has type translation disabled (#type_translation=).
70
- def initialize( file_name, options={} ) # :yields: db
71
- utf16 = options.fetch(:utf16, false)
72
- load_driver( options[:driver] )
73
-
74
- @statement_factory = options[:statement_factory] || Statement
75
-
76
- result, @handle = @driver.open( file_name, utf16 )
77
- Error.check( result, self, "could not open database" )
78
-
79
- @closed = false
80
- @results_as_hash = options.fetch(:results_as_hash,false)
81
- @type_translation = options.fetch(:type_translation,false)
82
- @translator = nil
83
- @transaction_active = false
84
-
85
- if block_given?
86
- begin
87
- yield self
88
- ensure
89
- self.close
90
- end
91
- end
92
- end
93
-
94
- # Return +true+ if the string is a valid (ie, parsable) SQL statement, and
95
- # +false+ otherwise. If +utf16+ is +true+, then the string is a UTF-16
96
- # character string.
97
- def complete?( string, utf16=false )
98
- @driver.complete?( string, utf16 )
99
- end
100
-
101
- # Return a string describing the last error to have occurred with this
102
- # database.
103
- def errmsg( utf16=false )
104
- @driver.errmsg( @handle, utf16 )
105
- end
106
-
107
- # Return an integer representing the last error to have occurred with this
108
- # database.
109
- def errcode
110
- @driver.errcode( @handle )
111
- end
112
-
113
- # Return the type translator employed by this database instance. Each
114
- # database instance has its own type translator; this allows for different
115
- # type handlers to be installed in each instance without affecting other
116
- # instances. Furthermore, the translators are instantiated lazily, so that
117
- # if a database does not use type translation, it will not be burdened by
118
- # the overhead of a useless type translator. (See the Translator class.)
119
- def translator
120
- @translator ||= Translator.new
121
- end
122
-
123
- # Closes this database.
124
- def close
125
- unless @closed
126
- result = @driver.close( @handle )
127
- Error.check( result, self )
128
- end
129
- @closed = true
130
- end
131
-
132
- # Returns +true+ if this database instance has been closed (see #close).
133
- def closed?
134
- @closed
135
- end
136
-
137
- # Installs (or removes) a block that will be invoked for every SQL
138
- # statement executed. The block receives a two parameters: the +data+
139
- # argument, and the SQL statement executed. If the block is +nil+,
140
- # any existing tracer will be uninstalled.
141
- def trace( data=nil, &block )
142
- @driver.trace( @handle, data, &block )
143
- end
144
-
145
- # Installs (or removes) a block that will be invoked for every access
146
- # to the database. If the block returns 0 (or +nil+), the statement
147
- # is allowed to proceed. Returning 1 causes an authorization error to
148
- # occur, and returning 2 causes the access to be silently denied.
149
- def authorizer( data=nil, &block )
150
- result = @driver.set_authorizer( @handle, data, &block )
151
- Error.check( result, self )
152
- end
153
-
154
- # Returns a Statement object representing the given SQL. This does not
155
- # execute the statement; it merely prepares the statement for execution.
156
- #
157
- # The Statement can then be executed using Statement#execute.
158
- #
159
- def prepare( sql )
160
- stmt = @statement_factory.new( self, sql )
161
- if block_given?
162
- begin
163
- yield stmt
164
- ensure
165
- stmt.close
166
- end
167
- else
168
- return stmt
169
- end
170
- end
171
-
172
- # Executes the given SQL statement. If additional parameters are given,
173
- # they are treated as bind variables, and are bound to the placeholders in
174
- # the query.
175
- #
176
- # Note that if any of the values passed to this are hashes, then the
177
- # key/value pairs are each bound separately, with the key being used as
178
- # the name of the placeholder to bind the value to.
179
- #
180
- # The block is optional. If given, it will be invoked for each row returned
181
- # by the query. Otherwise, any results are accumulated into an array and
182
- # returned wholesale.
183
- #
184
- # See also #execute2, #query, and #execute_batch for additional ways of
185
- # executing statements.
186
- def execute( sql, *bind_vars )
187
- prepare( sql ) do |stmt|
188
- result = stmt.execute( *bind_vars )
189
- if block_given?
190
- result.each { |row| yield row }
191
- else
192
- return result.inject( [] ) { |arr,row| arr << row; arr }
193
- end
194
- end
195
- end
196
-
197
- # Executes the given SQL statement, exactly as with #execute. However, the
198
- # first row returned (either via the block, or in the returned array) is
199
- # always the names of the columns. Subsequent rows correspond to the data
200
- # from the result set.
201
- #
202
- # Thus, even if the query itself returns no rows, this method will always
203
- # return at least one row--the names of the columns.
204
- #
205
- # See also #execute, #query, and #execute_batch for additional ways of
206
- # executing statements.
207
- def execute2( sql, *bind_vars )
208
- prepare( sql ) do |stmt|
209
- result = stmt.execute( *bind_vars )
210
- if block_given?
211
- yield result.columns
212
- result.each { |row| yield row }
213
- else
214
- return result.inject( [ result.columns ] ) { |arr,row|
215
- arr << row; arr }
216
- end
217
- end
218
- end
219
-
220
- # Executes all SQL statements in the given string. By contrast, the other
221
- # means of executing queries will only execute the first statement in the
222
- # string, ignoring all subsequent statements. This will execute each one
223
- # in turn. The same bind parameters, if given, will be applied to each
224
- # statement.
225
- #
226
- # This always returns +nil+, making it unsuitable for queries that return
227
- # rows.
228
- def execute_batch( sql, *bind_vars )
229
- sql = sql.strip
230
- until sql.empty? do
231
- prepare( sql ) do |stmt|
232
- stmt.execute( *bind_vars )
233
- sql = stmt.remainder.strip
234
- end
235
- end
236
- nil
237
- end
238
-
239
- # This is a convenience method for creating a statement, binding
240
- # paramters to it, and calling execute:
241
- #
242
- # result = db.query( "select * from foo where a=?", 5 )
243
- # # is the same as
244
- # result = db.prepare( "select * from foo where a=?" ).execute( 5 )
245
- #
246
- # You must be sure to call +close+ on the ResultSet instance that is
247
- # returned, or you could have problems with locks on the table. If called
248
- # with a block, +close+ will be invoked implicitly when the block
249
- # terminates.
250
- def query( sql, *bind_vars )
251
- result = prepare( sql ).execute( *bind_vars )
252
- if block_given?
253
- begin
254
- yield result
255
- ensure
256
- result.close
257
- end
258
- else
259
- return result
260
- end
261
- end
262
-
263
- # A convenience method for obtaining the first row of a result set, and
264
- # discarding all others. It is otherwise identical to #execute.
265
- #
266
- # See also #get_first_value.
267
- def get_first_row( sql, *bind_vars )
268
- execute( sql, *bind_vars ) { |row| return row }
269
- nil
270
- end
271
-
272
- # A convenience method for obtaining the first value of the first row of a
273
- # result set, and discarding all other values and rows. It is otherwise
274
- # identical to #execute.
275
- #
276
- # See also #get_first_row.
277
- def get_first_value( sql, *bind_vars )
278
- execute( sql, *bind_vars ) { |row| return row[0] }
279
- nil
280
- end
281
-
282
- # Obtains the unique row ID of the last row to be inserted by this Database
283
- # instance.
284
- def last_insert_row_id
285
- @driver.last_insert_rowid( @handle )
286
- end
287
-
288
- # Returns the number of changes made to this database instance by the last
289
- # operation performed. Note that a "delete from table" without a where
290
- # clause will not affect this value.
291
- def changes
292
- @driver.changes( @handle )
293
- end
294
-
295
- # Returns the total number of changes made to this database instance
296
- # since it was opened.
297
- def total_changes
298
- @driver.total_changes( @handle )
299
- end
300
-
301
- # Interrupts the currently executing operation, causing it to abort.
302
- def interrupt
303
- @driver.interrupt( @handle )
304
- end
305
-
306
- # Register a busy handler with this database instance. When a requested
307
- # resource is busy, this handler will be invoked. If the handler returns
308
- # +false+, the operation will be aborted; otherwise, the resource will
309
- # be requested again.
310
- #
311
- # The handler will be invoked with the name of the resource that was
312
- # busy, and the number of times it has been retried.
313
- #
314
- # See also the mutually exclusive #busy_timeout.
315
- def busy_handler( data=nil, &block ) # :yields: data, retries
316
- result = @driver.busy_handler( @handle, data, &block )
317
- Error.check( result, self )
318
- end
319
-
320
- # Indicates that if a request for a resource terminates because that
321
- # resource is busy, SQLite should sleep and retry for up to the indicated
322
- # number of milliseconds. By default, SQLite does not retry
323
- # busy resources. To restore the default behavior, send 0 as the
324
- # +ms+ parameter.
325
- #
326
- # See also the mutually exclusive #busy_handler.
327
- def busy_timeout( ms )
328
- result = @driver.busy_timeout( @handle, ms )
329
- Error.check( result, self )
330
- end
331
-
332
- # Creates a new function for use in SQL statements. It will be added as
333
- # +name+, with the given +arity+. (For variable arity functions, use
334
- # -1 for the arity.)
335
- #
336
- # The block should accept at least one parameter--the FunctionProxy
337
- # instance that wraps this function invocation--and any other
338
- # arguments it needs (up to its arity).
339
- #
340
- # The block does not return a value directly. Instead, it will invoke
341
- # the FunctionProxy#set_result method on the +func+ parameter and
342
- # indicate the return value that way.
343
- #
344
- # Example:
345
- #
346
- # db.create_function( "maim", 1 ) do |func, value|
347
- # if value.nil?
348
- # func.result = nil
349
- # else
350
- # func.result = value.split(//).sort.join
351
- # end
352
- # end
353
- #
354
- # puts db.get_first_value( "select maim(name) from table" )
355
- def create_function( name, arity, text_rep=Constants::TextRep::ANY,
356
- &block ) # :yields: func, *args
357
- # begin
358
- callback = proc do |func,*args|
359
- begin
360
- block.call( FunctionProxy.new( @driver, func ),
361
- *args.map{|v| Value.new(self,v)} )
362
- rescue StandardError, Exception => e
363
- @driver.result_error( func,
364
- "#{e.message} (#{e.class})", -1 )
365
- end
366
- end
367
-
368
- result = @driver.create_function( @handle, name, arity, text_rep, nil,
369
- callback, nil, nil )
370
- Error.check( result, self )
371
-
372
- self
373
- end
374
-
375
- # Creates a new aggregate function for use in SQL statements. Aggregate
376
- # functions are functions that apply over every row in the result set,
377
- # instead of over just a single row. (A very common aggregate function
378
- # is the "count" function, for determining the number of rows that match
379
- # a query.)
380
- #
381
- # The new function will be added as +name+, with the given +arity+. (For
382
- # variable arity functions, use -1 for the arity.)
383
- #
384
- # The +step+ parameter must be a proc object that accepts as its first
385
- # parameter a FunctionProxy instance (representing the function
386
- # invocation), with any subsequent parameters (up to the function's arity).
387
- # The +step+ callback will be invoked once for each row of the result set.
388
- #
389
- # The +finalize+ parameter must be a +proc+ object that accepts only a
390
- # single parameter, the FunctionProxy instance representing the current
391
- # function invocation. It should invoke FunctionProxy#set_result to
392
- # store the result of the function.
393
- #
394
- # Example:
395
- #
396
- # db.create_aggregate( "lengths", 1 ) do
397
- # step do |func, value|
398
- # func[ :total ] ||= 0
399
- # func[ :total ] += ( value ? value.length : 0 )
400
- # end
401
- #
402
- # finalize do |func|
403
- # func.set_result( func[ :total ] || 0 )
404
- # end
405
- # end
406
- #
407
- # puts db.get_first_value( "select lengths(name) from table" )
408
- #
409
- # See also #create_aggregate_handler for a more object-oriented approach to
410
- # aggregate functions.
411
- def create_aggregate( name, arity, step=nil, finalize=nil,
412
- text_rep=Constants::TextRep::ANY, &block )
413
- # begin
414
- if block
415
- proxy = AggregateDefinitionProxy.new
416
- proxy.instance_eval(&block)
417
- step ||= proxy.step_callback
418
- finalize ||= proxy.finalize_callback
419
- end
420
-
421
- step_callback = proc do |func,*args|
422
- ctx = @driver.aggregate_context( func )
423
- unless ctx[:__error]
424
- begin
425
- step.call( FunctionProxy.new( @driver, func, ctx ),
426
- *args.map{|v| Value.new(self,v)} )
427
- rescue Exception => e
428
- ctx[:__error] = e
429
- end
430
- end
431
- end
432
-
433
- finalize_callback = proc do |func|
434
- ctx = @driver.aggregate_context( func )
435
- unless ctx[:__error]
436
- begin
437
- finalize.call( FunctionProxy.new( @driver, func, ctx ) )
438
- rescue Exception => e
439
- @driver.result_error( func,
440
- "#{e.message} (#{e.class})", -1 )
441
- end
442
- else
443
- e = ctx[:__error]
444
- @driver.result_error( func,
445
- "#{e.message} (#{e.class})", -1 )
446
- end
447
- end
448
-
449
- result = @driver.create_function( @handle, name, arity, text_rep, nil,
450
- nil, step_callback, finalize_callback )
451
- Error.check( result, self )
452
-
453
- self
454
- end
455
-
456
- # This is another approach to creating an aggregate function (see
457
- # #create_aggregate). Instead of explicitly specifying the name,
458
- # callbacks, arity, and type, you specify a factory object
459
- # (the "handler") that knows how to obtain all of that information. The
460
- # handler should respond to the following messages:
461
- #
462
- # +arity+:: corresponds to the +arity+ parameter of #create_aggregate. This
463
- # message is optional, and if the handler does not respond to it,
464
- # the function will have an arity of -1.
465
- # +name+:: this is the name of the function. The handler _must_ implement
466
- # this message.
467
- # +new+:: this must be implemented by the handler. It should return a new
468
- # instance of the object that will handle a specific invocation of
469
- # the function.
470
- #
471
- # The handler instance (the object returned by the +new+ message, described
472
- # above), must respond to the following messages:
473
- #
474
- # +step+:: this is the method that will be called for each step of the
475
- # aggregate function's evaluation. It should implement the same
476
- # signature as the +step+ callback for #create_aggregate.
477
- # +finalize+:: this is the method that will be called to finalize the
478
- # aggregate function's evaluation. It should implement the
479
- # same signature as the +finalize+ callback for
480
- # #create_aggregate.
481
- #
482
- # Example:
483
- #
484
- # class LengthsAggregateHandler
485
- # def self.arity; 1; end
486
- #
487
- # def initialize
488
- # @total = 0
489
- # end
490
- #
491
- # def step( ctx, name )
492
- # @total += ( name ? name.length : 0 )
493
- # end
494
- #
495
- # def finalize( ctx )
496
- # ctx.set_result( @total )
497
- # end
498
- # end
499
- #
500
- # db.create_aggregate_handler( LengthsAggregateHandler )
501
- # puts db.get_first_value( "select lengths(name) from A" )
502
- def create_aggregate_handler( handler )
503
- arity = -1
504
- text_rep = Constants::TextRep::ANY
505
-
506
- arity = handler.arity if handler.respond_to?(:arity)
507
- text_rep = handler.text_rep if handler.respond_to?(:text_rep)
508
- name = handler.name
509
-
510
- step = proc do |func,*args|
511
- ctx = @driver.aggregate_context( func )
512
- unless ctx[ :__error ]
513
- ctx[ :handler ] ||= handler.new
514
- begin
515
- ctx[ :handler ].step( FunctionProxy.new( @driver, func, ctx ),
516
- *args.map{|v| Value.new(self,v)} )
517
- rescue Exception, StandardError => e
518
- ctx[ :__error ] = e
519
- end
520
- end
521
- end
522
-
523
- finalize = proc do |func|
524
- ctx = @driver.aggregate_context( func )
525
- unless ctx[ :__error ]
526
- ctx[ :handler ] ||= handler.new
527
- begin
528
- ctx[ :handler ].finalize( FunctionProxy.new( @driver, func, ctx ) )
529
- rescue Exception => e
530
- ctx[ :__error ] = e
531
- end
532
- end
533
-
534
- if ctx[ :__error ]
535
- e = ctx[ :__error ]
536
- @driver.sqlite3_result_error( func, "#{e.message} (#{e.class})", -1 )
537
- end
538
- end
539
-
540
- result = @driver.create_function( @handle, name, arity, text_rep, nil,
541
- nil, step, finalize )
542
- Error.check( result, self )
543
-
544
- self
545
- end
546
-
547
- # Begins a new transaction. Note that nested transactions are not allowed
548
- # by SQLite, so attempting to nest a transaction will result in a runtime
549
- # exception.
550
- #
551
- # The +mode+ parameter may be either <tt>:deferred</tt> (the default),
552
- # <tt>:immediate</tt>, or <tt>:exclusive</tt>.
553
- #
554
- # If a block is given, the database instance is yielded to it, and the
555
- # transaction is committed when the block terminates. If the block
556
- # raises an exception, a rollback will be performed instead. Note that if
557
- # a block is given, #commit and #rollback should never be called
558
- # explicitly or you'll get an error when the block terminates.
559
- #
560
- # If a block is not given, it is the caller's responsibility to end the
561
- # transaction explicitly, either by calling #commit, or by calling
562
- # #rollback.
563
- def transaction( mode = :deferred )
564
- execute "begin #{mode.to_s} transaction"
565
- @transaction_active = true
566
-
567
- if block_given?
568
- abort = false
569
- begin
570
- yield self
571
- rescue ::Object
572
- abort = true
573
- raise
574
- ensure
575
- abort and rollback or commit
576
- end
577
- end
578
-
579
- true
580
- end
581
-
582
- # Commits the current transaction. If there is no current transaction,
583
- # this will cause an error to be raised. This returns +true+, in order
584
- # to allow it to be used in idioms like
585
- # <tt>abort? and rollback or commit</tt>.
586
- def commit
587
- execute "commit transaction"
588
- @transaction_active = false
589
- true
590
- end
591
-
592
- # Rolls the current transaction back. If there is no current transaction,
593
- # this will cause an error to be raised. This returns +true+, in order
594
- # to allow it to be used in idioms like
595
- # <tt>abort? and rollback or commit</tt>.
596
- def rollback
597
- execute "rollback transaction"
598
- @transaction_active = false
599
- true
600
- end
601
-
602
- # Returns +true+ if there is a transaction active, and +false+ otherwise.
603
- def transaction_active?
604
- @transaction_active
605
- end
606
-
607
- # Loads the corresponding driver, or if it is nil, attempts to locate a
608
- # suitable driver.
609
- def load_driver( driver )
610
- case driver
611
- when Class
612
- # do nothing--use what was given
613
- when Symbol, String
614
- require "sqlite3/driver/#{driver.to_s.downcase}/driver"
615
- driver = SQLite3::Driver.const_get( driver )::Driver
616
- else
617
- [ "Native", "DL" ].each do |d|
618
- begin
619
- require "sqlite3/driver/#{d.downcase}/driver"
620
- driver = SQLite3::Driver.const_get( d )::Driver
621
- break
622
- rescue SyntaxError
623
- raise
624
- rescue ScriptError, Exception, NameError
625
- end
626
- end
627
- raise "no driver for sqlite3 found" unless driver
628
- end
629
-
630
- @driver = driver.new
631
- end
632
- private :load_driver
633
-
634
- # A helper class for dealing with custom functions (see #create_function,
635
- # #create_aggregate, and #create_aggregate_handler). It encapsulates the
636
- # opaque function object that represents the current invocation. It also
637
- # provides more convenient access to the API functions that operate on
638
- # the function object.
639
- #
640
- # This class will almost _always_ be instantiated indirectly, by working
641
- # with the create methods mentioned above.
642
- class FunctionProxy
643
-
644
- # Create a new FunctionProxy that encapsulates the given +func+ object.
645
- # If context is non-nil, the functions context will be set to that. If
646
- # it is non-nil, it must quack like a Hash. If it is nil, then none of
647
- # the context functions will be available.
648
- def initialize( driver, func, context=nil )
649
- @driver = driver
650
- @func = func
651
- @context = context
652
- end
653
-
654
- # Calls #set_result to set the result of this function.
655
- def result=( result )
656
- set_result( result )
657
- end
658
-
659
- # Set the result of the function to the given value. The function will
660
- # then return this value.
661
- def set_result( result, utf16=false )
662
- @driver.result_text( @func, result, utf16 )
663
- end
664
-
665
- # Set the result of the function to the given error message.
666
- # The function will then return that error.
667
- def set_error( error )
668
- @driver.result_error( @func, error.to_s, -1 )
669
- end
670
-
671
- # (Only available to aggregate functions.) Returns the number of rows
672
- # that the aggregate has processed so far. This will include the current
673
- # row, and so will always return at least 1.
674
- def count
675
- ensure_aggregate!
676
- @driver.aggregate_count( @func )
677
- end
678
-
679
- # Returns the value with the given key from the context. This is only
680
- # available to aggregate functions.
681
- def []( key )
682
- ensure_aggregate!
683
- @context[ key ]
684
- end
685
-
686
- # Sets the value with the given key in the context. This is only
687
- # available to aggregate functions.
688
- def []=( key, value )
689
- ensure_aggregate!
690
- @context[ key ] = value
691
- end
692
-
693
- # A function for performing a sanity check, to ensure that the function
694
- # being invoked is an aggregate function. This is implied by the
695
- # existence of the context variable.
696
- def ensure_aggregate!
697
- unless @context
698
- raise MisuseException, "function is not an aggregate"
699
- end
700
- end
701
- private :ensure_aggregate!
702
-
703
- end
704
-
705
- # A proxy used for defining the callbacks to an aggregate function.
706
- class AggregateDefinitionProxy # :nodoc:
707
- attr_reader :step_callback, :finalize_callback
708
-
709
- def step( &block )
710
- @step_callback = block
711
- end
712
-
713
- def finalize( &block )
714
- @finalize_callback = block
715
- end
716
- end
717
-
718
- end
719
-
720
- end
721
-
1
+ require 'sqlite3/constants'
2
+ require 'sqlite3/errors'
3
+ require 'sqlite3/pragmas'
4
+ require 'sqlite3/statement'
5
+ require 'sqlite3/translator'
6
+ require 'sqlite3/value'
7
+
8
+ module SQLite3
9
+
10
+ # The Database class encapsulates a single connection to a SQLite3 database.
11
+ # Its usage is very straightforward:
12
+ #
13
+ # require 'sqlite3'
14
+ #
15
+ # SQLite3::Database.new( "data.db" ) do |db|
16
+ # db.execute( "select * from table" ) do |row|
17
+ # p row
18
+ # end
19
+ # end
20
+ #
21
+ # It wraps the lower-level methods provides by the selected driver, and
22
+ # includes the Pragmas module for access to various pragma convenience
23
+ # methods.
24
+ #
25
+ # The Database class provides type translation services as well, by which
26
+ # the SQLite3 data types (which are all represented as strings) may be
27
+ # converted into their corresponding types (as defined in the schemas
28
+ # for their tables). This translation only occurs when querying data from
29
+ # the database--insertions and updates are all still typeless.
30
+ #
31
+ # Furthermore, the Database class has been designed to work well with the
32
+ # ArrayFields module from Ara Howard. If you require the ArrayFields
33
+ # module before performing a query, and if you have not enabled results as
34
+ # hashes, then the results will all be indexible by field name.
35
+ class Database
36
+ include Pragmas
37
+
38
+ class <<self
39
+
40
+ alias :open :new
41
+
42
+ # Quotes the given string, making it safe to use in an SQL statement.
43
+ # It replaces all instances of the single-quote character with two
44
+ # single-quote characters. The modified string is returned.
45
+ def quote( string )
46
+ string.gsub( /'/, "''" )
47
+ end
48
+
49
+ end
50
+
51
+ # The low-level opaque database handle that this object wraps.
52
+ attr_reader :handle
53
+
54
+ # A reference to the underlying SQLite3 driver used by this database.
55
+ attr_reader :driver
56
+
57
+ # A boolean that indicates whether rows in result sets should be returned
58
+ # as hashes or not. By default, rows are returned as arrays.
59
+ attr_accessor :results_as_hash
60
+
61
+ # A boolean indicating whether or not type translation is enabled for this
62
+ # database.
63
+ attr_accessor :type_translation
64
+
65
+ # Create a new Database object that opens the given file. If utf16
66
+ # is +true+, the filename is interpreted as a UTF-16 encoded string.
67
+ #
68
+ # By default, the new database will return result rows as arrays
69
+ # (#results_as_hash) and has type translation disabled (#type_translation=).
70
+ def initialize( file_name, options={} ) # :yields: db
71
+ utf16 = options.fetch(:utf16, false)
72
+ load_driver( options[:driver] )
73
+
74
+ @statement_factory = options[:statement_factory] || Statement
75
+
76
+ result, @handle = @driver.open( file_name, utf16 )
77
+ Error.check( result, self, "could not open database" )
78
+
79
+ @closed = false
80
+ @results_as_hash = options.fetch(:results_as_hash,false)
81
+ @type_translation = options.fetch(:type_translation,false)
82
+ @translator = nil
83
+ @transaction_active = false
84
+
85
+ if block_given?
86
+ begin
87
+ yield self
88
+ ensure
89
+ self.close
90
+ end
91
+ end
92
+ end
93
+
94
+ # Return +true+ if the string is a valid (ie, parsable) SQL statement, and
95
+ # +false+ otherwise. If +utf16+ is +true+, then the string is a UTF-16
96
+ # character string.
97
+ def complete?( string, utf16=false )
98
+ @driver.complete?( string, utf16 )
99
+ end
100
+
101
+ # Return a string describing the last error to have occurred with this
102
+ # database.
103
+ def errmsg( utf16=false )
104
+ @driver.errmsg( @handle, utf16 )
105
+ end
106
+
107
+ # Return an integer representing the last error to have occurred with this
108
+ # database.
109
+ def errcode
110
+ @driver.errcode( @handle )
111
+ end
112
+
113
+ # Return the type translator employed by this database instance. Each
114
+ # database instance has its own type translator; this allows for different
115
+ # type handlers to be installed in each instance without affecting other
116
+ # instances. Furthermore, the translators are instantiated lazily, so that
117
+ # if a database does not use type translation, it will not be burdened by
118
+ # the overhead of a useless type translator. (See the Translator class.)
119
+ def translator
120
+ @translator ||= Translator.new
121
+ end
122
+
123
+ # Closes this database.
124
+ def close
125
+ unless @closed
126
+ result = @driver.close( @handle )
127
+ Error.check( result, self )
128
+ end
129
+ @closed = true
130
+ end
131
+
132
+ # Returns +true+ if this database instance has been closed (see #close).
133
+ def closed?
134
+ @closed
135
+ end
136
+
137
+ # Installs (or removes) a block that will be invoked for every SQL
138
+ # statement executed. The block receives a two parameters: the +data+
139
+ # argument, and the SQL statement executed. If the block is +nil+,
140
+ # any existing tracer will be uninstalled.
141
+ def trace( data=nil, &block )
142
+ @driver.trace( @handle, data, &block )
143
+ end
144
+
145
+ # Installs (or removes) a block that will be invoked for every access
146
+ # to the database. If the block returns 0 (or +nil+), the statement
147
+ # is allowed to proceed. Returning 1 causes an authorization error to
148
+ # occur, and returning 2 causes the access to be silently denied.
149
+ def authorizer( data=nil, &block )
150
+ result = @driver.set_authorizer( @handle, data, &block )
151
+ Error.check( result, self )
152
+ end
153
+
154
+ # Returns a Statement object representing the given SQL. This does not
155
+ # execute the statement; it merely prepares the statement for execution.
156
+ #
157
+ # The Statement can then be executed using Statement#execute.
158
+ #
159
+ def prepare( sql )
160
+ stmt = @statement_factory.new( self, sql )
161
+ if block_given?
162
+ begin
163
+ yield stmt
164
+ ensure
165
+ stmt.close
166
+ end
167
+ else
168
+ return stmt
169
+ end
170
+ end
171
+
172
+ # Executes the given SQL statement. If additional parameters are given,
173
+ # they are treated as bind variables, and are bound to the placeholders in
174
+ # the query.
175
+ #
176
+ # Note that if any of the values passed to this are hashes, then the
177
+ # key/value pairs are each bound separately, with the key being used as
178
+ # the name of the placeholder to bind the value to.
179
+ #
180
+ # The block is optional. If given, it will be invoked for each row returned
181
+ # by the query. Otherwise, any results are accumulated into an array and
182
+ # returned wholesale.
183
+ #
184
+ # See also #execute2, #query, and #execute_batch for additional ways of
185
+ # executing statements.
186
+ def execute( sql, *bind_vars )
187
+ prepare( sql ) do |stmt|
188
+ result = stmt.execute( *bind_vars )
189
+ if block_given?
190
+ result.each { |row| yield row }
191
+ else
192
+ return result.inject( [] ) { |arr,row| arr << row; arr }
193
+ end
194
+ end
195
+ end
196
+
197
+ # Executes the given SQL statement, exactly as with #execute. However, the
198
+ # first row returned (either via the block, or in the returned array) is
199
+ # always the names of the columns. Subsequent rows correspond to the data
200
+ # from the result set.
201
+ #
202
+ # Thus, even if the query itself returns no rows, this method will always
203
+ # return at least one row--the names of the columns.
204
+ #
205
+ # See also #execute, #query, and #execute_batch for additional ways of
206
+ # executing statements.
207
+ def execute2( sql, *bind_vars )
208
+ prepare( sql ) do |stmt|
209
+ result = stmt.execute( *bind_vars )
210
+ if block_given?
211
+ yield result.columns
212
+ result.each { |row| yield row }
213
+ else
214
+ return result.inject( [ result.columns ] ) { |arr,row|
215
+ arr << row; arr }
216
+ end
217
+ end
218
+ end
219
+
220
+ # Executes all SQL statements in the given string. By contrast, the other
221
+ # means of executing queries will only execute the first statement in the
222
+ # string, ignoring all subsequent statements. This will execute each one
223
+ # in turn. The same bind parameters, if given, will be applied to each
224
+ # statement.
225
+ #
226
+ # This always returns +nil+, making it unsuitable for queries that return
227
+ # rows.
228
+ def execute_batch( sql, *bind_vars )
229
+ sql = sql.strip
230
+ until sql.empty? do
231
+ prepare( sql ) do |stmt|
232
+ stmt.execute( *bind_vars )
233
+ sql = stmt.remainder.strip
234
+ end
235
+ end
236
+ nil
237
+ end
238
+
239
+ # This is a convenience method for creating a statement, binding
240
+ # paramters to it, and calling execute:
241
+ #
242
+ # result = db.query( "select * from foo where a=?", 5 )
243
+ # # is the same as
244
+ # result = db.prepare( "select * from foo where a=?" ).execute( 5 )
245
+ #
246
+ # You must be sure to call +close+ on the ResultSet instance that is
247
+ # returned, or you could have problems with locks on the table. If called
248
+ # with a block, +close+ will be invoked implicitly when the block
249
+ # terminates.
250
+ def query( sql, *bind_vars )
251
+ result = prepare( sql ).execute( *bind_vars )
252
+ if block_given?
253
+ begin
254
+ yield result
255
+ ensure
256
+ result.close
257
+ end
258
+ else
259
+ return result
260
+ end
261
+ end
262
+
263
+ # A convenience method for obtaining the first row of a result set, and
264
+ # discarding all others. It is otherwise identical to #execute.
265
+ #
266
+ # See also #get_first_value.
267
+ def get_first_row( sql, *bind_vars )
268
+ execute( sql, *bind_vars ) { |row| return row }
269
+ nil
270
+ end
271
+
272
+ # A convenience method for obtaining the first value of the first row of a
273
+ # result set, and discarding all other values and rows. It is otherwise
274
+ # identical to #execute.
275
+ #
276
+ # See also #get_first_row.
277
+ def get_first_value( sql, *bind_vars )
278
+ execute( sql, *bind_vars ) { |row| return row[0] }
279
+ nil
280
+ end
281
+
282
+ # Obtains the unique row ID of the last row to be inserted by this Database
283
+ # instance.
284
+ def last_insert_row_id
285
+ @driver.last_insert_rowid( @handle )
286
+ end
287
+
288
+ # Returns the number of changes made to this database instance by the last
289
+ # operation performed. Note that a "delete from table" without a where
290
+ # clause will not affect this value.
291
+ def changes
292
+ @driver.changes( @handle )
293
+ end
294
+
295
+ # Returns the total number of changes made to this database instance
296
+ # since it was opened.
297
+ def total_changes
298
+ @driver.total_changes( @handle )
299
+ end
300
+
301
+ # Interrupts the currently executing operation, causing it to abort.
302
+ def interrupt
303
+ @driver.interrupt( @handle )
304
+ end
305
+
306
+ # Register a busy handler with this database instance. When a requested
307
+ # resource is busy, this handler will be invoked. If the handler returns
308
+ # +false+, the operation will be aborted; otherwise, the resource will
309
+ # be requested again.
310
+ #
311
+ # The handler will be invoked with the name of the resource that was
312
+ # busy, and the number of times it has been retried.
313
+ #
314
+ # See also the mutually exclusive #busy_timeout.
315
+ def busy_handler( data=nil, &block ) # :yields: data, retries
316
+ result = @driver.busy_handler( @handle, data, &block )
317
+ Error.check( result, self )
318
+ end
319
+
320
+ # Indicates that if a request for a resource terminates because that
321
+ # resource is busy, SQLite should sleep and retry for up to the indicated
322
+ # number of milliseconds. By default, SQLite does not retry
323
+ # busy resources. To restore the default behavior, send 0 as the
324
+ # +ms+ parameter.
325
+ #
326
+ # See also the mutually exclusive #busy_handler.
327
+ def busy_timeout( ms )
328
+ result = @driver.busy_timeout( @handle, ms )
329
+ Error.check( result, self )
330
+ end
331
+
332
+ # Creates a new function for use in SQL statements. It will be added as
333
+ # +name+, with the given +arity+. (For variable arity functions, use
334
+ # -1 for the arity.)
335
+ #
336
+ # The block should accept at least one parameter--the FunctionProxy
337
+ # instance that wraps this function invocation--and any other
338
+ # arguments it needs (up to its arity).
339
+ #
340
+ # The block does not return a value directly. Instead, it will invoke
341
+ # the FunctionProxy#set_result method on the +func+ parameter and
342
+ # indicate the return value that way.
343
+ #
344
+ # Example:
345
+ #
346
+ # db.create_function( "maim", 1 ) do |func, value|
347
+ # if value.nil?
348
+ # func.result = nil
349
+ # else
350
+ # func.result = value.split(//).sort.join
351
+ # end
352
+ # end
353
+ #
354
+ # puts db.get_first_value( "select maim(name) from table" )
355
+ def create_function( name, arity, text_rep=Constants::TextRep::ANY,
356
+ &block ) # :yields: func, *args
357
+ # begin
358
+ callback = proc do |func,*args|
359
+ begin
360
+ block.call( FunctionProxy.new( @driver, func ),
361
+ *args.map{|v| Value.new(self,v)} )
362
+ rescue StandardError, Exception => e
363
+ @driver.result_error( func,
364
+ "#{e.message} (#{e.class})", -1 )
365
+ end
366
+ end
367
+
368
+ result = @driver.create_function( @handle, name, arity, text_rep, nil,
369
+ callback, nil, nil )
370
+ Error.check( result, self )
371
+
372
+ self
373
+ end
374
+
375
+ # Creates a new aggregate function for use in SQL statements. Aggregate
376
+ # functions are functions that apply over every row in the result set,
377
+ # instead of over just a single row. (A very common aggregate function
378
+ # is the "count" function, for determining the number of rows that match
379
+ # a query.)
380
+ #
381
+ # The new function will be added as +name+, with the given +arity+. (For
382
+ # variable arity functions, use -1 for the arity.)
383
+ #
384
+ # The +step+ parameter must be a proc object that accepts as its first
385
+ # parameter a FunctionProxy instance (representing the function
386
+ # invocation), with any subsequent parameters (up to the function's arity).
387
+ # The +step+ callback will be invoked once for each row of the result set.
388
+ #
389
+ # The +finalize+ parameter must be a +proc+ object that accepts only a
390
+ # single parameter, the FunctionProxy instance representing the current
391
+ # function invocation. It should invoke FunctionProxy#set_result to
392
+ # store the result of the function.
393
+ #
394
+ # Example:
395
+ #
396
+ # db.create_aggregate( "lengths", 1 ) do
397
+ # step do |func, value|
398
+ # func[ :total ] ||= 0
399
+ # func[ :total ] += ( value ? value.length : 0 )
400
+ # end
401
+ #
402
+ # finalize do |func|
403
+ # func.set_result( func[ :total ] || 0 )
404
+ # end
405
+ # end
406
+ #
407
+ # puts db.get_first_value( "select lengths(name) from table" )
408
+ #
409
+ # See also #create_aggregate_handler for a more object-oriented approach to
410
+ # aggregate functions.
411
+ def create_aggregate( name, arity, step=nil, finalize=nil,
412
+ text_rep=Constants::TextRep::ANY, &block )
413
+ # begin
414
+ if block
415
+ proxy = AggregateDefinitionProxy.new
416
+ proxy.instance_eval(&block)
417
+ step ||= proxy.step_callback
418
+ finalize ||= proxy.finalize_callback
419
+ end
420
+
421
+ step_callback = proc do |func,*args|
422
+ ctx = @driver.aggregate_context( func )
423
+ unless ctx[:__error]
424
+ begin
425
+ step.call( FunctionProxy.new( @driver, func, ctx ),
426
+ *args.map{|v| Value.new(self,v)} )
427
+ rescue Exception => e
428
+ ctx[:__error] = e
429
+ end
430
+ end
431
+ end
432
+
433
+ finalize_callback = proc do |func|
434
+ ctx = @driver.aggregate_context( func )
435
+ unless ctx[:__error]
436
+ begin
437
+ finalize.call( FunctionProxy.new( @driver, func, ctx ) )
438
+ rescue Exception => e
439
+ @driver.result_error( func,
440
+ "#{e.message} (#{e.class})", -1 )
441
+ end
442
+ else
443
+ e = ctx[:__error]
444
+ @driver.result_error( func,
445
+ "#{e.message} (#{e.class})", -1 )
446
+ end
447
+ end
448
+
449
+ result = @driver.create_function( @handle, name, arity, text_rep, nil,
450
+ nil, step_callback, finalize_callback )
451
+ Error.check( result, self )
452
+
453
+ self
454
+ end
455
+
456
+ # This is another approach to creating an aggregate function (see
457
+ # #create_aggregate). Instead of explicitly specifying the name,
458
+ # callbacks, arity, and type, you specify a factory object
459
+ # (the "handler") that knows how to obtain all of that information. The
460
+ # handler should respond to the following messages:
461
+ #
462
+ # +arity+:: corresponds to the +arity+ parameter of #create_aggregate. This
463
+ # message is optional, and if the handler does not respond to it,
464
+ # the function will have an arity of -1.
465
+ # +name+:: this is the name of the function. The handler _must_ implement
466
+ # this message.
467
+ # +new+:: this must be implemented by the handler. It should return a new
468
+ # instance of the object that will handle a specific invocation of
469
+ # the function.
470
+ #
471
+ # The handler instance (the object returned by the +new+ message, described
472
+ # above), must respond to the following messages:
473
+ #
474
+ # +step+:: this is the method that will be called for each step of the
475
+ # aggregate function's evaluation. It should implement the same
476
+ # signature as the +step+ callback for #create_aggregate.
477
+ # +finalize+:: this is the method that will be called to finalize the
478
+ # aggregate function's evaluation. It should implement the
479
+ # same signature as the +finalize+ callback for
480
+ # #create_aggregate.
481
+ #
482
+ # Example:
483
+ #
484
+ # class LengthsAggregateHandler
485
+ # def self.arity; 1; end
486
+ #
487
+ # def initialize
488
+ # @total = 0
489
+ # end
490
+ #
491
+ # def step( ctx, name )
492
+ # @total += ( name ? name.length : 0 )
493
+ # end
494
+ #
495
+ # def finalize( ctx )
496
+ # ctx.set_result( @total )
497
+ # end
498
+ # end
499
+ #
500
+ # db.create_aggregate_handler( LengthsAggregateHandler )
501
+ # puts db.get_first_value( "select lengths(name) from A" )
502
+ def create_aggregate_handler( handler )
503
+ arity = -1
504
+ text_rep = Constants::TextRep::ANY
505
+
506
+ arity = handler.arity if handler.respond_to?(:arity)
507
+ text_rep = handler.text_rep if handler.respond_to?(:text_rep)
508
+ name = handler.name
509
+
510
+ step = proc do |func,*args|
511
+ ctx = @driver.aggregate_context( func )
512
+ unless ctx[ :__error ]
513
+ ctx[ :handler ] ||= handler.new
514
+ begin
515
+ ctx[ :handler ].step( FunctionProxy.new( @driver, func, ctx ),
516
+ *args.map{|v| Value.new(self,v)} )
517
+ rescue Exception, StandardError => e
518
+ ctx[ :__error ] = e
519
+ end
520
+ end
521
+ end
522
+
523
+ finalize = proc do |func|
524
+ ctx = @driver.aggregate_context( func )
525
+ unless ctx[ :__error ]
526
+ ctx[ :handler ] ||= handler.new
527
+ begin
528
+ ctx[ :handler ].finalize( FunctionProxy.new( @driver, func, ctx ) )
529
+ rescue Exception => e
530
+ ctx[ :__error ] = e
531
+ end
532
+ end
533
+
534
+ if ctx[ :__error ]
535
+ e = ctx[ :__error ]
536
+ @driver.sqlite3_result_error( func, "#{e.message} (#{e.class})", -1 )
537
+ end
538
+ end
539
+
540
+ result = @driver.create_function( @handle, name, arity, text_rep, nil,
541
+ nil, step, finalize )
542
+ Error.check( result, self )
543
+
544
+ self
545
+ end
546
+
547
+ # Begins a new transaction. Note that nested transactions are not allowed
548
+ # by SQLite, so attempting to nest a transaction will result in a runtime
549
+ # exception.
550
+ #
551
+ # The +mode+ parameter may be either <tt>:deferred</tt> (the default),
552
+ # <tt>:immediate</tt>, or <tt>:exclusive</tt>.
553
+ #
554
+ # If a block is given, the database instance is yielded to it, and the
555
+ # transaction is committed when the block terminates. If the block
556
+ # raises an exception, a rollback will be performed instead. Note that if
557
+ # a block is given, #commit and #rollback should never be called
558
+ # explicitly or you'll get an error when the block terminates.
559
+ #
560
+ # If a block is not given, it is the caller's responsibility to end the
561
+ # transaction explicitly, either by calling #commit, or by calling
562
+ # #rollback.
563
+ def transaction( mode = :deferred )
564
+ execute "begin #{mode.to_s} transaction"
565
+ @transaction_active = true
566
+
567
+ if block_given?
568
+ abort = false
569
+ begin
570
+ yield self
571
+ rescue ::Object
572
+ abort = true
573
+ raise
574
+ ensure
575
+ abort and rollback or commit
576
+ end
577
+ end
578
+
579
+ true
580
+ end
581
+
582
+ # Commits the current transaction. If there is no current transaction,
583
+ # this will cause an error to be raised. This returns +true+, in order
584
+ # to allow it to be used in idioms like
585
+ # <tt>abort? and rollback or commit</tt>.
586
+ def commit
587
+ execute "commit transaction"
588
+ @transaction_active = false
589
+ true
590
+ end
591
+
592
+ # Rolls the current transaction back. If there is no current transaction,
593
+ # this will cause an error to be raised. This returns +true+, in order
594
+ # to allow it to be used in idioms like
595
+ # <tt>abort? and rollback or commit</tt>.
596
+ def rollback
597
+ execute "rollback transaction"
598
+ @transaction_active = false
599
+ true
600
+ end
601
+
602
+ # Returns +true+ if there is a transaction active, and +false+ otherwise.
603
+ def transaction_active?
604
+ @transaction_active
605
+ end
606
+
607
+ # Loads the corresponding driver, or if it is nil, attempts to locate a
608
+ # suitable driver.
609
+ def load_driver( driver )
610
+ case driver
611
+ when Class
612
+ # do nothing--use what was given
613
+ when Symbol, String
614
+ require "sqlite3/driver/#{driver.to_s.downcase}/driver"
615
+ driver = SQLite3::Driver.const_get( driver )::Driver
616
+ else
617
+ [ "Native", "DL" ].each do |d|
618
+ begin
619
+ require "sqlite3/driver/#{d.downcase}/driver"
620
+ driver = SQLite3::Driver.const_get( d )::Driver
621
+ break
622
+ rescue SyntaxError
623
+ raise
624
+ rescue ScriptError, Exception, NameError
625
+ end
626
+ end
627
+ raise "no driver for sqlite3 found" unless driver
628
+ end
629
+
630
+ @driver = driver.new
631
+ end
632
+ private :load_driver
633
+
634
+ # A helper class for dealing with custom functions (see #create_function,
635
+ # #create_aggregate, and #create_aggregate_handler). It encapsulates the
636
+ # opaque function object that represents the current invocation. It also
637
+ # provides more convenient access to the API functions that operate on
638
+ # the function object.
639
+ #
640
+ # This class will almost _always_ be instantiated indirectly, by working
641
+ # with the create methods mentioned above.
642
+ class FunctionProxy
643
+
644
+ # Create a new FunctionProxy that encapsulates the given +func+ object.
645
+ # If context is non-nil, the functions context will be set to that. If
646
+ # it is non-nil, it must quack like a Hash. If it is nil, then none of
647
+ # the context functions will be available.
648
+ def initialize( driver, func, context=nil )
649
+ @driver = driver
650
+ @func = func
651
+ @context = context
652
+ end
653
+
654
+ # Calls #set_result to set the result of this function.
655
+ def result=( result )
656
+ set_result( result )
657
+ end
658
+
659
+ # Set the result of the function to the given value. The function will
660
+ # then return this value.
661
+ def set_result( result, utf16=false )
662
+ @driver.result_text( @func, result, utf16 )
663
+ end
664
+
665
+ # Set the result of the function to the given error message.
666
+ # The function will then return that error.
667
+ def set_error( error )
668
+ @driver.result_error( @func, error.to_s, -1 )
669
+ end
670
+
671
+ # (Only available to aggregate functions.) Returns the number of rows
672
+ # that the aggregate has processed so far. This will include the current
673
+ # row, and so will always return at least 1.
674
+ def count
675
+ ensure_aggregate!
676
+ @driver.aggregate_count( @func )
677
+ end
678
+
679
+ # Returns the value with the given key from the context. This is only
680
+ # available to aggregate functions.
681
+ def []( key )
682
+ ensure_aggregate!
683
+ @context[ key ]
684
+ end
685
+
686
+ # Sets the value with the given key in the context. This is only
687
+ # available to aggregate functions.
688
+ def []=( key, value )
689
+ ensure_aggregate!
690
+ @context[ key ] = value
691
+ end
692
+
693
+ # A function for performing a sanity check, to ensure that the function
694
+ # being invoked is an aggregate function. This is implied by the
695
+ # existence of the context variable.
696
+ def ensure_aggregate!
697
+ unless @context
698
+ raise MisuseException, "function is not an aggregate"
699
+ end
700
+ end
701
+ private :ensure_aggregate!
702
+
703
+ end
704
+
705
+ # A proxy used for defining the callbacks to an aggregate function.
706
+ class AggregateDefinitionProxy # :nodoc:
707
+ attr_reader :step_callback, :finalize_callback
708
+
709
+ def step( &block )
710
+ @step_callback = block
711
+ end
712
+
713
+ def finalize( &block )
714
+ @finalize_callback = block
715
+ end
716
+ end
717
+
718
+ end
719
+
720
+ end
721
+