OOro

Configuration

Config, connections, pool settings, logger, timeout, extensions, and shard options.

Config shape

type Config struct {
    Default     string
    Connections map[string]ConnectionConfig
    TablePrefix string
    Location    *time.Location
    Pool        PoolConfig
    Shards      map[string]ShardConfig
    Cache       CacheStore
    Extensions  []Extension
    Logger      Logger
    LogLevel    LogLevel
    Timeout     TimeoutConfig
    Retry       RetryConfig
}

The important rule: all database drivers live under Connections.

Time location

db, err := oro.Open(oro.Config{
    Location: time.FixedZone("CST", 8*60*60),
})

Oro stores all time.Time values in UTC. This includes automatic CreatedAt / UpdatedAt / soft-delete timestamps, user-provided time fields, and time values used in query conditions.

When rows are scanned back, Oro converts time.Time values to Config.Location. If Location is not set, it defaults to time.UTC.

Table prefix

db, err := oro.Open(oro.Config{
    TablePrefix: "tenant_",
})

TablePrefix converts logical table names to physical table names at compile time.

  • s.Table("products") syncs and queries tenant_products.
  • db.Table("products") also queries tenant_products.
  • Already-prefixed names are not prefixed twice.
  • Qualified names keep their namespace and prefix the final table part, so shop.products becomes shop.tenant_products.
  • Raw SQL is never rewritten; use db.TableName("products") when composing raw SQL.
rows, err := db.Raw("select * from "+db.TableName("products")).Get(ctx)

Connections

type ConnectionConfig struct {
    Driver oro.Driver
    Reads  []oro.Driver
    Pool   *oro.PoolConfig
}
  • Driver is the primary connection.
  • Reads are read replicas.
  • Pool overrides global pool settings for this connection.

Pool

Pool: oro.PoolConfig{
    MaxOpenConns:    20,
    MaxIdleConns:    10,
    ConnMaxLifetime: time.Hour,
    ConnMaxIdleTime: 10 * time.Minute,
    PingOnOpen:      true,
}

Global pool config applies to every connection unless overridden.

Logger

Oro exposes a small logger interface so standard slog or any structured logger can be adapted.

db, err := oro.Open(oro.Config{
    Logger:   myLogger,
    LogLevel: oro.LogLevelInfo,
})

The ORM does not force a logging package into application code.

Timeout and retry

db, err := oro.Open(oro.Config{
    Timeout: oro.TimeoutConfig{
        Query:       5 * time.Second,
        Transaction: 10 * time.Second,
    },
    Retry: oro.RetryConfig{
        ReadAttempts:       2,
        TxDeadlockAttempts: 3,
    },
})

Query-level timeout is also available:

rows, err := db.Use[Product]().Timeout(2 * time.Second).Get(ctx)

Extensions

Extensions: []oro.Extension{
    tenant.Extension(tenant.Fields("TenantID", "AppID")),
}

Extension packages provide optional behavior without growing the core ORM surface. See Extensions and Tenant Extension.

Shards

Shards: map[string]oro.ShardConfig{
    "orders": {
        Connections: []string{"orders_0", "orders_1"},
        Strategy:    oro.ModShard("TenantID"),
    },
}

ModShard uses the number of configured Connections as the shard count.

Models opt into shard groups in Define:

func (Order) Define(s *oro.SchemaBuilder) {
    s.Shard("orders", "TenantID")
}
Edit this page