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,178 @@
1
+ /*
2
+ * Copyright (C) 2021 Liquidaty and the zsv/lib contributors
3
+ * All rights reserved
4
+ *
5
+ * This file is part of zsv/lib, distributed under the license defined at
6
+ * https://opensource.org/licenses/MIT
7
+ */
8
+
9
+ #include <unistd.h>
10
+ #include <zsv/utils/os.h>
11
+ #include <stdio.h>
12
+ #include <errno.h>
13
+
14
+ #ifdef WIN32
15
+ #include "win/fopen_longpath.c"
16
+ #include "win/remove_longpath.c"
17
+ #endif
18
+
19
+ /**
20
+ * zsv_fopen(): same as normal fopen(), except on Win it also works with long filenames
21
+ */
22
+ #if defined(_WIN32) || defined(WIN32) || defined(WIN)
23
+ FILE *zsv_fopen(const char *fname, const char *mode) {
24
+ if (strlen(fname) >= MAX_PATH)
25
+ return zsv_fopen_longpath(fname, mode);
26
+ return fopen(fname, mode);
27
+ }
28
+ #endif
29
+
30
+ #ifndef _WIN32
31
+
32
+ void zsv_perror(const char *s) {
33
+ perror(s);
34
+ }
35
+
36
+ int zsv_replace_file(const char *src, const char *dst) {
37
+ int save_errno = 0;
38
+
39
+ if (rename(src, dst) == 0) {
40
+ return 0;
41
+ }
42
+
43
+ if (errno != EXDEV) {
44
+ return errno;
45
+ }
46
+
47
+ // Fallback: copy and remove
48
+ FILE *fp_in = zsv_fopen(src, "rb");
49
+ if (!fp_in)
50
+ return errno;
51
+
52
+ FILE *fp_out = zsv_fopen(dst, "wb");
53
+ if (!fp_out) {
54
+ save_errno = errno;
55
+ fclose(fp_in);
56
+ return save_errno;
57
+ }
58
+
59
+ char buffer[4096];
60
+ size_t bytes_read;
61
+ while ((bytes_read = fread(buffer, 1, sizeof(buffer), fp_in)) > 0) {
62
+ if (fwrite(buffer, 1, bytes_read, fp_out) != bytes_read) {
63
+ fclose(fp_out);
64
+ fclose(fp_in);
65
+ return EOF;
66
+ }
67
+ }
68
+
69
+ fclose(fp_out);
70
+ fclose(fp_in);
71
+
72
+ if (remove(src) != 0)
73
+ return errno;
74
+
75
+ return 0;
76
+ }
77
+
78
+ #else
79
+ #include <windows.h>
80
+ #include <strsafe.h>
81
+
82
+ static void strlcpy(register char *dst, register const char *src, size_t n) {
83
+ for (; *src != '\0' && n > 1; n--) {
84
+ *dst++ = *src++;
85
+ }
86
+ *dst = '\0';
87
+ }
88
+
89
+ static void change_slashes_to_backslashes(char *path) {
90
+ int i;
91
+ for (i = 0; path[i] != '\0'; i++) {
92
+ if (path[i] == '/') {
93
+ path[i] = '\\';
94
+ }
95
+ if ((path[i] == '\\') && (i > 0)) {
96
+ while (path[i + 1] == '\\' || path[i + 1] == '/') {
97
+ (void)memmove(path + i + 1, path + i + 2, strlen(path + i + 1));
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ void zsv_win_to_unicode(const void *path, wchar_t *wbuf, size_t wbuf_len) {
104
+ char buf[PATH_MAX], buf2[PATH_MAX];
105
+ strlcpy(buf, path, sizeof(buf));
106
+
107
+ change_slashes_to_backslashes(buf);
108
+
109
+ /* Convert to Unicode and back. If doubly-converted string does not
110
+ * match the original, something is fishy, reject. */
111
+ memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
112
+ MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int)wbuf_len);
113
+ WideCharToMultiByte(CP_UTF8, 0, wbuf, (int)wbuf_len, buf2, sizeof(buf2), NULL, NULL);
114
+ if (strcmp(buf, buf2) != 0) {
115
+ wbuf[0] = L'\0';
116
+ }
117
+ }
118
+
119
+ #include <wchar.h>
120
+
121
+ int zsv_replace_file(const char *src, const char *dest) {
122
+ wchar_t wdest[PATH_MAX], wsrc[PATH_MAX];
123
+
124
+ zsv_win_to_unicode(dest, wdest, ARRAY_SIZE(wdest));
125
+ zsv_win_to_unicode(src, wsrc, ARRAY_SIZE(wsrc));
126
+
127
+ if (MoveFileExW(wsrc, wdest, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) // success
128
+ return 0;
129
+
130
+ if (GetLastError() == 2) // file not found, could be target. use simple rename
131
+ return _wrename(wsrc, wdest); // returns 0 on success
132
+
133
+ return 1; // fail
134
+ }
135
+
136
+ static void zsv_win_printLastError(void) {
137
+ DWORD dw = GetLastError();
138
+ LPVOID lpMsgBuf;
139
+ LPVOID lpDisplayBuf;
140
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw,
141
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
142
+ // Display the error message and exit the process
143
+ lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
144
+ StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s\r\n"), lpMsgBuf);
145
+ fprintf(stderr, "%s\r\n", (LPCTSTR)lpDisplayBuf);
146
+ LocalFree(lpMsgBuf);
147
+ LocalFree(lpDisplayBuf);
148
+ }
149
+
150
+ void zsv_perror(const char *s) {
151
+ if (s && *s)
152
+ fwrite(s, 1, strlen(s), stderr);
153
+ zsv_win_printLastError();
154
+ }
155
+
156
+ #endif
157
+
158
+ unsigned int zsv_get_number_of_cores() {
159
+ long ncores = 1; // Default to 1 in case of failure
160
+
161
+ #ifdef _WIN32
162
+ // Implementation for Windows (when cross-compiled with mingw64)
163
+ SYSTEM_INFO sysinfo;
164
+ GetSystemInfo(&sysinfo);
165
+ ncores = sysinfo.dwNumberOfProcessors;
166
+ #elif defined(_SC_NPROCESSORS_ONLN)
167
+ // Implementation for Linux and macOS (uses POSIX standard sysconf)
168
+ // _SC_NPROCESSORS_ONLN gets the number of *online* processors.
169
+ ncores = sysconf(_SC_NPROCESSORS_ONLN);
170
+ #else
171
+ // Fallback for other POSIX-like systems that might not define the symbol
172
+ // or for unexpected compilation environments.
173
+ #error Undefined! _SC_NPROCESSORS_ONLN
174
+ xx ncores = 1;
175
+ #endif
176
+ // Ensure we return a positive value
177
+ return (unsigned int)(ncores > 0 ? ncores : 1);
178
+ }
@@ -0,0 +1,258 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <inttypes.h>
5
+
6
+ #include <sqlite3.h>
7
+
8
+ #include <zsv.h>
9
+ #include <zsv/utils/overwrite.h>
10
+ #include <zsv/utils/cache.h>
11
+ #include <zsv/utils/file.h>
12
+ #include <zsv/utils/os.h>
13
+
14
+ #define zsv_overwrite_sqlite3_prefix "sqlite3://"
15
+ #define zsv_overwrite_sql_prefix "sql="
16
+
17
+ /* Overwrite structure for CSV or SQLITE3 sources */
18
+ void *zsv_overwrite_context_new(struct zsv_overwrite_opts *opts) {
19
+ struct zsv_overwrite_ctx *ctx = calloc(1, sizeof(*ctx));
20
+ if (ctx && opts->src) {
21
+ if (!(ctx->src = strdup(opts->src)))
22
+ fprintf(stderr, "zsv_overwrite_context_new: out of memory!\n");
23
+ }
24
+ return ctx;
25
+ }
26
+
27
+ enum zsv_status zsv_overwrite_context_delete(void *h) {
28
+ struct zsv_overwrite_ctx *ctx = h;
29
+ if (ctx->sqlite3.filename)
30
+ free(ctx->sqlite3.filename);
31
+ if (ctx->sqlite3.stmt)
32
+ sqlite3_finalize(ctx->sqlite3.stmt);
33
+ if (ctx->sqlite3.db)
34
+ sqlite3_close(ctx->sqlite3.db);
35
+ if (ctx->csv.f)
36
+ fclose(ctx->csv.f);
37
+ if (ctx->csv.parser)
38
+ zsv_delete(ctx->csv.parser);
39
+ free(ctx->src);
40
+ free(ctx);
41
+ return zsv_status_ok;
42
+ }
43
+
44
+ static enum zsv_status zsv_next_overwrite_csv(void *h, struct zsv_overwrite_data *odata) {
45
+ struct zsv_overwrite_ctx *ctx = h;
46
+ if (zsv_next_row(ctx->csv.parser) != zsv_status_row)
47
+ odata->have = 0;
48
+ else {
49
+ // row, column, value
50
+ struct zsv_cell row = zsv_get_cell(ctx->csv.parser, 0);
51
+ struct zsv_cell col = zsv_get_cell(ctx->csv.parser, 1);
52
+ struct zsv_cell val = zsv_get_cell(ctx->csv.parser, 2);
53
+ struct zsv_cell author = {0};
54
+ struct zsv_cell timestamp = {0};
55
+ struct zsv_cell old_value = {0};
56
+ if (ctx->author_ix)
57
+ author = zsv_get_cell(ctx->csv.parser, ctx->author_ix);
58
+ if (ctx->timestamp_ix)
59
+ timestamp = zsv_get_cell(ctx->csv.parser, ctx->timestamp_ix);
60
+ if (ctx->old_value_ix)
61
+ old_value = zsv_get_cell(ctx->csv.parser, ctx->old_value_ix);
62
+ if (row.len && col.len) {
63
+ char *end = (char *)(row.str + row.len);
64
+ char **endp = &end;
65
+ odata->row_ix = strtoumax((char *)row.str, endp, 10);
66
+ end = (char *)(col.str + col.len);
67
+ odata->col_ix = strtoumax((char *)col.str, endp, 10);
68
+ odata->val = val;
69
+ odata->author = author;
70
+ odata->old_value = old_value;
71
+ } else {
72
+ odata->row_ix = 0;
73
+ odata->col_ix = 0;
74
+ odata->val.len = 0;
75
+ odata->old_value.len = 0;
76
+ odata->author.len = 0;
77
+ }
78
+
79
+ if (timestamp.len) {
80
+ char *end = (char *)(timestamp.str + timestamp.len);
81
+ char **endp = &end;
82
+ odata->timestamp = strtoumax((char *)timestamp.str, endp, 10);
83
+ }
84
+ }
85
+ return zsv_status_ok;
86
+ }
87
+
88
+ static enum zsv_status zsv_next_overwrite_sqlite3(void *h, struct zsv_overwrite_data *odata) {
89
+ struct zsv_overwrite_ctx *ctx = h;
90
+ if (odata->have) {
91
+ sqlite3_stmt *stmt = ctx->sqlite3.stmt;
92
+ if (stmt) {
93
+ if (sqlite3_step(stmt) == SQLITE_ROW) {
94
+ // row, column, value
95
+ odata->row_ix = sqlite3_column_int64(stmt, 0);
96
+ odata->col_ix = sqlite3_column_int64(stmt, 1);
97
+ odata->val.str = (unsigned char *)sqlite3_column_text(stmt, 2);
98
+ odata->val.len = sqlite3_column_bytes(stmt, 2);
99
+ odata->timestamp = sqlite3_column_int64(stmt, 3);
100
+ odata->author.str = (unsigned char *)sqlite3_column_text(stmt, 4);
101
+ odata->author.len = sqlite3_column_bytes(stmt, 4);
102
+ } else {
103
+ odata->row_ix = 0;
104
+ odata->col_ix = 0;
105
+ odata->val.len = 0;
106
+ odata->timestamp = 0;
107
+ odata->author.len = 0;
108
+ odata->have = 0;
109
+ }
110
+ }
111
+ }
112
+ return zsv_status_ok;
113
+ }
114
+
115
+ enum zsv_status zsv_overwrite_next(void *h, struct zsv_overwrite_data *odata) {
116
+ struct zsv_overwrite_ctx *ctx = h;
117
+ return ctx->next(ctx, odata);
118
+ }
119
+
120
+ static enum zsv_status zsv_overwrite_init_sqlite3(struct zsv_overwrite_ctx *ctx, const char *source, size_t len) {
121
+ char ok = 0;
122
+ size_t pfx_len;
123
+ if (len > (pfx_len = strlen(zsv_overwrite_sqlite3_prefix)) &&
124
+ !memcmp(source, zsv_overwrite_sqlite3_prefix, pfx_len)) {
125
+ ctx->sqlite3.filename = malloc(len - pfx_len + 1);
126
+ memcpy(ctx->sqlite3.filename, source + pfx_len, len - pfx_len);
127
+ ctx->sqlite3.filename[len - pfx_len] = '\0';
128
+ char *q = memchr(ctx->sqlite3.filename, '?', len - pfx_len);
129
+ if (q) {
130
+ *q = '\0';
131
+ q++;
132
+ const char *sql = strstr(q, zsv_overwrite_sql_prefix);
133
+ if (sql)
134
+ ctx->sqlite3.sql = sql + strlen(zsv_overwrite_sql_prefix);
135
+ }
136
+
137
+ if (!ctx->sqlite3.filename || !*ctx->sqlite3.filename) {
138
+ fprintf(stderr, "Missing sqlite3 file name\n");
139
+ return zsv_status_error;
140
+ }
141
+
142
+ if (!ctx->sqlite3.sql || !*ctx->sqlite3.sql) {
143
+ // to do: detect it from the db
144
+ fprintf(stderr, "Missing sql select statement for sqlite3 overwrite data e.g.:\n"
145
+ " select row, column, value from overwrites order by row, column\n");
146
+ return zsv_status_error;
147
+ }
148
+ ok = 1;
149
+ } else if (len > strlen(".sqlite3") && !strcmp(source + len - strlen(".sqlite3"), ".sqlite3")) {
150
+ ctx->sqlite3.filename = strdup(source);
151
+ ctx->sqlite3.sql = "select * from overwrites order by row, column";
152
+ ok = 1;
153
+ }
154
+
155
+ if (ok) {
156
+ int rc = sqlite3_open_v2(ctx->sqlite3.filename, &ctx->sqlite3.db, SQLITE_OPEN_READONLY, NULL);
157
+ if (rc != SQLITE_OK || !ctx->sqlite3.db) {
158
+ fprintf(stderr, "%s: %s\n", sqlite3_errstr(rc), ctx->sqlite3.filename);
159
+ return zsv_status_error;
160
+ }
161
+
162
+ rc = sqlite3_prepare_v2(ctx->sqlite3.db, ctx->sqlite3.sql, -1, &ctx->sqlite3.stmt, NULL);
163
+ if (rc != SQLITE_OK || !ctx->sqlite3.stmt) {
164
+ fprintf(stderr, "%s\n", sqlite3_errmsg(ctx->sqlite3.db));
165
+ return zsv_status_error;
166
+ }
167
+
168
+ // successful sqlite3 connection
169
+ return zsv_status_ok;
170
+ }
171
+
172
+ fprintf(stderr, "Invalid overwrite source: %s\n", source);
173
+ return zsv_status_error;
174
+ }
175
+
176
+ enum zsv_status zsv_overwrite_open(void *h) {
177
+ struct zsv_overwrite_ctx *ctx = h;
178
+ if (!ctx->src)
179
+ return zsv_status_ok;
180
+ char ok = 0;
181
+ size_t src_len = strlen(ctx->src);
182
+ if ((src_len > strlen(zsv_overwrite_sqlite3_prefix) &&
183
+ !memcmp(zsv_overwrite_sqlite3_prefix, ctx->src, strlen(zsv_overwrite_sqlite3_prefix))) ||
184
+ (src_len > strlen(".sqlite3") && !strcmp(ctx->src + src_len - strlen(".sqlite3"), ".sqlite3"))) {
185
+ if (zsv_overwrite_init_sqlite3(ctx, ctx->src, src_len) == zsv_status_ok) {
186
+ ctx->next = zsv_next_overwrite_sqlite3;
187
+ ok = 1;
188
+ }
189
+ } else { // csv
190
+ struct zsv_opts opts = {0};
191
+ ctx->csv.f = opts.stream = zsv_fopen(ctx->src, "rb");
192
+ if (!ctx->csv.f) {
193
+ perror(ctx->src);
194
+ return zsv_status_error;
195
+ }
196
+ if (!(ctx->csv.parser = zsv_new(&opts)))
197
+ return zsv_status_memory;
198
+
199
+ if (zsv_next_row(ctx->csv.parser) != zsv_status_row) {
200
+ fprintf(stderr, "Unable to fetch any data from overwrite source %s\n", ctx->src);
201
+ } else {
202
+ // row, column, value
203
+ struct zsv_cell row = zsv_get_cell(ctx->csv.parser, 0);
204
+ struct zsv_cell col = zsv_get_cell(ctx->csv.parser, 1);
205
+ struct zsv_cell val = zsv_get_cell(ctx->csv.parser, 2);
206
+ if (row.len < 3 || memcmp(row.str, "row", 3) || col.len < 3 || memcmp(col.str, "col", 3) || val.len < 3 ||
207
+ memcmp(val.str, "val", 3))
208
+ fprintf(stderr, "Warning! overwrite expects 'row,col,value' header, got '%.*s,%.*s,%.*s'\n", (int)row.len,
209
+ row.str, (int)col.len, col.str, (int)val.len, val.str);
210
+ struct zsv_cell next;
211
+ for (size_t i = 3; (next = zsv_get_cell(ctx->csv.parser, i)).len > 0; i++) {
212
+ if (!memcmp(next.str, "timestamp", 9)) {
213
+ ctx->timestamp_ix = i;
214
+ } else if (!memcmp(next.str, "author", 6)) {
215
+ ctx->author_ix = i;
216
+ } else if (!memcmp(next.str, "old value", 9)) {
217
+ ctx->old_value_ix = i;
218
+ }
219
+ }
220
+ }
221
+ ctx->next = zsv_next_overwrite_csv;
222
+ ok = 1;
223
+ }
224
+ return ok ? zsv_status_ok : zsv_status_error;
225
+ }
226
+
227
+ /*
228
+ * zsv_overwrite_auto() returns:
229
+ * - zsv_status_done if a valid overwrite file was found
230
+ * - zsv_status_no_more_input if no overwrite file was found
231
+ * - a different status code on error
232
+ */
233
+ enum zsv_status zsv_overwrite_auto(struct zsv_opts *opts, const char *csv_path) {
234
+ enum zsv_status status = zsv_status_error;
235
+ if (opts->overwrite.ctx || opts->overwrite.open || opts->overwrite.next || opts->overwrite.close)
236
+ status = zsv_status_error;
237
+ else {
238
+ unsigned char *overwrite_fn = zsv_cache_filepath((const unsigned char *)csv_path, zsv_cache_type_overwrite, 0, 0);
239
+ if (!overwrite_fn)
240
+ status = zsv_status_memory;
241
+ else if (!zsv_file_exists((char *)overwrite_fn))
242
+ status = zsv_status_no_more_input;
243
+ else {
244
+ struct zsv_overwrite_opts overwrite_opts = {0};
245
+ overwrite_opts.src = (char *)overwrite_fn;
246
+ if (!(opts->overwrite.ctx = zsv_overwrite_context_new(&overwrite_opts)))
247
+ status = zsv_status_memory;
248
+ else {
249
+ opts->overwrite.open = zsv_overwrite_open;
250
+ opts->overwrite.next = zsv_overwrite_next;
251
+ opts->overwrite.close = zsv_overwrite_context_delete;
252
+ status = zsv_status_done;
253
+ }
254
+ }
255
+ free(overwrite_fn);
256
+ }
257
+ return status;
258
+ }
@@ -0,0 +1,246 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <sqlite3.h>
4
+ #include <errno.h>
5
+ #include <limits.h>
6
+
7
+ #include <zsv.h>
8
+ #include <zsv/utils/writer.h>
9
+ #include <zsv/utils/dirs.h>
10
+ #include <zsv/utils/file.h>
11
+ #include <zsv/utils/os.h>
12
+ #include <zsv/utils/overwrite.h>
13
+ #include <zsv/utils/overwrite_writer.h>
14
+
15
+ static enum zsv_status zsv_overwrite_writer_init(struct zsv_overwrite *data) {
16
+ enum zsv_status err = zsv_status_ok;
17
+ int tmp_err = 0;
18
+ if (zsv_mkdirs(data->ctx->src, 1) && !zsv_file_readable(data->ctx->src, &tmp_err, NULL)) {
19
+ err = zsv_status_error;
20
+ perror(data->ctx->src);
21
+ return err;
22
+ }
23
+
24
+ sqlite3_stmt *query = NULL;
25
+
26
+ if (sqlite3_open_v2(data->ctx->src, &data->ctx->sqlite3.db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK ||
27
+ data->mode == zsvsheet_mode_add || data->mode == zsvsheet_mode_bulk || data->mode == zsvsheet_mode_remove ||
28
+ data->mode == zsvsheet_mode_clear) {
29
+ sqlite3_close(data->ctx->sqlite3.db);
30
+ if (sqlite3_open_v2(data->ctx->src, &data->ctx->sqlite3.db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) !=
31
+ SQLITE_OK) {
32
+ err = zsv_status_error;
33
+ fprintf(stderr, "Failed to open conn: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
34
+ return err;
35
+ }
36
+
37
+ if (sqlite3_exec(data->ctx->sqlite3.db, "PRAGMA foreign_keys = on", NULL, NULL, NULL) != SQLITE_OK) {
38
+ err = zsv_status_error;
39
+ fprintf(stderr, "Could not enable foreign keys: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
40
+ return err;
41
+ }
42
+
43
+ if (sqlite3_prepare_v2(data->ctx->sqlite3.db,
44
+ "CREATE TABLE IF NOT EXISTS overwrites ( row integer, column integer, value string, "
45
+ "timestamp varchar(25), author varchar(25) );",
46
+ -1, &query, NULL) == SQLITE_OK) {
47
+ if (sqlite3_step(query) != SQLITE_DONE) {
48
+ err = zsv_status_error;
49
+ fprintf(stderr, "Failed to step: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
50
+ return err;
51
+ }
52
+ } else {
53
+ err = zsv_status_error;
54
+ fprintf(stderr, "Failed to prepare1: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
55
+ }
56
+
57
+ if (query)
58
+ sqlite3_finalize(query);
59
+
60
+ if (sqlite3_prepare_v2(data->ctx->sqlite3.db, "CREATE UNIQUE INDEX overwrites_uix ON overwrites (row, column)", -1,
61
+ &query, NULL) == SQLITE_OK) {
62
+ if (sqlite3_step(query) != SQLITE_DONE) {
63
+ err = zsv_status_error;
64
+ fprintf(stderr, "Failed to step: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
65
+ return err;
66
+ }
67
+ if (query)
68
+ sqlite3_finalize(query);
69
+ }
70
+ }
71
+
72
+ if (!data->ctx->sqlite3.db)
73
+ err = zsv_status_error;
74
+
75
+ return err;
76
+ }
77
+
78
+ struct zsv_overwrite *zsv_overwrite_writer_new(struct zsv_overwrite_args *args, struct zsv_overwrite_opts *ctx_opts) {
79
+ struct zsv_overwrite *data = calloc(1, sizeof(*data));
80
+ data->overwrite = calloc(1, sizeof(*data->overwrite));
81
+ data->overwrite->old_value = args->overwrite->old_value;
82
+ data->force = args->force;
83
+ data->all = args->all;
84
+ data->a1 = args->a1;
85
+ data->bulk_file = args->bulk_file;
86
+ data->mode = args->mode;
87
+ data->ctx = zsv_overwrite_context_new(ctx_opts);
88
+ data->overwrite = args->overwrite;
89
+ data->next = args->next;
90
+ struct zsv_csv_writer_options writer_opts = {0};
91
+ data->writer = zsv_writer_new(&writer_opts);
92
+
93
+ enum zsv_status err = zsv_status_ok;
94
+ if (data->mode == zsvsheet_mode_list) {
95
+ if ((err = (zsv_overwrite_open(data->ctx)))) // use open when it's read-only
96
+ fprintf(stderr, "Failed to initalize database\n");
97
+ } else {
98
+ if ((err = zsv_overwrite_writer_init(data))) // use init when writing to db
99
+ fprintf(stderr, "Failed to initalize database\n");
100
+ }
101
+
102
+ return err == zsv_status_ok ? data : NULL;
103
+ }
104
+
105
+ void zsv_overwrite_writer_delete(struct zsv_overwrite *data) {
106
+ if (data->writer)
107
+ zsv_writer_delete(data->writer);
108
+ if (data->ctx)
109
+ zsv_overwrite_context_delete(data->ctx);
110
+
111
+ if (data->overwrite && data->mode != zsvsheet_mode_bulk)
112
+ free(data->overwrite->val.str);
113
+
114
+ if (data->all)
115
+ zsv_remove(data->ctx->src);
116
+ free(data);
117
+ }
118
+
119
+ enum zsv_status zsv_overwrite_writer_add(struct zsv_overwrite *data) {
120
+ if (!data->overwrite->val.str)
121
+ return zsv_status_error;
122
+ if (data->force)
123
+ data->ctx->sqlite3.sql =
124
+ "INSERT OR REPLACE INTO overwrites (row, column, value, timestamp, author) VALUES (?, ?, ?, ?, ?)";
125
+ else if (data->overwrite->old_value.len > 0)
126
+ data->ctx->sqlite3.sql = "INSERT OR REPLACE INTO overwrites (row, column, value, timestamp, author) SELECT ?, ?, "
127
+ "?, ?, ? WHERE EXISTS (SELECT 1 FROM overwrites WHERE value = ?)";
128
+ else
129
+ data->ctx->sqlite3.sql = "INSERT INTO overwrites (row, column, value, timestamp, author) VALUES (?, ?, ?, ?, ?)";
130
+
131
+ enum zsv_status err = zsv_status_ok;
132
+ sqlite3_stmt *query = NULL;
133
+
134
+ if (sqlite3_prepare_v2(data->ctx->sqlite3.db, data->ctx->sqlite3.sql, -1, &query, NULL) == SQLITE_OK) {
135
+ sqlite3_bind_int64(query, 1, data->overwrite->row_ix);
136
+ sqlite3_bind_int64(query, 2, data->overwrite->col_ix);
137
+ sqlite3_bind_text(query, 3, (const char *)data->overwrite->val.str, data->overwrite->val.len, SQLITE_STATIC);
138
+ if (data->overwrite->timestamp)
139
+ sqlite3_bind_int64(query, 4, data->overwrite->timestamp);
140
+ else
141
+ sqlite3_bind_null(query, 4);
142
+ if (data->overwrite->author.len > 0)
143
+ sqlite3_bind_text(query, 5, (const char *)data->overwrite->author.str, data->overwrite->author.len,
144
+ SQLITE_STATIC);
145
+ else
146
+ sqlite3_bind_text(query, 5, "", -1, SQLITE_STATIC);
147
+
148
+ if (data->overwrite->old_value.len > 0)
149
+ sqlite3_bind_text(query, 6, (const char *)data->overwrite->old_value.str, data->overwrite->old_value.len,
150
+ SQLITE_STATIC);
151
+
152
+ if (sqlite3_step(query) != SQLITE_DONE) {
153
+ err = zsv_status_error;
154
+ if (data->mode == zsvsheet_mode_bulk)
155
+ sqlite3_exec(data->ctx->sqlite3.db, "ROLLBACK", NULL, NULL, NULL);
156
+ fprintf(stderr, "Value already exists at row %zu and column %zu, use --force to force insert\n",
157
+ data->overwrite->row_ix, data->overwrite->col_ix);
158
+ }
159
+ } else {
160
+ err = zsv_status_error;
161
+ if (data->mode == zsvsheet_mode_bulk)
162
+ sqlite3_exec(data->ctx->sqlite3.db, "ROLLBACK", NULL, NULL, NULL);
163
+ fprintf(stderr, "Failed to prepare2: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
164
+ }
165
+
166
+ if (query)
167
+ sqlite3_finalize(query);
168
+
169
+ return err;
170
+ }
171
+
172
+ enum zsv_status zsv_overwrite_writer_remove(struct zsv_overwrite *data) {
173
+ enum zsv_status err = zsv_status_ok;
174
+ if (data->all) {
175
+ err = zsv_overwrite_writer_clear(data);
176
+ return err;
177
+ }
178
+
179
+ data->ctx->sqlite3.sql = data->overwrite->old_value.len > 0
180
+ ? "DELETE FROM overwrites WHERE row = ? AND column = ? AND value = ?"
181
+ : "DELETE FROM overwrites WHERE row = ? AND column = ?";
182
+
183
+ sqlite3_stmt *query = NULL;
184
+ if (sqlite3_prepare_v2(data->ctx->sqlite3.db, data->ctx->sqlite3.sql, -1, &query, NULL) != SQLITE_OK) {
185
+ err = zsv_status_error;
186
+ if (data->mode == zsvsheet_mode_bulk)
187
+ sqlite3_exec(data->ctx->sqlite3.db, "ROLLBACK", NULL, NULL, NULL);
188
+ fprintf(stderr, "Could not prepare: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
189
+ return err;
190
+ }
191
+ sqlite3_bind_int64(query, 1, data->overwrite->row_ix);
192
+ sqlite3_bind_int64(query, 2, data->overwrite->col_ix);
193
+ if (data->overwrite->old_value.len > 0)
194
+ sqlite3_bind_text(query, 3, (const char *)data->overwrite->old_value.str, data->overwrite->old_value.len,
195
+ SQLITE_STATIC);
196
+
197
+ if (sqlite3_step(query) != SQLITE_DONE) {
198
+ err = zsv_status_error;
199
+ if (data->mode == zsvsheet_mode_bulk)
200
+ sqlite3_exec(data->ctx->sqlite3.db, "ROLLBACK", NULL, NULL, NULL);
201
+ fprintf(stderr, "Could not step: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
202
+ return err;
203
+ }
204
+ if (query)
205
+ sqlite3_finalize(query);
206
+ return err;
207
+ }
208
+
209
+ enum zsv_status zsv_overwrite_writer_bulk(struct zsv_overwrite *data) {
210
+ free(data->ctx->src);
211
+ data->ctx->src = (char *)data->bulk_file;
212
+ if (zsv_overwrite_open(data->ctx) != zsv_status_ok) {
213
+ fprintf(stderr, "Could not open\n");
214
+ return zsv_status_error;
215
+ }
216
+ data->overwrite->have = 1;
217
+ data->ctx->row_ix = 1;
218
+ if (sqlite3_exec(data->ctx->sqlite3.db, "BEGIN TRANSACTION", NULL, NULL, NULL) == SQLITE_OK) {
219
+ while (data->ctx->next(data->ctx, data->overwrite) == zsv_status_ok && data->overwrite->have) {
220
+ data->next(data);
221
+ data->overwrite->timestamp = 0;
222
+ }
223
+ if (sqlite3_exec(data->ctx->sqlite3.db, "COMMIT", NULL, NULL, NULL) != SQLITE_OK)
224
+ fprintf(stderr, "Could not commit changes: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
225
+ } else
226
+ fprintf(stderr, "Could not begin transaction: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
227
+ return zsv_status_ok;
228
+ }
229
+
230
+ enum zsv_status zsv_overwrite_writer_clear(struct zsv_overwrite *data) {
231
+ enum zsv_status err = zsv_status_ok;
232
+ sqlite3_stmt *query = NULL;
233
+ if (sqlite3_prepare_v2(data->ctx->sqlite3.db, "DELETE FROM overwrites", -1, &query, NULL) == SQLITE_OK) {
234
+ if (sqlite3_step(query) != SQLITE_DONE) {
235
+ err = zsv_status_error;
236
+ fprintf(stderr, "Failed to step: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
237
+ return err;
238
+ }
239
+ } else {
240
+ err = zsv_status_error;
241
+ fprintf(stderr, "Could not prepare: %s\n", sqlite3_errmsg(data->ctx->sqlite3.db));
242
+ }
243
+ if (query)
244
+ sqlite3_finalize(query);
245
+ return err;
246
+ }