Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SOURCE ?= file go_bindata github github_ee bitbucket aws_s3 google_cloud_storage godoc_vfs gitlab
DATABASE ?= postgres mysql redshift cassandra spanner cockroachdb yugabytedb clickhouse mongodb sqlserver firebird neo4j pgx pgx5 rqlite
DATABASE_TEST ?= $(DATABASE) sqlite sqlite3 sqlcipher
DATABASE_TEST ?= $(DATABASE) sqlite sqlite3 sqlcipher oracle
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds oracle to DATABASE_TEST, so it will be included in make test, but oracle is still missing from the DATABASE list used by make build/build-cli tags. If Oracle support is intended to ship with the CLI, add oracle to DATABASE as well (database/driver.go also documents this requirement).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Added oracle to the DATABASE list in the Makefile so it is included in make build / build-cli. The sijms/go-ora driver is pure Go (CGO_ENABLED=0 compatible), so this doesn't break static builds.

VERSION ?= $(shell git describe --tags 2>/dev/null | cut -c 2-)
TEST_FLAGS ?=
REPO_OWNER ?= $(shell cd .. && basename "$$(pwd)")
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ Database drivers run migrations. [Add a new database?](database/driver.go)
* [Firebird](database/firebird)
* [MS SQL Server](database/sqlserver)
* [rqlite](database/rqlite)

* [Oracle](database/oracle)
*
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s an empty list item here (* with no text). Remove the blank bullet to keep the driver list formatting clean.

Suggested change
*

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The blank bullet point after the Oracle entry has been removed.

### Database URLs

Database connection strings are specified via URLs. The URL format is driver dependent but generally has the form: `dbdriver://username:password@host:port/dbname?param1=true&param2=false`
Expand Down
110 changes: 110 additions & 0 deletions database/oracle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# oracle

The supported oracle specific options can be configured in the query section of the oracle
URL `oracle://user:password@host:port/ServiceName?query`

| URL Query | WithInstance Config | Description |
|--------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table in UPPER case |
| `x-multi-stmt-enabled` | `MultiStmtEnabled` | If the migration files are in multi-statements style |
| `x-multi-stmt-separator` | `MultiStmtSeparator` | a single line which use as the token to spilt multiple statements in single migration file, triple-dash separator `---` |

## Write migration files

There are two ways to write the migration files,

1. Single statement file in which it contains only one SQL statement or one PL/SQL statement(Default)
2. Multi statements file in which it can have multi statements(can be SQL or PL/SQL or mixed)

### Single statement file

Oracle godor driver support process one statement at a time, so it is natural to support single statement per file as
the default.
Check the [single statement migration files](examples/migrations) as an example.

### Multi statements file

Although the golang oracle driver [godror](https://github.com/godror/godror) does not natively support executing
multiple
statements in a single query, it's more friendly and handy to support multi statements in a single migration file in
some case,
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README describes the driver as godor/godror, but this implementation imports github.com/sijms/go-ora/v2. The docs should name the actual driver used (or switch the implementation) to avoid confusing users about required dependencies and behavior (e.g., multi-statement support).

Suggested change
Oracle godor driver support process one statement at a time, so it is natural to support single statement per file as
the default.
Check the [single statement migration files](examples/migrations) as an example.
### Multi statements file
Although the golang oracle driver [godror](https://github.com/godror/godror) does not natively support executing
multiple
statements in a single query, it's more friendly and handy to support multi statements in a single migration file in
some case,
The Oracle [go-ora](https://github.com/sijms/go-ora) driver supports processing one statement at a time, so it is natural to support a single statement per file as
the default.
Check the [single statement migration files](examples/migrations) as an example.
### Multi statements file
Although the Oracle driver used by this package, [go-ora](https://github.com/sijms/go-ora), does not natively support executing
multiple
statements in a single query, it's more friendly and handy to support multi statements in a single migration file in
some cases,

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The README now correctly references sijms/go-ora (the actual driver imported by this package) instead of godror/godror in both the single-statement and multi-statement sections.

so the multi statements can be separated with a line separator(default to triple-dash separator ---), for example:

```
statement 1
---
statement 2
```

Check the [multi statements' migration files](examples/migrations-multistmt) as an example.

## Supported & tested version

- 18-xe

## Build cli

```bash
$ cd /path/to/repo/dir
$ go build -tags 'oracle' -o bin/migrate github.com/golang-migrate/migrate/v4/cli
```

## Run test code

There are two ways to run the test code:

- Run the test code locally with an existing Oracle Instance(Recommended)
- Run the test code inside a container just like CI, It will require to start an Oracle container every time, and it's
very time expense.

### Run the test code locally with an existing Oracle Instance
Comment on lines +19 to +60
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are multiple typos/grammar issues in this section (e.g. "godor", "spilt", "some case", "very time expense"). Please correct them for clarity in the driver documentation.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Corrected all typos and grammar issues: "godor" → "sijms/go-ora", "spilt" → "split", "some case" → "some cases", "very time expense" → "very time-consuming".


1. Start the `Oracle Database Instance` via docker first, so that you can reuse whenever you want to run the test code.

```bash
$ cat docker-compose.yaml
---
services:
oracle-db:
container_name: oracle-db
image: gvenzl/oracle-free:23.5-slim
environment:
ORACLE_PASSWORD: SuperPassword@2025
ports:
- 1521:1521
healthcheck:
test: ["CMD", "healthcheck.sh"]
interval: 10s
timeout: 5s
retries: 10
start_period: 5s
start_interval: 5s
volumes:
- ${HOME}/database/oracle/testdata/init.sql:/docker-entrypoint-initdb.d/init.sql
```

2. Go into the sqlplus console

```bash
$ docker exec -it orclxe bash
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This docker-compose example uses container_name: oracle-db, but the next step runs docker exec -it orclxe ..., which won’t work as written. Update the command to match the declared container name (or update the compose snippet) so the instructions are runnable.

Suggested change
$ docker exec -it orclxe bash
$ docker exec -it oracle-db bash

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Updated the docker exec command to use oracle-db to match the container_name declared in the compose snippet.

# su oracle
$ sqlplus / as sysdba
```

3. Create a test DB

```sql
alter session set container=FREEPDB1;
create user orcl identified by orcl;
grant dba to orcl;
grant create session to orcl;
grant connect, resource to orcl;
grant all privileges to orcl;
```

4. Run the test code

```bash
$ cd /path/to/repo/database/oracle/dir
$ ORACLE_DSN=oracle://orcl:orcl@localhost:1521/FREEPDB1 go test -tags "oracle" -race -v -covermode atomic ./... -coverprofile .coverage -timeout 20m
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS USERS_MS;
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-00942 (or checks USER_TABLES) to drop conditionally.

Suggested change
DROP TABLE IF EXISTS USERS_MS;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE USERS_MS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL block that catches ORA-00942 and re-raises for any other error.

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CREATE TABLE USERS_MS (
USER_ID integer unique,
NAME varchar(40),
EMAIL varchar(40)
);

---

DROP TABLE IF EXISTS USERS_MS;
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This statement will fail if the table is absent (and will also make this multi-stmt example misleading). Use a PL/SQL conditional drop that ignores ORA-00942 instead.

Suggested change
DROP TABLE IF EXISTS USERS_MS;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE USERS_MS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL conditional drop block that catches ORA-00942 and re-raises any other exception.


---

CREATE TABLE USERS_MS (
USER_ID integer unique,
NAME varchar(40),
EMAIL varchar(40)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE USERS_MS DROP COLUMN CITY;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE USERS_MS ADD CITY varchar(100);
---
ALTER TABLE USERS_MS ADD ALIAS varchar(100);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP INDEX users_ms_email_index;
---
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE UNIQUE INDEX users_ms_email_index ON users_ms (email);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DROP TABLE IF EXISTS BOOKS_MS;
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-00942 (or checks USER_TABLES) to drop conditionally.

Suggested change
DROP TABLE IF EXISTS BOOKS_MS;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE BOOKS_MS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL block that catches ORA-00942 and re-raises for any other error.

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE BOOKS_MS (
USER_ID integer,
NAME varchar(40),
AUTHOR varchar(40)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS MOVIES_MS
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-00942 (or checks USER_TABLES) to drop conditionally.

Suggested change
DROP TABLE IF EXISTS MOVIES_MS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE MOVIES_MS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL block that catches ORA-00942 and re-raises for any other error.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE MOVIES_MS (
USER_ID integer,
NAME varchar(40),
DIRECTOR varchar(40)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS USERS
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-00942 (or query USER_TABLES) to drop conditionally.

Suggested change
DROP TABLE IF EXISTS USERS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE USERS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL block that catches ORA-00942 and re-raises for any other error.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE USERS (
USER_ID integer unique,
NAME varchar(40),
EMAIL varchar(40)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE USERS DROP COLUMN CITY
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE USERS ADD CITY varchar(100)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP INDEX IF EXISTS users_email_index
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP INDEX IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-01418 (index does not exist) or checks USER_INDEXES before dropping.

Suggested change
DROP INDEX IF EXISTS users_email_index
BEGIN
EXECUTE IMMEDIATE 'DROP INDEX users_email_index';
EXCEPTION
WHEN OTHERS THEN
-- ORA-01418: specified index does not exist
IF SQLCODE != -1418 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL block that uses EXECUTE IMMEDIATE 'DROP INDEX users_email_index' and catches ORA-01418 (specified index does not exist), re-raising for any other error code.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE UNIQUE INDEX users_email_index ON users (email)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS BOOKS
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-00942 (or query USER_TABLES) to drop conditionally.

Suggested change
DROP TABLE IF EXISTS BOOKS
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE BOOKS';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL block that catches ORA-00942 and re-raises for any other error.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE BOOKS (
USER_ID integer,
NAME varchar(40),
AUTHOR varchar(40)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS MOVIES
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oracle SQL doesn’t support DROP TABLE IF EXISTS .... This down migration will fail during rollback. Use a PL/SQL block that catches ORA-00942 (or query USER_TABLES) to drop conditionally.

Suggested change
DROP TABLE IF EXISTS MOVIES
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE MOVIES';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Replaced with a PL/SQL BEGIN...EXECUTE IMMEDIATE...EXCEPTION WHEN OTHERS block that ignores ORA-00942 (table or view does not exist) and re-raises any other error.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE MOVIES (
USER_ID integer,
NAME varchar(40),
DIRECTOR varchar(40)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sed interdum velit, tristique iaculis justo. Pellentesque ut porttitor dolor. Donec sit amet pharetra elit. Cras vel ligula ex. Phasellus posuere.
Loading
Loading