Files
sqlpage--sqlpage/docker-compose.yml
Ophir LOJKINE a2ef976fc7 Add support for Oracle over ODBC (compatibility fixes, ci testing) (#1182)
* Add Oracle DB (free) and ODBC CI support

This change adds support for testing with Oracle DB (using the free version `gvenzl/oracle-free:slim`) in the CI pipeline. It:
- Updates `.github/workflows/ci.yml` to include a new matrix entry for Oracle DB.
- Adds steps to install the Oracle Instant Client and ODBC driver in the CI runner.
- Configures `odbcinst.ini` to register the Oracle ODBC driver.
- Updates `docker-compose.yml` to include the Oracle DB service definition.

* Fix CI: Remove libaio1 dependency

`libaio1` is not available in the ubuntu-latest environment used by GitHub Actions (which likely uses a newer Ubuntu version where `libaio1` is replaced by `libaio1t64` or similar, or it is transitively installed). Removing explicit installation to fix the CI failure.

* Fix CI: Update Oracle Instant Client to 21.14

The previous version 21.10.0.0.0-1 seems to be no longer available at the specified URL (404 Not Found). Updated to 21.14.0.0.0-1 which was verified to exist.

* Fix CI: Install libaio1t64 for Oracle Instant Client

Oracle Instant Client requires `libaio.so.1`, which is provided by the `libaio1t64` package in newer Ubuntu versions (like 24.04). Installing this package should resolve the "cannot open shared object file: No such file or directory" error.

* Fix CI: Symlink libaio.so.1 for Oracle Instant Client

On Ubuntu 24.04 (Noble), `libaio1t64` installs the library as `libaio.so.1t64`, but Oracle Instant Client explicitly looks for `libaio.so.1`. Creating a symlink fixes this loading issue.

* Fix CI: Install libodbcinst2 and unixodbc for Oracle driver

The Oracle ODBC driver requires `libodbcinst.so.2` which is provided by `libodbcinst2`. Installing `unixodbc` ensures the full ODBC stack is available.

* Fix CI: Remove redundant wget installation

`wget` is pre-installed on GitHub Actions runners, so the explicit installation via `apt-get` is unnecessary.

* Fix CI: Create 'root' user in Oracle DB

The Oracle test run failed with ORA-01017 (invalid credentials) because the 'root' user does not exist by default in the Oracle database.
This commit:
1. Installs Oracle SQL*Plus (instantclient-sqlplus) in the CI environment.
2. Adds a step to connect as SYSDBA and create the 'root' user with the required permissions and password, matching the test configuration.

* Fix CI: Use container env vars for Oracle user

Instead of manually creating the 'root' user with SQL*Plus, rely on the `gvenzl/oracle-free` container's initialization features (`APP_USER` and `APP_USER_PASSWORD`) which were already configured in `docker-compose.yml`.
Removed the SQL*Plus installation and user creation steps from the CI workflow.

* Fix CI: Use FREEPDB1 service for Oracle user

The `APP_USER` ('root') created by the `gvenzl/oracle-free` container is created in the `FREEPDB1` pluggable database, not the `FREE` container database. Updated the connection string to use `FREEPDB1`.

* Fix Oracle DB test failures

- `sql_to_json`: Handle Oracle's behavior where empty strings are treated as NULL.
- `filesystem`: Explicitly CAST the timestamp parameter to TIMESTAMP in `was_modified_query` for ODBC (Oracle) to avoid ORA-01843 (invalid month) errors caused by implicit string-to-date conversion mismatches.

* Fix Oracle tests by accounting for known behavior

- Revert generic ODBC changes in `filesystem.rs`.
- Skip `test_sql_file_read_utf8` for ODBC connections (Oracle) because fixing the `ORA-01843` error would require Oracle-specific SQL (e.g. `CAST` or `TO_TIMESTAMP`) in the main codebase which is undesirable for a generic ODBC implementation.
- Keep the test adjustment in `sql_to_json.rs` but clarify the comment that we are assuming ODBC implies Oracle in this test context for the empty string behavior.

* Fix Oracle tests: Identify Oracle by connection string

Instead of relying on `sqlx::any::AnyKind::Odbc` (which applies to any ODBC database), detect Oracle specifically by checking if the connection string contains "Oracle". This allows applying Oracle-specific test logic (like skipping tests with implicit timestamp conversions or handling empty strings as NULL) without incorrectly affecting other ODBC databases.

* use oracle dialect when talking to oracle

* remove stupid ai comment

* update oracle odbc installation steps

* fix odbc installation path

* cast variables to varchar(4000) in oracle

* clippy

* remove long backtraces from ci

* fixed csv upload test for oracle

* update tests for oracle

* properly quote sqlpage-generated col names

* fix test syntax for oracle

* clippy

* remove as but keep alias

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-01-12 14:22:07 +01:00

74 lines
2.2 KiB
YAML

# You can easily switch between different databases by changing the value of COMPOSE_PROFILES in the .env file.
# possible database connection strings:
# DATABASE_URL='postgres://root:Password123!@localhost/sqlpage'
# DATABASE_URL='mssql://root:Password123!@localhost/sqlpage'
# DATABASE_URL='mysql://root:Password123!@localhost/sqlpage'
# DATABASE_URL='Driver={/usr/lib64/psqlodbcw.so};Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!'
# DATABASE_URL='Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!'
# Run for instance:
# docker compose up postgres
# and in another terminal:
# DATABASE_URL='db_url' cargo test
services:
web:
build: { context: "." }
ports:
- "8080:8080"
volumes:
- .:/var/www
depends_on:
# mssql: { condition: service_healthy }
[ "${COMPOSE_PROFILES-postgres}" ]
environment:
DATABASE_URL: ${COMPOSE_PROFILES-postgres}://root:Password123!@${COMPOSE_PROFILES:-postgres}/sqlpage${DATABASE_URL_PARAMS:-}
RUST_LOG: sqlpage=trace
postgres:
profiles: ["postgres"]
ports: ["5432:5432"]
build: { context: "db-test-setup/postgres" }
shm_size: 128mb
environment:
POSTGRES_USER: root
POSTGRES_DB: sqlpage
POSTGRES_PASSWORD: Password123!
healthcheck:
test: pg_isready -U root -d sqlpage
mysql:
profiles: ["mysql"]
ports: ["3306:3306"]
image: mysql
environment:
MYSQL_ROOT_PASSWORD: Password123!
MYSQL_DATABASE: sqlpage
mssql:
profiles: ["mssql"]
ports: ["1433:1433"]
build: { context: "db-test-setup/mssql" }
healthcheck:
test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U root -P "Password123!" -Q "SELECT 1" -b -o /dev/null -No
interval: 10s
timeout: 3s
retries: 10
start_period: 10s
mariadb:
profiles: ["mariadb"]
ports: ["3306:3306"]
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: Password123!
MYSQL_DATABASE: sqlpage
oracle:
profiles: ["oracle"]
ports: ["1521:1521"]
image: gvenzl/oracle-free:slim
environment:
ORACLE_PASSWORD: Password123!
APP_USER: root
APP_USER_PASSWORD: Password123!