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 e2271ea6dc0..0487ceb0eaa 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 @@ -50,11 +50,6 @@ spring-jdbc - - com.zaxxer - HikariCP - - @@ -85,6 +80,18 @@ true + + com.oracle.database.jdbc + ojdbc11 + 23.4.0.24.05 + + + + org.springframework.boot + spring-boot-starter-jdbc + test + + 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/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 62658ac700e..3e4cb6737e6 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 @@ -78,6 +78,7 @@ static JdbcChatMemoryRepositoryDialect from(DataSource dataSource) { case "MySQL", "MariaDB" -> new MysqlChatMemoryRepositoryDialect(); case "Microsoft SQL Server" -> new SqlServerChatMemoryRepositoryDialect(); case "HSQL Database Engine" -> new HsqldbChatMemoryRepositoryDialect(); + case "Oracle" -> new OracleChatMemoryRepositoryDialect(); default -> // Add more as needed new PostgresChatMemoryRepositoryDialect(); }; diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/OracleChatMemoryRepositoryDialect.java b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/OracleChatMemoryRepositoryDialect.java new file mode 100644 index 00000000000..466046cb14b --- /dev/null +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/java/org/springframework/ai/chat/memory/repository/jdbc/OracleChatMemoryRepositoryDialect.java @@ -0,0 +1,24 @@ +package org.springframework.ai.chat.memory.repository.jdbc; + +public class OracleChatMemoryRepositoryDialect implements JdbcChatMemoryRepositoryDialect { + + @Override + public String getSelectMessagesSql() { + return "SELECT content, type FROM SPRING_AI_CHAT_MEMORY WHERE CONVERSATION_ID = ? ORDER BY \"TIMESTAMP\""; + } + + @Override + public String getInsertMessageSql() { + return "INSERT INTO SPRING_AI_CHAT_MEMORY (CONVERSATION_ID, CONTENT, TYPE, \"TIMESTAMP\") VALUES (?, ?, ?, ?)"; + } + + @Override + public String getSelectConversationIdsSql() { + return "SELECT DISTINCT conversation_id FROM SPRING_AI_CHAT_MEMORY"; + } + + @Override + public String getDeleteMessagesSql() { + return "DELETE FROM SPRING_AI_CHAT_MEMORY WHERE CONVERSATION_ID = ?"; + } +} diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/resources/org/springframework/ai/chat/memory/repository/jdbc/schema-oracle.sql b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/resources/org/springframework/ai/chat/memory/repository/jdbc/schema-oracle.sql new file mode 100644 index 00000000000..47a411299b5 --- /dev/null +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/main/resources/org/springframework/ai/chat/memory/repository/jdbc/schema-oracle.sql @@ -0,0 +1,21 @@ +DROP TABLE SPRING_AI_CHAT_MEMORY; + +CREATE TABLE SPRING_AI_CHAT_MEMORY ( + CONVERSATION_ID VARCHAR2(36 CHAR) NOT NULL, + CONTENT CLOB NOT NULL, + "TYPE" VARCHAR2(10 CHAR) NOT NULL CHECK ( + "TYPE" IN ( + 'USER', + 'ASSISTANT', + 'SYSTEM', + 'TOOL' + ) + ), + "TIMESTAMP" TIMESTAMP NOT NULL +); + +CREATE INDEX SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_TIMESTAMP_IDX + ON SPRING_AI_CHAT_MEMORY( + CONVERSATION_ID, + 'TIMESTAMP' + ); \ No newline at end of file diff --git a/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryOracleIT.java b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryOracleIT.java new file mode 100644 index 00000000000..de86511f4b7 --- /dev/null +++ b/memory/repository/spring-ai-model-chat-memory-repository-jdbc/src/test/java/org/springframework/ai/chat/memory/repository/jdbc/JdbcChatMemoryRepositoryOracleIT.java @@ -0,0 +1,16 @@ +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; + +@SpringBootTest +@TestPropertySource(properties = { + "spring.datasource.url=jdbc:oracle:thin:@localhost:1521/FREEPDB1", + "spring.datasource.username=scott", + "spring.datasource.password=tiger"}) + +@Sql(scripts = "classpath:org/springframework/ai/chat/memory/repository/jdbc/schema-oracle.sql") +class JdbcChatMemoryRepositoryOracleIT extends AbstractJdbcChatMemoryRepositoryIT { + +} diff --git a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat-memory.adoc b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat-memory.adoc index 4231a2dbcb6..18b28a15969 100644 --- a/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat-memory.adoc +++ b/spring-ai-docs/src/main/antora/modules/ROOT/pages/api/chat-memory.adoc @@ -128,6 +128,7 @@ Spring AI supports multiple relational databases via a dialect abstraction. The - MySQL / MariaDB - SQL Server - HSQLDB +- Oracle Database The correct dialect can be auto-detected from the JDBC URL when using `JdbcChatMemoryRepositoryDialect.from(DataSource)`. You can extend support for other databases by implementing the `JdbcChatMemoryRepositoryDialect` interface.