Skip to content

Commit 2ba35a6

Browse files
quaffnamsoo2
authored andcommitted
Align JdbcChatMemoryRepositoryProperties with other modules in Spring Boot
Such as `BatchProperties.Jdbc`, `IntegrationProperties.Jdbc`, `JdbcSessionProperties` and `QuartzProperties.Jdbc` 1. Reuse Spring Boot's `DatabaseInitializationMode` 2. Allow to customize platform 3. add `OnJdbcChatMemoryRepositoryDatasourceInitializationCondition` for `JdbcChatMemoryRepositorySchemaInitializer` Signed-off-by: Yanming Zhou <[email protected]> Signed-off-by: minsoo.nam <[email protected]>
1 parent ed49565 commit 2ba35a6

File tree

6 files changed

+56
-79
lines changed

6 files changed

+56
-79
lines changed

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/model/chat/memory/repository/jdbc/autoconfigure/JdbcChatMemoryRepositoryAutoConfiguration.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,23 @@
1818

1919
import javax.sql.DataSource;
2020

21-
import org.slf4j.Logger;
22-
import org.slf4j.LoggerFactory;
23-
2421
import org.springframework.ai.chat.memory.jdbc.JdbcChatMemoryDialect;
2522
import org.springframework.ai.chat.memory.jdbc.JdbcChatMemoryRepository;
2623
import org.springframework.ai.model.chat.memory.autoconfigure.ChatMemoryAutoConfiguration;
2724
import org.springframework.boot.autoconfigure.AutoConfiguration;
2825
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2926
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3027
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
28+
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
3129
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3230
import org.springframework.context.annotation.Bean;
31+
import org.springframework.context.annotation.Conditional;
3332
import org.springframework.jdbc.core.JdbcTemplate;
3433

3534
/**
3635
* @author Jonathan Leijendekker
3736
* @author Thomas Vitale
37+
* @author Yanming Zhou
3838
* @since 1.0.0
3939
*/
4040
@AutoConfiguration(after = JdbcTemplateAutoConfiguration.class, before = ChatMemoryAutoConfiguration.class)
@@ -51,9 +51,19 @@ JdbcChatMemoryRepository jdbcChatMemoryRepository(JdbcTemplate jdbcTemplate, Dat
5151

5252
@Bean
5353
@ConditionalOnMissingBean
54+
@Conditional(OnJdbcChatMemoryRepositoryDatasourceInitializationCondition.class)
5455
JdbcChatMemoryRepositorySchemaInitializer jdbcChatMemoryScriptDatabaseInitializer(DataSource dataSource,
5556
JdbcChatMemoryRepositoryProperties properties) {
5657
return new JdbcChatMemoryRepositorySchemaInitializer(dataSource, properties);
5758
}
5859

60+
static class OnJdbcChatMemoryRepositoryDatasourceInitializationCondition extends OnDatabaseInitializationCondition {
61+
62+
OnJdbcChatMemoryRepositoryDatasourceInitializationCondition() {
63+
super("Jdbc Chat Memory Repository",
64+
JdbcChatMemoryRepositoryProperties.CONFIG_PREFIX + ".initialize-schema");
65+
}
66+
67+
}
68+
5969
}

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/model/chat/memory/repository/jdbc/autoconfigure/JdbcChatMemoryRepositoryProperties.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@
1717
package org.springframework.ai.model.chat.memory.repository.jdbc.autoconfigure;
1818

1919
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
import org.springframework.boot.sql.init.DatabaseInitializationMode;
2021

2122
/**
2223
* @author Jonathan Leijendekker
2324
* @author Thomas Vitale
25+
* @author Yanming Zhou
2426
* @since 1.0.0
2527
*/
2628
@ConfigurationProperties(JdbcChatMemoryRepositoryProperties.CONFIG_PREFIX)
2729
public class JdbcChatMemoryRepositoryProperties {
2830

2931
public static final String CONFIG_PREFIX = "spring.ai.chat.memory.repository.jdbc";
3032

33+
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/ai/chat/memory/jdbc/schema-@@platform@@.sql";
34+
3135
/**
3236
* Whether to initialize the schema on startup. Values: embedded, always, never.
3337
* Default is embedded.
@@ -38,7 +42,13 @@ public class JdbcChatMemoryRepositoryProperties {
3842
* Locations of schema (DDL) scripts. Supports comma-separated list. Default is
3943
* classpath:org/springframework/ai/chat/memory/jdbc/schema-@@platform@@.sql
4044
*/
41-
private String schema = "classpath:org/springframework/ai/chat/memory/jdbc/schema-@@platform@@.sql";
45+
private String schema = DEFAULT_SCHEMA_LOCATION;
46+
47+
/**
48+
* Platform to use in initialization scripts if the @@platform@@ placeholder is used.
49+
* Auto-detected by default.
50+
*/
51+
private String platform;
4252

4353
public DatabaseInitializationMode getInitializeSchema() {
4454
return this.initializeSchema;
@@ -48,6 +58,14 @@ public void setInitializeSchema(DatabaseInitializationMode initializeSchema) {
4858
this.initializeSchema = initializeSchema;
4959
}
5060

61+
public String getPlatform() {
62+
return platform;
63+
}
64+
65+
public void setPlatform(String platform) {
66+
this.platform = platform;
67+
}
68+
5169
public String getSchema() {
5270
return this.schema;
5371
}
@@ -56,23 +74,4 @@ public void setSchema(String schema) {
5674
this.schema = schema;
5775
}
5876

59-
public enum DatabaseInitializationMode {
60-
61-
/**
62-
* Always initialize the database.
63-
*/
64-
ALWAYS,
65-
66-
/**
67-
* Only initialize an embedded database.
68-
*/
69-
EMBEDDED,
70-
71-
/**
72-
* Never initialize the database.
73-
*/
74-
NEVER
75-
76-
}
77-
7877
}

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/model/chat/memory/repository/jdbc/autoconfigure/JdbcChatMemoryRepositorySchemaInitializer.java

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -22,71 +22,38 @@
2222

2323
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
2424
import org.springframework.boot.jdbc.init.PlatformPlaceholderDatabaseDriverResolver;
25-
import org.springframework.boot.sql.init.DatabaseInitializationMode;
2625
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
2726
import org.springframework.util.StringUtils;
2827

2928
/**
3029
* Performs database initialization for the JDBC Chat Memory Repository.
3130
*
3231
* @author Mark Pollack
32+
* @author Yanming Zhou
3333
* @since 1.0.0
3434
*/
3535
class JdbcChatMemoryRepositorySchemaInitializer extends DataSourceScriptDatabaseInitializer {
3636

37-
private static final String DEFAULT_SCHEMA_LOCATION = "classpath:org/springframework/ai/chat/memory/jdbc/schema-@@platform@@.sql";
38-
3937
JdbcChatMemoryRepositorySchemaInitializer(DataSource dataSource, JdbcChatMemoryRepositoryProperties properties) {
4038
super(dataSource, getSettings(dataSource, properties));
4139
}
4240

4341
static DatabaseInitializationSettings getSettings(DataSource dataSource,
4442
JdbcChatMemoryRepositoryProperties properties) {
4543
var settings = new DatabaseInitializationSettings();
46-
47-
// Determine schema locations
48-
String schemaProp = properties.getSchema();
49-
List<String> schemaLocations;
50-
PlatformPlaceholderDatabaseDriverResolver resolver = new PlatformPlaceholderDatabaseDriverResolver();
51-
try {
52-
String url = dataSource.getConnection().getMetaData().getURL().toLowerCase();
53-
if (url.contains("hsqldb")) {
54-
schemaLocations = List.of("classpath:org/springframework/ai/chat/memory/jdbc/schema-hsqldb.sql");
55-
}
56-
else if (StringUtils.hasText(schemaProp)) {
57-
schemaLocations = resolver.resolveAll(dataSource, schemaProp);
58-
}
59-
else {
60-
schemaLocations = resolver.resolveAll(dataSource, DEFAULT_SCHEMA_LOCATION);
61-
}
62-
}
63-
catch (Exception e) {
64-
// fallback to default
65-
if (StringUtils.hasText(schemaProp)) {
66-
schemaLocations = resolver.resolveAll(dataSource, schemaProp);
67-
}
68-
else {
69-
schemaLocations = resolver.resolveAll(dataSource, DEFAULT_SCHEMA_LOCATION);
70-
}
71-
}
72-
settings.setSchemaLocations(schemaLocations);
73-
74-
// Determine initialization mode
75-
JdbcChatMemoryRepositoryProperties.DatabaseInitializationMode init = properties.getInitializeSchema();
76-
DatabaseInitializationMode mode;
77-
if (JdbcChatMemoryRepositoryProperties.DatabaseInitializationMode.ALWAYS.equals(init)) {
78-
mode = DatabaseInitializationMode.ALWAYS;
79-
}
80-
else if (JdbcChatMemoryRepositoryProperties.DatabaseInitializationMode.NEVER.equals(init)) {
81-
mode = DatabaseInitializationMode.NEVER;
82-
}
83-
else {
84-
// embedded or default
85-
mode = DatabaseInitializationMode.EMBEDDED;
86-
}
87-
settings.setMode(mode);
44+
settings.setSchemaLocations(resolveSchemaLocations(dataSource, properties));
45+
settings.setMode(properties.getInitializeSchema());
8846
settings.setContinueOnError(true);
8947
return settings;
9048
}
9149

50+
private static List<String> resolveSchemaLocations(DataSource dataSource,
51+
JdbcChatMemoryRepositoryProperties properties) {
52+
PlatformPlaceholderDatabaseDriverResolver platformResolver = new PlatformPlaceholderDatabaseDriverResolver();
53+
if (StringUtils.hasText(properties.getPlatform())) {
54+
return platformResolver.resolveAll(properties.getPlatform(), properties.getSchema());
55+
}
56+
return platformResolver.resolveAll(dataSource, properties.getSchema());
57+
}
58+
9259
}

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/model/chat/memory/repository/jdbc/autoconfigure/JdbcChatMemoryPostgresqlAutoConfigurationIT.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
* @author Jonathan Leijendekker
3939
* @author Thomas Vitale
4040
* @author Linar Abzaltdinov
41+
* @author Yanming Zhou
4142
*/
4243
class JdbcChatMemoryPostgresqlAutoConfigurationIT {
4344

@@ -49,14 +50,14 @@ class JdbcChatMemoryPostgresqlAutoConfigurationIT {
4950
@Test
5051
void jdbcChatMemoryScriptDatabaseInitializer_shouldBeLoaded() {
5152
this.contextRunner.withPropertyValues("spring.ai.chat.memory.repository.jdbc.initialize-schema=always")
52-
.run(context -> assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue());
53+
.run(context -> assertThat(context).hasBean("jdbcChatMemoryScriptDatabaseInitializer"));
5354
}
5455

5556
@Test
5657
void jdbcChatMemoryScriptDatabaseInitializer_shouldNotRunSchemaInit() {
5758
this.contextRunner.withPropertyValues("spring.ai.chat.memory.repository.jdbc.initialize-schema=never")
5859
.run(context -> {
59-
assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue();
60+
assertThat(context).doesNotHaveBean("jdbcChatMemoryScriptDatabaseInitializer");
6061
// Optionally, check that the schema is not initialized (could check table
6162
// absence if needed)
6263
});
@@ -65,7 +66,7 @@ void jdbcChatMemoryScriptDatabaseInitializer_shouldNotRunSchemaInit() {
6566
@Test
6667
void initializeSchemaEmbeddedDefault() {
6768
this.contextRunner.withPropertyValues("spring.ai.chat.memory.repository.jdbc.initialize-schema=embedded")
68-
.run(context -> assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue());
69+
.run(context -> assertThat(context).hasBean("jdbcChatMemoryScriptDatabaseInitializer"));
6970
}
7071

7172
@Test

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/model/chat/memory/repository/jdbc/autoconfigure/JdbcChatMemoryRepositoryPropertiesTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import org.junit.jupiter.api.Test;
2020

21+
import org.springframework.boot.sql.init.DatabaseInitializationMode;
22+
2123
import static org.assertj.core.api.Assertions.assertThat;
2224

2325
/**
@@ -28,16 +30,14 @@ class JdbcChatMemoryRepositoryPropertiesTests {
2830
@Test
2931
void defaultValues() {
3032
var props = new JdbcChatMemoryRepositoryProperties();
31-
assertThat(props.getInitializeSchema())
32-
.isEqualTo(JdbcChatMemoryRepositoryProperties.DatabaseInitializationMode.EMBEDDED);
33+
assertThat(props.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.EMBEDDED);
3334
}
3435

3536
@Test
3637
void customValues() {
3738
var props = new JdbcChatMemoryRepositoryProperties();
38-
props.setInitializeSchema(JdbcChatMemoryRepositoryProperties.DatabaseInitializationMode.NEVER);
39-
assertThat(props.getInitializeSchema())
40-
.isEqualTo(JdbcChatMemoryRepositoryProperties.DatabaseInitializationMode.NEVER);
39+
props.setInitializeSchema(DatabaseInitializationMode.NEVER);
40+
assertThat(props.getInitializeSchema()).isEqualTo(DatabaseInitializationMode.NEVER);
4141
}
4242

4343
}

auto-configurations/models/chat/memory/repository/spring-ai-autoconfigure-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/model/chat/memory/repository/jdbc/autoconfigure/JdbcChatMemorySqlServerAutoConfigurationIT.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,21 @@ class JdbcChatMemorySqlServerAutoConfigurationIT {
5252
@Test
5353
void jdbcChatMemoryScriptDatabaseInitializer_shouldBeLoaded() {
5454
this.contextRunner.withPropertyValues("spring.ai.chat.memory.repository.jdbc.initialize-schema=always")
55-
.run(context -> assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue());
55+
.run(context -> assertThat(context).hasBean("jdbcChatMemoryScriptDatabaseInitializer"));
5656
}
5757

5858
@Test
5959
void jdbcChatMemoryScriptDatabaseInitializer_shouldNotRunSchemaInit() {
6060
this.contextRunner.withPropertyValues("spring.ai.chat.memory.repository.jdbc.initialize-schema=never")
6161
.run(context -> {
62-
assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue();
62+
assertThat(context).doesNotHaveBean("jdbcChatMemoryScriptDatabaseInitializer");
6363
});
6464
}
6565

6666
@Test
6767
void initializeSchemaEmbeddedDefault() {
6868
this.contextRunner.withPropertyValues("spring.ai.chat.memory.repository.jdbc.initialize-schema=embedded")
69-
.run(context -> assertThat(context.containsBean("jdbcChatMemoryScriptDatabaseInitializer")).isTrue());
69+
.run(context -> assertThat(context).hasBean("jdbcChatMemoryScriptDatabaseInitializer"));
7070
}
7171

7272
@Test

0 commit comments

Comments
 (0)