https://github.com/ryanmalonzo/postgo
[WIP] A minimalist, type-safe PostgreSQL ORM for Go built with delightful developer experience.
https://github.com/ryanmalonzo/postgo
developer-experience dx go orm postgresql
Last synced: 8 months ago
JSON representation
[WIP] A minimalist, type-safe PostgreSQL ORM for Go built with delightful developer experience.
- Host: GitHub
- URL: https://github.com/ryanmalonzo/postgo
- Owner: ryanmalonzo
- Created: 2025-04-29T09:03:01.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-07-08T21:02:48.000Z (11 months ago)
- Last Synced: 2025-07-08T22:19:33.014Z (11 months ago)
- Topics: developer-experience, dx, go, orm, postgresql
- Language: Go
- Homepage:
- Size: 3.96 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# postgo - ORM PostgreSQL avec système de typage automatique
Un ORM PostgreSQL simple et léger offrant une **Developer Experience optimale** grâce à un système de génération de code qui fournit autocomplétion complète, validation des types et sécurité à la compilation.
## Installation
```bash
go mod tidy
```
## Démarrage rapide
### 1. Définir votre schéma dans `db/schema.go`
```go
func createUserTable() *TableBuilder {
return NewTable("users").
AddAttribute("name", String).NotNull().Build().
AddAttribute("email", String).NotNull().Unique().Build().
AddAttribute("password", String).NotNull().Build()
}
```
### 2. Générer le code typé
```bash
make generate
```
### 3. Utiliser avec autocomplétion complète
```go
package main
import (
"postgo/db"
"postgo/generated"
)
func main() {
conn, err := db.NewConnection("localhost", 5432, "postgo", "postgo", "postgo")
if err != nil {
panic(err)
}
defer conn.Close()
// L'IDE propose automatiquement tous les noms de colonnes !
err = generated.Users.Insert().
SetName("John Doe"). // string
SetEmail("john@example.com"). // string avec contrainte UNIQUE
SetPassword("secret123"). // string avec contrainte NOT NULL
Execute(conn)
if err != nil {
fmt.Printf("Erreur: %v\n", err)
}
// Update avec autocomplétion complète et validation !
err = generated.Users.Update().
SetName("John Doe Updated").
SetEmail("john.updated@example.com").
Where("id = 1").
Execute(conn)
if err != nil {
fmt.Printf("Erreur: %v\n", err)
}
}
```
## Utilisation
### Définition du schéma
Toutes les tables sont définies dans `db/schema.go` avec le builder pattern :
```go
// Table avec différents types de données
func createCompanyTable() *TableBuilder {
return NewTable("companies").
AddAttribute("name", String).NotNull().Unique().Build().
AddAttribute("employee_count", Integer).Build().
AddAttribute("revenue", Float).Build().
AddAttribute("is_public", Boolean).NotNull().Build()
}
```
#### Types de données disponibles
- `String` - VARCHAR(255)
- `Integer` - INTEGER
- `Float` - FLOAT
- `Boolean` - BOOLEAN
#### Contraintes disponibles
- `.NotNull()` - Ajoute NOT NULL
- `.Unique()` - Ajoute UNIQUE
### Génération et utilisation du code
```bash
# Générer le code typé
make generate
# Nettoyer et régénérer
make regen
# Tester la compilation
make test
```
Le code généré fournit :
- **Autocomplétion IDE complète** pour tous les noms de colonnes
- **Validation des types à la compilation** (impossible de passer un `int` à une colonne `string`)
- **Validation des contraintes à l'exécution** (champs NOT NULL obligatoires)
- **Prévention des erreurs** de frappe et d'incohérences
```go
// Types automatiquement détectés
generated.Companies.Insert().
SetName("Tech Corp"). // string (NOT NULL)
SetEmployeeCount(150). // int
SetRevenue(1250000.50). // float64
SetIsPublic(true). // bool (NOT NULL)
Execute(conn)
// ❌ Erreurs détectées à la compilation
generated.Users.Insert().
SetEmployeeCount("string") // Type incorrect
SetInvalidColumn("value") // Colonne inexistante
```
### Opérations Update
Le système génère également des builders typés pour les mises à jour :
```go
// Update simple avec validation automatique
generated.Users.Update().
SetName("Nouveau nom").
SetEmail("nouveau@email.com").
Where("id = 1").
Execute(conn)
// Update avec validation "au moins une colonne"
err := generated.Companies.Update().
Where("name = 'Tech Corp'"). // ❌ Erreur : aucune colonne à mettre à jour
Execute(conn)
// Update avec conditions WHERE complexes
generated.Posts.Update().
SetPublished(true).
Where("published = false AND created_at < '2024-01-01'").
Execute(conn)
```
## Architecture
### Composants principaux
- **Schéma centralisé** (`db/schema.go`) : Définition de toutes les tables
- **Générateur de code** (`cmd/generate/`) : Analyse le schéma et génère le code Go typé
- **Code généré** (`generated/`) : Structures typées avec autocomplétion complète
- **Connection** : Gestionnaire de connexion PostgreSQL
### SQL généré
Le système génère automatiquement :
- Un ID SERIAL PRIMARY KEY pour chaque table
- Les définitions de colonnes avec leurs types
- Les contraintes NOT NULL et UNIQUE
Exemple de SQL généré :
```sql
CREATE TABLE IF NOT EXISTS "users" (
"id" SERIAL PRIMARY KEY,
"name" VARCHAR(255) NOT NULL,
"email" VARCHAR(255) NOT NULL UNIQUE,
"password" VARCHAR(255) NOT NULL
)
```
## Workflow de développement
Le workflow est optimisé pour la productivité :
1. **Modifier le schéma** dans `db/schema.go`
2. **Régénérer** avec `make generate`
3. **Utiliser immédiatement** avec autocomplétion complète
```bash
# Cycle de développement
make regen # Nettoie, régénère et teste
```
## Démonstration
```bash
# Démo complète avec le système typé
go run . -demo=typed
```
## Test avec Docker
Pour tester rapidement avec PostgreSQL :
```bash
docker compose up -d
```
Cela démarre PostgreSQL et Adminer sur http://localhost:8080
## Philosophie
postgo est volontairement simple tout en offrant une **Developer Experience moderne** :
- ✅ **ID auto-incrémenté obligatoire** pour chaque table
- ✅ **Types de base** (String, Integer, Float, Boolean)
- ✅ **Contraintes essentielles** (NOT NULL, UNIQUE)
- ✅ **Opérations CRUD typées** (Insert, Update avec autocomplétion)
- ✅ **Autocomplétion complète** grâce au code généré
- ✅ **Validation à la compilation** pour éviter les erreurs
- ✅ **Simplicité d'usage** avec API intuitive
Limitations volontaires :
- ❌ Pas de foreign keys
- ❌ Pas d'index personnalisés
- ❌ Pas de relations complexes
L'objectif est de fournir un outil **simple, sûr et productif** pour des cas d'usage basiques avec la meilleure expérience développeur possible.