UUID Support
go-lightning supports UUID primary keys through dedicated insert functions.
When to Use UUIDs
UUIDs are useful when you need:
- Globally unique identifiers across systems
- IDs that don't reveal sequence information
- Client-generated IDs before server insertion
- Distributed systems without ID coordination
Model Definition
Define your model with a string ID:
type Session struct {
Id string
UserId int
Token string
ExpiresAt time.Time
}When registering, go-lightning detects that Id is not an integer and sets HasIntId = false. This changes how INSERT queries are generated.
InsertUuid
Use this when you want go-lightning to generate the UUID:
func InsertUuid[T any](ex Executor, t *T) (string, error)Example
type Session struct {
Id string
UserId int
Token string
ExpiresAt time.Time
}
lit.RegisterModel[Session](lit.PostgreSQL)
session := Session{
UserId: 123,
Token: "abc123",
ExpiresAt: time.Now().Add(24 * time.Hour),
}
// go-lightning generates UUID and sets it on the struct
uuid, err := lit.InsertUuid(db, &session)
if err != nil {
return err
}
fmt.Printf("Created session: %s\n", uuid)
fmt.Printf("session.Id is also set: %s\n", session.Id)
// Both print the same UUIDHow It Works
- Generates a new UUID using
github.com/google/uuid - Sets the UUID on the struct's
Idfield - Executes the INSERT with all fields including the ID
- Returns the generated UUID
InsertExistingUuid
Use this when you already have a UUID:
func InsertExistingUuid[T any](ex Executor, t *T) errorExample
session := Session{
Id: "550e8400-e29b-41d4-a716-446655440000", // Pre-generated or received from client
UserId: 123,
Token: "abc123",
ExpiresAt: time.Now().Add(24 * time.Hour),
}
err := lit.InsertExistingUuid(db, &session)
if err != nil {
return err
}Use Cases
- Receiving UUIDs from clients (e.g., offline-first apps)
- Migrating data with existing IDs
- Testing with deterministic IDs
- Distributed ID generation (e.g., from a separate service)
Database Schema
Ensure your database table can store UUIDs:
PostgreSQL
CREATE TABLE sessions (
id UUID PRIMARY KEY,
user_id INTEGER NOT NULL,
token VARCHAR(255) NOT NULL,
expires_at TIMESTAMP NOT NULL
);Or with text storage:
CREATE TABLE sessions (
id VARCHAR(36) PRIMARY KEY,
user_id INTEGER NOT NULL,
token VARCHAR(255) NOT NULL,
expires_at TIMESTAMP NOT NULL
);MySQL
CREATE TABLE sessions (
id VARCHAR(36) PRIMARY KEY,
user_id INT NOT NULL,
token VARCHAR(255) NOT NULL,
expires_at DATETIME NOT NULL
);Or with BINARY storage for efficiency:
CREATE TABLE sessions (
id BINARY(16) PRIMARY KEY,
user_id INT NOT NULL,
token VARCHAR(255) NOT NULL,
expires_at DATETIME NOT NULL
);Complete Example
package main
import (
"database/sql"
"time"
"github.com/tracewayapp/go-lightning/lit"
_ "github.com/lib/pq"
)
type ApiKey struct {
Id string
UserId int
Name string
Key string
CreatedAt time.Time
}
func init() {
lit.RegisterModel[ApiKey](lit.PostgreSQL)
}
type ApiKeyRepository struct{}
func (r *ApiKeyRepository) Create(ex lit.Executor, userId int, name string, key string) (*ApiKey, error) {
apiKey := ApiKey{
UserId: userId,
Name: name,
Key: key,
CreatedAt: time.Now(),
}
_, err := lit.InsertUuid(ex, &apiKey)
if err != nil {
return nil, err
}
return &apiKey, nil
}
func (r *ApiKeyRepository) FindById(ex lit.Executor, id string) (*ApiKey, error) {
return lit.SelectSingle[ApiKey](ex,
"SELECT id, user_id, name, key, created_at FROM api_keys WHERE id = $1", id)
}
func (r *ApiKeyRepository) FindByUserId(ex lit.Executor, userId int) ([]*ApiKey, error) {
return lit.Select[ApiKey](ex,
"SELECT id, user_id, name, key, created_at FROM api_keys WHERE user_id = $1", userId)
}