zsv 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +36 -0
  3. data/LICENSE +21 -0
  4. data/README.md +311 -0
  5. data/ext/zsv/common.h +34 -0
  6. data/ext/zsv/extconf.rb +137 -0
  7. data/ext/zsv/options.c +126 -0
  8. data/ext/zsv/options.h +31 -0
  9. data/ext/zsv/options_internal.h +8 -0
  10. data/ext/zsv/parser.c +300 -0
  11. data/ext/zsv/parser.h +62 -0
  12. data/ext/zsv/row.c +122 -0
  13. data/ext/zsv/row.h +39 -0
  14. data/ext/zsv/vendor/zsv-1.3.0/app/2db.c +756 -0
  15. data/ext/zsv/vendor/zsv-1.3.0/app/2json.c +381 -0
  16. data/ext/zsv/vendor/zsv-1.3.0/app/2tsv.c +228 -0
  17. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/help.c +123 -0
  18. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/license.c +39 -0
  19. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/register.c +104 -0
  20. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/thirdparty.c +41 -0
  21. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/unregister.c +1 -0
  22. data/ext/zsv/vendor/zsv-1.3.0/app/builtin/version.c +14 -0
  23. data/ext/zsv/vendor/zsv-1.3.0/app/check/simdutf_wrapper.h +19 -0
  24. data/ext/zsv/vendor/zsv-1.3.0/app/check/utf8.c +116 -0
  25. data/ext/zsv/vendor/zsv-1.3.0/app/check.c +194 -0
  26. data/ext/zsv/vendor/zsv-1.3.0/app/cli.c +796 -0
  27. data/ext/zsv/vendor/zsv-1.3.0/app/cli_const.h +41 -0
  28. data/ext/zsv/vendor/zsv-1.3.0/app/cli_export.h +16 -0
  29. data/ext/zsv/vendor/zsv-1.3.0/app/cli_ini.c +280 -0
  30. data/ext/zsv/vendor/zsv-1.3.0/app/cli_internal.h +36 -0
  31. data/ext/zsv/vendor/zsv-1.3.0/app/compare.c +913 -0
  32. data/ext/zsv/vendor/zsv-1.3.0/app/compare.h +23 -0
  33. data/ext/zsv/vendor/zsv-1.3.0/app/compare_added_column.c +20 -0
  34. data/ext/zsv/vendor/zsv-1.3.0/app/compare_internal.h +140 -0
  35. data/ext/zsv/vendor/zsv-1.3.0/app/compare_sort.c +91 -0
  36. data/ext/zsv/vendor/zsv-1.3.0/app/compare_unique_colname.c +81 -0
  37. data/ext/zsv/vendor/zsv-1.3.0/app/count-pull.c +82 -0
  38. data/ext/zsv/vendor/zsv-1.3.0/app/count.c +404 -0
  39. data/ext/zsv/vendor/zsv-1.3.0/app/desc.c +569 -0
  40. data/ext/zsv/vendor/zsv-1.3.0/app/echo.c +365 -0
  41. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/my_extension.c +366 -0
  42. data/ext/zsv/vendor/zsv-1.3.0/app/ext_example/mysheet_extension.c +341 -0
  43. data/ext/zsv/vendor/zsv-1.3.0/app/ext_template/YOUR_EXTENSION_zsvext.c +263 -0
  44. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.c +298 -0
  45. data/ext/zsv/vendor/zsv-1.3.0/app/external/inih/ini.h +157 -0
  46. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/json_numeric.c +177 -0
  47. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.c +444 -0
  48. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/jsonwriter.h +145 -0
  49. data/ext/zsv/vendor/zsv-1.3.0/app/external/json_writer-1.01/utils.c +110 -0
  50. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/include/memfile.h +15 -0
  51. data/ext/zsv/vendor/zsv-1.3.0/app/external/memfile-1.0/src/memfile.c +64 -0
  52. data/ext/zsv/vendor/zsv-1.3.0/app/external/sglib/sglib.h +1955 -0
  53. data/ext/zsv/vendor/zsv-1.3.0/app/external/simdutf/simdutf.h +6802 -0
  54. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.c +230517 -0
  55. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3.h +12174 -0
  56. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_and_csv_vtab.c +2 -0
  57. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.c +142 -0
  58. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-mem.h +49 -0
  59. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab-zsv.c +485 -0
  60. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3_csv_vtab.c +1015 -0
  61. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/sqlite3ext.h +663 -0
  62. data/ext/zsv/vendor/zsv-1.3.0/app/external/sqlite3/vtab_helper.c +85 -0
  63. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_common.h +75 -0
  64. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_gen.h +167 -0
  65. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_parse.h +228 -0
  66. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_tree.h +186 -0
  67. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/build/yajl-2.1.1/include/yajl/yajl_version.h +23 -0
  68. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_common.h +76 -0
  69. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_gen.h +167 -0
  70. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_parse.h +238 -0
  71. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/api/yajl_tree.h +186 -0
  72. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl.c +184 -0
  73. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.c +52 -0
  74. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_alloc.h +34 -0
  75. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.c +103 -0
  76. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_buf.h +57 -0
  77. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_bytestack.h +69 -0
  78. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.c +220 -0
  79. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_encode.h +34 -0
  80. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_gen.c +362 -0
  81. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.c +764 -0
  82. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_lex.h +117 -0
  83. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.c +508 -0
  84. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_parser.h +78 -0
  85. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_tree.c +505 -0
  86. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl/src/yajl_version.c +7 -0
  87. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/json_value.h +59 -0
  88. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper/yajl_helper.h +208 -0
  89. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper.c +795 -0
  90. data/ext/zsv/vendor/zsv-1.3.0/app/external/yajl_helper/yajl_helper_internal.h +28 -0
  91. data/ext/zsv/vendor/zsv-1.3.0/app/flatten.c +851 -0
  92. data/ext/zsv/vendor/zsv-1.3.0/app/jq.c +106 -0
  93. data/ext/zsv/vendor/zsv-1.3.0/app/jq.h +6 -0
  94. data/ext/zsv/vendor/zsv-1.3.0/app/mv.c +113 -0
  95. data/ext/zsv/vendor/zsv-1.3.0/app/noop.c +90 -0
  96. data/ext/zsv/vendor/zsv-1.3.0/app/overwrite.c +295 -0
  97. data/ext/zsv/vendor/zsv-1.3.0/app/paste.c +175 -0
  98. data/ext/zsv/vendor/zsv-1.3.0/app/pretty.c +693 -0
  99. data/ext/zsv/vendor/zsv-1.3.0/app/prop.c +980 -0
  100. data/ext/zsv/vendor/zsv-1.3.0/app/rm.c +131 -0
  101. data/ext/zsv/vendor/zsv-1.3.0/app/select/fixed.c +130 -0
  102. data/ext/zsv/vendor/zsv-1.3.0/app/select/internal.h +118 -0
  103. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.c +45 -0
  104. data/ext/zsv/vendor/zsv-1.3.0/app/select/parallel.h +41 -0
  105. data/ext/zsv/vendor/zsv-1.3.0/app/select/processing.c +107 -0
  106. data/ext/zsv/vendor/zsv-1.3.0/app/select/rand.c +20 -0
  107. data/ext/zsv/vendor/zsv-1.3.0/app/select/regex.c +61 -0
  108. data/ext/zsv/vendor/zsv-1.3.0/app/select/search.c +14 -0
  109. data/ext/zsv/vendor/zsv-1.3.0/app/select/selection.c +192 -0
  110. data/ext/zsv/vendor/zsv-1.3.0/app/select/usage.c +72 -0
  111. data/ext/zsv/vendor/zsv-1.3.0/app/select-pull.c +812 -0
  112. data/ext/zsv/vendor/zsv-1.3.0/app/select.c +753 -0
  113. data/ext/zsv/vendor/zsv-1.3.0/app/serialize.c +372 -0
  114. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/curses.h +15 -0
  115. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/cursor.c +119 -0
  116. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/errors.c +45 -0
  117. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.c +63 -0
  118. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/file.h +12 -0
  119. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/filter.c +166 -0
  120. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers.c +214 -0
  121. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/handlers_internal.h +128 -0
  122. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/help.c +43 -0
  123. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.c +81 -0
  124. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/index.h +25 -0
  125. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.c +325 -0
  126. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/key-bindings.h +73 -0
  127. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/lexer.c +203 -0
  128. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/newline_handler.c +7 -0
  129. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/pivot.c +318 -0
  130. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.c +134 -0
  131. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/procedure.h +119 -0
  132. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/read-data.c +322 -0
  133. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.c +203 -0
  134. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/screen_buffer.h +36 -0
  135. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet-sql.c +167 -0
  136. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sheet_internal.h +36 -0
  137. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/sqlfilter.c +153 -0
  138. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/terminfo.c +32 -0
  139. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.c +312 -0
  140. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/transformation.h +29 -0
  141. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/ui_buffer.c +266 -0
  142. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/usage.c +9 -0
  143. data/ext/zsv/vendor/zsv-1.3.0/app/sheet/utf8-width.c +60 -0
  144. data/ext/zsv/vendor/zsv-1.3.0/app/sheet.c +1007 -0
  145. data/ext/zsv/vendor/zsv-1.3.0/app/sql.c +453 -0
  146. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.c +101 -0
  147. data/ext/zsv/vendor/zsv-1.3.0/app/sql_internal.h +49 -0
  148. data/ext/zsv/vendor/zsv-1.3.0/app/stack.c +393 -0
  149. data/ext/zsv/vendor/zsv-1.3.0/app/utils/arg.c +322 -0
  150. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cache.c +228 -0
  151. data/ext/zsv/vendor/zsv-1.3.0/app/utils/cat.c +91 -0
  152. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.c +240 -0
  153. data/ext/zsv/vendor/zsv-1.3.0/app/utils/chunk.h +63 -0
  154. data/ext/zsv/vendor/zsv-1.3.0/app/utils/clock.c +57 -0
  155. data/ext/zsv/vendor/zsv-1.3.0/app/utils/db.c +148 -0
  156. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs-no-jq.c +2 -0
  157. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs.c +427 -0
  158. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_from_json.c +253 -0
  159. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dirs_to_json.c +121 -0
  160. data/ext/zsv/vendor/zsv-1.3.0/app/utils/dl.c +20 -0
  161. data/ext/zsv/vendor/zsv-1.3.0/app/utils/emcc/fs_api.c +159 -0
  162. data/ext/zsv/vendor/zsv-1.3.0/app/utils/err.c +24 -0
  163. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file-mem.c +180 -0
  164. data/ext/zsv/vendor/zsv-1.3.0/app/utils/file.c +256 -0
  165. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.c +197 -0
  166. data/ext/zsv/vendor/zsv-1.3.0/app/utils/index.h +49 -0
  167. data/ext/zsv/vendor/zsv-1.3.0/app/utils/jq.c +400 -0
  168. data/ext/zsv/vendor/zsv-1.3.0/app/utils/json.c +120 -0
  169. data/ext/zsv/vendor/zsv-1.3.0/app/utils/mem.c +18 -0
  170. data/ext/zsv/vendor/zsv-1.3.0/app/utils/memmem.c +132 -0
  171. data/ext/zsv/vendor/zsv-1.3.0/app/utils/os.c +178 -0
  172. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite.c +258 -0
  173. data/ext/zsv/vendor/zsv-1.3.0/app/utils/overwrite_writer.c +246 -0
  174. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8-test.c +123 -0
  175. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.c +153 -0
  176. data/ext/zsv/vendor/zsv-1.3.0/app/utils/pcre2-8/pcre2-8.h +54 -0
  177. data/ext/zsv/vendor/zsv-1.3.0/app/utils/prop.c +267 -0
  178. data/ext/zsv/vendor/zsv-1.3.0/app/utils/signal.c +53 -0
  179. data/ext/zsv/vendor/zsv-1.3.0/app/utils/string.c +357 -0
  180. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dir_exists_longpath.c +83 -0
  181. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/dl.c +33 -0
  182. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/fopen_longpath.c +184 -0
  183. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/foreach_dirent_longpath.c +292 -0
  184. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.c +259 -0
  185. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/io.h +13 -0
  186. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/mkdir_longpath.c +255 -0
  187. data/ext/zsv/vendor/zsv-1.3.0/app/utils/win/remove_longpath.c +96 -0
  188. data/ext/zsv/vendor/zsv-1.3.0/app/utils/writer.c +361 -0
  189. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command.h +40 -0
  190. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_command_standalone.c +16 -0
  191. data/ext/zsv/vendor/zsv-1.3.0/app/zsv_main.h +44 -0
  192. data/ext/zsv/vendor/zsv-1.3.0/examples/js/zsv_parser_api_dummy.c +3 -0
  193. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/parse_by_chunk.c +100 -0
  194. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/print_my_column.c +143 -0
  195. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/pull.c +89 -0
  196. data/ext/zsv/vendor/zsv-1.3.0/examples/lib/simple.c +123 -0
  197. data/ext/zsv/vendor/zsv-1.3.0/fuzz/fuzz.c +16 -0
  198. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/api.h +336 -0
  199. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/common.h +361 -0
  200. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation.h +62 -0
  201. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/implementation_private.h +113 -0
  202. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext/sheet.h +73 -0
  203. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/ext.h +329 -0
  204. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/arg.h +90 -0
  205. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/cache.h +49 -0
  206. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/clock.h +36 -0
  207. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/compiler.h +58 -0
  208. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/db.h +19 -0
  209. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dirs.h +147 -0
  210. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/dl.h +22 -0
  211. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/emcc/fs_api.h +28 -0
  212. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/err.h +22 -0
  213. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file-mem.h +17 -0
  214. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/file.h +99 -0
  215. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/jq.h +65 -0
  216. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/json.h +19 -0
  217. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/mem.h +19 -0
  218. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/memmem.h +13 -0
  219. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/os.h +54 -0
  220. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite.h +71 -0
  221. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/overwrite_writer.h +53 -0
  222. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/prop.h +107 -0
  223. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/signal.h +18 -0
  224. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/sql.h +11 -0
  225. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/string.h +148 -0
  226. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/utf8.h +41 -0
  227. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/win/dl.h +25 -0
  228. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/utils/writer.h +101 -0
  229. data/ext/zsv/vendor/zsv-1.3.0/include/zsv/zsv_export.h +33 -0
  230. data/ext/zsv/vendor/zsv-1.3.0/include/zsv.h +20 -0
  231. data/ext/zsv/vendor/zsv-1.3.0/src/vector_delim.c +60 -0
  232. data/ext/zsv/vendor/zsv-1.3.0/src/zsv.c +484 -0
  233. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_internal.c +731 -0
  234. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_delim.c +285 -0
  235. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_scan_fixed.c +88 -0
  236. data/ext/zsv/vendor/zsv-1.3.0/src/zsv_strencode.c +51 -0
  237. data/ext/zsv/zsv_ext.c +343 -0
  238. data/lib/zsv/version.rb +5 -0
  239. data/lib/zsv.rb +81 -0
  240. metadata +340 -0
@@ -0,0 +1,2 @@
1
+ #include "sqlite3.c"
2
+ #include "sqlite3_csv_vtab-zsv.c"
@@ -0,0 +1,142 @@
1
+ #include <pthread.h>
2
+
3
+ /**
4
+ * see sqlite3_csv_vtab-mem.h for background info
5
+ */
6
+ #if defined(_WIN32) || defined(_WIN64)
7
+ #include <process.h>
8
+ #else
9
+ #include <unistd.h>
10
+ #endif
11
+
12
+ struct sqlite3_zsv_data {
13
+ struct sqlite3_zsv_data *next;
14
+ pid_t pid;
15
+ char *filename;
16
+ struct zsv_opts opts;
17
+ struct zsv_prop_handler custom_prop_handler;
18
+ };
19
+
20
+ pthread_mutex_t sqlite3_zsv_data_mutex;
21
+ struct sqlite3_zsv_data *sqlite3_zsv_data_g = NULL;
22
+
23
+ /**
24
+ * Our shared memory structure should be locked for read/write
25
+ */
26
+ static int sqlite3_zsv_data_lock(void) {
27
+ #ifndef NO_THREADING
28
+ pthread_mutex_lock(&sqlite3_zsv_data_mutex);
29
+ #endif
30
+ return 0;
31
+ }
32
+
33
+ static int sqlite3_zsv_data_unlock(void) {
34
+ #ifndef NO_THREADING
35
+ pthread_mutex_unlock(&sqlite3_zsv_data_mutex);
36
+ #endif
37
+ return 0;
38
+ }
39
+
40
+ static void sqlite3_zsv_data_delete(struct sqlite3_zsv_data *e) {
41
+ if (e) {
42
+ free(e->filename);
43
+ }
44
+ free(e);
45
+ }
46
+
47
+ void sqlite3_zsv_list_delete(void **list) {
48
+ for (struct sqlite3_zsv_data *next, *e = *list; e; e = next) {
49
+ next = e->next;
50
+ sqlite3_zsv_data_delete(e);
51
+ }
52
+ #ifndef NO_THREADING
53
+ pthread_mutex_destroy(&sqlite3_zsv_data_mutex);
54
+ #endif
55
+ *list = NULL;
56
+ }
57
+
58
+ static struct sqlite3_zsv_data *sqlite3_zsv_data_new(const char *filename, struct zsv_opts *opts,
59
+ struct zsv_prop_handler *custom_prop_handler) {
60
+ if (!filename)
61
+ return NULL;
62
+ struct sqlite3_zsv_data *e = calloc(1, sizeof(*e));
63
+ if (e) {
64
+ e->pid = getpid();
65
+ e->filename = strdup(filename);
66
+ if (opts)
67
+ e->opts = *opts;
68
+ if (custom_prop_handler)
69
+ e->custom_prop_handler = *custom_prop_handler;
70
+ if (e->filename)
71
+ return e;
72
+ }
73
+ sqlite3_zsv_data_delete(e);
74
+ return NULL;
75
+ }
76
+
77
+ int sqlite3_zsv_list_add(const char *filename, struct zsv_opts *opts, struct zsv_prop_handler *custom_prop_handler) {
78
+ struct sqlite3_zsv_data **list = &sqlite3_zsv_data_g;
79
+ struct sqlite3_zsv_data *e = sqlite3_zsv_data_new(filename, opts, custom_prop_handler);
80
+ if (e) {
81
+ struct sqlite3_zsv_data **next;
82
+ if (sqlite3_zsv_data_lock()) {
83
+ sqlite3_zsv_data_delete(e);
84
+ return -1;
85
+ } else {
86
+ for (next = list; *next; next = &(*next)->next)
87
+ ;
88
+ *next = e;
89
+ sqlite3_zsv_data_unlock();
90
+ return 0;
91
+ }
92
+ }
93
+ return ENOMEM;
94
+ }
95
+
96
+ static int sqlite3_zsv_data_cmp(struct sqlite3_zsv_data *x, const char *filename, pid_t pid) {
97
+ return strcmp(x->filename, filename) && x->pid == pid;
98
+ }
99
+
100
+ struct sqlite3_zsv_data *sqlite3_zsv_data_find(const char *filename) {
101
+ struct sqlite3_zsv_data *list = sqlite3_zsv_data_g;
102
+ struct sqlite3_zsv_data *found = NULL;
103
+ pid_t pid = getpid();
104
+ if (!sqlite3_zsv_data_lock()) {
105
+ for (struct sqlite3_zsv_data *e = list; e && !found; e = e->next) {
106
+ if (!sqlite3_zsv_data_cmp(e, filename, pid))
107
+ found = e;
108
+ }
109
+ if (sqlite3_zsv_data_unlock())
110
+ fprintf(stderr, "Error unlocking sqlite3-csv-zsv shared mem lock\n");
111
+ }
112
+ return found;
113
+ }
114
+
115
+ int sqlite3_zsv_list_remove(const char *filename) {
116
+ if (!filename)
117
+ return 0;
118
+ struct sqlite3_zsv_data **list = &sqlite3_zsv_data_g;
119
+ struct sqlite3_zsv_data *found = NULL;
120
+ pid_t pid = getpid();
121
+ if (*list) {
122
+ if (!sqlite3_zsv_data_cmp(*list, filename, pid)) {
123
+ // found a match at the head of list
124
+ found = *list;
125
+ *list = found->next;
126
+ } else {
127
+ // look for a match somewhere after the first element
128
+ for (struct sqlite3_zsv_data *prior = *list; prior->next != NULL; prior = prior->next) {
129
+ if (!sqlite3_zsv_data_cmp(prior->next, filename, pid)) {
130
+ found = prior->next;
131
+ prior->next = prior->next->next;
132
+ break;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ if (found) {
138
+ sqlite3_zsv_data_delete(found);
139
+ return 0;
140
+ }
141
+ return ENOENT; // not found
142
+ }
@@ -0,0 +1,49 @@
1
+ #ifndef SQLITE3_CSV_VTAB_ZSV_H
2
+ #define SQLITE3_CSV_VTAB_ZSV_H
3
+
4
+ #include <zsv.h>
5
+ #include <zsv/utils/prop.h>
6
+
7
+ /**
8
+ * when sqlite3 opens a CSV file using ZSV, it needs a way to know
9
+ * what options to open with (such as user-specified delimiter, header offset
10
+ * or span, etc
11
+ *
12
+ * In particular, it needs access to:
13
+ * - zsv options (struct zsv_opts)
14
+ * - custom property handler (struct zsv_prop_handler *)
15
+ * - options used (const char *) [but this can be passed via connection string]
16
+ *
17
+ * Some ways to pass this info are:
18
+ * - Embed it in the text of the URI passed to the module's xConnect function.
19
+ * This is not practical because we need to pass pointers
20
+ * - Use a single global variable that can hold only one set of data at a time.
21
+ * This was the old approach, via `zsv_set_default_opts` etc, which has the
22
+ * usual drawbacks of using a single global variable structure
23
+ * - Use a shared memory structure that can support multiple sets of data
24
+ * That is the approach implemented here. Data is identified by the related
25
+ * filename and caller pid
26
+ *
27
+ * sqlite3_create_module_v2 is passed the shared memory root pointer,
28
+ * but it's not really needed because there is no way for it to be
29
+ * dynamic so it always has to point to the single global location
30
+ *
31
+ * Prior to calling xConnect, the caller should save data for the related
32
+ * file via `sqlite3_zsv_data_add()`; xConnect then does a lookup to
33
+ * locate and use the saved data
34
+ */
35
+
36
+ struct sqlite3_zsv_data;
37
+
38
+ void sqlite3_zsv_list_delete(struct sqlite3_zsv_data **list);
39
+
40
+ int sqlite3_zsv_list_add(const char *filename, struct zsv_opts *opts, struct zsv_prop_handler *custom_prop_handler);
41
+
42
+ struct sqlite3_zsv_data *sqlite3_csv_vtab_zsv_find(const char *filename);
43
+
44
+ /**
45
+ * Remove from list. Return 0 on success, non-zero on error
46
+ */
47
+ int sqlite3_zsv_list_remove(const char *filename);
48
+
49
+ #endif
@@ -0,0 +1,485 @@
1
+ /* clang-format off */
2
+ /*
3
+ * This file has been modified from its original form, in order to use the ZSV csv parser
4
+ * The preamble / disclaimer to the original file is included below
5
+ * The modifications to this file are subject to the same license (MIT) as the ZSV parser
6
+ * as described at https://github.com/liquidaty/zsv/blob/main/LICENSE
7
+ */
8
+
9
+ /*
10
+ ** 2016-05-28
11
+ **
12
+ ** The author disclaims copyright to this source code. In place of
13
+ ** a legal notice, here is a blessing:
14
+ **
15
+ ** May you do good and not evil.
16
+ ** May you find forgiveness for yourself and forgive others.
17
+ ** May you share freely, never taking more than you give.
18
+ **
19
+ ******************************************************************************
20
+ **
21
+ ** This file contains the implementation of an SQLite virtual table for
22
+ ** reading CSV files
23
+ **
24
+ ** Usage:
25
+ **
26
+ ** .load ./csv
27
+ ** CREATE VIRTUAL TABLE temp.csv USING csv(filename=FILENAME);
28
+ ** SELECT * FROM csv;
29
+ **
30
+ ** The input file is assumed to have a single header row, followed by data rows
31
+ ** Instead of specifying a file, the text of the CSV can be loaded using
32
+ ** the data= parameter.
33
+ **
34
+ ** If the columns=N parameter is supplied, then the CSV file is assumed to have
35
+ ** N columns. If both the columns= and schema= parameters are omitted, then
36
+ ** the number and names of the columns is determined by the first line of
37
+ ** the CSV input.
38
+ **
39
+ ** Some extra debugging features (used for testing virtual tables) are available
40
+ ** if this module is compiled with -DSQLITE_TEST.
41
+ */
42
+ #include "sqlite3.h"
43
+ #include "sqlite3ext.h"
44
+ SQLITE_EXTENSION_INIT1
45
+ #include <string.h>
46
+ #include <stdlib.h>
47
+ #include <assert.h>
48
+ #include <stdarg.h>
49
+ #include <ctype.h>
50
+ #include <stdio.h>
51
+ #include <zsv.h>
52
+ #include <zsv/utils/string.h>
53
+ #include <zsv/utils/arg.h>
54
+ #include <zsv/utils/prop.h>
55
+ #include "sqlite3_csv_vtab-mem.c"
56
+
57
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
58
+
59
+ /*
60
+ ** A macro to hint to the compiler that a function should not be
61
+ ** inlined.
62
+ */
63
+ #if defined(__GNUC__)
64
+ # define CSV_NOINLINE __attribute__((noinline))
65
+ #elif defined(_MSC_VER) && _MSC_VER>=1310
66
+ # define CSV_NOINLINE __declspec(noinline)
67
+ #else
68
+ # define CSV_NOINLINE
69
+ #endif
70
+
71
+
72
+ /* Max size of the error message in a CsvReader */
73
+ #define CSV_MXERR 200
74
+
75
+ /* Size of the CsvReader input buffer */
76
+ #define CSV_INBUFSZ 1024
77
+
78
+ /* Forward references to the various virtual table methods implemented
79
+ ** in this file. */
80
+ static int zsvtabCreate(sqlite3*, void*, int, const char*const*,
81
+ sqlite3_vtab**,char**);
82
+ static int zsvtabConnect(sqlite3*, void*, int, const char*const*,
83
+ sqlite3_vtab**,char**);
84
+ static int zsvtabBestIndex(sqlite3_vtab*,sqlite3_index_info*);
85
+ static int zsvtabDisconnect(sqlite3_vtab*);
86
+ static int zsvtabOpen(sqlite3_vtab*, sqlite3_vtab_cursor**);
87
+ static int zsvtabClose(sqlite3_vtab_cursor*);
88
+ static int zsvtabFilter(sqlite3_vtab_cursor*, int idxNum, const char *idxStr,
89
+ int argc, sqlite3_value **argv);
90
+ static int zsvtabNext(sqlite3_vtab_cursor*);
91
+ static int zsvtabEof(sqlite3_vtab_cursor*);
92
+ static int zsvtabColumn(sqlite3_vtab_cursor*,sqlite3_context*,int);
93
+ static int zsvtabRowid(sqlite3_vtab_cursor*,sqlite3_int64*);
94
+
95
+ /* An instance of the CSV virtual table */
96
+ typedef struct zsvTable {
97
+ sqlite3_vtab base; /* Base class. Must be first */
98
+ char *zFilename; /* Name of the CSV file */
99
+ struct zsv_opts parser_opts;
100
+ struct zsv_prop_handler custom_prop_handler;
101
+ enum zsv_status parser_status;
102
+ zsv_parser parser;
103
+ sqlite_int64 rowCount;
104
+ } zsvTable;
105
+
106
+ struct zsvTable *zsvTable_new(const char *filename) {
107
+ struct zsvTable *z = sqlite3_malloc(sizeof(*z));
108
+ if(z) {
109
+ memset(z, 0, sizeof(*z));
110
+ struct sqlite3_zsv_data *d = sqlite3_zsv_data_find(filename);
111
+ if(d) {
112
+ z->parser_opts = d->opts; // zsv_get_default_opts();
113
+ z->custom_prop_handler = d->custom_prop_handler; // zsv_get_default_custom_prop_handler();
114
+ }
115
+ }
116
+ return z;
117
+ }
118
+
119
+ /* Allowed values for tstFlags */
120
+ #define CSVTEST_FIDX 0x0001 /* Pretend that constrained searchs cost less*/
121
+
122
+ /* A cursor for the CSV virtual table */
123
+ typedef struct zsvCursor {
124
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
125
+ } zsvCursor;
126
+
127
+ /*
128
+ ** The xConnect and xCreate methods do the same thing, but they must be
129
+ ** different so that the virtual table is not an eponymous virtual table.
130
+ o*/
131
+ static int zsvtabCreate(
132
+ sqlite3 *db,
133
+ void *pAux,
134
+ int argc, const char *const*argv,
135
+ sqlite3_vtab **ppVtab,
136
+ char **pzErr
137
+ ){
138
+ return zsvtabConnect(db, pAux, argc, argv, ppVtab, pzErr);
139
+ }
140
+
141
+ static void zsvTable_free(struct zsvTable *z) {
142
+ if(z->parser)
143
+ zsv_delete(z->parser);
144
+ z->parser = NULL;
145
+ z->rowCount = 0;
146
+ }
147
+
148
+ static void zsvTable_delete(struct zsvTable *z) {
149
+ if(z) {
150
+ zsvTable_free(z);
151
+ sqlite3_free(z->zFilename);
152
+ sqlite3_free(z);
153
+ }
154
+ }
155
+
156
+ #include "vtab_helper.c"
157
+
158
+ #define BLANK_COLUMN_NAME_PREFIX "Blank_Column"
159
+ unsigned blank_column_name_count = 0;
160
+
161
+ /**
162
+ * Parameters:
163
+ * filename=FILENAME Name of file containing CSV content
164
+ *
165
+ * The number of columns in the first row of the input file determines the
166
+ * column names and column count
167
+ */
168
+ static int zsvtabConnect(
169
+ sqlite3 *db,
170
+ void *_pAux,
171
+ int argc, const char *const*argv,
172
+ sqlite3_vtab **ppVtab,
173
+ char **pzErr
174
+ ){
175
+ (void)(_pAux);
176
+ zsvTable pTmp = { 0 };
177
+ int rc = SQLITE_OK; /* Result code from this routine */
178
+ #define ZSVTABCONNECT_PARAM_MAX 2
179
+ static const char *azParam[ZSVTABCONNECT_PARAM_MAX] = {
180
+ "filename"
181
+ };
182
+ char *azPValue[ZSVTABCONNECT_PARAM_MAX]; /* Parameter values */
183
+ memset(azPValue, 0, sizeof(azPValue));
184
+ # define CSV_FILENAME (azPValue[0])
185
+
186
+ char *schema = NULL;
187
+ zsvTable *pNew = NULL;
188
+
189
+ char *errmsg = NULL;
190
+ // set parameters
191
+ for(int i=3; i<argc; i++){
192
+ const char *z = argv[i];
193
+ const char *zValue;
194
+ size_t j;
195
+ for(j=0; j<sizeof(azParam)/sizeof(azParam[0]); j++){
196
+ if(csv_string_parameter(&errmsg, azParam[j], z, &azPValue[j]) ) break;
197
+ }
198
+ if( j<sizeof(azParam)/sizeof(azParam[0]) ){
199
+ if( errmsg ) goto zsvtab_connect_error;
200
+ } else {
201
+ asprintf(&errmsg, "bad parameter: '%s'", z);
202
+ goto zsvtab_connect_error;
203
+ }
204
+ }
205
+
206
+ if(!CSV_FILENAME) {
207
+ asprintf(&errmsg, "No csv filename provided");
208
+ goto zsvtab_connect_error;
209
+ }
210
+
211
+ pNew = zsvTable_new(CSV_FILENAME);
212
+ if(!pNew)
213
+ goto zsvtab_connect_oom;
214
+ if(pTmp.parser_opts.max_columns)
215
+ pNew->parser_opts.max_columns = pTmp.parser_opts.max_columns;
216
+ else if(!pNew->parser_opts.max_columns)
217
+ pNew->parser_opts.max_columns = 2000; /* default max columns */
218
+
219
+ if(!(pNew->parser_opts.stream = fopen(CSV_FILENAME, "rb"))) {
220
+ asprintf(&errmsg, "Unable to open for reading: %s", CSV_FILENAME);
221
+ goto zsvtab_connect_error;
222
+ }
223
+
224
+ pNew->zFilename = CSV_FILENAME;
225
+ CSV_FILENAME = 0; // in use; don't free
226
+ if(zsv_new_with_properties(&pNew->parser_opts, &pNew->custom_prop_handler, pNew->zFilename,
227
+ &pNew->parser) != zsv_status_ok)
228
+ goto zsvtab_connect_error;
229
+
230
+ if((pNew->parser_status = zsv_next_row(pNew->parser)) != zsv_status_row) {
231
+ asprintf(&errmsg, "Could not fetch header row: %s", zsv_parse_status_desc(pNew->parser_status));
232
+ goto zsvtab_connect_error;
233
+ }
234
+
235
+ *ppVtab = (sqlite3_vtab*)pNew;
236
+
237
+ // generate the CREATE TABLE statement
238
+ sqlite3_str *pStr = sqlite3_str_new(0);
239
+ sqlite3_str_appendf(pStr, "CREATE TABLE x(");
240
+
241
+ // for each column, add a spec to CREATE TABLE
242
+ for(size_t i = 0, j = zsv_cell_count(pNew->parser); i < j; i++) {
243
+ struct zsv_cell cell = zsv_get_cell(pNew->parser, i);
244
+ size_t len = cell.len;
245
+ unsigned char *utf8_value = (unsigned char *)zsv_strtrim(cell.str, &len);
246
+
247
+ if(!len) {
248
+ if(blank_column_name_count++)
249
+ sqlite3_str_appendf(pStr, "%s\"%s_%u\" TEXT", i > 0 ? "," : "", BLANK_COLUMN_NAME_PREFIX, blank_column_name_count - 1);
250
+ else
251
+ sqlite3_str_appendf(pStr, "%s\"%s\" TEXT", i > 0 ? "," : "", BLANK_COLUMN_NAME_PREFIX);
252
+ } else
253
+ sqlite3_str_appendf(pStr, "%s\"%.*w\" TEXT", i > 0 ? "," : "", len, utf8_value);
254
+ // to do: deal with duplicate column names
255
+ }
256
+
257
+ sqlite3_str_appendf(pStr, ")");
258
+ schema = sqlite3_str_finish(pStr);
259
+ if(!schema)
260
+ goto zsvtab_connect_oom;
261
+
262
+ // advance cursor to first data row
263
+ pNew->parser_status = zsv_next_row(pNew->parser);
264
+ pNew->rowCount = 1;
265
+
266
+ #ifdef SQLITE_TEST
267
+ pNew->tstFlags = tstFlags;
268
+ #endif
269
+
270
+ rc = sqlite3_declare_vtab(db, schema);
271
+ if( rc ){
272
+ asprintf(&errmsg, "bad schema: '%s' - %s", schema, sqlite3_errmsg(db));
273
+ goto zsvtab_connect_error;
274
+ }
275
+ for(unsigned int i=0; i<sizeof(azPValue)/sizeof(azPValue[0]); i++) {
276
+ sqlite3_free(azPValue[i]);
277
+ }
278
+ sqlite3_free(schema);
279
+
280
+ /* Rationale for DIRECTONLY:
281
+ ** An attacker who controls a database schema could use this vtab
282
+ ** to exfiltrate sensitive data from other files in the filesystem.
283
+ ** And, recommended practice is to put all CSV virtual tables in the
284
+ ** TEMP namespace, so they should still be usable from within TEMP
285
+ ** views, so there shouldn't be a serious loss of functionality by
286
+ ** prohibiting the use of this vtab from persistent triggers and views.
287
+ */
288
+ sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
289
+ return SQLITE_OK;
290
+
291
+ zsvtab_connect_oom:
292
+ rc = SQLITE_NOMEM;
293
+ asprintf(&errmsg, "Out of memory!");
294
+
295
+ zsvtab_connect_error:
296
+ if( pNew ) zsvtabDisconnect(&pNew->base);
297
+ for(unsigned int i=0; i<sizeof(azPValue)/sizeof(azPValue[0]); i++){
298
+ sqlite3_free(azPValue[i]);
299
+ }
300
+ sqlite3_free(schema);
301
+ if(errmsg) {
302
+ sqlite3_free(*pzErr);
303
+ *pzErr = sqlite3_mprintf("%s", errmsg);
304
+ free(errmsg);
305
+ }
306
+ if( rc==SQLITE_OK ) rc = SQLITE_ERROR;
307
+ return rc;
308
+ }
309
+
310
+ /*
311
+ ** Only a forward full table scan is supported. xBestIndex is mostly
312
+ ** a no-op. If CSVTEST_FIDX is set, then the presence of equality
313
+ ** constraints lowers the estimated cost, which is fiction, but is useful
314
+ ** for testing certain kinds of virtual table behavior.
315
+ */
316
+ static int zsvtabBestIndex(
317
+ sqlite3_vtab *tab,
318
+ sqlite3_index_info *pIdxInfo
319
+ ){
320
+ (void)(tab);
321
+ pIdxInfo->estimatedCost = 1000000;
322
+ return SQLITE_OK;
323
+ }
324
+
325
+ /*
326
+ ** This method is the destructor for a zsvTable object.
327
+ */
328
+ static int zsvtabDisconnect(sqlite3_vtab *pVtab){
329
+ zsvTable *p = (zsvTable*)pVtab;
330
+ zsvTable_delete(p);
331
+ return SQLITE_OK;
332
+ }
333
+
334
+ /*
335
+ ** Constructor for a new zsvTable cursor object.
336
+ */
337
+ static int zsvtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
338
+ (void)(p);
339
+ struct zsvCursor *pCur = sqlite3_malloc64(sizeof(*pCur));
340
+ if( pCur==0 ) return SQLITE_NOMEM;
341
+ memset(pCur, 0, sizeof(*pCur));
342
+ *ppCursor = &pCur->base;
343
+ return SQLITE_OK;
344
+ }
345
+
346
+ /*
347
+ ** Destructor for a zsvCursor.
348
+ */
349
+ static int zsvtabClose(sqlite3_vtab_cursor *cur){
350
+ sqlite3_free(cur);
351
+ return SQLITE_OK;
352
+ }
353
+
354
+ /*
355
+ ** Only a full table scan is supported. So xFilter simply rewinds to
356
+ ** the beginning.
357
+ */
358
+ static int zsvtabFilter(
359
+ sqlite3_vtab_cursor *pVtabCursor,
360
+ int idxNum, const char *idxStr,
361
+ int argc, sqlite3_value **argv
362
+ ){
363
+ (void)(idxNum);
364
+ (void)(idxStr);
365
+ (void)(argc);
366
+ (void)(argv);
367
+ zsvTable *pTab = (zsvTable*)pVtabCursor->pVtab;
368
+
369
+ zsvTable_free(pTab);
370
+ fseek(pTab->parser_opts.stream, 0, SEEK_SET);
371
+
372
+ // reload and advance header, then first data row
373
+ if(zsv_new_with_properties(&pTab->parser_opts, &pTab->custom_prop_handler, pTab->zFilename,
374
+ &pTab->parser) != zsv_status_ok
375
+ || (pTab->parser_status = zsv_next_row(pTab->parser)) != zsv_status_row)
376
+ return SQLITE_ERROR;
377
+ pTab->parser_status = zsv_next_row(pTab->parser);
378
+ pTab->rowCount = 1;
379
+ return SQLITE_OK;
380
+ }
381
+
382
+
383
+ /*
384
+ ** Advance a zsvCursor to its next row of input.
385
+ ** Set the EOF marker via pTab->parser_status if we reach the end of input.
386
+ */
387
+ static int zsvtabNext(sqlite3_vtab_cursor *cur){
388
+ zsvTable *pTab = (zsvTable*)cur->pVtab;
389
+ pTab->parser_status = zsv_next_row(pTab->parser);
390
+ pTab->rowCount++;
391
+ return SQLITE_OK;
392
+ }
393
+
394
+ /*
395
+ ** Return TRUE if the cursor has been moved off of the last
396
+ ** row of output.
397
+ */
398
+ static int zsvtabEof(sqlite3_vtab_cursor *cur){
399
+ zsvTable *pTab = (zsvTable*)cur->pVtab;
400
+ return pTab->parser_status != zsv_status_row;
401
+ }
402
+
403
+ /*
404
+ ** Return values of columns for the row at which the zsvCursor
405
+ ** is currently pointing.
406
+ */
407
+ static int zsvtabColumn(
408
+ sqlite3_vtab_cursor *cur, /* The cursor */
409
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
410
+ int i /* Which column to return */
411
+ ){
412
+ zsvTable *pTab = (zsvTable*)cur->pVtab;
413
+ struct zsv_cell c = zsv_get_cell(pTab->parser, i);
414
+ sqlite3_result_text(ctx, (char *)c.str, c.len, SQLITE_STATIC);
415
+ return SQLITE_OK;
416
+ }
417
+
418
+
419
+ /*
420
+ ** Return the rowid for the current row.
421
+ */
422
+ static int zsvtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
423
+ zsvTable *pTab = (zsvTable*)cur->pVtab;
424
+ *pRowid = pTab->rowCount;
425
+ return SQLITE_OK;
426
+ }
427
+
428
+ sqlite3_module CsvModule = {
429
+ 0, /* iVersion */
430
+ zsvtabCreate, /* xCreate */
431
+ zsvtabConnect, /* xConnect */
432
+ zsvtabBestIndex, /* xBestIndex */
433
+ zsvtabDisconnect, /* xDisconnect */
434
+ zsvtabDisconnect, /* xDestroy */
435
+ zsvtabOpen, /* xOpen - open a cursor */
436
+ zsvtabClose, /* xClose - close a cursor */
437
+ zsvtabFilter, /* xFilter - configure scan constraints */
438
+ zsvtabNext, /* xNext - advance a cursor */
439
+ zsvtabEof, /* xEof - check for end of scan */
440
+ zsvtabColumn, /* xColumn - read data */
441
+ zsvtabRowid, /* xRowid - read data */
442
+ 0, /* xUpdate */
443
+ 0, /* xBegin */
444
+ 0, /* xSync */
445
+ 0, /* xCommit */
446
+ 0, /* xRollback */
447
+ 0, /* xFindMethod */
448
+ 0, /* xRename */
449
+ 0, 0, 0, 0 /* xSavepoint, xRelease, xRollbackTo, xShadowName */
450
+ };
451
+
452
+ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
453
+
454
+
455
+ #ifdef _WIN32
456
+ __declspec(dllexport)
457
+ #endif
458
+ /*
459
+ ** This routine is called when the extension is loaded. The new
460
+ ** CSV virtual table module is registered with the calling database
461
+ ** connection.
462
+ */
463
+ int sqlite3_csv_init(
464
+ sqlite3 *db,
465
+ char **pzErrMsg,
466
+ const sqlite3_api_routines *pApi
467
+ ){
468
+ (void)(pzErrMsg);
469
+ #ifndef SQLITE_OMIT_VIRTUALTABLE
470
+ int rc;
471
+ SQLITE_EXTENSION_INIT2(pApi);
472
+ pthread_mutex_t init = PTHREAD_MUTEX_INITIALIZER;
473
+ memcpy(&sqlite3_zsv_data_mutex, &init, sizeof(init));
474
+ rc = sqlite3_create_module_v2(db, "csv", &CsvModule, &sqlite3_zsv_data_g, (void (*)(void *))sqlite3_zsv_list_delete);
475
+ #ifdef SQLITE_TEST
476
+ if( rc==SQLITE_OK ){
477
+ rc = sqlite3_create_module(db, "csv_wr", &CsvModuleFauxWrite, 0);
478
+ }
479
+ #endif
480
+ return rc;
481
+ #else
482
+ return SQLITE_OK;
483
+ #endif
484
+ }
485
+ /* clang-format on */