package org.javersion.store.jdbc; import static org.javersion.path.PropertyPath.ROOT; import static org.javersion.store.jdbc.ExecutorType.NONE; import static org.javersion.store.sql.QDocumentVersion.documentVersion; import static org.javersion.store.sql.QEntity.entity; import java.sql.Types; import javax.inject.Inject; import javax.sql.DataSource; import org.javersion.store.jdbc.*; import org.javersion.store.jdbc.DocumentStoreOptions.Builder; import org.javersion.store.sql.QDocumentVersion; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.support.TransactionTemplate; import com.google.common.collect.ImmutableMap; import com.querydsl.core.types.dsl.StringPath; import com.querydsl.sql.ColumnMetadata; import com.querydsl.sql.SQLExpressions; import com.querydsl.sql.SQLQueryFactory; import com.querydsl.sql.SQLTemplates; @Configuration @EnableAutoConfiguration @EnableTransactionManagement(proxyTargetClass = true) public class PersistenceTestConfiguration { @Inject PlatformTransactionManager transactionManager; @Value("${querydsl.sqlTemplates}") private Class<? extends SQLTemplates> sqlTemplatesClass; @Bean public SQLTemplates sqlTemplates() { try { return sqlTemplatesClass.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } @Bean public com.querydsl.sql.Configuration configuration(SQLTemplates sqlTemplates) { com.querydsl.sql.Configuration configuration = new com.querydsl.sql.Configuration(sqlTemplates); AbstractVersionStoreJdbc.registerTypes("DOCUMENT_", configuration); AbstractVersionStoreJdbc.registerTypes("ENTITY_", configuration); return configuration; } @Bean public SQLQueryFactory queryFactory(final DataSource dataSource, com.querydsl.sql.Configuration configuration) { return new SQLQueryFactory(configuration, () -> DataSourceUtils.getConnection(dataSource)); } @Bean public Transactions transactions() { return new SpringTransactions(); } @Bean public DocumentStoreOptions<String, String, JDocumentVersion<String>> documentStoreOptions( Transactions transactions, SQLQueryFactory queryFactory ) { return documentOptionsBuilder(transactions).build(queryFactory); } @Bean public DocumentVersionStoreJdbc<String, String, JDocumentVersion<String>> documentStore(DocumentStoreOptions<String, String, JDocumentVersion<String>> documentStoreOptions) { return new DocumentVersionStoreJdbc<>(documentStoreOptions); } @Bean public DocumentVersionStoreJdbc<String, String, JDocumentVersion<String>> mappedDocumentStore(Transactions transactions, SQLQueryFactory queryFactory) { return new DocumentVersionStoreJdbc<>( documentOptionsBuilder(transactions) .versionTableProperties(ImmutableMap.of( ROOT.property("name"), documentVersion.name, ROOT.property("id"), documentVersion.id)) .transactions(transactions) .queryFactory(queryFactory) .build()); } @Bean public CustomEntityVersionStore entityStore(EntityStoreOptions<String, String, JEntityVersion<String>> entityStoreOptions) { return new CustomEntityVersionStore(entityStoreOptions); } @Bean public EntityStoreOptions<String, String, JEntityVersion<String>> entityStoreOptions( Transactions transactions, SQLQueryFactory queryFactory ) { MyQDocumentVersion version = new MyQDocumentVersion("ENTITY_VERSION", "ENTITY_VERSION"); MyQDocumentVersion since = new MyQDocumentVersion("SINCE", "ENTITY_VERSION"); return new EntityStoreOptions.Builder<String, String, JEntityVersion<String>>() .defaultsFor("ENTITY") .entityTable(new JEntity<>(entity, entity.id)) .versionTable(new JEntityVersion<>(version, version.docId)) .versionTableSince(new JEntityVersion<>(since, since.docId)) .transactions(transactions) .queryFactory(queryFactory) .optimizerType(NONE) .publisherType(NONE) .build(); } @Bean public TransactionTemplate transactionTemplate() { return new TransactionTemplate(transactionManager); } private Builder<String, String, JDocumentVersion<String>> documentOptionsBuilder(Transactions transactions) { QDocumentVersion sinceVersion = new QDocumentVersion("SINCE"); return new Builder<String, String, JDocumentVersion<String>>() .defaultsFor("DOCUMENT") .versionTable(new JDocumentVersion<>(documentVersion, documentVersion.docId)) .versionTableSince(new JDocumentVersion<>(sinceVersion, sinceVersion.docId)) .nextOrdinal(SQLExpressions.nextval("DOCUMENT_VERSION_ORDINAL_SEQ")) .transactions(transactions) .optimizerType(NONE) .publisherType(NONE); } private class MyQDocumentVersion extends QEntityVersionBase<MyQDocumentVersion> { public final StringPath docId = createString("docId"); public final StringPath comment = createString("comment"); public MyQDocumentVersion(String variable, String table) { super(MyQDocumentVersion.class, variable, table, table); addMetadata(docId, ColumnMetadata.named("DOC_ID").ofType(Types.VARCHAR).withSize(255).notNull()); addMetadata(comment, ColumnMetadata.named("COMMENT").ofType(Types.VARCHAR).withSize(255)); } } }