Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 535a91d4be | |||
| bd54e85727 | |||
| b042b2d508 | |||
| af1733dc9a |
320
README.md
320
README.md
@@ -6,264 +6,160 @@
|
|||||||
[](https://go.dev/dl/)
|
[](https://go.dev/dl/)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
> Database Relations Specification Tool for Go
|
> Bidirectional database schema conversion, validation, and templating tool.
|
||||||
|
|
||||||
RelSpec is a comprehensive database relations management tool that reads, transforms, and writes database table specifications across multiple formats and ORMs.
|

|
||||||
|
|
||||||
## Overview
|
## Install
|
||||||
|
|
||||||
RelSpec provides bidirectional conversion, comparison, and validation of database specification formats, allowing you to:
|
|
||||||
- Inspect live databases and extract their structure
|
|
||||||
- Validate schemas against configurable rules and naming conventions
|
|
||||||
- Convert between different ORM models (GORM, Bun, etc.)
|
|
||||||
- Transform legacy schema definitions (Clarion DCTX, XML, JSON, etc.)
|
|
||||||
- Generate standardized specification files (JSON, YAML, etc.)
|
|
||||||
- Compare database schemas and track changes
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
### Readers (Input Formats)
|
|
||||||
|
|
||||||
RelSpec can read database schemas from multiple sources:
|
|
||||||
|
|
||||||
#### ORM Models
|
|
||||||
- [GORM](pkg/readers/gorm/README.md) - Go GORM model definitions
|
|
||||||
- [Bun](pkg/readers/bun/README.md) - Go Bun model definitions
|
|
||||||
- [Drizzle](pkg/readers/drizzle/README.md) - TypeScript Drizzle ORM schemas
|
|
||||||
- [Prisma](pkg/readers/prisma/README.md) - Prisma schema language
|
|
||||||
- [TypeORM](pkg/readers/typeorm/README.md) - TypeScript TypeORM entities
|
|
||||||
|
|
||||||
#### Database Inspection
|
|
||||||
- [PostgreSQL](pkg/readers/pgsql/README.md) - Direct PostgreSQL database introspection
|
|
||||||
- [SQLite](pkg/readers/sqlite/README.md) - Direct SQLite database introspection
|
|
||||||
|
|
||||||
#### Schema Formats
|
|
||||||
- [DBML](pkg/readers/dbml/README.md) - Database Markup Language (dbdiagram.io)
|
|
||||||
- [DCTX](pkg/readers/dctx/README.md) - Clarion database dictionary format
|
|
||||||
- [DrawDB](pkg/readers/drawdb/README.md) - DrawDB JSON format
|
|
||||||
- [GraphQL](pkg/readers/graphql/README.md) - GraphQL Schema Definition Language (SDL)
|
|
||||||
- [JSON](pkg/readers/json/README.md) - RelSpec canonical JSON format
|
|
||||||
- [YAML](pkg/readers/yaml/README.md) - RelSpec canonical YAML format
|
|
||||||
|
|
||||||
### Writers (Output Formats)
|
|
||||||
|
|
||||||
RelSpec can write database schemas to multiple formats:
|
|
||||||
|
|
||||||
#### ORM Models
|
|
||||||
- [GORM](pkg/writers/gorm/README.md) - Generate GORM-compatible Go structs
|
|
||||||
- [Bun](pkg/writers/bun/README.md) - Generate Bun-compatible Go structs
|
|
||||||
- [Drizzle](pkg/writers/drizzle/README.md) - Generate Drizzle ORM TypeScript schemas
|
|
||||||
- [Prisma](pkg/writers/prisma/README.md) - Generate Prisma schema files
|
|
||||||
- [TypeORM](pkg/writers/typeorm/README.md) - Generate TypeORM TypeScript entities
|
|
||||||
|
|
||||||
#### Database DDL
|
|
||||||
- [PostgreSQL](pkg/writers/pgsql/README.md) - PostgreSQL DDL (CREATE TABLE, etc.)
|
|
||||||
- [SQLite](pkg/writers/sqlite/README.md) - SQLite DDL with automatic schema flattening
|
|
||||||
|
|
||||||
#### Schema Formats
|
|
||||||
- [DBML](pkg/writers/dbml/README.md) - Database Markup Language
|
|
||||||
- [DCTX](pkg/writers/dctx/README.md) - Clarion database dictionary format
|
|
||||||
- [DrawDB](pkg/writers/drawdb/README.md) - DrawDB JSON format
|
|
||||||
- [GraphQL](pkg/writers/graphql/README.md) - GraphQL Schema Definition Language (SDL)
|
|
||||||
- [JSON](pkg/writers/json/README.md) - RelSpec canonical JSON format
|
|
||||||
- [YAML](pkg/writers/yaml/README.md) - RelSpec canonical YAML format
|
|
||||||
|
|
||||||
### Inspector (Schema Validation)
|
|
||||||
|
|
||||||
RelSpec includes a powerful schema validation and linting tool:
|
|
||||||
|
|
||||||
- [Inspector](pkg/inspector/README.md) - Validate database schemas against configurable rules
|
|
||||||
- Enforce naming conventions (snake_case, camelCase, custom patterns)
|
|
||||||
- Check primary key and foreign key standards
|
|
||||||
- Detect missing indexes on foreign keys
|
|
||||||
- Prevent use of SQL reserved keywords
|
|
||||||
- Ensure schema integrity (missing PKs, orphaned FKs, circular dependencies)
|
|
||||||
- Support for custom validation rules
|
|
||||||
- Multiple output formats (Markdown with colors, JSON)
|
|
||||||
- CI/CD integration ready
|
|
||||||
|
|
||||||
## Use of AI
|
|
||||||
[Rules and use of AI](./AI_USE.md)
|
|
||||||
|
|
||||||
## User Interface
|
|
||||||
|
|
||||||
RelSpec provides an interactive terminal-based user interface for managing and editing database schemas. The UI allows you to:
|
|
||||||
|
|
||||||
- **Browse Databases** - Navigate through your database structure with an intuitive menu system
|
|
||||||
- **Edit Schemas** - Create, modify, and organize database schemas
|
|
||||||
- **Manage Tables** - Add, update, or delete tables with full control over structure
|
|
||||||
- **Configure Columns** - Define column properties, data types, constraints, and relationships
|
|
||||||
- **Interactive Editing** - Real-time validation and feedback as you make changes
|
|
||||||
|
|
||||||
The interface supports multiple input formats, making it easy to load, edit, and save your database definitions in various formats.
|
|
||||||
|
|
||||||
<p align="center" width="100%">
|
|
||||||
<img src="./assets/image/screenshots/main_screen.jpg">
|
|
||||||
</p>
|
|
||||||
<p align="center" width="100%">
|
|
||||||
<img src="./assets/image/screenshots/table_view.jpg">
|
|
||||||
</p>
|
|
||||||
<p align="center" width="100%">
|
|
||||||
<img src="./assets/image/screenshots/edit_column.jpg">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go get github.com/wdevs/relspecgo
|
|
||||||
|
|
||||||
go install -v git.warky.dev/wdevs/relspecgo/cmd/relspec@latest
|
go install -v git.warky.dev/wdevs/relspecgo/cmd/relspec@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Supported Formats
|
||||||
|
|
||||||
### Interactive Schema Editor
|
| Direction | Formats |
|
||||||
|
|-----------|---------|
|
||||||
|
| **Readers** | `bun` `dbml` `dctx` `drawdb` `drizzle` `gorm` `graphql` `json` `mssql` `pgsql` `prisma` `sqldir` `sqlite` `typeorm` `yaml` |
|
||||||
|
| **Writers** | `bun` `dbml` `dctx` `drawdb` `drizzle` `gorm` `graphql` `json` `mssql` `pgsql` `prisma` `sqlexec` `sqlite` `template` `typeorm` `yaml` |
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### `convert` — Schema conversion
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Launch interactive editor with a DBML schema
|
# PostgreSQL → GORM models
|
||||||
relspec edit --from dbml --from-path schema.dbml --to dbml --to-path schema.dbml
|
relspec convert --from pgsql --from-conn "postgres://user:pass@localhost/mydb" \
|
||||||
|
--to gorm --to-path models/ --package models
|
||||||
|
|
||||||
# Edit PostgreSQL database in place
|
# DBML → PostgreSQL DDL
|
||||||
relspec edit --from pgsql --from-conn "postgres://user:pass@localhost/mydb" \
|
relspec convert --from dbml --from-path schema.dbml --to pgsql --to-path schema.sql
|
||||||
--to pgsql --to-conn "postgres://user:pass@localhost/mydb"
|
|
||||||
|
|
||||||
# Edit JSON schema and save as GORM models
|
# PostgreSQL → SQLite (auto flattens schemas)
|
||||||
relspec edit --from json --from-path db.json --to gorm --to-path models/
|
relspec convert --from pgsql --from-conn "postgres://..." --to sqlite --to-path schema.sql
|
||||||
|
|
||||||
|
# Multiple input files merged
|
||||||
|
relspec convert --from json --from-list "a.json,b.json" --to yaml --to-path merged.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The `edit` command launches an interactive terminal user interface where you can:
|
### `merge` — Additive schema merge (never modifies existing items)
|
||||||
- Browse and navigate your database structure
|
|
||||||
- Create, modify, and delete schemas, tables, and columns
|
|
||||||
- Configure column properties, constraints, and relationships
|
|
||||||
- Save changes to various formats
|
|
||||||
- Import and merge schemas from other databases
|
|
||||||
|
|
||||||
### Schema Merging
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Merge two JSON schemas (additive merge - adds missing items only)
|
# Merge two JSON schemas
|
||||||
relspec merge --target json --target-path base.json \
|
relspec merge --target json --target-path base.json \
|
||||||
--source json --source-path additions.json \
|
--source json --source-path additions.json \
|
||||||
--output json --output-path merged.json
|
--output json --output-path merged.json
|
||||||
|
|
||||||
# Merge PostgreSQL database into JSON, skipping specific tables
|
# Merge PostgreSQL into JSON, skipping tables
|
||||||
relspec merge --target json --target-path current.json \
|
relspec merge --target json --target-path current.json \
|
||||||
--source pgsql --source-conn "postgres://user:pass@localhost/source_db" \
|
--source pgsql --source-conn "postgres://user:pass@localhost/db" \
|
||||||
--output json --output-path updated.json \
|
--output json --output-path updated.json \
|
||||||
--skip-tables "audit_log,temp_tables"
|
--skip-tables "audit_log,temp_tables"
|
||||||
|
|
||||||
# Cross-format merge (DBML + YAML → JSON)
|
|
||||||
relspec merge --target dbml --target-path base.dbml \
|
|
||||||
--source yaml --source-path additions.yaml \
|
|
||||||
--output json --output-path result.json \
|
|
||||||
--skip-relations --skip-views
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The `merge` command combines two database schemas additively:
|
Skip flags: `--skip-relations` `--skip-views` `--skip-domains` `--skip-enums` `--skip-sequences`
|
||||||
- Adds missing schemas, tables, columns, and other objects
|
|
||||||
- Never modifies or deletes existing items (safe operation)
|
|
||||||
- Supports selective merging with skip options (domains, relations, enums, views, sequences, specific tables)
|
|
||||||
- Works across any combination of supported formats
|
|
||||||
- Perfect for integrating multiple schema definitions or applying patches
|
|
||||||
|
|
||||||
### Schema Conversion
|
### `inspect` — Schema validation / linting
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Convert PostgreSQL database to GORM models
|
# Validate PostgreSQL database
|
||||||
relspec convert --from pgsql --from-conn "postgres://user:pass@localhost/mydb" \
|
|
||||||
--to gorm --to-path models/ --package models
|
|
||||||
|
|
||||||
# Convert GORM models to Bun
|
|
||||||
relspec convert --from gorm --from-path models.go \
|
|
||||||
--to bun --to-path bun_models.go --package models
|
|
||||||
|
|
||||||
# Export database schema to JSON
|
|
||||||
relspec convert --from pgsql --from-conn "postgres://..." \
|
|
||||||
--to json --to-path schema.json
|
|
||||||
|
|
||||||
# Convert DBML to PostgreSQL SQL
|
|
||||||
relspec convert --from dbml --from-path schema.dbml \
|
|
||||||
--to pgsql --to-path schema.sql
|
|
||||||
|
|
||||||
# Convert PostgreSQL database to SQLite (with automatic schema flattening)
|
|
||||||
relspec convert --from pgsql --from-conn "postgres://..." \
|
|
||||||
--to sqlite --to-path sqlite_schema.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
### Schema Validation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Validate a PostgreSQL database with default rules
|
|
||||||
relspec inspect --from pgsql --from-conn "postgres://user:pass@localhost/mydb"
|
relspec inspect --from pgsql --from-conn "postgres://user:pass@localhost/mydb"
|
||||||
|
|
||||||
# Validate DBML file with custom rules
|
# Validate DBML with custom rules
|
||||||
relspec inspect --from dbml --from-path schema.dbml --rules .relspec-rules.yaml
|
relspec inspect --from dbml --from-path schema.dbml --rules .relspec-rules.yaml
|
||||||
|
|
||||||
# Generate JSON validation report
|
# JSON report output
|
||||||
relspec inspect --from json --from-path db.json \
|
relspec inspect --from json --from-path db.json --output-format json --output report.json
|
||||||
--output-format json --output report.json
|
|
||||||
|
|
||||||
# Validate specific schema only
|
# Filter to specific schema
|
||||||
relspec inspect --from pgsql --from-conn "..." --schema public
|
relspec inspect --from pgsql --from-conn "..." --schema public
|
||||||
```
|
```
|
||||||
|
|
||||||
### Schema Comparison
|
Rules: naming conventions, PK/FK standards, missing indexes, reserved keywords, circular dependencies.
|
||||||
|
|
||||||
|
### `diff` — Schema comparison
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Compare two database schemas
|
|
||||||
relspec diff --from pgsql --from-conn "postgres://localhost/db1" \
|
relspec diff --from pgsql --from-conn "postgres://localhost/db1" \
|
||||||
--to pgsql --to-conn "postgres://localhost/db2"
|
--to pgsql --to-conn "postgres://localhost/db2"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `templ` — Custom template rendering
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Render database schema to Markdown docs
|
||||||
|
relspec templ --from pgsql --from-conn "postgres://user:pass@localhost/db" \
|
||||||
|
--template docs.tmpl --output schema-docs.md
|
||||||
|
|
||||||
|
# One TypeScript file per table
|
||||||
|
relspec templ --from dbml --from-path schema.dbml \
|
||||||
|
--template ts-model.tmpl --mode table \
|
||||||
|
--output ./models/ --filename-pattern "{{.Name | toCamelCase}}.ts"
|
||||||
|
```
|
||||||
|
|
||||||
|
Modes: `database` (default) · `schema` · `table` · `script`
|
||||||
|
|
||||||
|
Template functions: string utils (`toCamelCase`, `toSnakeCase`, `pluralize`, …), type converters (`sqlToGo`, `sqlToTypeScript`, …), filters, loop helpers, safe access.
|
||||||
|
|
||||||
|
### `edit` — Interactive TUI editor
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Edit DBML schema interactively
|
||||||
|
relspec edit --from dbml --from-path schema.dbml --to dbml --to-path schema.dbml
|
||||||
|
|
||||||
|
# Edit live PostgreSQL database
|
||||||
|
relspec edit --from pgsql --from-conn "postgres://user:pass@localhost/mydb" \
|
||||||
|
--to pgsql --to-conn "postgres://user:pass@localhost/mydb"
|
||||||
|
```
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="./assets/image/screenshots/main_screen.jpg">
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<img src="./assets/image/screenshots/table_view.jpg">
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<img src="./assets/image/screenshots/edit_column.jpg">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
**Prerequisites:** Go 1.24.0+
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make build # → build/relspec
|
||||||
|
make test # race detection + coverage
|
||||||
|
make lint # requires golangci-lint
|
||||||
|
make coverage # → coverage.html
|
||||||
|
make install # → $GOPATH/bin
|
||||||
|
```
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
relspecgo/
|
cmd/relspec/ CLI commands
|
||||||
├── cmd/
|
pkg/readers/ Input format readers
|
||||||
│ └── relspec/ # CLI application (convert, inspect, diff, scripts)
|
pkg/writers/ Output format writers
|
||||||
├── pkg/
|
pkg/inspector/ Schema validation
|
||||||
│ ├── readers/ # Input format readers (DBML, GORM, PostgreSQL, etc.)
|
pkg/diff/ Schema comparison
|
||||||
│ ├── writers/ # Output format writers (GORM, Bun, SQL, etc.)
|
pkg/merge/ Schema merging
|
||||||
│ ├── inspector/ # Schema validation and linting
|
pkg/models/ Internal data models
|
||||||
│ ├── diff/ # Schema comparison
|
pkg/transform/ Transformation logic
|
||||||
│ ├── models/ # Internal data models
|
pkg/pgsql/ PostgreSQL utilities
|
||||||
│ ├── transform/ # Transformation logic
|
|
||||||
│ └── pgsql/ # PostgreSQL utilities (keywords, data types)
|
|
||||||
├── examples/ # Usage examples
|
|
||||||
└── tests/ # Test files
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Todo
|
|
||||||
|
|
||||||
[Todo List of Features](./TODO.md)
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
### Prerequisites
|
|
||||||
- Go 1.21 or higher
|
|
||||||
- Access to test databases (optional)
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go build -o relspec ./cmd/relspec
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go test ./...
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Apache License 2.0 - See [LICENSE](LICENSE) for details.
|
|
||||||
|
|
||||||
Copyright 2025 Warky Devs
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributions welcome. Please open an issue or submit a pull request.
|
1. Register or sign in with GitHub at [git.warky.dev](https://git.warky.dev)
|
||||||
|
2. Clone the repository: `git clone https://git.warky.dev/wdevs/relspecgo.git`
|
||||||
|
3. Create a feature branch: `git checkout -b feature/your-feature-name`
|
||||||
|
4. Commit your changes and push the branch
|
||||||
|
5. Open a pull request with a description of the new feature or fix
|
||||||
|
|
||||||
|
For questions or discussion, join the Discord: [discord.gg/74rcTujp25](https://discord.gg/74rcTujp25) — `warkyhein`
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Todo](./TODO.md)
|
||||||
|
- [AI Use Policy](./AI_USE.md)
|
||||||
|
- [License](LICENSE) — Apache 2.0 · Copyright 2025 Warky Devs
|
||||||
|
|||||||
219
Story.md
Normal file
219
Story.md
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
|
||||||
|
# From Scripts to RelSpec: What Years of Database Pain Taught Me
|
||||||
|
|
||||||
|
It started as a need.
|
||||||
|
A problem I’ve carried with me since my early PHP days.
|
||||||
|
|
||||||
|
Every project meant doing the same work again. Same patterns, same fixes—just in a different codebase.
|
||||||
|
It became frustrating fast.
|
||||||
|
|
||||||
|
I wanted something solid. Not another workaround.
|
||||||
|
|
||||||
|
## The Early Tools Phase
|
||||||
|
|
||||||
|
Like most things in development, it began small.
|
||||||
|
|
||||||
|
A simple PHP script.
|
||||||
|
Then a few Python scripts.
|
||||||
|
|
||||||
|
Just tools—nothing fancy. The goal was straightforward: generate code faster and remove repetitive work. I even experimented with Clarion templates at one point, trying to bend existing systems into something useful.
|
||||||
|
|
||||||
|
Then came SQL scripts.
|
||||||
|
Then PostgreSQL migration stored procedures.
|
||||||
|
Then small Go programs using templates.
|
||||||
|
|
||||||
|
Each step was solving a problem I had at the time. Nothing unified. Nothing polished. Just survival tools.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Argitek: The First Real Attempt
|
||||||
|
|
||||||
|
Eventually, those scattered ideas turned into something more structured: Argitek.
|
||||||
|
|
||||||
|
Argitek powered a few real systems, including Powerbid. On paper, it sounded solid:
|
||||||
|
|
||||||
|
> “Argitek Next is a powerful code generation tool designed to streamline your development workflow.”
|
||||||
|
|
||||||
|
And technically, it worked.
|
||||||
|
|
||||||
|
It could generate code from predefined templates, adapt to different scenarios, and reduce repetitive work. But something was off.
|
||||||
|
|
||||||
|
It never felt *complete*.
|
||||||
|
Not something I could confidently release.
|
||||||
|
|
||||||
|
So I did what many developers do with almost-good-enough tools—I parked it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Breaking Point: Database Migrations
|
||||||
|
|
||||||
|
Over the years, one problem kept coming back:
|
||||||
|
|
||||||
|
Database migrations.
|
||||||
|
|
||||||
|
Not the clean, theoretical kind. The real ones.
|
||||||
|
|
||||||
|
* PostgreSQL to ORM mismatches
|
||||||
|
* DBML to SQL hacks
|
||||||
|
* GORM inconsistencies
|
||||||
|
* Manual fixes after “automated” migrations failed
|
||||||
|
|
||||||
|
It was always messy. Always unpredictable. Always more work than expected.
|
||||||
|
|
||||||
|
By 2025, after a particularly tough year, I had accumulated enough of these problems to stop ignoring them.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## December 2025: RelSpecGo Begins
|
||||||
|
|
||||||
|
In December 2025, I bootstrapped something new:
|
||||||
|
|
||||||
|
**RelSpecGo**
|
||||||
|
|
||||||
|
It started simple:
|
||||||
|
|
||||||
|
* Initial LICENSE
|
||||||
|
* Basic configuration
|
||||||
|
* A direction
|
||||||
|
|
||||||
|
By late December:
|
||||||
|
|
||||||
|
* SQL writer implemented
|
||||||
|
* Diff command added
|
||||||
|
|
||||||
|
January 2026:
|
||||||
|
|
||||||
|
* Documentation
|
||||||
|
|
||||||
|
February 2026:
|
||||||
|
|
||||||
|
* Schema editor UI (focused on relationships)
|
||||||
|
* MSSQL DDL writer
|
||||||
|
* Template support with `--from-list`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## April 2026: A Real Tool Emerges
|
||||||
|
|
||||||
|
By April 2026, it became something I could finally stand behind.
|
||||||
|
|
||||||
|
RelSpecGo reached version **1.0.44**, with:
|
||||||
|
|
||||||
|
* Packaging for AUR, Debian, and RPM
|
||||||
|
* Updated documentation and README
|
||||||
|
* A full toolchain for:
|
||||||
|
|
||||||
|
* Convert
|
||||||
|
* Merge
|
||||||
|
* Inspect
|
||||||
|
* Diff
|
||||||
|
* Template
|
||||||
|
* Edit
|
||||||
|
|
||||||
|
Support includes:
|
||||||
|
|
||||||
|
* bun
|
||||||
|
* dbml
|
||||||
|
* drizzle
|
||||||
|
* gorm
|
||||||
|
* prisma
|
||||||
|
* mssql
|
||||||
|
* pgsql
|
||||||
|
* sqlite
|
||||||
|
|
||||||
|
Plus:
|
||||||
|
|
||||||
|
* TUI editor
|
||||||
|
* Template engine
|
||||||
|
* Bidirectional schema handling
|
||||||
|
|
||||||
|
👉 RelSpecGo: [https://git.warky.dev/wdevs/relspecgo](https://git.warky.dev/wdevs/relspecgo)
|
||||||
|
|
||||||
|
This wasn’t just another generator anymore.
|
||||||
|
It became a system for managing *database truth*.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Lessons Learned (The Hard Way)
|
||||||
|
|
||||||
|
This journey wasn’t about tools. It was about understanding databases properly.
|
||||||
|
|
||||||
|
Here are the principles that stuck:
|
||||||
|
|
||||||
|
### 1. Data Loss Is Not Acceptable
|
||||||
|
|
||||||
|
Changing table structures should **never** result in lost data. If it does, the process is broken.
|
||||||
|
|
||||||
|
### 2. Minimal Beats Clever
|
||||||
|
|
||||||
|
The simpler the system, the easier it is to trust—and to fix.
|
||||||
|
|
||||||
|
### 3. Respect the Database
|
||||||
|
|
||||||
|
If you fight database rules, you will lose. Stay aligned with them.
|
||||||
|
|
||||||
|
### 4. Indexes and Keys Matter More Than You Think
|
||||||
|
|
||||||
|
Performance and correctness both depend on them. Ignore them at your own risk.
|
||||||
|
|
||||||
|
### 5. Version-Control Your Backend Logic
|
||||||
|
|
||||||
|
SQL scripts, functions, migrations—these must live in version control. No exceptions.
|
||||||
|
|
||||||
|
### 6. It’s Not Migration—It’s Adaptation
|
||||||
|
|
||||||
|
You’re not just moving data. You’re fixing inconsistencies and aligning systems.
|
||||||
|
|
||||||
|
### 7. Migrations Never Go as Planned
|
||||||
|
|
||||||
|
Always assume something will break. Plan for it.
|
||||||
|
|
||||||
|
### 8. One Source of Truth Is Non-Negotiable
|
||||||
|
|
||||||
|
Your database schema must have a single, authoritative definition.
|
||||||
|
|
||||||
|
### 9. ORM Mapping Is a First-Class Concern
|
||||||
|
|
||||||
|
Your application models must reflect the database correctly. Drift causes bugs.
|
||||||
|
|
||||||
|
### 10. Audit Trails Are Critical
|
||||||
|
|
||||||
|
If you can’t track changes, you can’t trust your system.
|
||||||
|
|
||||||
|
### 11. Manage Database Functions Properly
|
||||||
|
|
||||||
|
They are part of your system—not an afterthought.
|
||||||
|
|
||||||
|
### 12. If It’s Hard to Understand, It’s Too Complex
|
||||||
|
|
||||||
|
Clarity is a feature. Complexity is technical debt.
|
||||||
|
|
||||||
|
### 13. GUIDs Have Their Place
|
||||||
|
|
||||||
|
Especially when moving data across systems. They solve real problems.
|
||||||
|
|
||||||
|
### 14. But Simplicity Still Wins
|
||||||
|
|
||||||
|
Numbered primary keys are predictable, efficient, and easy to reason about.
|
||||||
|
|
||||||
|
### 15. JSON Is Power—Use It Carefully
|
||||||
|
|
||||||
|
It adds flexibility, but too much turns structure into chaos.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Closing Thoughts
|
||||||
|
|
||||||
|
Looking back, this wasn’t about building a tool.
|
||||||
|
|
||||||
|
It was about:
|
||||||
|
|
||||||
|
* Reducing friction
|
||||||
|
* Making systems predictable
|
||||||
|
* Respecting the database as the core of the system
|
||||||
|
|
||||||
|
RelSpecGo is just the current result of that journey.
|
||||||
|
|
||||||
|
Not the end.
|
||||||
|
|
||||||
|
Just the first version that feels *right*.
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 200 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 200 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 80 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 192 KiB |
@@ -1,8 +1,8 @@
|
|||||||
# Maintainer: Hein (Warky Devs) <hein@warky.dev>
|
# Maintainer: Hein (Warky Devs) <hein@warky.dev>
|
||||||
pkgname=relspec
|
pkgname=relspec
|
||||||
pkgver=1.0.43
|
pkgver=1.0.44
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Database schema conversion and analysis tool"
|
pkgdesc="RelSpec is a comprehensive database relations management tool that reads, transforms, and writes database table specifications across multiple formats and ORMs."
|
||||||
arch=('x86_64' 'aarch64')
|
arch=('x86_64' 'aarch64')
|
||||||
url="https://git.warky.dev/wdevs/relspecgo"
|
url="https://git.warky.dev/wdevs/relspecgo"
|
||||||
license=('MIT')
|
license=('MIT')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name: relspec
|
Name: relspec
|
||||||
Version: 1.0.43
|
Version: 1.0.44
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: Database schema conversion and analysis tool
|
Summary: RelSpec is a comprehensive database relations management tool that reads, transforms, and writes database table specifications across multiple formats and ORMs.
|
||||||
|
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://git.warky.dev/wdevs/relspecgo
|
URL: https://git.warky.dev/wdevs/relspecgo
|
||||||
|
|||||||
@@ -832,7 +832,11 @@ func (r *Reader) parseRef(refStr string) *models.Constraint {
|
|||||||
for _, action := range actionList {
|
for _, action := range actionList {
|
||||||
action = strings.TrimSpace(action)
|
action = strings.TrimSpace(action)
|
||||||
|
|
||||||
if strings.HasPrefix(action, "ondelete:") {
|
if strings.HasPrefix(action, "delete:") {
|
||||||
|
constraint.OnDelete = strings.TrimSpace(strings.TrimPrefix(action, "delete:"))
|
||||||
|
} else if strings.HasPrefix(action, "update:") {
|
||||||
|
constraint.OnUpdate = strings.TrimSpace(strings.TrimPrefix(action, "update:"))
|
||||||
|
} else if strings.HasPrefix(action, "ondelete:") {
|
||||||
constraint.OnDelete = strings.TrimSpace(strings.TrimPrefix(action, "ondelete:"))
|
constraint.OnDelete = strings.TrimSpace(strings.TrimPrefix(action, "ondelete:"))
|
||||||
} else if strings.HasPrefix(action, "onupdate:") {
|
} else if strings.HasPrefix(action, "onupdate:") {
|
||||||
constraint.OnUpdate = strings.TrimSpace(strings.TrimPrefix(action, "onupdate:"))
|
constraint.OnUpdate = strings.TrimSpace(strings.TrimPrefix(action, "onupdate:"))
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ Table admin.audit_logs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relationships
|
// Relationships
|
||||||
Ref: public.posts.user_id > public.users.id [ondelete: CASCADE, onupdate: CASCADE]
|
Ref: public.posts.user_id > public.users.id [delete: CASCADE, update: CASCADE]
|
||||||
Ref: public.comments.post_id > public.posts.id [ondelete: CASCADE]
|
Ref: public.comments.post_id > public.posts.id [delete: CASCADE]
|
||||||
Ref: public.comments.user_id > public.users.id [ondelete: SET NULL]
|
Ref: public.comments.user_id > public.users.id [delete: SET NULL]
|
||||||
Ref: admin.audit_logs.user_id > public.users.id [ondelete: SET NULL]
|
Ref: admin.audit_logs.user_id > public.users.id [delete: SET NULL]
|
||||||
|
|||||||
Reference in New Issue
Block a user