diff --git a/CHANGELOG.md b/CHANGELOG.md index 76afad3..b28c5c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,8 @@ # SmarterCSV 1.x Change Log -## 1.11.0 +## 1.11.0 (2024-07-02) * added SmarterCSV::Writer to output CSV files ([issue #44](https://github.com/tilo/smarter_csv/issues/44)) - * added SmarterCSV::Reader to isolate parsing of CSV files ## 1.10.3 (2024-03-10) * fixed issue when frozen options are handed in (thanks to Daniel Pepper) diff --git a/README.md b/README.md index 8544d27..0f817c5 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ This library provides a complete interface to CSV files and data. It offers tools to enable you to read and write to and from Strings or IO objects, as needed. -#### LATEST CHANGES +#### BREAKING CHANGES -* Version 1.10.0 has BREAKING CHANGES: +* Version 1.10.0 had BREAKING CHANGES: Changed behavior: + when `user_provided_headers` are provided: diff --git a/lib/smarter_csv/version.rb b/lib/smarter_csv/version.rb index 7373e59..255a0b9 100644 --- a/lib/smarter_csv/version.rb +++ b/lib/smarter_csv/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SmarterCSV - VERSION = "1.10.3" + VERSION = "1.11.0" end diff --git a/lib/smarter_csv/writer.rb b/lib/smarter_csv/writer.rb index cef0e1c..a92a13e 100644 --- a/lib/smarter_csv/writer.rb +++ b/lib/smarter_csv/writer.rb @@ -2,18 +2,33 @@ module SmarterCSV # - # Generate CSV files from batches of array_of_hashes data - # - automatically generates the header on-the-fly - # - automatically quotes fields containing the col_sep + # Generate CSV files # - # Optionally headers can be passed-in via the options, - # If any new headers are fund in the data, they will be appended to the headers. + # Create an instance of the Writer class with the filename and options. + # call `<<` one or mulltiple times to append data to the file. + # call `finalize` to save the file. # - # col_sep : defaults to , but can be set to any other character - # row_sep : defaults to LF \n , but can be set to \r\n or \r or anything else - # quote_char : defaults to " - # discover_headers : defaults to true - # headers : defaults to [] + # The `<<` method can take different arguments: + # * a signle Hash + # * an array of Hashes + # * nested arrays of arrays of Hashes + # + # By default SmarterCSV::Writer automatically discovers all headers that are present + # in the data on-the-fly. This can be disabled, then only given headers are used. + # Disabling can be useful when you want to select attributes from hashes, or ActiveRecord instances. + # + # If `discover_headers` is enabled, and headers are given, any new headers that are found in the data will still be appended. + # + # The Writer automatically quotes fields containing the col_sep, row_sep, or the quote_char. + # + # Options: + # col_sep : defaults to , but can be set to any other character + # row_sep : defaults to LF \n , but can be set to \r\n or \r or anything else + # quote_char : defaults to " + # discover_headers : defaults to true + # headers : defaults to [] + # force_quotes: defaults to false + # map_headers: defaults to {}, can be a hash of key -> value mappings # IMPORTANT NOTES: # * Data hashes could contain strings or symbols as keys. @@ -28,10 +43,11 @@ def initialize(file_path, options = {}) @row_sep = options[:row_sep] || "\n" # RFC4180 "\r\n" @col_sep = options[:col_sep] || ',' @quote_char = '"' - @force_quotes = options[:force_quotes] + @force_quotes = options[:force_quotes] == true @map_headers = options[:map_headers] || {} - @temp_file = Tempfile.new('tempfile', '/tmp') @output_file = File.open(file_path, 'w+') + # hidden state: + @temp_file = Tempfile.new('tempfile', '/tmp') @quote_regex = Regexp.union(@col_sep, @row_sep, @quote_char) end @@ -57,6 +73,7 @@ def finalize @output_file.write(@temp_file.read) @output_file.flush @output_file.close + @temp_file.delete end private