193 lines
4.8 KiB
Go
193 lines
4.8 KiB
Go
|
//
|
||
|
// configurators.go
|
||
|
// Copyright (C) 2023 tiglog <me@tiglog.com>
|
||
|
//
|
||
|
// Distributed under terms of the MIT license.
|
||
|
//
|
||
|
|
||
|
package orm
|
||
|
|
||
|
import (
|
||
|
"database/sql"
|
||
|
|
||
|
"git.hexq.cn/tiglog/golib/helper"
|
||
|
)
|
||
|
|
||
|
type EntityConfigurator struct {
|
||
|
connection string
|
||
|
table string
|
||
|
this Entity
|
||
|
relations map[string]interface{}
|
||
|
resolveRelations []func()
|
||
|
columnConstraints []*FieldConfigurator
|
||
|
}
|
||
|
|
||
|
func newEntityConfigurator() *EntityConfigurator {
|
||
|
return &EntityConfigurator{}
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) Table(name string) *EntityConfigurator {
|
||
|
ec.table = name
|
||
|
return ec
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) Connection(name string) *EntityConfigurator {
|
||
|
ec.connection = name
|
||
|
return ec
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) HasMany(property Entity, config HasManyConfig) *EntityConfigurator {
|
||
|
if ec.relations == nil {
|
||
|
ec.relations = map[string]interface{}{}
|
||
|
}
|
||
|
ec.resolveRelations = append(ec.resolveRelations, func() {
|
||
|
if config.PropertyForeignKey != "" && config.PropertyTable != "" {
|
||
|
ec.relations[config.PropertyTable] = config
|
||
|
return
|
||
|
}
|
||
|
configurator := newEntityConfigurator()
|
||
|
property.ConfigureEntity(configurator)
|
||
|
|
||
|
if config.PropertyTable == "" {
|
||
|
config.PropertyTable = configurator.table
|
||
|
}
|
||
|
|
||
|
if config.PropertyForeignKey == "" {
|
||
|
config.PropertyForeignKey = helper.NewPluralizeClient().Singular(ec.table) + "_id"
|
||
|
}
|
||
|
|
||
|
ec.relations[configurator.table] = config
|
||
|
|
||
|
return
|
||
|
})
|
||
|
return ec
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) HasOne(property Entity, config HasOneConfig) *EntityConfigurator {
|
||
|
if ec.relations == nil {
|
||
|
ec.relations = map[string]interface{}{}
|
||
|
}
|
||
|
ec.resolveRelations = append(ec.resolveRelations, func() {
|
||
|
if config.PropertyForeignKey != "" && config.PropertyTable != "" {
|
||
|
ec.relations[config.PropertyTable] = config
|
||
|
return
|
||
|
}
|
||
|
|
||
|
configurator := newEntityConfigurator()
|
||
|
property.ConfigureEntity(configurator)
|
||
|
|
||
|
if config.PropertyTable == "" {
|
||
|
config.PropertyTable = configurator.table
|
||
|
}
|
||
|
if config.PropertyForeignKey == "" {
|
||
|
config.PropertyForeignKey = helper.NewPluralizeClient().Singular(ec.table) + "_id"
|
||
|
}
|
||
|
|
||
|
ec.relations[configurator.table] = config
|
||
|
return
|
||
|
})
|
||
|
return ec
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) BelongsTo(owner Entity, config BelongsToConfig) *EntityConfigurator {
|
||
|
if ec.relations == nil {
|
||
|
ec.relations = map[string]interface{}{}
|
||
|
}
|
||
|
ec.resolveRelations = append(ec.resolveRelations, func() {
|
||
|
if config.ForeignColumnName != "" && config.LocalForeignKey != "" && config.OwnerTable != "" {
|
||
|
ec.relations[config.OwnerTable] = config
|
||
|
return
|
||
|
}
|
||
|
ownerConfigurator := newEntityConfigurator()
|
||
|
owner.ConfigureEntity(ownerConfigurator)
|
||
|
if config.OwnerTable == "" {
|
||
|
config.OwnerTable = ownerConfigurator.table
|
||
|
}
|
||
|
if config.LocalForeignKey == "" {
|
||
|
config.LocalForeignKey = helper.NewPluralizeClient().Singular(ownerConfigurator.table) + "_id"
|
||
|
}
|
||
|
if config.ForeignColumnName == "" {
|
||
|
config.ForeignColumnName = "id"
|
||
|
}
|
||
|
ec.relations[ownerConfigurator.table] = config
|
||
|
})
|
||
|
return ec
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) BelongsToMany(owner Entity, config BelongsToManyConfig) *EntityConfigurator {
|
||
|
if ec.relations == nil {
|
||
|
ec.relations = map[string]interface{}{}
|
||
|
}
|
||
|
ec.resolveRelations = append(ec.resolveRelations, func() {
|
||
|
ownerConfigurator := newEntityConfigurator()
|
||
|
owner.ConfigureEntity(ownerConfigurator)
|
||
|
|
||
|
if config.OwnerLookupColumn == "" {
|
||
|
var pkName string
|
||
|
for _, field := range genericFieldsOf(owner) {
|
||
|
if field.IsPK {
|
||
|
pkName = field.Name
|
||
|
}
|
||
|
}
|
||
|
config.OwnerLookupColumn = pkName
|
||
|
|
||
|
}
|
||
|
if config.OwnerTable == "" {
|
||
|
config.OwnerTable = ownerConfigurator.table
|
||
|
}
|
||
|
if config.IntermediateTable == "" {
|
||
|
panic("cannot infer intermediate table yet")
|
||
|
}
|
||
|
if config.IntermediatePropertyID == "" {
|
||
|
config.IntermediatePropertyID = helper.NewPluralizeClient().Singular(ownerConfigurator.table) + "_id"
|
||
|
}
|
||
|
if config.IntermediateOwnerID == "" {
|
||
|
config.IntermediateOwnerID = helper.NewPluralizeClient().Singular(ec.table) + "_id"
|
||
|
}
|
||
|
|
||
|
ec.relations[ownerConfigurator.table] = config
|
||
|
})
|
||
|
return ec
|
||
|
}
|
||
|
|
||
|
type FieldConfigurator struct {
|
||
|
fieldName string
|
||
|
nullable sql.NullBool
|
||
|
primaryKey bool
|
||
|
column string
|
||
|
isCreatedAt bool
|
||
|
isUpdatedAt bool
|
||
|
isDeletedAt bool
|
||
|
}
|
||
|
|
||
|
func (ec *EntityConfigurator) Field(name string) *FieldConfigurator {
|
||
|
cc := &FieldConfigurator{fieldName: name}
|
||
|
ec.columnConstraints = append(ec.columnConstraints, cc)
|
||
|
return cc
|
||
|
}
|
||
|
|
||
|
func (fc *FieldConfigurator) IsPrimaryKey() *FieldConfigurator {
|
||
|
fc.primaryKey = true
|
||
|
return fc
|
||
|
}
|
||
|
|
||
|
func (fc *FieldConfigurator) IsCreatedAt() *FieldConfigurator {
|
||
|
fc.isCreatedAt = true
|
||
|
return fc
|
||
|
}
|
||
|
|
||
|
func (fc *FieldConfigurator) IsUpdatedAt() *FieldConfigurator {
|
||
|
fc.isUpdatedAt = true
|
||
|
return fc
|
||
|
}
|
||
|
|
||
|
func (fc *FieldConfigurator) IsDeletedAt() *FieldConfigurator {
|
||
|
fc.isDeletedAt = true
|
||
|
return fc
|
||
|
}
|
||
|
|
||
|
func (fc *FieldConfigurator) ColumnName(name string) *FieldConfigurator {
|
||
|
fc.column = name
|
||
|
return fc
|
||
|
}
|