Skip to content

Commit 8af6a54

Browse files
perplexhubhchintamreddy
authored andcommitted
Merge pull request #119 from nstdio/gh114
Basic support for queries against Postgres jsonb type.
1 parent 2546ce3 commit 8af6a54

File tree

10 files changed

+448
-38
lines changed

10 files changed

+448
-38
lines changed

rsql-common/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
<artifactId>hamcrest</artifactId>
3838
<scope>test</scope>
3939
</dependency>
40+
<dependency>
41+
<groupId>io.hypersistence</groupId>
42+
<artifactId>hypersistence-utils-hibernate-62</artifactId>
43+
<version>3.5.1</version>
44+
<scope>test</scope>
45+
</dependency>
4046
<dependency>
4147
<groupId>com.h2database</groupId>
4248
<artifactId>h2</artifactId>

rsql-common/src/main/java/io/github/perplexhub/rsql/RSQLVisitorBase.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import javax.persistence.metamodel.ManagedType;
1313
import javax.persistence.metamodel.PluralAttribute;
1414

15+
import lombok.Getter;
16+
import org.springframework.core.convert.ConversionFailedException;
1517
import org.springframework.core.convert.support.ConfigurableConversionService;
18+
import org.springframework.orm.jpa.vendor.Database;
1619
import org.springframework.util.StringUtils;
1720

1821
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
@@ -26,6 +29,7 @@ public abstract class RSQLVisitorBase<R, A> implements RSQLVisitor<R, A> {
2629

2730
protected static volatile @Setter Map<Class, ManagedType> managedTypeMap;
2831
protected static volatile @Setter Map<String, EntityManager> entityManagerMap;
32+
protected static volatile @Setter @Getter Map<EntityManager, Database> entityManagerDatabase = Map.of();
2933
protected static final Map<Class, Class> primitiveToWrapper;
3034
protected static volatile @Setter Map<Class<?>, Map<String, String>> propertyRemapping;
3135
protected static volatile @Setter Map<Class<?>, List<String>> globalPropertyWhitelist;
Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,104 @@
11
package io.github.perplexhub.rsql;
22

3-
import java.util.Map;
4-
5-
import javax.persistence.EntityManager;
3+
import static java.util.stream.Collectors.collectingAndThen;
4+
import static java.util.stream.Collectors.toMap;
65

6+
import io.github.perplexhub.rsql.RSQLJPAAutoConfiguration.HibernateEntityManagerDatabaseConfiguration;
7+
import jakarta.persistence.EntityManager;
8+
import java.util.IdentityHashMap;
9+
import java.util.Map;
10+
import java.util.Map.Entry;
11+
import java.util.Objects;
12+
import java.util.Optional;
13+
import lombok.extern.slf4j.Slf4j;
14+
import org.hibernate.Session;
15+
import org.hibernate.dialect.AbstractHANADialect;
16+
import org.hibernate.dialect.CockroachDialect;
17+
import org.hibernate.dialect.DB2Dialect;
18+
import org.hibernate.dialect.DerbyDialect;
19+
import org.hibernate.dialect.Dialect;
20+
import org.hibernate.dialect.H2Dialect;
21+
import org.hibernate.dialect.HSQLDialect;
22+
import org.hibernate.dialect.MySQLDialect;
23+
import org.hibernate.dialect.OracleDialect;
24+
import org.hibernate.dialect.PostgreSQLDialect;
25+
import org.hibernate.dialect.SQLServerDialect;
26+
import org.hibernate.dialect.SybaseDialect;
27+
import org.hibernate.engine.spi.SessionImplementor;
28+
import org.hibernate.internal.SessionFactoryImpl;
29+
import org.springframework.beans.factory.ObjectProvider;
730
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
831
import org.springframework.context.annotation.Bean;
932
import org.springframework.context.annotation.Configuration;
10-
11-
import lombok.extern.slf4j.Slf4j;
33+
import org.springframework.context.annotation.Import;
34+
import org.springframework.orm.jpa.vendor.Database;
1235

1336
@Slf4j
1437
@Configuration
1538
@ConditionalOnClass(EntityManager.class)
39+
@Import(HibernateEntityManagerDatabaseConfiguration.class)
1640
public class RSQLJPAAutoConfiguration {
1741

18-
@Bean
19-
public RSQLCommonSupport rsqlCommonSupport(Map<String, EntityManager> entityManagerMap) {
20-
log.info("RSQLJPAAutoConfiguration.rsqlCommonSupport(entityManagerMap:{})", entityManagerMap.size());
21-
return new RSQLCommonSupport(entityManagerMap);
22-
}
42+
@Bean
43+
public RSQLCommonSupport rsqlCommonSupport(Map<String, EntityManager> entityManagerMap,
44+
ObjectProvider<EntityManagerDatabase> entityManagerDatabaseProvider) {
45+
log.info("RSQLJPAAutoConfiguration.rsqlCommonSupport(entityManagerMap:{})", entityManagerMap.size());
46+
var entityManagerDatabase = entityManagerDatabaseProvider.getIfAvailable(() -> new EntityManagerDatabase(Map.of()));
47+
48+
return new RSQLJPASupport(entityManagerMap, entityManagerDatabase.value());
49+
}
50+
51+
@Configuration
52+
@ConditionalOnClass(SessionImplementor.class)
53+
static
54+
class HibernateEntityManagerDatabaseConfiguration {
55+
56+
@Bean
57+
public EntityManagerDatabase entityManagerDatabase(ObjectProvider<EntityManager> entityManagers) {
58+
return entityManagers.stream()
59+
.map(entityManager -> {
60+
var sessionFactory = entityManager.unwrap(Session.class).getSessionFactory();
61+
var dialect = ((SessionFactoryImpl) sessionFactory).getJdbcServices().getDialect();
62+
63+
return Optional.ofNullable(toDatabase(dialect))
64+
.map(db -> Map.entry(entityManager, db))
65+
.orElse(null);
66+
})
67+
.filter(Objects::nonNull)
68+
.collect(collectingAndThen(
69+
toMap(Entry::getKey, Entry::getValue, (db1, db2) -> db1, IdentityHashMap::new),
70+
EntityManagerDatabase::new
71+
));
72+
}
73+
74+
private Database toDatabase(Dialect dialect) {
75+
if (dialect instanceof PostgreSQLDialect || dialect instanceof CockroachDialect) {
76+
return Database.POSTGRESQL;
77+
} else if (dialect instanceof MySQLDialect) {
78+
return Database.MYSQL;
79+
} else if (dialect instanceof SQLServerDialect) {
80+
return Database.SQL_SERVER;
81+
} else if (dialect instanceof OracleDialect) {
82+
return Database.ORACLE;
83+
} else if (dialect instanceof DerbyDialect) {
84+
return Database.DERBY;
85+
} else if (dialect instanceof DB2Dialect) {
86+
return Database.DB2;
87+
} else if (dialect instanceof H2Dialect) {
88+
return Database.H2;
89+
} else if (dialect instanceof AbstractHANADialect) {
90+
return Database.HANA;
91+
} else if (dialect instanceof HSQLDialect) {
92+
return Database.HSQL;
93+
} else if (dialect instanceof SybaseDialect) {
94+
return Database.SQL_SERVER;
95+
}
96+
97+
return null;
98+
}
99+
}
100+
101+
record EntityManagerDatabase(Map<EntityManager, Database> value) {
23102

103+
}
24104
}

rsql-jpa/pom.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,23 @@
4141
<artifactId>h2</artifactId>
4242
<scope>test</scope>
4343
</dependency>
44+
<dependency>
45+
<groupId>org.postgresql</groupId>
46+
<artifactId>postgresql</artifactId>
47+
<scope>test</scope>
48+
</dependency>
49+
<dependency>
50+
<groupId>org.testcontainers</groupId>
51+
<artifactId>postgresql</artifactId>
52+
<version>1.19.0</version>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>io.hypersistence</groupId>
57+
<artifactId>hypersistence-utils-hibernate-60</artifactId>
58+
<version>3.5.2</version>
59+
<scope>test</scope>
60+
</dependency>
4461
<dependency>
4562
<groupId>org.projectlombok</groupId>
4663
<artifactId>lombok</artifactId>

0 commit comments

Comments
 (0)