diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd1535976..39eff1b70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,7 +100,7 @@ jobs: db_url: "mssql://root:Password123!@127.0.0.1/sqlpage" - database: oracle container: oracle - db_url: "Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!" + db_url: "Driver=Oracle 23 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!" - database: duckdb container: "" db_url: "Driver=DuckDB;Database=/tmp/sqlpage-test.duckdb" @@ -123,17 +123,17 @@ jobs: run: | sudo apt-get update && sudo apt-get install -y unixodbc unzip sudo scripts/install-duckdb-odbc.sh + - name: Cache Oracle Instant Client archives + if: matrix.database == 'oracle' + uses: actions/cache@v6 + with: + path: ${{ runner.temp }}/sqlpage-oracle-instantclient-archives + key: oracle-instantclient-linux-x64-23.26.0.0.0-v1 - name: Install Oracle ODBC driver if: matrix.database == 'oracle' run: | - sudo apt-get install -y alien libaio1t64 libodbcinst2 unixodbc - sudo rpm --import https://yum.oracle.com/RPM-GPG-KEY-oracle-ol8 - wget https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient21/x86_64/getPackage/oracle-instantclient-{basic,odbc}-21.21.0.0.0-1.el8.x86_64.rpm - sudo alien -i oracle-instantclient-basic-21.21.0.0.0-1.el8.x86_64.rpm - sudo alien -i oracle-instantclient-odbc-21.21.0.0.0-1.el8.x86_64.rpm - sudo ln -s /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/libaio.so.1 - sudo /usr/lib/oracle/21/client64/bin/odbc_update_ini.sh / /usr/lib/oracle/21/client64/lib - echo "LD_LIBRARY_PATH=/usr/lib/oracle/21/client64/lib:$LD_LIBRARY_PATH" >> "$GITHUB_ENV" + sudo apt-get install -y libaio1t64 libodbcinst2 unixodbc unzip + scripts/install-oracle-odbc.sh - name: Start database container if: matrix.container != '' run: docker compose up --wait ${{ matrix.container }} diff --git a/docker-compose.yml b/docker-compose.yml index 677996dde..b17201540 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ # DATABASE_URL='postgres://root:Password123!@localhost/sqlpage' # DATABASE_URL='mssql://root:Password123!@localhost/sqlpage' # DATABASE_URL='mysql://root:Password123!@localhost/sqlpage' -# DATABASE_URL='Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!' +# DATABASE_URL='Driver=Oracle 23 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!' # DATABASE_URL='Driver=DuckDB;Database=/tmp/sqlpage-test.duckdb' # Run for instance: diff --git a/scripts/README.md b/scripts/README.md index 750695a6a..38ec96d4b 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -15,4 +15,5 @@ These scripts pass configuration between build stages through temporary files in - **`package-test-binaries.sh`**: Compiles the Rust test harnesses once and tars them, so the database matrix runs the same executables instead of recompiling SQLPage six times. - **`run-test-binaries.sh`**: Runs SQLPage compiled executables against whatever `DATABASE_URL` names. +- **`install-oracle-odbc.sh`**: Verifies and extracts the pinned Oracle Instant Client 23ai ZIPs, registers a private ODBC driver, and writes its environment to `GITHUB_ENV`. CI caches the archives under `RUNNER_TEMP`. Requires curl, unzip, unixODBC, and libaio. - **`test-examples-hurl.sh`**: Starts an example's containers and runs its `test.hurl` suite. Takes an example path to filter on. diff --git a/scripts/install-oracle-odbc.sh b/scripts/install-oracle-odbc.sh new file mode 100755 index 000000000..a7afbb98a --- /dev/null +++ b/scripts/install-oracle-odbc.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -euo pipefail + +: "${GITHUB_ENV:?Set GITHUB_ENV to the file that should receive the driver environment}" + +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +# Oracle Instant Client 23ai (23.26.x). 21c is an older innovation release; +# 23ai matches the database server used in CI (gvenzl/oracle-free:23.x) +# and may have fixed or changed the client cleanup path involved in the +# finiSqora exit hang. Download the official ZIPs instead of converting +# RPMs to Debian packages. CI caches the archives; verify them even on +# cache hits. +oracle_version="23.26.0.0.0" +oracle_build="2326000" +oracle_dir="instantclient_23_26" +oracle_driver="Oracle 23 ODBC driver" +oracle_so="libsqora.so.23.1" +archive_dir="${RUNNER_TEMP:-/tmp}/sqlpage-oracle-instantclient-archives" +install_dir="${RUNNER_TEMP:-/tmp}/sqlpage-oracle-instantclient" +mkdir -p "$archive_dir" "$install_dir" + +for package in basic odbc; do + archive="instantclient-${package}-linux.x64-${oracle_version}.zip" + if [[ ! -f "$archive_dir/$archive" ]]; then + curl --fail --location --remove-on-error --retry 3 --connect-timeout 15 \ + --max-time 300 --output "$archive_dir/$archive" \ + "https://download.oracle.com/otn_software/linux/instantclient/${oracle_build}/$archive" + fi +done + +( + cd "$archive_dir" + sha256sum --check <<'CHECKSUMS' +d6c79cbcf0ff209363e779855c690d4fc730aed847e9198a2c439bcf34760af5 instantclient-basic-linux.x64-23.26.0.0.0.zip +e4e715d2dbf7f1c6907adceb8a62bea33d3ae2ae4466118df346b6c213af4fb4 instantclient-odbc-linux.x64-23.26.0.0.0.zip +CHECKSUMS +) + +for package in basic odbc; do + unzip -oq "$archive_dir/instantclient-${package}-linux.x64-${oracle_version}.zip" -d "$install_dir" +done +client_dir="$install_dir/$oracle_dir" + +# Ubuntu 24.04's libaio package uses a different SONAME from Oracle's client. +libaio_path="$(ldconfig -p | awk '$1 ~ /^libaio\.so\.1(t64)?$/ { path = $NF } END { print path }')" +test -n "$libaio_path" +ln -sf "$libaio_path" "$client_dir/libaio.so.1" + +cat > "$install_dir/odbcinst.ini" <> "$GITHUB_ENV"