Extensions
Install optional Oro packages through Config.Extensions without growing the core ORM surface.
Extensions are optional packages that add cross-cutting behavior or higher-level data structures without making Oro core larger.
db, err := oro.Open(oro.Config{
Connections: map[string]oro.ConnectionConfig{
"default": {Driver: sqlite.Open("app.db")},
},
Extensions: []oro.Extension{
tenant.Extension(tenant.Fields("TenantID")),
nestedset.Extension(),
},
})
What extensions can do
An extension can hook into specific lifecycle points:
| Hook | Purpose |
|---|---|
Install |
validate configuration or initialize state |
ApplyQuery |
append query conditions, such as tenant filters |
ApplyWrite |
inject or validate write values |
ApplyConnection |
route queries to another connection |
ShardValues |
provide shard routing values |
CacheKeyValues |
add extension state to automatic cache keys |
Query-chain Apply
Query-chain extensions compose through db.Use[T]().Apply(...). Extension packages provide behavior objects, while Where, With, OrderBy, pagination, aggregation, and other query methods still come from the core ModelQuery.
products, err := db.Use[Product]().
Apply(translation.Locale("zh-CN")).
Where("Status", "online").
OrderByDesc("ID").
Get(ctx)
children, err := db.Use[Category]().
Apply(nestedset.DescendantsOf(root), nestedset.DefaultOrder()).
Where("Status", "enabled").
Get(ctx)
Structural business services remain in extension packages. For example, tree-aware create, move, and delete operations use nestedset.Use[Category](db) because they are not simple query filters.
Embedded extension fields
Some extensions need model fields. Oro supports this through marked embedded field structs:
type Category struct {
oro.Model
nestedset.NodeFields
Name string
}
nestedset.NodeFields implements Oro’s embedded-field marker, so the schema parser treats its exported fields as normal model fields. This keeps extension fields reusable without struct tags or code generation.
First-party extensions
| Package | Purpose |
|---|---|
extensions/development |
extension development guide for global hooks, apply objects, and embedded fields |
extensions/tenant |
tenant filters, write injection, connection routing, shard values, cache key values |
extensions/softdelete |
conventional soft-delete fields, default deleted-row filtering, restore, and force delete |
extensions/audit |
fill creator/updater/deleter fields and record write audit logs |
extensions/translation |
translated model fields stored in a JSON column with locale and fallback handling |
extensions/metrics |
export SQL, cache, and transaction events as metrics samples |
extensions/logroll |
single-table rolling retention for append-only log data |
extensions/nestedset |
hierarchical data with ParentID, _lft, _rgt, and Depth |