Skip to content

Commit

Permalink
Merge pull request #37 from doug-martin/master
Browse files Browse the repository at this point in the history
v0.3.0
  • Loading branch information
doug-martin committed May 15, 2014
2 parents e2fc34c + 2a17742 commit 6901d21
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 53 deletions.
1 change: 0 additions & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"boss": false,
"debug": false,
"eqnull": true,
"es5": true,
"esnext": true,
"evil": false,
"expr": true,
Expand Down
6 changes: 6 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# v0.3.0

* You can now specify `objectMode` when parsing a csv which will cause `data` events to have an object emitted.
* You can now pipe directly to the stream returned from `createWriteStream`
* You can now transform csvs by piping output from parsing into a formatter.

# v0.2.5

* Fixed issue where not all rows are emitted when using `pause` and `resume`
Expand Down
54 changes: 37 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
<a name="top"></a>


[![build status](https://secure.travis-ci.org/C2FO/fast-csv.png)](http://travis-ci.org/C2FO/fast-csv)
[![build status](https://secure.travis-ci.org/C2FO/fast-csv.png)](http://travis-ci.org/C2FO/fast-csv)
# Fast-csv

This is a library that provides CSV parsing and formatting.
Expand All @@ -18,6 +15,7 @@ This is a library that provides CSV parsing and formatting.

All methods accept the following `options`

* `objectMode=true`: Ensure that `data` events have an object emitted rather than the stringified version set to false to have a stringified buffer.
* `headers=false`: Ste to true if you expect the first line of your `CSV` to contain headers, alternatly you can specify an array of headers to use.
* `ignoreEmpty=false`: If you wish to ignore empty rows.
* `delimiter=','`: If your data uses an alternate delimiter such as `;` or `\t`.
Expand All @@ -33,7 +31,6 @@ All methods accept the following `options`

**events**

`parse-error`: Emitted if there was an error parsing a row.
`record`: Emitted when a record is parsed.
`data-invalid`: Emitted if there was invalid row encounted, **only emitted if the `validate` function is used**.
`data`: Emitted with the `stringified` version of a record.
Expand All @@ -56,7 +53,7 @@ var csvStream = csv()
stream.pipe(csvStream);
```

**`.fromPath(path[, options])**
**`.fromPath(path[, options])`**

This method parses a file from the specified path.

Expand All @@ -73,7 +70,7 @@ csv
});
```

**`.fromString(string[, options])**
**`.fromString(string[, options])`**

This method parses a string

Expand All @@ -94,7 +91,7 @@ csv
});
```

**`.fromStream(stream[, options])**
**`.fromStream(stream[, options])`**

This accepted a readable stream to parse data from.

Expand Down Expand Up @@ -223,7 +220,7 @@ This is the lowest level of the write methods, it creates a stream that can be u
```javascript
var csvStream = csv.createWriteStream({headers: true}),
writableStream = fs.createWritableStream("my.csv");
writableStream = fs.createWriteStream("my.csv");

writableStream.on("finish", function(){
console.log("DONE!");
Expand Down Expand Up @@ -333,6 +330,37 @@ csv.writeToString([
], {headers: true}); //"a,b\na1,b1\na2,b2\n"
```
## Piping from Parser to Writer
You can use `fast-csv` to pipe the output from a parsed CSV to a transformed CSV by setting the parser to `objectMode` and using `createWriteStream`.
```javascript
csv
.fromPath("in.csv", {headers: true})
.pipe(csv.createWriteStream({headers: true}))
.pipe(fs.createWriteStream("out.csv", {encoding: "utf8"}));
```
When piping from a parser to a formatter the transforms are maintained also.
```javascript
csv
.fromPath("in.csv", {headers: true})
.transform(function(obj){
return {
name: obj.Name,
address: obj.Address,
emailAddress: obj.Email_Address,
verified: obj.Verified
};
})
.pipe(csv.createWriteStream({headers: true}))
.pipe(fs.createWriteStream("out.csv", {encoding: "utf8"}));
```
The output will contain formatted result from the transform function.
## Benchmarks
`Parsing 20000 records AVG over 3 runs`
Expand Down Expand Up @@ -371,11 +399,3 @@ MIT <https://github.com/C2FO/fast-csv/raw/master/LICENSE>
* Code: `git clone git://github.com/C2FO/fast-csv.git`
* Website: <http://c2fo.com>
* Twitter: [http://twitter.com/c2fo](http://twitter.com/c2fo) - 877.465.4045

##Namespaces





##Classes
6 changes: 6 additions & 0 deletions docs/History.html
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@



<h1>v0.3.0</h1>
<ul>
<li>You can now specify <code>objectMode</code> when parsing a csv which will cause <code>data</code> events to have an object emitted.</li>
<li>You can now pipe directly to the stream returned from <code>createWriteStream</code></li>
<li>You can now transform csvs by piping output from parsing into a formatter.</li>
</ul>
<h1>v0.2.5</h1>
<ul>
<li>Fixed issue where not all rows are emitted when using <code>pause</code> and <code>resume</code></li>
Expand Down
37 changes: 27 additions & 10 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@



<p><a name="top"></a></p>
<p> <a href="http://travis-ci.org/C2FO/fast-csv"><img src="https://secure.travis-ci.org/C2FO/fast-csv.png" alt="build status"></a></p>
<p><a href="http://travis-ci.org/C2FO/fast-csv"><img src="https://secure.travis-ci.org/C2FO/fast-csv.png" alt="build status"></a></p>
<h1>Fast-csv</h1>
<p>This is a library that provides CSV parsing and formatting.</p>
<p><strong>NOTE</strong> As of v0.2.0 <code>fast-csv</code> supports multi-line values.</p>
Expand All @@ -188,6 +187,7 @@ <h2>Usage</h2>
<h3>Parsing</h3>
<p>All methods accept the following <code>options</code></p>
<ul>
<li><code>objectMode=true</code>: Ensure that <code>data</code> events have an object emitted rather than the stringified version set to false to have a stringified buffer.</li>
<li><code>headers=false</code>: Ste to true if you expect the first line of your <code>CSV</code> to contain headers, alternatly you can specify an array of headers to use.</li>
<li><code>ignoreEmpty=false</code>: If you wish to ignore empty rows.</li>
<li><code>delimiter=&#39;,&#39;</code>: If your data uses an alternate delimiter such as <code>;</code> or <code>\t</code>.<ul>
Expand All @@ -207,8 +207,7 @@ <h3>Parsing</h3>
</li>
</ul>
<p><strong>events</strong></p>
<p><code>parse-error</code>: Emitted if there was an error parsing a row.
<code>record</code>: Emitted when a record is parsed.
<p><code>record</code>: Emitted when a record is parsed.
<code>data-invalid</code>: Emitted if there was invalid row encounted, <strong>only emitted if the <code>validate</code> function is used</strong>.
<code>data</code>: Emitted with the <code>stringified</code> version of a record.</p>
<p><strong>([options])</strong></p>
Expand All @@ -224,7 +223,7 @@ <h3>Parsing</h3>
});

stream.pipe(csvStream);</code></pre>
<p><strong>`.fromPath(path[, options])</strong></p>
<p><strong><code>.fromPath(path[, options])</code></strong></p>
<p>This method parses a file from the specified path.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var csv = require(&quot;fast-csv&quot;);

Expand All @@ -236,7 +235,7 @@ <h3>Parsing</h3>
.on(&quot;end&quot;, function(){
console.log(&quot;done&quot;);
});</code></pre>
<p><strong>`.fromString(string[, options])</strong></p>
<p><strong><code>.fromString(string[, options])</code></strong></p>
<p>This method parses a string</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var csv = require(&quot;fast-csv&quot;);

Expand All @@ -252,7 +251,7 @@ <h3>Parsing</h3>
.on(&quot;end&quot;, function(){
console.log(&quot;done&quot;);
});</code></pre>
<p><strong>`.fromStream(stream[, options])</strong></p>
<p><strong><code>.fromStream(stream[, options])</code></strong></p>
<p>This accepted a readable stream to parse data from.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var stream = fs.createReadStream(&quot;my.csv&quot;);

Expand Down Expand Up @@ -342,7 +341,7 @@ <h3>Formatting</h3>
<p><strong><code>createWriteStream(options)</code></strong></p>
<p>This is the lowest level of the write methods, it creates a stream that can be used to create a csv of unknown size and pipe to an output csv.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">var csvStream = csv.createWriteStream({headers: true}),
writableStream = fs.createWritableStream(&quot;my.csv&quot;);
writableStream = fs.createWriteStream(&quot;my.csv&quot;);

writableStream.on(&quot;finish&quot;, function(){
console.log(&quot;DONE!&quot;);
Expand Down Expand Up @@ -417,6 +416,26 @@ <h3>Formatting</h3>
{a: &quot;a1&quot;, b: &quot;b1&quot;},
{a: &quot;a2&quot;, b: &quot;b2&quot;}
], {headers: true}); //&quot;a,b\na1,b1\na2,b2\n&quot;</code></pre>
<h2>Piping from Parser to Writer</h2>
<p>You can use <code>fast-csv</code> to pipe the output from a parsed CSV to a transformed CSV by setting the parser to <code>objectMode</code> and using <code>createWriteStream</code>.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">csv
.fromPath(&quot;in.csv&quot;, {headers: true})
.pipe(csv.createWriteStream({headers: true}))
.pipe(fs.createWriteStream(&quot;out.csv&quot;, {encoding: &quot;utf8&quot;}));</code></pre>
<p>When piping from a parser to a formatter the transforms are maintained also.</p>
<pre class='prettyprint linenums lang-js'><code class="lang-javascript">csv
.fromPath(&quot;in.csv&quot;, {headers: true})
.transform(function(obj){
return {
name: obj.Name,
address: obj.Address,
emailAddress: obj.Email_Address,
verified: obj.Verified
};
})
.pipe(csv.createWriteStream({headers: true}))
.pipe(fs.createWriteStream(&quot;out.csv&quot;, {encoding: &quot;utf8&quot;}));</code></pre>
<p>The output will contain formatted result from the transform function.</p>
<h2>Benchmarks</h2>
<p><code>Parsing 20000 records AVG over 3 runs</code></p>
<pre class='prettyprint linenums lang-js'><code>fast-csv: 198.67ms
Expand All @@ -438,8 +457,6 @@ <h2>Meta</h2>
<li>Website: <a href="http://c2fo.com">http://c2fo.com</a></li>
<li>Twitter: <a href="http://twitter.com/c2fo"><a href="http://twitter.com/c2fo">http://twitter.com/c2fo</a></a> - 877.465.4045</li>
</ul>
<h2>Namespaces</h2>
<h2>Classes</h2>


<hr>
Expand Down
31 changes: 24 additions & 7 deletions lib/formatter.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
var fs = require("fs"),
util = require("util"),
extended = require("./extended"),
isUndefinedOrNull = extended.isUndefinedOrNull,
hash = extended.hash,
stream = require("stream"),
Transform = stream.Transform,
LINE_BREAK = extended.LINE_BREAK;

function createFormatter(options) {
Expand Down Expand Up @@ -73,7 +75,7 @@ function wrapWriter(writer, options) {
hasHeaders = extended.has(options, "headers") ? options.headers : true,
parsedHeaders = hasHeaders ? false : true,
headersLength = 0, i = -1,
writerWrite = writer.push, headers,
writerWrite = writer.write, headers,
buffer = [],
totalCount = 0,
MAX_BUFFER_SIZE = options.maxBuffer || 100000;
Expand All @@ -82,7 +84,7 @@ function wrapWriter(writer, options) {
if (item) {
var isHash = !extended.isArray(item), vals;
if (!parsedHeaders) {
totalCount++
totalCount++;
parsedHeaders = true;
if (isHash) {
headers = hash.keys(item);
Expand Down Expand Up @@ -117,17 +119,32 @@ function wrapWriter(writer, options) {
writerWrite.call(writer, new Buffer(buffer.join("")).toString("utf8"));
buffer.length = 0;
}
writerWrite.call(writer, null);
writer.end();
}
};
return writer;
}

function CsvTransformStream(opts) {
Transform.call(this, opts);
wrapWriter(this, opts);
}

util.inherits(CsvTransformStream, Transform);

extended(CsvTransformStream).extend({

_transform: function (str, encoding, cb) {
cb(null, str);
},
_flush: function (cb) {
this.write(null);
cb(null);
}
});

function createWriteStream(options) {
var writer = new stream.Readable();
writer._read = function () {
};
return wrapWriter(writer, options);
return new CsvTransformStream(options);
}

function write(arr, options) {
Expand Down
Loading

0 comments on commit 6901d21

Please sign in to comment.