diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0d66089..dd4e8cc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,6 +2,7 @@ name: CI
permissions:
contents: write
+ actions: write
on:
push:
@@ -20,7 +21,7 @@ env:
jobs:
test:
- if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main' && github.ref != 'refs/heads/nightly')
+ if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main')
runs-on: ubuntu-latest
steps:
@@ -63,6 +64,14 @@ jobs:
restore-keys: |
pip-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
+ - name: Cache uv
+ uses: actions/cache@v4
+ with:
+ path: ${{ env.UV_CACHE_DIR }}
+ key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('**/uv.lock', '**/pyproject.toml') }}
+ restore-keys: |
+ uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
+
- name: Cache wheelhouse
uses: actions/cache@v4
with:
@@ -82,7 +91,7 @@ jobs:
run: |
mkdir -p "${WHEEL_CACHE_DIR}"
- if ls "${WHEEL_CACHE_DIR}"/wxPython*.whl >/dev/null 2>&1; then
+ if ls "${WHEEL_CACHE_DIR}"/wxpython-*.whl >/dev/null 2>&1; then
echo "wxPython wheel found in cache, skipping wheel build"
echo "needs_build=false" >> "$GITHUB_OUTPUT"
else
@@ -95,10 +104,19 @@ jobs:
run: |
mkdir -p "${WHEEL_CACHE_DIR}"
python -m pip wheel -w "${WHEEL_CACHE_DIR}" -r requirements.lock.txt
+ find "${PIP_CACHE_DIR}/wheels" -type f -name 'wxpython-*.whl' -exec cp -u {} "${WHEEL_CACHE_DIR}/" \;
- name: Upgrade build tooling
run: uv pip install -U pip setuptools wheel
+ - name: Preinstall wxPython from wheelhouse
+ run: |
+ if ls "${WHEEL_CACHE_DIR}"/wxpython-*.whl >/dev/null 2>&1; then
+ uv pip install --no-index --find-links "${WHEEL_CACHE_DIR}" wxpython==4.2.5
+ else
+ echo "No wxPython wheel found in wheelhouse"
+ fi
+
- name: Install dependencies from wheelhouse (fallback on build)
run: |
if uv sync --extra dev --find-links "${WHEEL_CACHE_DIR}" --no-build; then
@@ -109,10 +127,10 @@ jobs:
fi
- name: Run tests (--all)
- run: xvfb-run -a ./scripts/runtest.sh --all
+ run: xvfb-run -a uv run ./scripts/runtest.py --all
update:
- if: github.event_name == 'push' && github.ref == 'refs/heads/nightly'
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[skip ci]')
runs-on: ubuntu-latest
steps:
@@ -155,6 +173,14 @@ jobs:
restore-keys: |
pip-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
+ - name: Cache uv
+ uses: actions/cache@v4
+ with:
+ path: ${{ env.UV_CACHE_DIR }}
+ key: uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-${{ hashFiles('**/uv.lock', '**/pyproject.toml') }}
+ restore-keys: |
+ uv-${{ runner.os }}-py${{ env.PYTHON_VERSION }}-
+
- name: Cache wheelhouse
uses: actions/cache@v4
with:
@@ -174,7 +200,7 @@ jobs:
run: |
mkdir -p "${WHEEL_CACHE_DIR}"
- if ls "${WHEEL_CACHE_DIR}"/wxPython*.whl >/dev/null 2>&1; then
+ if ls "${WHEEL_CACHE_DIR}"/wxpython-*.whl >/dev/null 2>&1; then
echo "wxPython wheel found in cache, skipping wheel build"
echo "needs_build=false" >> "$GITHUB_OUTPUT"
else
@@ -187,10 +213,19 @@ jobs:
run: |
mkdir -p "${WHEEL_CACHE_DIR}"
python -m pip wheel -w "${WHEEL_CACHE_DIR}" -r requirements.lock.txt
+ find "${PIP_CACHE_DIR}/wheels" -type f -name 'wxpython-*.whl' -exec cp -u {} "${WHEEL_CACHE_DIR}/" \;
- name: Upgrade build tooling
run: uv pip install -U pip setuptools wheel
+ - name: Preinstall wxPython from wheelhouse
+ run: |
+ if ls "${WHEEL_CACHE_DIR}"/wxpython-*.whl >/dev/null 2>&1; then
+ uv pip install --no-index --find-links "${WHEEL_CACHE_DIR}" wxpython==4.2.5
+ else
+ echo "No wxPython wheel found in wheelhouse"
+ fi
+
- name: Install dependencies from wheelhouse (fallback on build)
run: |
if uv sync --extra dev --find-links "${WHEEL_CACHE_DIR}" --no-build; then
@@ -201,7 +236,7 @@ jobs:
fi
- name: Run tests and update README (--update)
- run: xvfb-run -a ./scripts/runtest.sh --update
+ run: xvfb-run -a uv run ./scripts/runtest.py --update
- name: Commit and push updated README
run: |
@@ -221,7 +256,8 @@ jobs:
run: echo "Build scripts are not ready yet."
release:
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
+ # Temporarily disabled: release flow is not ready yet.
+ if: false
runs-on: ubuntu-latest
steps:
@@ -267,4 +303,4 @@ jobs:
echo "Release $tag already exists"
else
gh release create "$tag" --generate-notes --title "$tag"
- fi
+ fi
\ No newline at end of file
diff --git a/CODE_STYLE.md b/CODE_STYLE.md
index 5189a1f..b6190a5 100644
--- a/CODE_STYLE.md
+++ b/CODE_STYLE.md
@@ -1,14 +1,65 @@
-# Code Style Guidelines (v1.4)
+# Code Style Guidelines (v1.5)
These rules define the expected coding style for this project.
-They apply to all contributors, including humans, AI-assisted tools, and automated systems.
-They are mandatory unless explicitly stated otherwise.
+
+They apply to all contributors:
+
+- human developers
+- AI-assisted tools
+- coding agents
+- automated systems
+
+These rules are **mandatory** unless explicitly stated otherwise.
+
+If a requested change conflicts with these rules, the change must **stop** and clarification must be requested.
+
+---
+
+## Core Rules (Quick Reference)
+
+The following rules are the most critical and must always be respected:
+
+1. All code, comments, documentation, commit messages, and user-facing text MUST be written in English.
+2. Python typing rules MUST be respected (PEP 585 generics; `Optional[T]`, not `T | None`).
+3. Import ordering and grouping rules MUST be followed exactly.
+4. Functions and methods MUST NOT exceed 50 lines.
+5. Code changes MUST avoid modifying unrelated code.
+6. Naming MUST remain explicit and descriptive (no aggressive abbreviations).
+7. Code MUST remain mypy-friendly whenever possible.
+
+When generating or modifying code, tools and agents MUST consult this file before producing changes.
+
+---
+
+## Mandatory Rules
+
+The following rules are strict and MUST NOT be violated:
+
+- English must always be used for code and documentation.
+- `typing.Optional[T]` MUST be used instead of `T | None`.
+- `from __future__ import annotations` MUST NOT be used.
+- Import ordering rules MUST be respected exactly.
+- Functions MUST NOT exceed the maximum size limit.
+
+---
+
+## Usage by AI Tools
+
+AI-assisted tools and coding agents MUST read this file before generating or modifying code.
+
+If a requested change conflicts with these rules, the tool MUST:
+
+1. stop the modification
+2. explain the conflict
+3. request clarification
+
+Agents MUST prioritize deterministic rules over stylistic interpretation.
---
## Design Principles
-#### These principles explain why the rules exist. They protect consistency over time.
+These principles explain why the rules exist. They protect consistency over time.
- Determinism over preference
A rule must always produce the same result. Subjective rules lead to debates and inconsistency.
@@ -476,6 +527,8 @@ def get_dialect() -> str:
return connection.engine.value.dialect
```
+If exact ordering cannot be determined automatically, prefer consistency with the surrounding file.
+
---
## 7. Variable Definition Order
@@ -586,8 +639,8 @@ class Example:
## 10. Walrus Operator ( := )
-- Always try to use the walrus operator when it improves clarity and avoids redundant calls.
-- Do NOT use it if it reduces readability.
+- The walrus operator MAY be used when it improves clarity and avoids redundant calls.
+- It MUST NOT be used when it makes the control flow harder to read.
#### Good examples
diff --git a/PROJECT_STATUS.md b/PROJECT_STATUS.md
index c2efc22..7c0e50c 100644
--- a/PROJECT_STATUS.md
+++ b/PROJECT_STATUS.md
@@ -1,6 +1,6 @@
# PeterSQL — Project Status
-> **Last Updated:** 2026-03-07
+> **Last Updated:** 2026-03-10
> **Validation Policy:** new engine features are marked **PARTIAL** until broader integration validation is complete.
---
@@ -21,10 +21,14 @@
| Area | Current State |
|------|---------------|
-| **PostgreSQL Function** | Class + CRUD methods exist, context introspection exists, still considered under validation. |
-| **PostgreSQL Procedure** | Class + CRUD methods exist, context introspection exists, still considered under validation. |
+| **MySQL Procedure** | Class + CRUD methods exist, context introspection exists, integration tests added, broader validation still ongoing. |
+| **MariaDB Procedure** | Class + CRUD methods exist, context introspection exists, integration tests added, broader validation still ongoing. |
+| **PostgreSQL Function** | Class + CRUD methods exist, context introspection exists, integration tests now cover create/alter/drop across supported PG versions; broader validation still ongoing. |
+| **PostgreSQL Procedure** | Class + CRUD methods exist, context introspection exists, integration tests now cover create/alter/drop across supported PG versions; broader validation still ongoing. |
| **Check Constraints (MySQL/MariaDB/PostgreSQL)** | Engine classes and introspection exist, cross-version validation still needed. |
| **Connection Reliability Features** | Persistent connection statistics, empty DB password support, and TLS auto-retry are implemented and need longer real-world validation. |
+| **SQL Dump / Backup** | `SQLDatabase.dump()` produces object-driven `.sql` dumps (schema + records); restore/import workflow is still missing. |
+| **Database Lifecycle (Create/Drop)** | Engine database objects expose lifecycle methods, but context/UI workflow parity is still incomplete. |
### ❌ Missing / Not Implemented
@@ -34,7 +38,6 @@
| **Database Create/Drop UI** | No complete create/drop workflow across engines. |
| **Schema/Sequence Management** | PostgreSQL schema/sequence CRUD is not available. |
| **User/Role/Grants** | Not implemented for any engine. |
-| **Import/Export** | Dump/restore and structured data import/export not implemented. |
---
@@ -69,8 +72,8 @@
| Table / Column / Index / FK / Record | ✅ | ✅ | ✅ | ✅ | Stable core workflow. |
| View / Trigger / Function | ✅ | ✅ | ✅ | ✅ | Implemented in engine layer. |
| Check Constraint | 🟡 | 🟡 | 🟡 | 🟡 | Implemented (`MySQLCheck` + `get_checks()`), validation ongoing. |
-| Procedure | ❌ | ❌ | ❌ | ❌ | `build_empty_procedure` still not implemented. |
-| Database Create/Drop | ❌ | ✅ | ❌ | ❌ | Read-only listing in context. |
+| Procedure | 🟡 | 🟡 | 🟡 | 🟡 | Implemented (`MySQLProcedure` + `get_procedures()`), broader validation ongoing. |
+| Database Create/Drop | 🟡 | ✅ | 🟡 | 🟡 | Engine object lifecycle methods exist; context/UI wiring still partial. |
---
@@ -81,8 +84,8 @@
| Table / Column / Index / FK / Record | ✅ | ✅ | ✅ | ✅ | Stable core workflow. |
| View / Trigger / Function | ✅ | ✅ | ✅ | ✅ | Implemented in engine layer. |
| Check Constraint | 🟡 | 🟡 | 🟡 | 🟡 | Implemented (`MariaDBCheck` + `get_checks()`), validation ongoing. |
-| Procedure | ❌ | ❌ | ❌ | ❌ | `build_empty_procedure` still not implemented. |
-| Database Create/Drop | ❌ | ✅ | ❌ | ❌ | Read-only listing in context. |
+| Procedure | 🟡 | 🟡 | 🟡 | 🟡 | Implemented (`MariaDBProcedure` + `get_procedures()`), broader validation ongoing. |
+| Database Create/Drop | 🟡 | ✅ | 🟡 | 🟡 | Engine object lifecycle methods exist; context/UI wiring still partial. |
---
@@ -95,6 +98,7 @@
| Function | 🟡 | 🟡 | 🟡 | 🟡 | `PostgreSQLFunction` implemented, still under validation. |
| Procedure | 🟡 | 🟡 | 🟡 | 🟡 | `PostgreSQLProcedure` implemented, still under validation. |
| Check Constraint | 🟡 | 🟡 | 🟡 | 🟡 | Implemented (`PostgreSQLCheck` + `get_checks()`), validation ongoing. |
+| Database Create/Drop | 🟡 | ✅ | 🟡 | 🟡 | Engine object lifecycle methods exist; context/UI wiring still partial. |
| Schema / Sequence | ❌ | 🟡 | ❌ | ❌ | Basic schema visibility exists; no CRUD layer yet. |
---
@@ -123,12 +127,16 @@
- Persistent connection statistics in connection model and dialog.
- Empty database password accepted in connection validation.
- Automatic TLS retry path for MySQL/MariaDB when server requires TLS.
+- Unit reliability coverage for MySQL/MariaDB TLS auto-retry and SSH tunnel lifecycle contracts.
+- SQL dump/backup pipeline is now object-driven via `SQLDatabase.dump()` + per-object `raw_create()`.
- CI workflow split into `test`, `update` (nightly), and `release` jobs.
### Main Remaining Risks
-- Newly implemented PostgreSQL Function/Procedure paths need broader integration validation.
+- PostgreSQL Function/Procedure now have integration coverage for create/alter/drop, but still need broader long-run/manual validation.
- Check constraints across MySQL/MariaDB/PostgreSQL need more cross-version coverage.
+- SQL dump/backup still needs broader cross-engine manual restore validation.
+- SSH tunnel integration validation with testcontainers remains blocked (existing SSH integration suites are still skipped).
- UI parity lags engine parity for Trigger/Function/Procedure editors.
---
@@ -137,16 +145,13 @@
### Priority A — Validate Newly Implemented Features
-1. PostgreSQL Function integration validation (all supported PG variants).
-2. PostgreSQL Procedure integration validation (all supported PG variants).
-3. Check constraints validation matrix for MySQL, MariaDB, PostgreSQL.
-4. Connection statistics + TLS auto-retry robustness checks.
+1. PostgreSQL Function/Procedure long-run validation (manual workflows + regression suites after integration coverage).
+2. Check constraints validation matrix for MySQL, MariaDB, PostgreSQL.
+3. Connection statistics + TLS auto-retry robustness checks.
### Priority B — Close Engine Gaps
-1. MySQL Procedure implementation.
-2. MariaDB Procedure implementation.
-3. Database create/drop methods in engine contexts.
+1. Complete context/UI wiring for database lifecycle (create/drop) across engines.
### Priority C — UI Completeness
@@ -159,7 +164,7 @@
1. PostgreSQL schema CRUD.
2. PostgreSQL sequence CRUD.
3. User/role/grants management.
-4. Import/export workflows.
+4. Restore and structured import/export workflows.
---
diff --git a/PeterSQL.fbp b/PeterSQL.fbp
index 594082d..ec7b972 100755
--- a/PeterSQL.fbp
+++ b/PeterSQL.fbp
@@ -31,7 +31,7 @@
1
0
0
-