[jOOQ/jOOQ#4941] Add LoaderListenerStep.onRowStart() for preprocessing input data

This commit is contained in:
Lukas Eder 2020-07-22 16:26:32 +02:00
parent 9e3a1dc5ec
commit 9acb5772b4
4 changed files with 70 additions and 8 deletions

View File

@ -49,6 +49,19 @@ import org.jetbrains.annotations.NotNull;
*/
public interface LoaderContext {
/**
* Override the row that will be processed. Changing it has now effect on
* the {@link LoaderListenerStep#onRowEnd(LoaderRowListener)} event.
*/
@NotNull
LoaderContext row(Object[] row);
/**
* The row that will be or has been processed.
*/
@NotNull
Object[] row();
/**
* A list of errors that might have happened during the load.
*/

View File

@ -37,7 +37,7 @@
*/
package org.jooq;
import org.jetbrains.annotations.*;
import org.jetbrains.annotations.NotNull;
/**
@ -70,8 +70,26 @@ public interface LoaderListenerStep<R extends Record> extends LoaderLoadStep<R>
/**
* Specify a listener that is invoked whenever a row has been processed.
*
* @deprecated - 3.14.0 - [#4941] - Use {@link #onRowEnd(LoaderRowListener)}
* instead.
*/
@Deprecated
@NotNull
@Support
LoaderLoadStep<R> onRow(LoaderRowListener listener);
/**
* Specify a listener that is invoked before a row is processed.
*/
@NotNull
@Support
LoaderLoadStep<R> onRowStart(LoaderRowListener listener);
/**
* Specify a listener that is invoked after a row has been processed.
*/
@NotNull
@Support
LoaderLoadStep<R> onRowEnd(LoaderRowListener listener);
}

View File

@ -47,7 +47,7 @@ package org.jooq;
public interface LoaderRowListener {
/**
* A row has been processed by the {@link Loader}
* A row will be or has been processed by the {@link Loader}.
*/
void row(LoaderContext ctx);
}

View File

@ -178,8 +178,9 @@ final class LoaderImpl<R extends Record> implements
// Result data
// -----------
private LoaderRowListener listener;
private LoaderContext result = new DefaultLoaderContext();
private LoaderRowListener onRowStart;
private LoaderRowListener onRowEnd;
private LoaderContext rowCtx = new DefaultLoaderContext();
private int ignored;
private int processed;
private int stored;
@ -645,7 +646,18 @@ final class LoaderImpl<R extends Record> implements
@Override
public final LoaderImpl<R> onRow(LoaderRowListener l) {
listener = l;
return onRowEnd(l);
}
@Override
public final LoaderImpl<R> onRowStart(LoaderRowListener l) {
onRowStart = l;
return this;
}
@Override
public final LoaderImpl<R> onRowEnd(LoaderRowListener l) {
onRowEnd = l;
return this;
}
@ -817,6 +829,12 @@ final class LoaderImpl<R extends Record> implements
if (fields[i].getType() == byte[].class && row[i] instanceof String)
row[i] = DatatypeConverter.parseBase64Binary((String) row[i]);
rowCtx.row(row);
if (onRowStart != null) {
onRowStart.row(rowCtx);
row = rowCtx.row();
}
// TODO: In batch mode, we can probably optimise this by not creating
// new statements every time, just to convert bind values to their
// appropriate target types. But beware of SQL dialects that tend to
@ -916,8 +934,8 @@ final class LoaderImpl<R extends Record> implements
}
finally {
if (listener != null)
listener.row(result);
if (onRowEnd != null)
onRowEnd.row(rowCtx);
}
// rows:
}
@ -1037,10 +1055,23 @@ final class LoaderImpl<R extends Record> implements
@Override
public final LoaderContext result() {
return result;
return rowCtx;
}
private class DefaultLoaderContext implements LoaderContext {
Object[] row;
@Override
public final LoaderContext row(Object[] r) {
this.row = r;
return this;
}
@Override
public final Object[] row() {
return row;
}
@Override
public final List<LoaderError> errors() {
return errors;