Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RecordUnmapper construction API #5896

Open
lukaseder opened this issue Feb 20, 2017 · 4 comments
Open

Add RecordUnmapper construction API #5896

lukaseder opened this issue Feb 20, 2017 · 4 comments

Comments

@lukaseder
Copy link
Member

lukaseder commented Feb 20, 2017

This feature extends #2520:

It should be possible to implement an "unmapper" by pairing Field and Function as such:

// R is the target record type, E is the user POJO type
interface RecordUnmapper<E, R extends Record> {
  <T> RecordUnmapper<E, R> add(Field<T> field, Function<E, T> function);
}

This can then be used as such:

unMapper
    .add(field("COL1"), e -> e.getCol1().value)
    .add(field("COL2"), PojoClass::getCol2);

See also:
https://groups.google.com/d/msg/jooq-user/7hfDlmEwfQI/Z_F86FM0CAAJ

@steinard
Copy link

I am very interested in this functionality.

@thomasgillet
Copy link

I would be interested too. I use my own TwoWayFieldMapper, which is both a RecorMapper and RecordUnmapper. Could help if the unmapping part was natively supported by jOOQ.

Here a simplified version:

public interface TwoWayMapper<R extends Record, E> extends RecordMapper<R, E> {
	public R unmap(E e);
}

public class TwoWayFieldMapper<R extends Record, E> implements TwoWayMapper<R, E> {
	
	private final Supplier<R> rFactory;
	private final Supplier<E> eFactory;
	private BiConsumer<R, E> r2e = null;
	private BiConsumer<E, R> e2r = null;
	
	public TwoWayFieldMapper(Supplier<R> rFactory, Supplier<E> eFactory) {
		this.rFactory = rFactory;
		this.eFactory = eFactory;
	}

	public <T> TwoWayFieldMapper<R, E> add(Field<T> field, Function<E, T> getter, BiConsumer<E, T> setter) {
		return add(
			(r, e) -> setter.accept(e, r.get(field)),
			(e, r) -> r.set(field, getter.apply(e))
		);
	}
	
	// Here there is room for various helpers:
	// - converter support (since Converter already works both ways),
	// - "embedded" classes (which already exists to some degree in DefaultRecordMapper),
	// - nested results...
	
	private TwoWayFieldMapper<R, E> add(BiConsumer<R, E> from, BiConsumer<E, R> to) {
		r2e = r2e == null ? from : r2e.andThen(from);
		e2r = e2r == null ? to : e2r.andThen(to);
		return this;
	}
	
	@Override
	public E map(R record) {
		E e = eFactory.get();
		r2e.accept(record, e);
		return e;
	}

	@Override
	public R unmap(E e) {
		R r = rFactory.get();
		e2r.accept(e, r);
		return r;
	}
}

@lukaseder
Copy link
Member Author

Yeah, perhaps that sort of utility will be useful later on. Thanks for sharing.

@lukaseder
Copy link
Member Author

#2520 is now implemented for 3.10. We can now look into implementing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants