Skip to content

Commit

Permalink
Add support for writing Json object per line
Browse files Browse the repository at this point in the history
  • Loading branch information
dsyer committed Aug 3, 2024
1 parent d82a3a1 commit 41ae65e
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.Writer;
import tech.tablesaw.io.Destination;
import tech.tablesaw.io.WriteOptions;
import tech.tablesaw.io.jsonl.JsonlWriteOptions;

public class JsonWriteOptions extends WriteOptions {

Expand Down
31 changes: 31 additions & 0 deletions json/src/main/java/tech/tablesaw/io/jsonl/JsonlWriteOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package tech.tablesaw.io.jsonl;

import java.io.Writer;
import tech.tablesaw.io.Destination;
import tech.tablesaw.io.WriteOptions;

public class JsonlWriteOptions extends WriteOptions {

private JsonlWriteOptions(Builder builder) {
super(builder);
}

public static Builder builder(Writer writer) {
return new Builder(new Destination(writer));
}

public static Builder builder(Destination destination) {
return new Builder(destination);
}

public static class Builder extends WriteOptions.Builder {

protected Builder(Destination destination) {
super(destination);
}

public JsonlWriteOptions build() {
return new JsonlWriteOptions(this);
}
}
}
67 changes: 67 additions & 0 deletions json/src/main/java/tech/tablesaw/io/jsonl/JsonlWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package tech.tablesaw.io.jsonl;

import java.io.IOException;
import java.io.Writer;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import tech.tablesaw.api.Table;
import tech.tablesaw.io.DataWriter;
import tech.tablesaw.io.Destination;
import tech.tablesaw.io.RuntimeIOException;
import tech.tablesaw.io.WriterRegistry;

public class JsonlWriter implements DataWriter<JsonlWriteOptions> {

private static final JsonlWriter INSTANCE = new JsonlWriter();
private static final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

static {
register(Table.defaultWriterRegistry);
}

public static void register(WriterRegistry registry) {
registry.registerExtension("jsonl", INSTANCE);
registry.registerOptions(JsonlWriteOptions.class, INSTANCE);
}

public void write(Table table, JsonlWriteOptions options) {
try (Writer writer = options.destination().createWriter()) {
for (int r = 0; r < table.rowCount(); r++) {
ObjectNode row = mapper.createObjectNode();
for (int c = 0; c < table.columnCount(); c++) {
row.set(table.column(c).name(), mapper.convertValue(table.get(r, c), JsonNode.class));
}
String str = mapper.writeValueAsString(row);
writer.write(str);
if (r < table.rowCount() - 1) {
writer.write("\n");
}
}
} catch (IOException e) {
throw new RuntimeIOException(e);
}
}

@Override
public void write(Table table, Destination dest) {
write(table, JsonlWriteOptions.builder(dest).build());
}
}
32 changes: 32 additions & 0 deletions json/src/test/java/tech/tablesaw/io/jsonl/JsonlWriterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package tech.tablesaw.io.jsonl;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

import tech.tablesaw.api.Table;

public class JsonlWriterTest {

@Test
public void arrayOfObjects() {
String json = "{\"a\":1453438800000,\"b\":-2.144}\n{\"a\":1454043600000,\"b\":-2.976}\n{\"a\":1454648400000,\"b\":-2.954}";
Table table = Table.read().string(json, "jsonl");
String output = table.write().toString("jsonl");
assertEquals(json, output);
}
}

0 comments on commit 41ae65e

Please sign in to comment.