Skip to content

Commit 81bbe3a

Browse files
authored
Merge pull request #18 from robmckinnon/update_elixir_1-9
Update for Elixir 1.9
2 parents ac329a7 + 08c113c commit 81bbe3a

File tree

6 files changed

+65
-43
lines changed

6 files changed

+65
-43
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/docs
66
erl_crash.dump
77
*.ez
8+
.elixir_ls

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ elixir:
66
- 1.6.6
77
- 1.7.4
88
- 1.8.1
9+
- 1.9.1
910
after_script:
10-
- mix deps.get --only docs
11+
- MIX_ENV=docs mix deps.get --only docs
1112
- MIX_ENV=docs mix inch.report

README.md

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,83 +10,95 @@ Create Elixir structs, maps with atom keys, and keyword lists from CSV/TSV data.
1010

1111
You can view [full DataMorph API documentation on hexdocs](https://hexdocs.pm/data_morph/DataMorph.html).
1212

13+
Note, we should never convert user input to atoms. This is because atoms are not
14+
garbage collected. Once an atom is created, it is never reclaimed.
15+
16+
Generating atoms from user input would mean the user can inject enough
17+
different names to exhaust our system memory, or we reach the Erlang VM limit
18+
for the maximum number of atoms which will bring our system down regardless.
19+
1320
## Installation
1421

1522
Add
1623
```elixir
17-
{:data_morph, "~> 0.0.9"}
24+
{:data_morph, "~> 0.1.0"}
1825
```
1926
to your deps in `mix.exs` like so:
2027

2128
```elixir
2229
defp deps do
2330
[
24-
{:data_morph, "~> 0.0.9"}
31+
{:data_morph, "~> 0.1.0"}
2532
]
2633
end
2734
```
2835

2936
## Usage examples
3037

31-
Define a struct and return stream of structs created from a `tsv` string, a `namespace` atom and `name` string.
38+
Given a CSV file of data like this:
39+
40+
```sh
41+
(echo "name,iso-code" && echo New Zealand,nz && echo United Kingdom,gb) > tmp.csv
42+
```
43+
44+
Define a struct and return stream of structs created from a `csv` stream,
45+
a `namespace` string or atom, and a `name` string or atom.
3246

3347
```elixir
34-
"name\tiso\n" <>
35-
"New Zealand\tnz\n" <>
36-
"United Kingdom\tgb" \
37-
|> DataMorph.structs_from_tsv(OpenRegister, "country") \
48+
File.stream!('./tmp.csv') \
49+
|> DataMorph.structs_from_csv("my-module", :iso_country) \
3850
|> Enum.to_list
3951
# [
40-
# %OpenRegister.Country{iso: "nz", name: "New Zealand"},
41-
# %OpenRegister.Country{iso: "gb", name: "United Kingdom"}
52+
# %MyModule.IsoCountry{iso_code: "nz", name: "New Zealand"},
53+
# %MyModule.IsoCountry{iso_code: "gb", name: "United Kingdom"}
4254
# ]
4355
```
4456

45-
Define a struct and return stream of structs created from a `csv` file stream,
46-
and a `namespace` string and `name` atom.
47-
48-
```sh
49-
(echo name,iso && echo New Zealand,nz && echo United Kingdom,gb) > tmp.csv
50-
```
57+
Return stream of maps created from a `csv` stream.
5158

5259
```elixir
5360
File.stream!('./tmp.csv') \
54-
|> DataMorph.structs_from_csv("open-register", :iso_country) \
61+
|> DataMorph.maps_from_csv() \
5562
|> Enum.to_list
5663
# [
57-
# %OpenRegister.IsoCountry{iso: "nz", name: "New Zealand"},
58-
# %OpenRegister.IsoCountry{iso: "gb", name: "United Kingdom"}
64+
# %{iso_code: "nz", name: "New Zealand"},
65+
# %{iso_code: "gb", name: "United Kingdom"}
5966
# ]
6067
```
6168

62-
Define a struct and puts stream of structs created from a stream of `csv`
63-
on standard input, and a `namespace` atom, and `name` string.
69+
Return a stream of keyword lists created from a stream of `csv`.
70+
6471
```sh
6572
(echo name,iso && echo New Zealand,NZ) | \
66-
mix run -e 'IO.puts inspect \
67-
IO.stream(:stdio, :line) \
68-
|> DataMorph.structs_from_csv(:ex, "ample") \
69-
|> Enum.at(0)'
70-
# %Ex.Ample{iso: "NZ", name: "New Zealand"}
73+
mix run -e 'IO.stream(:stdio, :line) \
74+
|> DataMorph.keyword_lists_from_csv() \
75+
|> IO.inspect'
76+
# [[name: "New Zealand", iso: "NZ"]]
7177
```
7278

73-
Add additional new fields to struct when called again with different `tsv`.
79+
Add new fields to struct when called twice with different fields in `tsv`.
7480

7581
```elixir
7682
"name\tiso\n" <>
7783
"New Zealand\tnz\n" <>
7884
"United Kingdom\tgb" \
79-
|> DataMorph.structs_from_tsv(OpenRegister, "country") \
85+
|> DataMorph.structs_from_tsv(MyModule, "country") \
8086
|> Enum.to_list
87+
# [
88+
# %MyModule.Country{iso: "nz", name: "New Zealand"},
89+
# %MyModule.Country{iso: "gb", name: "United Kingdom"}
90+
# ]
8191

8292
"name\tacronym\n" <>
8393
"New Zealand\tNZ\n" <>
8494
"United Kingdom\tUK" \
85-
|> DataMorph.structs_from_tsv(OpenRegister, "country") \
95+
|> DataMorph.structs_from_tsv("MyModule", :country) \
8696
|> Enum.to_list
97+
# warning: redefining module MyModule.Country
98+
# (current version defined in memory)
8799
# [
88-
# %OpenRegister.Country{acronym: "NZ", iso: nil, name: "New Zealand"},
89-
# %OpenRegister.Country{acronym: "UK", iso: nil, name: "United Kingdom"}
100+
# %MyModule.Country{acronym: "NZ", iso: nil, name: "New Zealand"},
101+
# %MyModule.Country{acronym: "UK", iso: nil, name: "United Kingdom"}
90102
# ]
91103
```
92104

lib/data_morph.ex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
defmodule DataMorph do
22
@moduledoc ~S"""
3-
Create Elixir structs, maps with atom keys, and keyword lists from CSV/TSV data.
3+
Create Elixir structs, maps with atom keys, and keyword lists from CSV/TSV
4+
data.
5+
6+
Note, we should never convert user input to atoms. This is because atoms are
7+
not garbage collected. Once an atom is created, it is never reclaimed.
8+
9+
Generating atoms from user input would mean the user can inject enough
10+
different names to exhaust our system memory, or we reach the Erlang VM limit
11+
for the maximum number of atoms which will bring our system down regardless.
412
513
## Examples
614

mix.exs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
defmodule DataMorph.Mixfile do
22
use Mix.Project
33

4-
@version "0.0.9"
4+
@version "0.1.0"
55

66
def project do
77
[
88
app: :data_morph,
99
version: @version,
10-
elixir: "~> 1.3 or ~> 1.4 or ~> 1.5 or ~> 1.6 or ~> 1.7 or ~> 1.8",
10+
elixir: "~> 1.3 or ~> 1.4 or ~> 1.5 or ~> 1.6 or ~> 1.7 or ~> 1.8 or ~> 1.9",
1111
description: description(),
1212
deps: deps(),
1313
package: package(),
@@ -25,12 +25,12 @@ defmodule DataMorph.Mixfile do
2525

2626
defp deps do
2727
[
28-
{:csv, "~> 2.3"},
28+
{:csv, "~> 2.3.1"},
2929
# Docs dependencies
30-
{:ex_doc, "~> 0.19", only: :docs},
31-
{:inch_ex, "~> 2.0", only: :docs},
30+
{:ex_doc, "~> 0.21.1", only: :docs, runtime: false},
31+
{:inch_ex, "~> 2.0", only: :docs, runtime: false},
3232
# Test dependencies
33-
{:mix_test_watch, "~> 0.9", only: :dev}
33+
{:mix_test_watch, "~> 0.9", only: :dev, runtime: false}
3434
]
3535
end
3636

mix.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
%{
22
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
3-
"csv": {:hex, :csv, "2.3.0", "e30e4bbe633653a5c2da43cab42a61623e0acc80ef40c321bc29f0d698697bd3", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"},
4-
"earmark": {:hex, :earmark, "1.3.1", "73812f447f7a42358d3ba79283cfa3075a7580a3a2ed457616d6517ac3738cb9", [:mix], [], "hexpm"},
5-
"ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
3+
"csv": {:hex, :csv, "2.3.1", "9ce11eff5a74a07baf3787b2b19dd798724d29a9c3a492a41df39f6af686da0e", [:mix], [{:parallel_stream, "~> 1.0.4", [hex: :parallel_stream, repo: "hexpm", optional: false]}], "hexpm"},
4+
"earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"},
5+
"ex_doc": {:hex, :ex_doc, "0.21.1", "5ac36660846967cd869255f4426467a11672fec3d8db602c429425ce5b613b90", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
66
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
77
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
88
"inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
99
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
10-
"makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
11-
"makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
10+
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
11+
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
1212
"mix_test_watch": {:hex, :mix_test_watch, "0.9.0", "c72132a6071261893518fa08e121e911c9358713f62794a90c95db59042af375", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm"},
1313
"nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},
1414
"parallel_stream": {:hex, :parallel_stream, "1.0.6", "b967be2b23f0f6787fab7ed681b4c45a215a81481fb62b01a5b750fa8f30f76c", [:mix], [], "hexpm"},

0 commit comments

Comments
 (0)