diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/pom.xml b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/pom.xml index 45ad75e5269..4a1a7bd4ba9 100644 --- a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/pom.xml +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/pom.xml @@ -80,6 +80,13 @@ true + + com.h2database + h2 + test + true + + org.springframework.boot spring-boot-starter-test diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/H2ChatMemoryRepositoryDialect.java b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/H2ChatMemoryRepositoryDialect.java new file mode 100644 index 00000000000..56d8a25ecc1 --- /dev/null +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/H2ChatMemoryRepositoryDialect.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.chat.memory.repository.jdbc; + +/** + * H2-specific SQL dialect for chat memory repository. + * + * @author Yanming Zhou + */ +public class H2ChatMemoryRepositoryDialect implements JdbcChatMemoryRepositoryDialect { + + @Override + public String getSelectMessagesSql() { + return "SELECT content, type FROM SPRING_AI_CHAT_MEMORY WHERE conversation_id = ? ORDER BY timestamp ASC"; + } + + @Override + public String getInsertMessageSql() { + return "INSERT INTO SPRING_AI_CHAT_MEMORY (conversation_id, content, type, timestamp) VALUES (?, ?, ?, ?)"; + } + + @Override + public String getDeleteMessagesSql() { + return "DELETE FROM SPRING_AI_CHAT_MEMORY WHERE conversation_id = ?"; + } + + @Override + public String getSelectConversationIdsSql() { + return "SELECT DISTINCT conversation_id FROM SPRING_AI_CHAT_MEMORY"; + } + +} diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java index 3d7032df4bd..5247605e22c 100644 --- a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryDialect.java @@ -58,10 +58,7 @@ static JdbcChatMemoryRepositoryDialect from(DataSource dataSource) { if (url.contains("postgresql")) { return new PostgresChatMemoryRepositoryDialect(); } - if (url.contains("mysql")) { - return new MysqlChatMemoryRepositoryDialect(); - } - if (url.contains("mariadb")) { + if (url.contains("mysql") || url.contains("mariadb")) { return new MysqlChatMemoryRepositoryDialect(); } if (url.contains("sqlserver")) { @@ -70,6 +67,9 @@ static JdbcChatMemoryRepositoryDialect from(DataSource dataSource) { if (url.contains("hsqldb")) { return new HsqldbChatMemoryRepositoryDialect(); } + if (url.contains("h2")) { + return new H2ChatMemoryRepositoryDialect(); + } // Add more as needed } catch (Exception ignored) { diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/resources/org/springframework/ai/chat/memory/repository/jdbc/schema-h2.sql b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/resources/org/springframework/ai/chat/memory/repository/jdbc/schema-h2.sql new file mode 100644 index 00000000000..da29e6b3b70 --- /dev/null +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/resources/org/springframework/ai/chat/memory/repository/jdbc/schema-h2.sql @@ -0,0 +1,10 @@ +CREATE TABLE SPRING_AI_CHAT_MEMORY ( + conversation_id VARCHAR(36) NOT NULL, + content LONGVARCHAR NOT NULL, + type VARCHAR(10) NOT NULL, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL +); + +CREATE INDEX SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_TIMESTAMP_IDX ON SPRING_AI_CHAT_MEMORY(conversation_id, timestamp DESC); + +ALTER TABLE SPRING_AI_CHAT_MEMORY ADD CONSTRAINT TYPE_CHECK CHECK (type IN ('USER', 'ASSISTANT', 'SYSTEM', 'TOOL')); diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryH2IT.java b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryH2IT.java new file mode 100644 index 00000000000..be6672291cc --- /dev/null +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryH2IT.java @@ -0,0 +1,34 @@ +/* + * Copyright 2023-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.chat.memory.repository.jdbc; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.jdbc.Sql; + +/** + * Integration tests for {@link JdbcChatMemoryRepository} with H2. + * + * @author Yanming Zhou + */ +@SpringBootTest +@TestPropertySource(properties = { "spring.datasource.url=jdbc:h2:mem:mydb" }) +@Sql(scripts = "classpath:org/springframework/ai/chat/memory/repository/jdbc/schema-h2.sql", + executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS) +class JdbcChatMemoryRepositoryH2IT extends AbstractJdbcChatMemoryRepositoryIT { + +}