Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
69 changes: 69 additions & 0 deletions .github/workflows/converged-database-lab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: converged-database-lab
on:
push:
branches: [main]
paths:
- 'labs/converged-database-lab/**'
- '.github/workflows/converged-database-lab.yml'
pull_request:
paths:
- 'labs/converged-database-lab/**'
- '.github/workflows/converged-database-lab.yml'
schedule:
- cron: '17 6 * * *' # nightly: substantive freshness, not cosmetic
workflow_dispatch:

jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 45
defaults:
run:
working-directory: labs/converged-database-lab
steps:
- uses: actions/checkout@v4

- name: Free disk space
run: sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL

- name: Boot lab (build + init)
run: |
docker compose up -d --build oracle
# Health check polls every 15s with up to 40 retries + 120s start_period.
# We wait up to 90 × 15s = 22.5 min, which covers the cold-start image pull
# and DB initialization in CI. Break early once healthy; fail fast on unhealthy.
for i in $(seq 1 90); do
status=$(docker inspect -f '{{.State.Health.Status}}' lab-oracle 2>/dev/null || echo "starting")
[ "$status" = "healthy" ] && echo "Healthy after $((i * 15))s" && break
if [ "$status" = "unhealthy" ]; then
echo "Container is unhealthy — printing last 100 log lines and aborting"
docker logs lab-oracle --tail 100
exit 1
fi
echo "[$i/90] status=$status — sleeping 15s"
sleep 15
done
final=$(docker inspect -f '{{.State.Health.Status}}' lab-oracle)
if [ "$final" != "healthy" ]; then
echo "Container never became healthy (status=$final)"
docker logs lab-oracle --tail 100
exit 1
fi

- name: Verify domain initialized
# Use a heredoc piped to sqlplus to avoid all shell-quoting issues.
# The grep checks for 'customers=200' in the output.
run: |
docker exec lab-oracle bash -c "sqlplus -s / as sysdba <<'ENDSQL'
ALTER SESSION SET CONTAINER=FREEPDB1;
SELECT 'customers='||COUNT(*) FROM lab_user.customers;
ENDSQL
" | grep -q 'customers=200'

- uses: actions/setup-python@v5
with: { python-version: '3.11' }

- name: Run validator
run: |
pip install -r validator/requirements.txt
python validator/run.py
60 changes: 43 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,58 @@
# terraform-oci-ocloud-asset-database
# Oracle UMT Developer Hub

[![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=oracle-devrel_terraform-oci-ocloud-asset-database)](https://sonarcloud.io/dashboard?id=oracle-devrel_terraform-oci-ocloud-asset-database)
[![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://oss.oracle.com/licenses/upl/)

## THIS IS A NEW, BLANK REPO THAT IS NOT READY FOR USE YET. PLEASE CHECK BACK SOON!
Technical resources for developers learning **Unified Model Theory (UMT)** and converged data modeling on **Oracle AI Database 26ai** — *model the domain once, project the access for every consumer.*

## Introduction
MISSING
This hub collects hands-on, **runnable** labs and companion material for the UMT / converged-database content series. Nothing here is slideware: every lab boots a real Oracle AI Database 26ai container and proves its claims by executing them — document, relational, graph, vector, spatial, and full-text in **one engine, one transaction, one optimizer.**

> **One truth. Many shapes. Every claim runs.**

## What You'll Find

This repository is organized so that each runnable asset lives in its own folder under a category. More labs and companion material will be added as the series grows.

### 🧪 Labs (`/labs`)

Self-contained, runnable labs that validate converged-model claims against a live Oracle AI Database 26ai. Each lab includes a Docker environment, a validator, and its own README and quickstart, and runs itself nightly in CI so the proofs stay honest.

| Name | Description | Link |
| --- | --- | --- |
| converged-database-lab | Runnable proofs for the converged-database article series — JSON Relational Duality, single-table vs. converged modeling, graph, vector, spatial, and full-text claims, each executing against a free Oracle AI Database 26ai container. | [![View Lab](https://img.shields.io/badge/View%20Lab-blue?style=flat-square)](./labs/converged-database-lab) |

*More labs coming as the content series expands.*

## Getting Started
MISSING

### Prerequisites
MISSING
Each lab is self-contained. To run the converged-database lab:

## Notes/Issues
MISSING
```bash
cd labs/converged-database-lab
docker compose up -d --build oracle # ~2 GB image; first boot seeds the domain (~2 min)
pip install -r validator/requirements.txt
python validator/run.py # runs every module, prints ASSERT results
```

## URLs
* Nothing at this time
See the lab's own [README](./labs/converged-database-lab) for details, troubleshooting, and the module map.

## About Unified Model Theory

Relational and document are not competing paradigms — they are **orthogonal projections of the same truth.** UMT models the domain once as a normalized **canonical form**, then projects whatever **shape** each consumer needs — a document, a graph, a vector, a relational result — from that single source, with no copies to drift out of sync. On a converged engine, the access pattern still drives the model; you just stop walking through one-way doors to serve it.

## Contributing
This project is open source. Please submit your contributions by forking this repository and submitting a pull request! Oracle appreciates any contributions that are made by the open source community.

This project welcomes contributions from the community. Before submitting a pull request, please [review our contribution guide](./CONTRIBUTING.md).

## Security

Please consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process.

## License
Copyright (c) 2024 Oracle and/or its affiliates.

Licensed under the Universal Permissive License (UPL), Version 1.0.
Copyright (c) 2026 Oracle and/or its affiliates.

Released under the Universal Permissive License v1.0 as shown at <https://oss.oracle.com/licenses/upl/>.

See [LICENSE](LICENSE.txt) for more details.
## Disclaimer

ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK.
ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY WARRANTY OF ANY KIND, INCLUDING THAT THE CONTENT IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. ANY OPEN SOURCE SOFTWARE IS PROVIDED BY THE APPLICABLE LICENSOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9 changes: 9 additions & 0 deletions labs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Labs

Self-contained, runnable labs that validate converged-model claims against a live **Oracle AI Database 26ai**. Each lab ships a Docker environment, a validator, and its own README, and runs itself nightly in CI so the proofs stay honest.

| Name | Description | Link |
| --- | --- | --- |
| converged-database-lab | Runnable proofs for the converged-database article series — JSON Relational Duality, single-table vs. converged modeling, graph, vector, spatial, and full-text claims, each executing against a free Oracle AI Database 26ai container. | [./converged-database-lab](./converged-database-lab) |

*More labs coming as the content series expands.*
2 changes: 2 additions & 0 deletions labs/converged-database-lab/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ORACLE_PASSWORD=LabAdmin2026
LAB_PASSWORD=LabUser2026
7 changes: 7 additions & 0 deletions labs/converged-database-lab/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.env
*.log
__pycache__/
validator/results.json
validator/.venv/
docker/.data/
*.pyc
144 changes: 144 additions & 0 deletions labs/converged-database-lab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# converged-database-lab

![validate](https://github.com/oracle-devrel/oracle-umt-developer-hub/actions/workflows/converged-database-lab.yml/badge.svg)

Runnable proofs for the converged-database article series — every technical claim in the articles executes here, nightly, against a free container.

**One truth. Many shapes. Every claim runs.**

---

## About the name: 26ai vs 23.26.x

Oracle AI Database 26ai is the product name — a long-term-support release announced October 2025. Container tags use a year.quarter version string convention, so `gvenzl/oracle-free:23.26.x` tags are the 26ai release line. Prose in this repo always says 26ai; the version string appears only where a tag or connection string requires it.

---

## Quickstart

```bash
docker compose up -d --build oracle # ~2 GB image; first boot seeds the domain (~2 min)
pip install -r validator/requirements.txt
python validator/run.py # runs every module, prints ASSERT results
```

If the container goes `unhealthy`, check `docker logs lab-oracle` — the most common cause is an ORDS install failure on first boot; `docker compose down -v && docker compose up -d --build oracle` usually resolves it.

**Connection cheatsheet**

| Interface | Connection string |
|-----------|-------------------|
| SQL | `LAB_USER/LabUser2026@localhost:1521/FREEPDB1` |
| MongoDB API | `mongodb://LAB_USER:LabUser2026@localhost:27017/lab_user?authMechanism=PLAIN&authSource=$external&tls=false&loadBalanced=true&retryWrites=false` |
| ORDS | `http://localhost:8181` |

These are demo credentials. Override via `.env` — see `.env.example`.

---

## The shared domain

All modules run against one deterministically seeded domain. Seeds use an LCG (seed 42) so `docker compose down -v && docker compose up -d --build oracle` produces byte-for-byte identical data every rebuild.

**Tables**

| Object | Rows | Data model exercised |
|--------|------|----------------------|
| `customers` | 200 | Relational — primary entity, FK target |
| `products` | 50 | Relational + JSON (`attributes` column: color, warrantyMonths) |
| `stores` | 6 | Relational + Spatial (`SDO_GEOMETRY`, WGS-84 coordinates) |
| `orders` | 1,000 | Relational — transactional fact table |
| `order_items` | ~2,500 (avg 2.5/order) | Relational — composite PK, line items |
| `devices` | 40 | Relational — device fingerprints |
| `customer_devices` | 200 | Relational — M:M link; graph edge source |
| `referrals` | 64 | Relational — self-referential; graph edge source (60 chain + 4-hop cycle 10→11→12→13→10) |
| `support_tickets` | 300 | Relational + Vector (`VECTOR(8, FLOAT32)` — 8-dim demo embeddings, see note) |

**JSON collection table**

| Object | Data model exercised |
|--------|----------------------|
| `events` | JSON-native collection (Oracle `JSON COLLECTION TABLE`) |

**JSON Relational Duality Views**

| View | Projection |
|------|------------|
| `customer_profile_dv` | Customer + nested orders + line items; writeable via MongoDB API |
| `order_dv` | Order-centric shape over the same rows — second projection of one stored truth |

**Property graph**

| Object | Vertices / Edges |
|--------|-----------------|
| `customer_graph` | 240 vertices (200 customers + 40 devices); 264 edges (200 `customer_devices` + 64 `referrals`) |

**Indexes**

| Index | Type | Purpose |
|-------|------|---------|
| `idx_orders_customer` | B-tree | Customer order range scans |
| `idx_items_product` | B-tree | Product-level aggregations |
| `idx_tickets_customer` | B-tree | Per-customer ticket lookups |
| `ticket_text_idx` | Oracle Text (SEARCH INDEX) | Full-text keyword search on ticket bodies |
| `ticket_vec_idx` | Vector IVF (NEIGHBOR PARTITIONS, COSINE) | Approximate nearest-neighbor on embeddings |

**Note on embeddings:** The 8-dim vectors are deterministic demo values generated by the LCG seed. All engine behaviors demonstrated (distance functions, vector indexes, transactions, cross-model joins) are dimension-independent. Module 03 documents the optional real-model flow using `DBMS_VECTOR.LOAD_ONNX_MODEL` with all-MiniLM-L12-v2.

**Oracle AI Database 26ai Free limits:** 2 CPU / 2 GB SGA+PGA / 12 GB data. The compose file caps the container at 2 CPUs and 4 GB (headroom for ORDS and OS overhead).

---

## Modules

| # | Slug | Status | Proofs | Assertions | Links |
|---|------|--------|--------|------------|-------|
| 01 | `what-is-a-converged-database` | Live | 4 | 14 | [README](modules/01-what-is-a-converged-database/README.md) · article link lands at publish |
| 02 | `converged-vs-multi-model` | Arrives with its article | — | — | — |
| 03 | `vector-db-vs-converged` | Arrives with its article | — | — | — |
| 04 | `ai-agents-enterprise-data` | Arrives with its article | — | — | — |
| 05 | `json-graph-vector-relational-one-db` | Arrives with its article | — | — | — |
| 06 | `polyglot-vs-converged` | Arrives with its article | — | — | — |
| 07 | `reading-stonebraker-and-pavlo` | Arrives with its article | — | — | — |

---

## Validation contract

Scripts live in `modules/NN-slug/scripts/` and run in lexical order — modules first, then scripts within each module.

- **`*.sql`** — executed statement-by-statement via python-oracledb (thin mode) as `LAB_USER` against `localhost:1521/FREEPDB1`. PL/SQL blocks end with a line containing only `/`; plain SQL ends with `;`. The harness rolls back after each script so demos leave the domain unchanged.
- **`*.js`** — executed with `mongosh` inside the `lab-oracle` container against the MongoDB API (port 27017). JS scripts auto-commit through the MongoDB API, so they must clean up explicitly — delete what they insert, restore what they update.

**Assertion convention:** SQL scripts assert by SELECTing a string of the form `ASSERT:<name>:PASS|FAIL` as the first column. JS scripts `print()` the same string. The validator harvests these lines and reports per-script.

**Results:** written to `validator/results.json` (gitignored).

**CI:** runs on push to `main`/`article/**`, on pull requests, and on a nightly cron (`17 6 * * *`). The job uploads `results.json` as a build artifact.

See [validator/README.md](validator/README.md) for the full authoring contract.

---

## MongoDB comparison profile

```bash
docker compose --profile mongodb up -d
```

Boots `mongo:8.2` as a single-node replica set (required for transactions) on host port 27027. Used for head-to-head demos in modules 03 and 06.

**Beta note:** `$vectorSearch`, `$search`, and `$changeStream` are beta in the Oracle 26ai MongoDB API per Oracle documentation. Modules that use these stages label them explicitly.

---

## Related work

- [github.com/rhoulihan/unified-model-theory](https://github.com/rhoulihan/unified-model-theory) — the UMT framework this lab demonstrates
- Article links added as they publish

---

## License

Universal Permissive License v1.0 — see [LICENSE](LICENSE).
41 changes: 41 additions & 0 deletions labs/converged-database-lab/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: converged-database-lab

services:
oracle:
build:
context: ./docker
dockerfile: Dockerfile.oracle
container_name: lab-oracle
ports: ['1521:1521', '8181:8181', '27017:27017']
environment:
ORACLE_PASSWORD: '${ORACLE_PASSWORD:-LabAdmin2026}'
APP_USER: 'LAB_USER'
APP_USER_PASSWORD: '${LAB_PASSWORD:-LabUser2026}'
volumes:
- oracle-data:/opt/oracle/oradata
healthcheck:
test: ['CMD-SHELL', '/opt/oracle/healthcheck.sh && curl -so /dev/null -w "%{http_code}" http://localhost:8181/ | grep -q "302\|200"']
interval: 15s
timeout: 10s
retries: 40
start_period: 120s
deploy:
resources:
limits: { cpus: '2', memory: 4G }

# Comparison target for head-to-head demos (modules 03/06). Single-node replica set
# (transactions require it). Start with: docker compose --profile mongodb up -d
mongodb:
image: mongo:8.2
container_name: lab-mongodb
profiles: ['mongodb']
command: ['mongod', '--replSet', 'rs0', '--bind_ip_all']
ports: ['27027:27017']
healthcheck:
test: ['CMD', 'mongosh', '--quiet', '--eval', "try { rs.status().ok } catch (e) { rs.initiate().ok }"]
interval: 10s
timeout: 10s
retries: 12

volumes:
oracle-data:
44 changes: 44 additions & 0 deletions labs/converged-database-lab/docker/Dockerfile.oracle
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Oracle AI Database 26ai Free + ORDS + MongoDB API.
# Note: gvenzl image tags use year.quarter numbering (23.26.x == the 26ai release line).
FROM gvenzl/oracle-free:23.26.0-faststart

USER root
COPY scripts/install-ords.sh /tmp/install-ords.sh
RUN chmod +x /tmp/install-ords.sh && /tmp/install-ords.sh && rm /tmp/install-ords.sh
RUN chown -R oracle:oinstall /etc/ords

# mongosh: used to verify and exercise the MongoDB API (port 27017) from inside
# the container — the validator harness runs *.js scripts through it.
RUN printf '[mongodb-org-8.0]\nname=MongoDB Repository\nbaseurl=https://repo.mongodb.org/yum/redhat/8/mongodb-org/8.0/x86_64/\ngpgcheck=1\nenabled=1\ngpgkey=https://pgp.mongodb.com/server-8.0.asc\n' > /etc/yum.repos.d/mongodb-org-8.0.repo \
&& microdnf install -y mongodb-mongosh \
&& microdnf clean all

# Bake Oracle's prebuilt augmented all-MiniLM-L12-v2 ONNX model into the image so
# every fresh build (and CI) loads identical in-DB embeddings deterministically —
# no network dependency at init time. This is the official model published by
# Oracle Machine Learning: the 26ai docs "ONNX Pipeline Models: Text Embedding"
# page redirects (/pls/topic/lookup?...&id=oml_ai_models_object_storage) to the
# OML-ai-models object-storage bucket whose index lists this exact URL. The zip
# (~122.6 MB) unpacks to all_MiniLM_L12_v2.onnx (~133.3 MB, 384-dim output),
# loaded by docker/init/08-vector-model.sql via DBMS_VECTOR.LOAD_ONNX_MODEL.
# Placed AFTER the ORDS + mongosh layers so their (slow) cache layers are reused
# when only the model layer changes. Fails the build loudly if the URL stops
# resolving rather than baking a broken image.
ARG MINILM_URL=https://adwc4pm.objectstorage.us-ashburn-1.oci.customer-oci.com/p/TtH6hL2y25EypZ0-rrczRZ1aXp7v1ONbRBfCiT-BDBN8WLKQ3lgyW6RxCfIFLdA6/n/adwc4pm/b/OML-ai-models/o/all_MiniLM_L12_v2_augmented.zip
RUN microdnf install -y unzip \
&& microdnf clean all \
&& mkdir -p /opt/oracle/models \
&& curl -fsSL -o /tmp/minilm.zip "$MINILM_URL" \
&& unzip -o /tmp/minilm.zip -d /opt/oracle/models \
&& test -s /opt/oracle/models/all_MiniLM_L12_v2.onnx \
&& rm -f /tmp/minilm.zip \
&& chown -R oracle:oinstall /opt/oracle/models

COPY init/ /container-entrypoint-initdb.d/

COPY scripts/entrypoint.sh /opt/oracle/scripts/entrypoint.sh
RUN chmod +x /opt/oracle/scripts/entrypoint.sh

USER oracle
EXPOSE 1521 8181 27017
ENTRYPOINT ["/opt/oracle/scripts/entrypoint.sh"]
Empty file.
Loading
Loading