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
52 changes: 44 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: CI

permissions:
contents: write
actions: write

on:
push:
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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: |
Expand All @@ -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:
Expand Down Expand Up @@ -267,4 +303,4 @@ jobs:
echo "Release $tag already exists"
else
gh release create "$tag" --generate-notes --title "$tag"
fi
fi
65 changes: 59 additions & 6 deletions CODE_STYLE.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
39 changes: 22 additions & 17 deletions PROJECT_STATUS.md
Original file line number Diff line number Diff line change
@@ -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.

---
Expand All @@ -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

Expand All @@ -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. |

---

Expand Down Expand Up @@ -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. |

---

Expand All @@ -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. |

---

Expand All @@ -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. |

---
Expand Down Expand Up @@ -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.

---
Expand All @@ -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

Expand All @@ -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.

---

Expand Down
Loading
Loading