Skip to content

yyle88/gormcnm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

64 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GitHub Workflow Status (branch) GoDoc Coverage Status Supported Go Versions GitHub Release Go Report Card

πŸ—οΈ GORMCNM - Foundation of Type-Safe GORM Ecosystem

gormcnm is the foundational library that powers the entire GORM type-safety ecosystem. As the cornerstone of enterprise-grade Go database operations, it provides the core ColumnName[T] generic type that enables compile-time type safety, eliminates hardcoded strings, and transforms GORM into a truly robust ORM solution.

🎯 The Foundation Layer: Just as React needs a virtual DOM and Spring needs dependency injection, GORM needs gormcnm for enterprise-grade type safety.


CHINESE README

δΈ­ζ–‡θ―΄ζ˜Ž


🌟 Why GORMCNM is Essential

⚑ The Core Problem GORMCNM Solves

Traditional GORM queries are fragile and error-prone:

// ❌ Traditional: Brittle hardcoded strings
db.Where("username = ?", "alice").Where("age >= ?", 18).First(&user)

Problems:

  • ❌ Runtime failures from typos ("usrname" vs "username")
  • ❌ Silent bugs when model fields change
  • ❌ No type checking between column types and values
  • ❌ Refactoring nightmares across large codebases

✨ The GORMCNM Solution

// βœ… GORMCNM: Type-safe, refactor-proof, enterprise-ready
const (
colUsername = gormcnm.ColumnName[string]("username")
colAge = gormcnm.ColumnName[int]("age")
)

db.Where(colUsername.Eq("alice")).Where(colAge.Gte(18)).First(&user)

Benefits:

  • βœ… Compile-time validation catches errors before deployment
  • βœ… IDE auto-completion prevents typos completely
  • βœ… Automatic refactoring when model fields change
  • βœ… Type safety ensures value types match column types

πŸ—οΈ GORMCNM Ecosystem Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GORM Type-Safe Ecosystem                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚
β”‚  β”‚  gormzhcn   β”‚    β”‚  gormmom    β”‚    β”‚  gormrepo   β”‚              β”‚
β”‚  β”‚ Chinese API │───▢│ Native Lang │───▢│  Package    │─────┐        β”‚
β”‚  β”‚  Localize   β”‚    β”‚  Smart Tags β”‚    β”‚  Pattern    β”‚     β”‚        β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚        β”‚
β”‚         β”‚                   β”‚                              β”‚        β”‚
β”‚         β”‚                   β–Ό                              β–Ό        β”‚
β”‚         β”‚            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚         β”‚            β”‚ gormcngen   β”‚              β”‚Application  β”‚   β”‚
β”‚         β”‚            β”‚Code Generate│─────────────▢│Custom Code  β”‚   β”‚
β”‚         β”‚            β”‚AST Operationβ”‚              β”‚             β”‚   β”‚
β”‚         β”‚            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚         β”‚                   β”‚                              β–²        β”‚
β”‚         β”‚                   β–Ό                              β”‚        β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Άβ”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β—„β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β”‚                       β”‚   GORMCNM   β”‚                               β”‚
β”‚                       β”‚ FOUNDATION  β”‚                               β”‚
β”‚                       β”‚ Type-Safe   β”‚                               β”‚
β”‚                       β”‚ Core Logic  β”‚                               β”‚
β”‚                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β”‚
β”‚                              β”‚                                      β”‚
β”‚                              β–Ό                                      β”‚
β”‚                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                               β”‚
β”‚                       β”‚    GORM     β”‚                               β”‚
β”‚                       β”‚  Database   β”‚                               β”‚
β”‚                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

GORMCNM sits at the foundation layer, providing the core type-safe primitives that all other ecosystem components depend on.


πŸš€ Installation

go get github.com/yyle88/gormcnm

πŸ’‘ Core Concept: Generic Column Names

The ColumnName[T] Type

At the heart of GORMCNM is the generic ColumnName[T] type:

type ColumnName[T any] string

This simple yet powerful type provides:

  • Type-safe operations: Eq(), Ne(), Gt(), Lt(), In(), Between(), etc.
  • Value-key pairs: Kv() for updates, Kw() for map building
  • Expression building: ExprAdd(), ExprSub(), ExprMul(), etc.
  • Order clauses: Asc(), Desc(), OrderByBottle() for complex sorting

Language Ecosystem Comparison

Language ORM Type-Safe Columns Example
Java MyBatis Plus Example::getName wrapper.eq(Example::getName, "alice")
Python SQLAlchemy Example.name query.filter(Example.name == "alice")
Go GORMCNM cls.Name.Eq() db.Where(cls.Name.Eq("alice"))

πŸ”₯ Quick Start Example

package main

import (
	"fmt"
	"github.com/google/uuid"
	"github.com/yyle88/done"
	"github.com/yyle88/gormcnm"
	"github.com/yyle88/rese"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

type User struct {
	ID       uint   `gorm:"primaryKey"`
	Username string `gorm:"uniqueIndex"`
	Age      int
	Email    string `gorm:"index"`
}

// Define type-safe columns
const (
	colID       = gormcnm.ColumnName[uint]("id")
	colUsername = gormcnm.ColumnName[string]("username")
	colAge      = gormcnm.ColumnName[int]("age")
	colEmail    = gormcnm.ColumnName[string]("email")
)

func main() {
	// Setup database
	dsn := fmt.Sprintf("file:db-%s?mode=memory&cache=shared", uuid.New().String())
	db := rese.P1(gorm.Open(sqlite.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
	}))
	defer rese.F0(rese.P1(db.DB()).Close)

	done.Done(db.AutoMigrate(&User{}))

	// Insert test data
	users := []*User{
		{Username: "alice", Age: 25, Email: "alice@example.com"},
		{Username: "bob", Age: 30, Email: "bob@example.com"},
	}
	done.Done(db.Create(users).Error)

	// Type-safe queries
	var user User
	done.Done(db.Where(colUsername.Eq("alice")).First(&user).Error)
	fmt.Printf("Found user: %+v\n", user)

	// Complex type-safe queries
	var adults []User
	done.Done(db.Where(colAge.Gte(25)).
		Where(colEmail.Like("%@example.com")).
		Find(&adults).Error)
	fmt.Printf("Adults: %d users\n", len(adults))

	// Type-safe updates
	done.Done(db.Model(&user).Where(colID.Eq(user.ID)).
		Update(colAge.Kv(26)).Error)

	// Bulk updates with type safety
	done.Done(db.Model(&User{}).
		Where(colAge.Between(20, 30)).
		Updates(colAge.Kw(99).Kw(colEmail.Kv("updated@example.com")).AsMap()).Error)
}

🎯 Core Features & Operations

Query Operations

// Comparison operations
db.Where(colAge.Eq(25))           // age = 25
db.Where(colAge.Ne(25)) // age != 25
db.Where(colAge.Gt(25)) // age > 25
db.Where(colAge.Gte(25)) // age >= 25
db.Where(colAge.Lt(30)) // age < 30
db.Where(colAge.Lte(30))          // age <= 30

// Range operations
db.Where(colAge.Between(18, 65)) // age BETWEEN 18 AND 65
db.Where(colAge.In([]int{18, 25, 30})) // age IN (18, 25, 30)

// String operations
db.Where(colUsername.Like("%admin%")) // username LIKE '%admin%'
db.Where(colEmail.IsNotNULL()) // email IS NOT NULL
db.Where(colUsername.BetweenAND("a", "m")) // username BETWEEN 'a' AND 'm'

Update Operations

// Single field updates
db.Model(&user).Update(colAge.Kv(26))

// Multiple field updates
updates := colAge.Kw(26).Kw(colEmail.Kv("new@example.com")).AsMap()
db.Model(&user).Updates(updates)

// Expression updates
db.Model(&user).Update(colAge.KeAdd(1))  // age = age + 1
db.Model(&user).Update(colAge.KeSub(2)) // age = age - 2

Ordering Operations

// Simple ordering
db.Order(colAge.Asc()) // ORDER BY age ASC
db.Order(colAge.Desc())  // ORDER BY age DESC

// Complex ordering for repository patterns
orderBottle := colAge.OrderByBottle("DESC")
// Used in advanced repository patterns with gormrepo

🏒 Enterprise-Grade Benefits

πŸ”’ Compile-Time Type Safety

  • Zero runtime column errors: All column references validated at compile time
  • Type matching: Ensures values match column types (string values for string columns)
  • Refactoring safety: IDE automatically updates all references when model fields change

πŸš€ Developer Productivity

  • IDE intelligence: Full auto-completion and error highlighting
  • Code clarity: Self-documenting queries that clearly show column operations
  • Reduced debugging: Eliminate entire classes of column-name-related bugs

🌍 Ecosystem Integration

  • gormcngen: Auto-generates column definitions
  • gormrepo: Repository pattern with type-safe queries
  • gormmom: Native language field support

⚑ Progressive Adoption

  • No breaking changes: Integrates seamlessly with existing GORM code
  • Incremental migration: Adopt type-safe columns one query at a time
  • Zero learning curve: Familiar GORM syntax with added type safety

πŸ”„ Traditional vs GORMCNM Comparison

Aspect Traditional GORM GORMCNM
Column References ❌ "username" (hardcoded strings) βœ… colUsername.Eq() (type-safe)
Error Detection ❌ Runtime failures βœ… Compile-time validation
Refactoring ❌ Manual find-replace, error-prone βœ… IDE auto-refactor, bulletproof
Type Checking ❌ No value-type validation βœ… Strong type checking
IDE Support ❌ No auto-completion for columns βœ… Full IntelliSense support
Maintainability 🟑 Manual maintenance required βœ… Self-maintaining with AST tools
Learning Curve 🟒 Familiar GORM syntax 🟒 Same syntax + type safety

Code Comparison

// ❌ Traditional GORM: Fragile and error-prone
db.Where("username = ?", "alice").
Where("age >= ?", 18).
Where("email LIKE ?", "%@company.com").
First(&user)

// βœ… GORMCNM: Type-safe and refactor-proof
db.Where(colUsername.Eq("alice")).
Where(colAge.Gte(18)).
Where(colEmail.Like("%@company.com")).
First(&user)

πŸ—οΈ Advanced Usage Patterns

Working with Generated Columns

When combined with gormcngen, you get auto-generated column structs:

type UserColumns struct {
ID       gormcnm.ColumnName[uint]
Username gormcnm.ColumnName[string]
Age      gormcnm.ColumnName[int]
Email    gormcnm.ColumnName[string]
}

func (*User) Columns() *UserColumns {
return &UserColumns{
ID:       "id",
Username: "username",
Age:      "age",
Email:    "email",
}
}

// Usage with generated columns
var user User
cls := user.Columns()
db.Where(cls.Username.Eq("alice")).
Where(cls.Age.Gte(18)).
First(&user)

Repository Pattern Integration

GORMCNM integrates seamlessly with gormrepo:

repo := gormrepo.NewRepo(gormclass.Use(&User{}))

// Type-safe repository queries
user, err := repo.Repo(db).First(func (db *gorm.DB, cls *UserColumns) *gorm.DB {
return db.Where(cls.Username.Eq("alice")).
Where(cls.Age.Gte(18))
})

Complex Query Building

// Build complex conditions with type safety
var users []User
err := db.Where(
colAge.Between(18, 65),
).Where(
colEmail.IsNotNULL(),
).Where(
colUsername.In([]string{"alice", "bob", "charlie"}),
).Order(
colAge.Asc(),
).Limit(10).Find(&users).Error

🌍 Global Ecosystem Impact

Java MyBatis Plus Equivalent

// Java: MyBatis Plus
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getUsername, "alice")
       .ge(User::getAge, 18);
List<User> users = userMapper.selectList(wrapper);

Python SQLAlchemy Equivalent

# Python: SQLAlchemy
users = session.query(User).filter(
    User.username == "alice",
    User.age >= 18
).all()

Go GORMCNM Solution

// Go: GORMCNM
var users []User
db.Where(colUsername.Eq("alice")).
Where(colAge.Gte(18)).
Find(&users)

GORMCNM brings the same level of type safety and developer experience to Go that other ecosystems take for granted.


πŸ“Š Performance & Production Readiness

Zero Performance Overhead

  • Compile-time only: All type checking happens during compilation
  • Runtime efficiency: Generated code is identical to hand-written GORM queries
  • Memory efficient: No reflection, no runtime type checking

Production Battle-Tested

  • Enterprise deployments: Used in production systems processing millions of queries
  • Comprehensive test coverage: Extensive test suites ensure reliability
  • Active maintenance: Regular updates and community support

πŸ”— Ecosystem Components

Foundation Layer

  • gormcnm - Type-safe column operations (this package)

Code Generation Layer

  • gormcngen - Auto-generates column structs from models
  • gormmom - Native language field tag management

Application Layer

  • gormrepo - Repository pattern with type-safe queries

🎯 Getting Started Checklist

  1. Install GORMCNM: go get github.com/yyle88/gormcnm
  2. Define column constants: Create type-safe column definitions for your models
  3. Replace hardcoded strings: Gradually migrate existing queries to use typed columns
  4. Add code generation: Optionally integrate with gormcngen for automatic column generation
  5. Scale with repository pattern: Use gormrepo for enterprise-grade database operations

πŸ“„ License

MIT License. See LICENSE.


🀝 Contributing

Contributions are welcome! Report bugs, suggest features, and contribute code:

  • πŸ› Found a bug? Open an issue on GitHub with reproduction steps
  • πŸ’‘ Have a feature idea? Create an issue to discuss the suggestion
  • πŸ“– Documentation confusing? Report it so we can improve
  • πŸš€ Need new features? Share your use cases to help us understand requirements
  • ⚑ Performance issue? Help us optimize by reporting slow operations
  • πŸ”§ Configuration problem? Ask questions about complex setups
  • πŸ“’ Follow project progress? Watch the repo for new releases and features
  • 🌟 Success stories? Share how this package improved your workflow
  • πŸ’¬ General feedback? All suggestions and comments are welcome

πŸ”§ Development

New code contributions, follow this process:

  1. Fork: Fork the repo on GitHub (using the webpage interface).
  2. Clone: Clone the forked project (git clone https://github.com/yourname/repo-name.git).
  3. Navigate: Navigate to the cloned project (cd repo-name)
  4. Branch: Create a feature branch (git checkout -b feature/xxx).
  5. Code: Implement your changes with comprehensive tests
  6. Testing: (Golang project) Ensure tests pass (go test ./...) and follow Go code style conventions
  7. Documentation: Update documentation for user-facing changes and use meaningful commit messages
  8. Stage: Stage changes (git add .)
  9. Commit: Commit changes (git commit -m "Add feature xxx") ensuring backward compatible code
  10. Push: Push to the branch (git push origin feature/xxx).
  11. PR: Open a pull request on GitHub (on the GitHub webpage) with detailed description.

Please ensure tests pass and include relevant documentation updates.


🌟 Support

Welcome to contribute to this project by submitting pull requests and reporting issues.

Project Support:

  • ⭐ Give GitHub stars if this project helps you
  • 🀝 Share with teammates and (golang) programming friends
  • πŸ“ Write tech blogs about development tools and workflows - we provide content writing support
  • 🌟 Join the ecosystem - committed to supporting open source and the (golang) development scene

Happy Coding with this package! πŸŽ‰


πŸ“ˆ GitHub Stars

starring


πŸ”— Related Projects

  • πŸ—οΈ gormcnm - Type-safe column foundation (this package)
  • πŸ€– gormcngen - Smart code generation
  • 🏒 gormrepo - Enterprise repository pattern
  • 🌍 gormmom - Native language programming

About

`gormcnm` - A Progressive, Type-Safe Approach to GORM Column Names Using Generics

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •