embulk-filter-base64 0.1.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 920673effb3067f179e366a12a6b1ea760a9c199
4
- data.tar.gz: a77a241890b994b2fabc95d1ae175f314f70f6ce
3
+ metadata.gz: 076a19622912f88e9f4c0446a5ff1b656de12cad
4
+ data.tar.gz: 62fe25a76158dfacafc3af6b57b34bb76cd1f34c
5
5
  SHA512:
6
- metadata.gz: 85586eecb14aeba081c8706353c393c11d7b3592b1ef3d3f3a5a90bcd8bce8268adaad14c044c35cab95a2da1c94eb6ebdadfb899ffcb2d982a7e287ef635e80
7
- data.tar.gz: db625af1af9e2ba4a3b4f38de4c23d5f1f48276be36b45b89edd0408b6eb7cc69f7f88f699edc96f373baa66ec06a0bc283f23cb9fd36b53fa8832bc67e31d3c
6
+ metadata.gz: 04e9a03179c8c906dda682eaa3db724a83fbf321f9559f0de6dd1797518ddc9be7382a0440e43c93ec440d574c79c23a3c1927e82b4e18d49a82162a26eb749c
7
+ data.tar.gz: a6b749e4f88042449bd4e0ee3b8cfa2fbfd937fe5a2370a6f10f833b818fa4a2305c7e0d811344010685b45d0171fde3e3707cc659c1f7ee7dc306bcd79ed877
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Base64 filter plugin for Embulk
2
2
 
3
- An Embulk filter plugin to encode/decode string by Base64.
3
+ An Embulk filter plugin to encode/decode string by Base64, Base32 and Base16.
4
4
 
5
5
  ## Overview
6
6
 
@@ -8,23 +8,21 @@ An Embulk filter plugin to encode/decode string by Base64.
8
8
 
9
9
  ## Configuration
10
10
 
11
- * columns: Input columns to encode/decode (array of hash, required)
11
+ * **columns**: Input columns to encode/decode (array of hash, required)
12
12
  - **name**
13
13
  + name of input column (string, required)
14
14
  - **decode**, **encode**
15
15
  + whether to encode or decode the value (boolean, default: `false`)
16
- + either one must be `true` and exception is thrown if both are `true` or both are `false`
17
-
18
- ## Limitation
19
-
20
- * Java8 environment is needed because this plugin uses [java.util.Base64](https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html) of Java8
21
- * Type of input value to be encoded must be string.
22
- - encoded value is string and is is needed to align the type of input and output value
23
- + e.g. 1234(string) is encoded into MTIzNA==(string)
24
- * Type of output decoded value is also string
25
- - this plugin does nothing like type casting
26
- + e.g. MTIzNA==(string) is decoded into 1234(string)
27
- - if you want type casting, use [embulk-filter-typecast](https://github.com/sonots/embulk-filter-typecast)
16
+ + either one must be `true` and exception is thrown when both are `true` or both are `false`
17
+ - **encording**
18
+ + encording type (string, default: 'Base64')
19
+ + must be one of the follwing, Base64, Base32, Base16
20
+ - **urlsafe**
21
+ + whether to use urlsafe character in encoded string
22
+ + works only when `encording: Base64`
23
+ - **hex**
24
+ + whether to maintain sort order of encoded string
25
+ + works only when `encording: Base32`
28
26
 
29
27
  ## Example
30
28
 
@@ -32,79 +30,53 @@ An Embulk filter plugin to encode/decode string by Base64.
32
30
 
33
31
  See [example_encode.yml](./example/example_encode.yml) and [example_encode.csv](./example/example_encode.csv).
34
32
 
33
+ input:
34
+
35
+ ```csv
36
+ 100,A0?B1>,A0?B1>,A0?B1>,A0?B1>,A0?B1>
37
+ 101,ab?cd~,ab?cd~,ab?cd~,ab?cd~,ab?cd~
38
+ ```
39
+
40
+ output:
41
+
35
42
  ```bash
36
- $ embulk preview -G example/example_encode.yml
37
- *************************** 1 ***************************
38
- id ( long) : 10
39
- string to encode (string) : Sm9obg==
40
- long to encode (string) : MTIzNDU2
41
- double to encode (string) : MzYuMjg=
42
- boolean to encode (string) : dHJ1ZQ==
43
- timestamp to encode (string) : MjAxNi0xMi0zMSAyMzo1OTo1OQ==
44
- json to encode (string) : eyJhZ2UiOiAyM30=
45
- *************************** 2 ***************************
46
- id ( long) : 11
47
- string to encode (string) : RGF2aWQ=
48
- long to encode (string) : MjM0NTY3
49
- double to encode (string) : MTI1LjE=
50
- boolean to encode (string) : ZmFsc2U=
51
- timestamp to encode (string) : MjAxNy0wMS0wMSAwMDowMDowMA==
52
- json to encode (string) : eyJhZ2UiOiAzNH0=
43
+ $ embulk preview example/example_encode.yml
44
+ +---------+---------------+------------------+------------------+------------------+---------------+
45
+ | id:long | Base64:string | Base64Url:string | Base32:string | Base32Hex:string | Base16:string |
46
+ +---------+---------------+------------------+------------------+------------------+---------------+
47
+ | 100 | QTA/QjE+ | QTA_QjE- | IEYD6QRRHY====== | 84O3UGHH7O====== | 41303F42313E |
48
+ | 101 | YWI/Y2R+ | YWI_Y2R- | MFRD6Y3EPY====== | C5H3UOR4FO====== | 61623F63647E |
49
+ +---------+---------------+------------------+------------------+------------------+---------------+
53
50
  ```
54
51
 
55
52
  ### decode
56
53
 
57
54
  See [example_decode.yml](./example/example_decode.yml) and [example_decode.csv](./example/example_decode.csv).
58
55
 
59
- ```bash
60
- $ embulk preview -G example/example_decode.yml
61
- *************************** 1 ***************************
62
- id ( long) : 10
63
- string to decode (string) : John
64
- long to decode (string) : 123456
65
- double to decode (string) : 36.28
66
- boolean to decode (string) : true
67
- timestamp to decode (string) : 2016-12-31 23:59:59
68
- json to decode (string) : {"age": 23}
69
- *************************** 2 ***************************
70
- id ( long) : 11
71
- string to decode (string) : David
72
- long to decode (string) : 234567
73
- double to decode (string) : 125.01
74
- boolean to decode (string) : false
75
- timestamp to decode (string) : 2017-01-01 00:00:00
76
- json to decode (string) : {"age": 34}
77
- ```
56
+ input:
78
57
 
79
- ### decode and cast type
58
+ ```csv
59
+ 100,QTA/QjE+,QTA_QjE-,IEYD6QRRHY======,84O3UGHH7O======,41303F42313E
60
+ 101,YWI/Y2R+,YWI_Y2R-,MFRD6Y3EPY======,C5H3UOR4FO======,61623F63647E
61
+ ```
80
62
 
81
- See [example_decode_with_typecast.yml](./example/example_decode_with_typecast.yml) and [example_decode.csv](./example/example_decode.csv).
63
+ output:
82
64
 
83
65
  ```bash
84
- $ embulk preview -G example/example_decode_with_typecast.yml
85
- *************************** 1 ***************************
86
- id ( long) : 10
87
- string to decode ( string) : John
88
- long to decode ( long) : 123,456
89
- double to decode ( double) : 36.28
90
- boolean to decode ( boolean) : true
91
- timestamp to decode (timestamp) : 2016-12-31 23:59:00.590 UTC
92
- json to decode ( json) : {"age":23}
93
- *************************** 2 ***************************
94
- id ( long) : 11
95
- string to decode ( string) : David
96
- long to decode ( long) : 234,567
97
- double to decode ( double) : 125.01
98
- boolean to decode ( boolean) : false
99
- timestamp to decode (timestamp) : 2017-01-01 00:00:00 UTC
100
- json to decode ( json) : {"age":34}
66
+ $ embulk preview example/example_decode.yml
67
+ +---------+---------------+------------------+---------------+------------------+---------------+
68
+ | id:long | Base64:string | Base64Url:string | Base32:string | Base32Hex:string | Base16:string |
69
+ +---------+---------------+------------------+---------------+------------------+---------------+
70
+ | 100 | A0?B1> | A0?B1> | A0?B1> | A0?B1> | A0?B1> |
71
+ | 101 | ab?cd~ | ab?cd~ | ab?cd~ | ab?cd~ | ab?cd~ |
72
+ +---------+---------------+------------------+---------------+------------------+---------------+
101
73
  ```
102
74
 
75
+ ## Limitation
103
76
 
104
- ### Todo
105
-
106
- * [Support base64 in apache commons codec](https://github.com/ysk24ok/embulk-filter-base64/issues/1)
107
- * [Support encoder/decoder of URL and MIME](https://github.com/ysk24ok/embulk-filter-base64/issues/2)
77
+ * Type of input value to be encoded must be string.
78
+ * Type of decoded output value will be string
79
+ - if you want type casting, use [embulk-filter-typecast](https://github.com/sonots/embulk-filter-typecast)
108
80
 
109
81
  ## Build
110
82
 
@@ -13,7 +13,7 @@ configurations {
13
13
  provided
14
14
  }
15
15
 
16
- version = "0.1.1"
16
+ version = "0.2.0"
17
17
 
18
18
  sourceCompatibility = 1.7
19
19
  targetCompatibility = 1.7
@@ -23,6 +23,7 @@ dependencies {
23
23
  provided "org.embulk:embulk-core:0.8.15"
24
24
  // compile "YOUR_JAR_DEPENDENCY_GROUP:YOUR_JAR_DEPENDENCY_MODULE:YOUR_JAR_DEPENDENCY_VERSION"
25
25
  testCompile "junit:junit:4.+"
26
+ testCompile "org.hamcrest:hamcrest-library:1.+"
26
27
  testCompile "org.embulk:embulk-core:0.8.15:tests"
27
28
  }
28
29
 
@@ -76,7 +77,7 @@ Gem::Specification.new do |spec|
76
77
  spec.version = "${project.version}"
77
78
  spec.authors = ["Yusuke NISHIOKA"]
78
79
  spec.summary = %[Base64 filter plugin for Embulk]
79
- spec.description = %[An Embulk filter plugin to encode/decode string by Base64.]
80
+ spec.description = %[An Embulk filter plugin to encode/decode string by Base64, Base32 and Base16.]
80
81
  spec.email = ["yusuke.nishioka.0713@gmail.com"]
81
82
  spec.licenses = ["MIT"]
82
83
  spec.homepage = "https://github.com/ysk24ok/embulk-filter-base64"
@@ -1,2 +1,2 @@
1
- 10,Sm9obg==,MTIzNDU2,MzYuMjg=,dHJ1ZQ==,MjAxNi0xMi0zMSAyMzo1OTo1OQ==,eyJhZ2UiOiAyM30=
2
- 11,RGF2aWQ=,MjM0NTY3,MTI1LjAx,ZmFsc2U=,MjAxNy0wMS0wMSAwMDowMDowMA==,eyJhZ2UiOiAzNH0=
1
+ 100,QTA/QjE+,QTA_QjE-,IEYD6QRRHY======,84O3UGHH7O======,41303F42313E
2
+ 101,YWI/Y2R+,YWI_Y2R-,MFRD6Y3EPY======,C5H3UOR4FO======,61623F63647E
@@ -4,21 +4,19 @@ in:
4
4
  parser:
5
5
  type: csv
6
6
  columns:
7
- - {name: id, type: long}
8
- - {name: string to decode, type: string}
9
- - {name: long to decode, type: string}
10
- - {name: double to decode, type: string}
11
- - {name: boolean to decode, type: string}
12
- - {name: timestamp to decode, type: string}
13
- - {name: json to decode, type: string}
7
+ - {name: id, type: long}
8
+ - {name: Base64, type: string}
9
+ - {name: Base64Url, type: string}
10
+ - {name: Base32, type: string}
11
+ - {name: Base32Hex, type: string}
12
+ - {name: Base16, type: string}
14
13
  filters:
15
14
  - type: base64
16
15
  columns:
17
- - {name: string to decode, decode: true}
18
- - {name: long to decode, decode: true}
19
- - {name: double to decode, decode: true}
20
- - {name: boolean to decode, decode: true}
21
- - {name: timestamp to decode, decode: true}
22
- - {name: json to decode, decode: true}
16
+ - {name: Base64, decode: true}
17
+ - {name: Base64Url, decode: true, urlsafe: true}
18
+ - {name: Base32, decode: true, encoding: Base32}
19
+ - {name: Base32Hex, decode: true, encoding: Base32, hex: true}
20
+ - {name: Base16, decode: true, encoding: Base16}
23
21
  out:
24
22
  type: stdout
@@ -1,2 +1,2 @@
1
- 10,John,123456,36.28,true,2016-12-31 23:59:59,{"age": 23}
2
- 11,David,234567,125.1,false,2017-01-01 00:00:00,{"age": 34}
1
+ 100,A0?B1>,A0?B1>,A0?B1>,A0?B1>,A0?B1>
2
+ 101,ab?cd~,ab?cd~,ab?cd~,ab?cd~,ab?cd~
@@ -4,21 +4,19 @@ in:
4
4
  parser:
5
5
  type: csv
6
6
  columns:
7
- - {name: id, type: long}
8
- - {name: string to encode, type: string}
9
- - {name: long to encode, type: string}
10
- - {name: double to encode, type: string}
11
- - {name: boolean to encode, type: string}
12
- - {name: timestamp to encode, type: string}
13
- - {name: json to encode, type: string}
7
+ - {name: id, type: long}
8
+ - {name: Base64, type: string}
9
+ - {name: Base64Url, type: string}
10
+ - {name: Base32, type: string}
11
+ - {name: Base32Hex, type: string}
12
+ - {name: Base16, type: string}
14
13
  filters:
15
14
  - type: base64
16
15
  columns:
17
- - {name: string to encode, encode: true}
18
- - {name: long to encode, encode: true}
19
- - {name: double to encode, encode: true}
20
- - {name: boolean to encode, encode: true}
21
- - {name: timestamp to encode, encode: true}
22
- - {name: json to encode, encode: true}
16
+ - {name: Base64, encode: true}
17
+ - {name: Base64Url, encode: true, urlsafe: true}
18
+ - {name: Base32, encode: true, encoding: Base32}
19
+ - {name: Base32Hex, encode: true, encoding: Base32, hex: true}
20
+ - {name: Base16, encode: true, encoding: Base16}
23
21
  out:
24
22
  type: stdout
@@ -0,0 +1,100 @@
1
+ package org.embulk.filter.base64;
2
+
3
+ import com.google.common.io.BaseEncoding;
4
+
5
+ import org.embulk.filter.base64.Base64FilterPlugin.ColumnTask;
6
+ import org.embulk.filter.base64.Base64FilterPlugin.PluginTask;
7
+ import org.embulk.spi.Column;
8
+
9
+ import java.util.HashMap;
10
+ import java.util.List;
11
+ import java.util.Map;
12
+ import java.util.Objects;
13
+
14
+ public class Base64Filter
15
+ {
16
+ private PluginTask task;
17
+ private final Map<String, ColumnTask> columnTaskMap;
18
+
19
+ Base64Filter(PluginTask task)
20
+ {
21
+ this.task = task;
22
+ this.columnTaskMap = getColumnTaskMap(task.getColumns());
23
+ }
24
+
25
+ private Map<String, ColumnTask> getColumnTaskMap(
26
+ List<ColumnTask> columnTasks)
27
+ {
28
+ Map<String, ColumnTask> m = new HashMap<>();
29
+ for (ColumnTask columnTask : columnTasks) {
30
+ m.put(columnTask.getName(), columnTask);
31
+ }
32
+ return m;
33
+ }
34
+
35
+ private ColumnTask getTask(Column column)
36
+ {
37
+ String colName = column.getName();
38
+ return columnTaskMap.get(colName);
39
+ }
40
+
41
+ public String doFilter(Column column, String inputValue)
42
+ {
43
+ ColumnTask colTask = getTask(column);
44
+ if (colTask == null) {
45
+ return inputValue;
46
+ }
47
+ String encoding = colTask.getEncoding();
48
+ boolean doEncode = colTask.getDoEncode().get();
49
+ boolean doDecode = colTask.getDoDecode().get();
50
+ // encode
51
+ if (doEncode && ! doDecode) {
52
+ byte[] inputAsBytes = inputValue.getBytes();
53
+ String encoded = null;
54
+ if (Objects.equals(encoding, "Base64")) {
55
+ if (colTask.getDoUrlsafe().get()) {
56
+ encoded = BaseEncoding.base64Url().encode(inputAsBytes);
57
+ }
58
+ else {
59
+ encoded = BaseEncoding.base64().encode(inputAsBytes);
60
+ }
61
+ }
62
+ else if (Objects.equals(encoding, "Base32")) {
63
+ if (colTask.getUseHex().get()) {
64
+ encoded = BaseEncoding.base32Hex().encode(inputAsBytes);
65
+ }
66
+ else {
67
+ encoded = BaseEncoding.base32().encode(inputAsBytes);
68
+ }
69
+ }
70
+ else if (Objects.equals(encoding, "Base16")) {
71
+ encoded = BaseEncoding.base16().encode(inputAsBytes);
72
+ }
73
+ return encoded;
74
+ }
75
+ // decode
76
+ else {
77
+ byte[] decodedAsBytes = null;
78
+ if (Objects.equals(encoding, "Base64")) {
79
+ if (colTask.getDoUrlsafe().get()) {
80
+ decodedAsBytes = BaseEncoding.base64Url().decode(inputValue);
81
+ }
82
+ else {
83
+ decodedAsBytes = BaseEncoding.base64().decode(inputValue);
84
+ }
85
+ }
86
+ else if (Objects.equals(encoding, "Base32")) {
87
+ if (colTask.getUseHex().get()) {
88
+ decodedAsBytes = BaseEncoding.base32Hex().decode(inputValue);
89
+ }
90
+ else {
91
+ decodedAsBytes = BaseEncoding.base32().decode(inputValue);
92
+ }
93
+ }
94
+ else if (Objects.equals(encoding, "Base16")) {
95
+ decodedAsBytes = BaseEncoding.base16().decode(inputValue);
96
+ }
97
+ return new String(decodedAsBytes);
98
+ }
99
+ }
100
+ }
@@ -1,29 +1,27 @@
1
1
  package org.embulk.filter.base64;
2
2
 
3
- import java.util.List;
4
- import java.util.Map;
5
- import java.util.HashMap;
6
- import java.util.Base64;
7
-
8
3
  import com.google.common.base.Optional;
4
+
9
5
  import org.embulk.config.Config;
10
6
  import org.embulk.config.ConfigDefault;
7
+ import org.embulk.config.ConfigException;
11
8
  import org.embulk.config.ConfigSource;
12
9
  import org.embulk.config.Task;
13
10
  import org.embulk.config.TaskSource;
14
11
  import org.embulk.spi.Column;
15
- import org.embulk.spi.ColumnVisitor;
16
- import org.embulk.spi.DataException;
17
12
  import org.embulk.spi.Exec;
18
13
  import org.embulk.spi.FilterPlugin;
19
14
  import org.embulk.spi.Page;
20
15
  import org.embulk.spi.PageBuilder;
21
- import org.embulk.spi.PageReader;
22
16
  import org.embulk.spi.PageOutput;
17
+ import org.embulk.spi.PageReader;
23
18
  import org.embulk.spi.Schema;
24
19
  import org.embulk.spi.type.Type;
25
20
  import org.embulk.spi.type.Types;
26
21
 
22
+ import java.util.Arrays;
23
+ import java.util.List;
24
+
27
25
  public class Base64FilterPlugin
28
26
  implements FilterPlugin
29
27
  {
@@ -31,17 +29,15 @@ public class Base64FilterPlugin
31
29
  extends Task
32
30
  {
33
31
  @Config("columns")
34
- public List<Base64ColumnTask> getColumns();
32
+ public List<ColumnTask> getColumns();
35
33
  }
36
34
 
37
- public interface Base64ColumnTask
35
+ public interface ColumnTask
38
36
  extends Task
39
37
  {
40
38
  @Config("name")
41
39
  public String getName();
42
40
 
43
- // TODO: getType
44
-
45
41
  @Config("encode")
46
42
  @ConfigDefault("false")
47
43
  public Optional<Boolean> getDoEncode();
@@ -49,27 +45,46 @@ public class Base64FilterPlugin
49
45
  @Config("decode")
50
46
  @ConfigDefault("false")
51
47
  public Optional<Boolean> getDoDecode();
48
+
49
+ @Config("encoding")
50
+ @ConfigDefault("\"Base64\"")
51
+ public String getEncoding();
52
+
53
+ @Config("urlsafe")
54
+ @ConfigDefault("false")
55
+ public Optional<Boolean> getDoUrlsafe();
56
+
57
+ @Config("hex")
58
+ @ConfigDefault("false")
59
+ public Optional<Boolean> getUseHex();
52
60
  }
53
61
 
54
62
  public void validate(PluginTask pluginTask, Schema inputSchema)
55
63
  {
56
- for (Base64ColumnTask task : pluginTask.getColumns()) {
57
- // throws exception if the column name does not exist
58
- inputSchema.lookupColumn(task.getName());
64
+ for (ColumnTask task : pluginTask.getColumns()) {
65
+ // throws exception when the column does not exist
66
+ Column column = inputSchema.lookupColumn(task.getName());
67
+ // check 'encode: true' or 'decode: true' in ColumnTask
59
68
  boolean doEncode = task.getDoEncode().get();
60
69
  boolean doDecode = task.getDoDecode().get();
61
70
  boolean bothTrue = doEncode && doDecode;
62
71
  boolean bothFalse = !doEncode && !doDecode;
63
72
  if (bothTrue || bothFalse) {
64
73
  String errMsg = "Specify either 'encode: true' or 'decode: true'";
65
- throw new DataException(errMsg);
74
+ throw new ConfigException(errMsg);
66
75
  }
67
- }
68
- for (Column column : inputSchema.getColumns()) {
76
+ // check 'encoding' option in ColumnTask
77
+ String[] allowedEncordings = {"Base16", "Base32", "Base64"};
78
+ String encoding = task.getEncoding();
79
+ if (!Arrays.asList(allowedEncordings).contains(encoding)) {
80
+ String errMsg = "Encording must be one of the following: Base16, Base32, Base64";
81
+ throw new ConfigException(errMsg);
82
+ }
83
+ // check type of input cloumn
69
84
  Type colType = column.getType();
70
85
  if (!Types.STRING.equals(colType)) {
71
86
  String errMsg = "Type of input columns must be string";
72
- throw new DataException(errMsg);
87
+ throw new ConfigException(errMsg);
73
88
  }
74
89
  }
75
90
  }
@@ -92,8 +107,9 @@ public class Base64FilterPlugin
92
107
  PageBuilder pageBuilder = new PageBuilder(
93
108
  Exec.getBufferAllocator(), outputSchema, output);
94
109
  PageReader pageReader = new PageReader(inputSchema);
110
+ Base64Filter filter = new Base64Filter(task);
95
111
  ColumnVisitorImpl visitor = new ColumnVisitorImpl(
96
- task, pageReader, pageBuilder);
112
+ pageReader, pageBuilder, filter);
97
113
 
98
114
  return new PageOutputImpl(
99
115
  pageReader, pageBuilder, outputSchema, visitor);
@@ -1,68 +1,21 @@
1
1
  package org.embulk.filter.base64;
2
2
 
3
- import java.util.List;
4
- import java.util.Map;
5
- import java.util.HashMap;
6
- import java.util.Base64;
7
-
8
- import org.embulk.config.Config;
9
- import org.embulk.config.ConfigDefault;
10
- import org.embulk.config.Task;
11
3
  import org.embulk.spi.Column;
12
4
  import org.embulk.spi.ColumnVisitor;
13
- import org.embulk.spi.DataException;
14
5
  import org.embulk.spi.PageBuilder;
15
6
  import org.embulk.spi.PageReader;
16
- import org.embulk.spi.Schema;
17
-
18
- import org.embulk.filter.base64.Base64FilterPlugin.Base64ColumnTask;
19
- import org.embulk.filter.base64.Base64FilterPlugin.PluginTask;
20
7
 
21
- public class ColumnVisitorImpl
22
- implements ColumnVisitor
8
+ public class ColumnVisitorImpl implements ColumnVisitor
23
9
  {
24
10
  private final PageReader pageReader;
25
11
  private final PageBuilder pageBuilder;
26
- private final Map<String, Base64ColumnTask> base64ColumnMap;
12
+ private final Base64Filter filter;
27
13
 
28
- ColumnVisitorImpl(PluginTask task, PageReader reader, PageBuilder builder)
14
+ ColumnVisitorImpl(PageReader reader, PageBuilder builder, Base64Filter filter)
29
15
  {
30
16
  this.pageReader = reader;
31
17
  this.pageBuilder = builder;
32
- this.base64ColumnMap = getBase64ColumnMap(task.getColumns());
33
- }
34
-
35
- private static Map<String, Base64ColumnTask> getBase64ColumnMap(
36
- List<Base64ColumnTask> columnTasks)
37
- {
38
- Map<String, Base64ColumnTask> m = new HashMap<>();
39
- for (Base64ColumnTask columnTask : columnTasks) {
40
- m.put(columnTask.getName(), columnTask);
41
- }
42
- return m;
43
- }
44
-
45
- private Base64ColumnTask getTask(Column column)
46
- {
47
- String colName = column.getName();
48
- return base64ColumnMap.get(colName);
49
- }
50
-
51
- private String executeTask(Base64ColumnTask task, Column column)
52
- {
53
- boolean doEncode = task.getDoEncode().get();
54
- boolean doDecode = task.getDoDecode().get();
55
- // encode
56
- if (doEncode) {
57
- String raw = pageReader.getString(column);
58
- return Base64.getEncoder().encodeToString(raw.getBytes());
59
- }
60
- // decode
61
- //else if (doDecode) {
62
- else {
63
- String encoded = pageReader.getString(column);
64
- return new String(Base64.getDecoder().decode(encoded));
65
- }
18
+ this.filter = filter;
66
19
  }
67
20
 
68
21
  @Override
@@ -108,17 +61,9 @@ public class ColumnVisitorImpl
108
61
  pageBuilder.setNull(outputColumn);
109
62
  }
110
63
  else {
111
- Base64ColumnTask task = getTask(outputColumn);
112
- // when there is no task executed on this column
113
- if (task == null) {
114
- pageBuilder.setString(
115
- outputColumn, pageReader.getString(outputColumn));
116
- // when there is a task
117
- }
118
- else {
119
- String str = executeTask(task, outputColumn);
120
- pageBuilder.setString(outputColumn, str);
121
- }
64
+ String outputValue = filter.doFilter(
65
+ outputColumn, pageReader.getString(outputColumn));
66
+ pageBuilder.setString(outputColumn, outputValue);
122
67
  }
123
68
  }
124
69
 
@@ -1,14 +1,14 @@
1
1
  package org.embulk.filter.base64;
2
2
 
3
3
  import org.embulk.EmbulkTestRuntime;
4
+ import org.embulk.config.ConfigException;
4
5
  import org.embulk.config.ConfigLoader;
5
6
  import org.embulk.config.ConfigSource;
6
- import org.embulk.spi.DataException;
7
+ import org.embulk.filter.base64.Base64FilterPlugin.PluginTask;
7
8
  import org.embulk.spi.Exec;
8
9
  import org.embulk.spi.Schema;
9
10
  import org.embulk.spi.SchemaConfigException;
10
11
  import org.embulk.spi.type.Types;
11
- import org.embulk.filter.base64.Base64FilterPlugin.PluginTask;
12
12
 
13
13
  import org.junit.Rule;
14
14
  import org.junit.Test;
@@ -39,8 +39,8 @@ public class TestBase64FilterPlugin
39
39
  PluginTask task = taskFromYamlString(
40
40
  "type: base64",
41
41
  "columns:",
42
- " - {name: to encode, type: string, encode: true}",
43
- " - {name: to decode, type: string, decode: true}"
42
+ " - {name: to encode, encode: true}",
43
+ " - {name: to decode, decode: true}"
44
44
  );
45
45
  Schema inputSchema = Schema.builder()
46
46
  .add("to encode", Types.STRING)
@@ -48,13 +48,13 @@ public class TestBase64FilterPlugin
48
48
  plugin.validate(task, inputSchema);
49
49
  }
50
50
 
51
- @Test(expected = DataException.class)
51
+ @Test(expected = ConfigException.class)
52
52
  public void testValidate_bothSpecified()
53
53
  {
54
54
  PluginTask task = taskFromYamlString(
55
55
  "type: base64",
56
56
  "columns:",
57
- " - {name: to encode, type: string, encode: true, decode: true}"
57
+ " - {name: to encode, encode: true, decode: true}"
58
58
  );
59
59
  Schema inputSchema = Schema.builder()
60
60
  .add("to encode", Types.STRING)
@@ -62,13 +62,13 @@ public class TestBase64FilterPlugin
62
62
  plugin.validate(task, inputSchema);
63
63
  }
64
64
 
65
- @Test(expected = DataException.class)
65
+ @Test(expected = ConfigException.class)
66
66
  public void testValidate_bothNotSpecified()
67
67
  {
68
68
  PluginTask task = taskFromYamlString(
69
69
  "type: base64",
70
70
  "columns:",
71
- " - {name: to encode, type: string}"
71
+ " - {name: to encode}"
72
72
  );
73
73
  Schema inputSchema = Schema.builder()
74
74
  .add("to encode", Types.STRING)
@@ -76,13 +76,13 @@ public class TestBase64FilterPlugin
76
76
  plugin.validate(task, inputSchema);
77
77
  }
78
78
 
79
- @Test(expected = DataException.class)
79
+ @Test(expected = ConfigException.class)
80
80
  public void testValidate_invalidInputType()
81
81
  {
82
82
  PluginTask task = taskFromYamlString(
83
83
  "type: base64",
84
84
  "columns:",
85
- " - {name: to encode, type: string, type: double}"
85
+ " - {name: to encode, encode: true}"
86
86
  );
87
87
  Schema inputSchema = Schema.builder()
88
88
  .add("to encode", Types.DOUBLE)
@@ -1,11 +1,8 @@
1
1
  package org.embulk.filter.base64;
2
2
 
3
- import java.util.List;
4
-
5
3
  import org.embulk.EmbulkTestRuntime;
6
- import org.embulk.config.ConfigLoader;
7
- import org.embulk.config.ConfigSource;
8
- import org.embulk.spi.Exec;
4
+ import org.embulk.filter.base64.Base64FilterPlugin.PageOutputImpl;
5
+ import org.embulk.filter.base64.Base64FilterPlugin.PluginTask;
9
6
  import org.embulk.spi.Page;
10
7
  import org.embulk.spi.PageBuilder;
11
8
  import org.embulk.spi.PageOutput;
@@ -15,20 +12,37 @@ import org.embulk.spi.Schema;
15
12
  import org.embulk.spi.TestPageBuilderReader.MockPageOutput;
16
13
  import org.embulk.spi.type.Types;
17
14
  import org.embulk.spi.util.Pages;
18
- import org.embulk.filter.base64.Base64FilterPlugin.PluginTask;
19
- import org.embulk.filter.base64.Base64FilterPlugin.PageOutputImpl;
20
- import org.embulk.filter.base64.ColumnVisitorImpl;
21
- import static org.embulk.filter.base64.TestBase64FilterPlugin.taskFromYamlString;
22
15
 
16
+ import org.junit.Before;
23
17
  import org.junit.Rule;
24
18
  import org.junit.Test;
25
- import static org.junit.Assert.*;
19
+
20
+ import static org.embulk.filter.base64.TestBase64FilterPlugin.taskFromYamlString;
21
+ import static org.junit.Assert.assertEquals;
22
+
23
+ import java.util.List;
26
24
 
27
25
  public class TestColumnVisitorImpl
28
26
  {
29
27
  @Rule
30
28
  public EmbulkTestRuntime runtime = new EmbulkTestRuntime();
31
29
 
30
+ private Schema inputSchemaToEncode;
31
+ private Schema inputSchemaToDecode;
32
+
33
+ @Before
34
+ public void createResource()
35
+ {
36
+ inputSchemaToEncode = Schema.builder()
37
+ .add("id", Types.LONG)
38
+ .add("to encode", Types.STRING)
39
+ .build();
40
+ inputSchemaToDecode = Schema.builder()
41
+ .add("id", Types.LONG)
42
+ .add("to decode", Types.STRING)
43
+ .build();
44
+ }
45
+
32
46
  private List<Object[]> filter(PluginTask task, Schema inputSchema, Object... objects)
33
47
  {
34
48
  MockPageOutput output = new MockPageOutput();
@@ -36,8 +50,9 @@ public class TestColumnVisitorImpl
36
50
  PageBuilder pageBuilder = new PageBuilder(
37
51
  runtime.getBufferAllocator(), outputSchema, output);
38
52
  PageReader pageReader = new PageReader(inputSchema);
53
+ Base64Filter filter = new Base64Filter(task);
39
54
  ColumnVisitorImpl visitor = new ColumnVisitorImpl(
40
- task, pageReader, pageBuilder);
55
+ pageReader, pageBuilder, filter);
41
56
 
42
57
  List<Page> pages = PageTestUtils.buildPage(
43
58
  runtime.getBufferAllocator(), inputSchema, objects);
@@ -52,42 +67,270 @@ public class TestColumnVisitorImpl
52
67
  }
53
68
 
54
69
  @Test
55
- public void testExecuteTask_encode()
70
+ public void testExecuteTask_encodeByBase64()
56
71
  {
72
+ // implicit
57
73
  PluginTask task = taskFromYamlString(
58
74
  "type: base64",
59
75
  "columns:",
60
- " - {name: to encode, type: string, encode: true}"
76
+ " - {name: id}",
77
+ " - {name: to encode, encode: true}"
61
78
  );
62
- Schema inputSchema = Schema.builder()
63
- .add("to encode", Types.STRING)
64
- .build();
65
- List<Object[]> records = filter(task, inputSchema,
66
- "John",
67
- "David"
79
+ List<Object[]> records = filter(task, inputSchemaToEncode,
80
+ Long.valueOf(100), "A0?B1>",
81
+ Long.valueOf(101), "ab?cd~"
68
82
  );
69
83
  assertEquals(2, records.size());
70
- assertEquals("Sm9obg==", records.get(0)[0]);
71
- assertEquals("RGF2aWQ=", records.get(1)[0]);
84
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
85
+ assertEquals("QTA/QjE+", records.get(0)[1]);
86
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
87
+ assertEquals("YWI/Y2R+", records.get(1)[1]);
88
+ // explicit
89
+ task = taskFromYamlString(
90
+ "type: base64",
91
+ "columns:",
92
+ " - {name: id}",
93
+ " - {name: to encode, encode: true, encoding: Base64}"
94
+ );
95
+ records = filter(task, inputSchemaToEncode,
96
+ Long.valueOf(100), "A0?B1>",
97
+ Long.valueOf(101), "ab?cd~"
98
+ );
99
+ assertEquals(2, records.size());
100
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
101
+ assertEquals("QTA/QjE+", records.get(0)[1]);
102
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
103
+ assertEquals("YWI/Y2R+", records.get(1)[1]);
72
104
  }
73
105
 
74
106
  @Test
75
- public void testExecuteTask_decode()
107
+ public void testExecuteTask_encodeByBase64Url()
76
108
  {
109
+ // implicit
77
110
  PluginTask task = taskFromYamlString(
78
111
  "type: base64",
79
112
  "columns:",
80
- " - {name: to decode, type: string, decode: true}"
113
+ " - {name: id}",
114
+ " - {name: to encode, encode: true, urlsafe: true}"
81
115
  );
82
- Schema inputSchema = Schema.builder()
83
- .add("to decode", Types.STRING)
84
- .build();
85
- List<Object[]> records = filter(task, inputSchema,
86
- "Sm9obg==",
87
- "RGF2aWQ="
116
+ List<Object[]> records = filter(task, inputSchemaToEncode,
117
+ Long.valueOf(100), "A0?B1>",
118
+ Long.valueOf(101), "ab?cd~"
119
+ );
120
+ assertEquals(2, records.size());
121
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
122
+ assertEquals("QTA_QjE-", records.get(0)[1]);
123
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
124
+ assertEquals("YWI_Y2R-", records.get(1)[1]);
125
+ // explicit
126
+ task = taskFromYamlString(
127
+ "type: base64",
128
+ "columns:",
129
+ " - {name: id}",
130
+ " - {name: to encode, encode: true, encoding: Base64, urlsafe: true}"
131
+ );
132
+ records = filter(task, inputSchemaToEncode,
133
+ Long.valueOf(100), "A0?B1>",
134
+ Long.valueOf(101), "ab?cd~"
135
+ );
136
+ assertEquals(2, records.size());
137
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
138
+ assertEquals("QTA_QjE-", records.get(0)[1]);
139
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
140
+ assertEquals("YWI_Y2R-", records.get(1)[1]);
141
+ }
142
+
143
+ @Test
144
+ public void testExecuteTask_encodeByBase32()
145
+ {
146
+ PluginTask task = taskFromYamlString(
147
+ "type: base64",
148
+ "columns:",
149
+ " - {name: id}",
150
+ " - {name: to encode, encode: true, encoding: Base32}"
151
+ );
152
+ List<Object[]> records = filter(task, inputSchemaToEncode,
153
+ Long.valueOf(100), "A0?B1>",
154
+ Long.valueOf(101), "ab?cd~"
155
+ );
156
+ assertEquals(2, records.size());
157
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
158
+ assertEquals("IEYD6QRRHY======", records.get(0)[1]);
159
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
160
+ assertEquals("MFRD6Y3EPY======", records.get(1)[1]);
161
+ }
162
+
163
+ @Test
164
+ public void testExecuteTask_encodeByBase32Hex()
165
+ {
166
+ PluginTask task = taskFromYamlString(
167
+ "type: base64",
168
+ "columns:",
169
+ " - {name: id}",
170
+ " - {name: to encode, encode: true, encoding: Base32, hex: true}"
171
+ );
172
+ List<Object[]> records = filter(task, inputSchemaToEncode,
173
+ Long.valueOf(100), "A0?B1>",
174
+ Long.valueOf(101), "ab?cd~"
175
+ );
176
+ assertEquals(2, records.size());
177
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
178
+ assertEquals("84O3UGHH7O======", records.get(0)[1]);
179
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
180
+ assertEquals("C5H3UOR4FO======", records.get(1)[1]);
181
+ }
182
+
183
+ @Test
184
+ public void testExecuteTask_encodeByBase16()
185
+ {
186
+ PluginTask task = taskFromYamlString(
187
+ "type: base64",
188
+ "columns:",
189
+ " - {name: id}",
190
+ " - {name: to encode, encode: true, encoding: Base16}"
191
+ );
192
+ List<Object[]> records = filter(task, inputSchemaToEncode,
193
+ Long.valueOf(100), "A0?B1>",
194
+ Long.valueOf(101), "ab?cd~"
195
+ );
196
+ assertEquals(2, records.size());
197
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
198
+ assertEquals("41303F42313E", records.get(0)[1]);
199
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
200
+ assertEquals("61623F63647E", records.get(1)[1]);
201
+ }
202
+
203
+ @Test
204
+ public void testExecuteTask_decodeByBase64()
205
+ {
206
+ // implicit
207
+ PluginTask task = taskFromYamlString(
208
+ "type: base64",
209
+ "columns:",
210
+ " - {name: id}",
211
+ " - {name: to decode, decode: true}"
212
+ );
213
+ List<Object[]> records = filter(task, inputSchemaToDecode,
214
+ Long.valueOf(100), "QTA/QjE+",
215
+ Long.valueOf(101), "YWI/Y2R+"
216
+ );
217
+ assertEquals(2, records.size());
218
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
219
+ assertEquals("A0?B1>", records.get(0)[1]);
220
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
221
+ assertEquals("ab?cd~", records.get(1)[1]);
222
+ // explicit
223
+ task = taskFromYamlString(
224
+ "type: base64",
225
+ "columns:",
226
+ " - {name: id}",
227
+ " - {name: to decode, decode: true, encoding: Base64}"
228
+ );
229
+ records = filter(task, inputSchemaToDecode,
230
+ Long.valueOf(100), "QTA/QjE+",
231
+ Long.valueOf(101), "YWI/Y2R+"
232
+ );
233
+ assertEquals(2, records.size());
234
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
235
+ assertEquals("A0?B1>", records.get(0)[1]);
236
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
237
+ assertEquals("ab?cd~", records.get(1)[1]);
238
+ }
239
+
240
+ @Test
241
+ public void testExecuteTask_decodeByBase64Url()
242
+ {
243
+ // implicit
244
+ PluginTask task = taskFromYamlString(
245
+ "type: base64",
246
+ "columns:",
247
+ " - {name: id}",
248
+ " - {name: to decode, decode: true, urlsafe: true}"
249
+ );
250
+ List<Object[]> records = filter(task, inputSchemaToDecode,
251
+ Long.valueOf(100), "QTA_QjE-",
252
+ Long.valueOf(101), "YWI_Y2R-"
253
+ );
254
+ assertEquals(2, records.size());
255
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
256
+ assertEquals("A0?B1>", records.get(0)[1]);
257
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
258
+ assertEquals("ab?cd~", records.get(1)[1]);
259
+ // explicit
260
+ task = taskFromYamlString(
261
+ "type: base64",
262
+ "columns:",
263
+ " - {name: id}",
264
+ " - {name: to decode, decode: true, encoding: Base64, urlsafe: true}"
265
+ );
266
+ records = filter(task, inputSchemaToDecode,
267
+ Long.valueOf(100), "QTA_QjE-",
268
+ Long.valueOf(101), "YWI_Y2R-"
269
+ );
270
+ assertEquals(2, records.size());
271
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
272
+ assertEquals("A0?B1>", records.get(0)[1]);
273
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
274
+ assertEquals("ab?cd~", records.get(1)[1]);
275
+ }
276
+
277
+ @Test
278
+ public void testExecuteTask_decodeByBase32()
279
+ {
280
+ PluginTask task = taskFromYamlString(
281
+ "type: base64",
282
+ "columns:",
283
+ " - {name: id}",
284
+ " - {name: to decode, decode: true, encoding: Base32}"
285
+ );
286
+ List<Object[]> records = filter(task, inputSchemaToDecode,
287
+ Long.valueOf(100), "IEYD6QRRHY======",
288
+ Long.valueOf(101), "MFRD6Y3EPY======"
289
+ );
290
+ assertEquals(2, records.size());
291
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
292
+ assertEquals("A0?B1>", records.get(0)[1]);
293
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
294
+ assertEquals("ab?cd~", records.get(1)[1]);
295
+ }
296
+
297
+ @Test
298
+ public void testExecuteTask_decodeByBase32Hex()
299
+ {
300
+ PluginTask task = taskFromYamlString(
301
+ "type: base64",
302
+ "columns:",
303
+ " - {name: id}",
304
+ " - {name: to decode, decode: true, encoding: Base32, hex: true}"
305
+ );
306
+ List<Object[]> records = filter(task, inputSchemaToDecode,
307
+ Long.valueOf(100), "84O3UGHH7O======",
308
+ Long.valueOf(101), "C5H3UOR4FO======"
309
+ );
310
+ assertEquals(2, records.size());
311
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
312
+ assertEquals("A0?B1>", records.get(0)[1]);
313
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
314
+ assertEquals("ab?cd~", records.get(1)[1]);
315
+ }
316
+
317
+ @Test
318
+ public void testExecuteTask_decodeByBase16()
319
+ {
320
+ PluginTask task = taskFromYamlString(
321
+ "type: base64",
322
+ "columns:",
323
+ " - {name: id}",
324
+ " - {name: to decode, decode: true, encoding: Base16}"
325
+ );
326
+ List<Object[]> records = filter(task, inputSchemaToDecode,
327
+ Long.valueOf(100), "41303F42313E",
328
+ Long.valueOf(101), "61623F63647E"
88
329
  );
89
330
  assertEquals(2, records.size());
90
- assertEquals("John", records.get(0)[0]);
91
- assertEquals("David", records.get(1)[0]);
331
+ assertEquals(Long.valueOf(100), records.get(0)[0]);
332
+ assertEquals("A0?B1>", records.get(0)[1]);
333
+ assertEquals(Long.valueOf(101), records.get(1)[0]);
334
+ assertEquals("ab?cd~", records.get(1)[1]);
92
335
  }
93
336
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-filter-base64
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke NISHIOKA
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-01 00:00:00.000000000 Z
11
+ date: 2017-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
- description: An Embulk filter plugin to encode/decode string by Base64.
41
+ description: An Embulk filter plugin to encode/decode string by Base64, Base32 and Base16.
42
42
  email:
43
43
  - yusuke.nishioka.0713@gmail.com
44
44
  executables: []
@@ -53,7 +53,6 @@ files:
53
53
  - config/checkstyle/default.xml
54
54
  - example/example_decode.csv
55
55
  - example/example_decode.yml
56
- - example/example_decode_with_typecast.yml
57
56
  - example/example_encode.csv
58
57
  - example/example_encode.yml
59
58
  - example/get_string.py
@@ -62,11 +61,12 @@ files:
62
61
  - gradlew
63
62
  - gradlew.bat
64
63
  - lib/embulk/filter/base64.rb
64
+ - src/main/java/org/embulk/filter/base64/Base64Filter.java
65
65
  - src/main/java/org/embulk/filter/base64/Base64FilterPlugin.java
66
66
  - src/main/java/org/embulk/filter/base64/ColumnVisitorImpl.java
67
67
  - src/test/java/org/embulk/filter/base64/TestBase64FilterPlugin.java
68
68
  - src/test/java/org/embulk/filter/base64/TestColumnVisitorImpl.java
69
- - classpath/embulk-filter-base64-0.1.1.jar
69
+ - classpath/embulk-filter-base64-0.2.0.jar
70
70
  homepage: https://github.com/ysk24ok/embulk-filter-base64
71
71
  licenses:
72
72
  - MIT
@@ -1,32 +0,0 @@
1
- in:
2
- type: file
3
- path_prefix: example/example_decode.csv
4
- parser:
5
- type: csv
6
- columns:
7
- - {name: id, type: long}
8
- - {name: string to decode, type: string}
9
- - {name: long to decode, type: string}
10
- - {name: double to decode, type: string}
11
- - {name: boolean to decode, type: string}
12
- - {name: timestamp to decode, type: string}
13
- - {name: json to decode, type: string}
14
- filters:
15
- - type: base64
16
- columns:
17
- - {name: string to decode, decode: true}
18
- - {name: long to decode, decode: true}
19
- - {name: double to decode, decode: true}
20
- - {name: boolean to decode, decode: true}
21
- - {name: timestamp to decode, decode: true}
22
- - {name: json to decode, decode: true}
23
- - type: typecast
24
- columns:
25
- - {name: string to decode, type: string}
26
- - {name: long to decode, type: long}
27
- - {name: double to decode, type: double}
28
- - {name: boolean to decode, type: boolean}
29
- - {name: timestamp to decode, type: timestamp, format: "%Y-%m-%d %H:%M:%N", timezone: "UTC"}
30
- - {name: json to decode, type: json}
31
- out:
32
- type: stdout