package org.gbif.checklistbank.postgres;
import java.io.IOException;
import java.io.Writer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A writer implementation that consumes a result stream from postgres
* querying using the postgres jdbc copy command.
* This is a very faste and direct way to execute select sql statements from postgres.
*
* Implement addRow to consume a single result row.
*
*/
public abstract class TabMapperBase extends Writer implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(TabMapperBase.class);
private final int ROW_SIZE;
private int idx;
private String[] row;
private String lastPartialString;
public TabMapperBase(int ROW_SIZE) {
this.ROW_SIZE = ROW_SIZE;
this.row = new String[ROW_SIZE];
}
protected abstract void addRow(String[] row);
@Override
public void close() throws IOException {
// nothing to do, override as needed
}
@Override
public void flush() throws IOException {
// nothing to do, override as needed
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
int b = off, t = off + len;
int bufStart = b;
while (b < t) {
char c = cbuf[b];
if (c == '\n' || c == '\t') {
if (lastPartialString != null) {
row[idx] = lastPartialString + new String(cbuf, bufStart, b - bufStart);
lastPartialString = null;
} else {
row[idx] = new String(cbuf, bufStart, b - bufStart);
if (row[idx].equals("\\N") || row[idx].equals("")) {
row[idx] = null;
}
}
bufStart = b + 1;
idx++;
}
if (c == '\n') {
if (idx > 1) {
// ignore empty rows
addRow(this.row);
}
idx = 0;
row = new String[ROW_SIZE];
}
b++;
}
if (bufStart <= t) {
lastPartialString = String.copyValueOf(cbuf, bufStart, b - bufStart);
}
}
}