{"id":28773423,"url":"https://github.com/ryanmalonzo/postgo","last_synced_at":"2025-10-07T18:58:14.621Z","repository":{"id":295765126,"uuid":"974757018","full_name":"ryanmalonzo/postgo","owner":"ryanmalonzo","description":"[WIP] A minimalist, type-safe PostgreSQL ORM for Go built with delightful developer experience.","archived":false,"fork":false,"pushed_at":"2025-07-08T21:02:48.000Z","size":4154,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-08T22:19:33.014Z","etag":null,"topics":["developer-experience","dx","go","orm","postgresql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryanmalonzo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-29T09:03:01.000Z","updated_at":"2025-05-27T14:53:44.000Z","dependencies_parsed_at":"2025-05-29T16:18:33.191Z","dependency_job_id":null,"html_url":"https://github.com/ryanmalonzo/postgo","commit_stats":null,"previous_names":["ryanmalonzo/postgo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ryanmalonzo/postgo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanmalonzo%2Fpostgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanmalonzo%2Fpostgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanmalonzo%2Fpostgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanmalonzo%2Fpostgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryanmalonzo","download_url":"https://codeload.github.com/ryanmalonzo/postgo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanmalonzo%2Fpostgo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264396622,"owners_count":23601541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-experience","dx","go","orm","postgresql"],"created_at":"2025-06-17T14:41:19.479Z","updated_at":"2025-10-07T18:58:14.614Z","avatar_url":"https://github.com/ryanmalonzo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# postgo - ORM PostgreSQL avec système de typage automatique\n\nUn 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.\n\n## Installation\n\n```bash\ngo mod tidy\n```\n\n## Démarrage rapide\n\n### 1. Définir votre schéma dans `db/schema.go`\n\n```go\nfunc createUserTable() *TableBuilder {\n    return NewTable(\"users\").\n        AddAttribute(\"name\", String).NotNull().Build().\n        AddAttribute(\"email\", String).NotNull().Unique().Build().\n        AddAttribute(\"password\", String).NotNull().Build()\n}\n```\n\n### 2. Générer le code typé\n\n```bash\nmake generate\n```\n\n### 3. Utiliser avec autocomplétion complète\n\n```go\npackage main\n\nimport (\n    \"postgo/db\"\n    \"postgo/generated\"\n)\n\nfunc main() {\n    conn, err := db.NewConnection(\"localhost\", 5432, \"postgo\", \"postgo\", \"postgo\")\n    if err != nil {\n        panic(err)\n    }\n    defer conn.Close()\n\n    // L'IDE propose automatiquement tous les noms de colonnes !\n    err = generated.Users.Insert().\n        SetName(\"John Doe\").          // string\n        SetEmail(\"john@example.com\"). // string avec contrainte UNIQUE  \n        SetPassword(\"secret123\").     // string avec contrainte NOT NULL\n        Execute(conn)\n    \n    if err != nil {\n        fmt.Printf(\"Erreur: %v\\n\", err)\n    }\n\n    // Update avec autocomplétion complète et validation !\n    err = generated.Users.Update().\n        SetName(\"John Doe Updated\").\n        SetEmail(\"john.updated@example.com\").\n        Where(\"id = 1\").\n        Execute(conn)\n    \n    if err != nil {\n        fmt.Printf(\"Erreur: %v\\n\", err)\n    }\n}\n```\n\n## Utilisation\n\n### Définition du schéma\n\nToutes les tables sont définies dans `db/schema.go` avec le builder pattern :\n\n```go\n// Table avec différents types de données\nfunc createCompanyTable() *TableBuilder {\n    return NewTable(\"companies\").\n        AddAttribute(\"name\", String).NotNull().Unique().Build().\n        AddAttribute(\"employee_count\", Integer).Build().\n        AddAttribute(\"revenue\", Float).Build().\n        AddAttribute(\"is_public\", Boolean).NotNull().Build()\n}\n```\n\n#### Types de données disponibles\n\n- `String` - VARCHAR(255)\n- `Integer` - INTEGER  \n- `Float` - FLOAT\n- `Boolean` - BOOLEAN\n\n#### Contraintes disponibles\n\n- `.NotNull()` - Ajoute NOT NULL\n- `.Unique()` - Ajoute UNIQUE\n\n### Génération et utilisation du code\n\n```bash\n# Générer le code typé\nmake generate\n\n# Nettoyer et régénérer\nmake regen\n\n# Tester la compilation\nmake test\n```\n\nLe code généré fournit :\n\n- **Autocomplétion IDE complète** pour tous les noms de colonnes\n- **Validation des types à la compilation** (impossible de passer un `int` à une colonne `string`)\n- **Validation des contraintes à l'exécution** (champs NOT NULL obligatoires)\n- **Prévention des erreurs** de frappe et d'incohérences\n\n```go\n// Types automatiquement détectés\ngenerated.Companies.Insert().\n    SetName(\"Tech Corp\").           // string (NOT NULL)\n    SetEmployeeCount(150).          // int\n    SetRevenue(1250000.50).         // float64\n    SetIsPublic(true).              // bool (NOT NULL)\n    Execute(conn)\n\n// ❌ Erreurs détectées à la compilation\ngenerated.Users.Insert().\n    SetEmployeeCount(\"string\")      // Type incorrect\n    SetInvalidColumn(\"value\")       // Colonne inexistante\n```\n\n### Opérations Update\n\nLe système génère également des builders typés pour les mises à jour :\n\n```go\n// Update simple avec validation automatique\ngenerated.Users.Update().\n    SetName(\"Nouveau nom\").\n    SetEmail(\"nouveau@email.com\").\n    Where(\"id = 1\").\n    Execute(conn)\n\n// Update avec validation \"au moins une colonne\"\nerr := generated.Companies.Update().\n    Where(\"name = 'Tech Corp'\").    // ❌ Erreur : aucune colonne à mettre à jour\n    Execute(conn)\n\n// Update avec conditions WHERE complexes\ngenerated.Posts.Update().\n    SetPublished(true).\n    Where(\"published = false AND created_at \u003c '2024-01-01'\").\n    Execute(conn)\n```\n\n## Architecture\n\n### Composants principaux\n\n- **Schéma centralisé** (`db/schema.go`) : Définition de toutes les tables\n- **Générateur de code** (`cmd/generate/`) : Analyse le schéma et génère le code Go typé\n- **Code généré** (`generated/`) : Structures typées avec autocomplétion complète\n- **Connection** : Gestionnaire de connexion PostgreSQL\n\n### SQL généré\n\nLe système génère automatiquement :\n\n- Un ID SERIAL PRIMARY KEY pour chaque table\n- Les définitions de colonnes avec leurs types\n- Les contraintes NOT NULL et UNIQUE\n\nExemple de SQL généré :\n\n```sql\nCREATE TABLE IF NOT EXISTS \"users\" (\n    \"id\" SERIAL PRIMARY KEY,\n    \"name\" VARCHAR(255) NOT NULL,\n    \"email\" VARCHAR(255) NOT NULL UNIQUE,\n    \"password\" VARCHAR(255) NOT NULL\n)\n```\n\n## Workflow de développement\n\nLe workflow est optimisé pour la productivité :\n\n1. **Modifier le schéma** dans `db/schema.go`\n2. **Régénérer** avec `make generate` \n3. **Utiliser immédiatement** avec autocomplétion complète\n\n```bash\n# Cycle de développement\nmake regen    # Nettoie, régénère et teste\n```\n\n## Démonstration\n\n```bash\n# Démo complète avec le système typé\ngo run . -demo=typed\n```\n\n## Test avec Docker\n\nPour tester rapidement avec PostgreSQL :\n\n```bash\ndocker compose up -d\n```\n\nCela démarre PostgreSQL et Adminer sur http://localhost:8080\n\n## Philosophie\n\npostgo est volontairement simple tout en offrant une **Developer Experience moderne** :\n\n- ✅ **ID auto-incrémenté obligatoire** pour chaque table\n- ✅ **Types de base** (String, Integer, Float, Boolean) \n- ✅ **Contraintes essentielles** (NOT NULL, UNIQUE)\n- ✅ **Opérations CRUD typées** (Insert, Update avec autocomplétion)\n- ✅ **Autocomplétion complète** grâce au code généré\n- ✅ **Validation à la compilation** pour éviter les erreurs\n- ✅ **Simplicité d'usage** avec API intuitive\n\nLimitations volontaires :\n- ❌ Pas de foreign keys\n- ❌ Pas d'index personnalisés  \n- ❌ Pas de relations complexes\n\nL'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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanmalonzo%2Fpostgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryanmalonzo%2Fpostgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanmalonzo%2Fpostgo/lists"}