package orm
import (
)
var _tables = newTables()
type tableInProgress struct {
table *Table
init1Once sync.Once
init2Once sync.Once
}
func ( *Table) *tableInProgress {
return &tableInProgress{
table: ,
}
}
func ( *tableInProgress) () bool {
var bool
.init1Once.Do(func() {
.table.init1()
= true
})
return
}
func ( *tableInProgress) () bool {
var bool
.init2Once.Do(func() {
.table.init2()
= true
})
return
}
func ( reflect.Type) *Table {
return _tables.Get()
}
func ( interface{}) {
_tables.Register()
}
type tables struct {
tables sync.Map
mu sync.RWMutex
inProgress map[reflect.Type]*tableInProgress
}
func () *tables {
return &tables{
inProgress: make(map[reflect.Type]*tableInProgress),
}
}
func ( *tables) ( interface{}) {
:= reflect.TypeOf()
if .Kind() == reflect.Ptr {
= .Elem()
}
_ = .Get()
}
func ( *tables) ( reflect.Type, bool) *Table {
if .Kind() != reflect.Struct {
panic(fmt.Errorf("got %s, wanted %s", .Kind(), reflect.Struct))
}
if , := .tables.Load(); {
return .(*Table)
}
.mu.Lock()
if , := .tables.Load(); {
.mu.Unlock()
return .(*Table)
}
var *Table
:= .inProgress[]
if == nil {
= newTable()
= newTableInProgress()
.inProgress[] =
} else {
= .table
}
.mu.Unlock()
.init1()
if {
return
}
if .init2() {
.mu.Lock()
delete(.inProgress, )
.tables.Store(, )
.mu.Unlock()
}
return
}
func ( *tables) ( reflect.Type) *Table {
return .get(, false)
}
func ( *tables) ( types.Safe) *Table {
var *Table
.tables.Range(func(, interface{}) bool {
:= .(*Table)
if .SQLName == {
=
return false
}
return true
})
return
}