diff options
author | 2021-08-12 21:03:24 +0200 | |
---|---|---|
committer | 2021-08-12 21:03:24 +0200 | |
commit | 98263a7de64269898a2f81207e38943b5c8e8653 (patch) | |
tree | 743c90f109a6c5d27832d1dcef2388d939f0f77a /vendor/github.com/go-pg/pg/v10/orm/tables.go | |
parent | Text duplication fix (#137) (diff) | |
download | gotosocial-98263a7de64269898a2f81207e38943b5c8e8653.tar.xz |
Grand test fixup (#138)
* start fixing up tests
* fix up tests + automate with drone
* fiddle with linting
* messing about with drone.yml
* some more fiddling
* hmmm
* add cache
* add vendor directory
* verbose
* ci updates
* update some little things
* update sig
Diffstat (limited to 'vendor/github.com/go-pg/pg/v10/orm/tables.go')
-rw-r--r-- | vendor/github.com/go-pg/pg/v10/orm/tables.go | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/vendor/github.com/go-pg/pg/v10/orm/tables.go b/vendor/github.com/go-pg/pg/v10/orm/tables.go new file mode 100644 index 000000000..fa937a54e --- /dev/null +++ b/vendor/github.com/go-pg/pg/v10/orm/tables.go @@ -0,0 +1,136 @@ +package orm + +import ( + "fmt" + "reflect" + "sync" + + "github.com/go-pg/pg/v10/types" +) + +var _tables = newTables() + +type tableInProgress struct { + table *Table + + init1Once sync.Once + init2Once sync.Once +} + +func newTableInProgress(table *Table) *tableInProgress { + return &tableInProgress{ + table: table, + } +} + +func (inp *tableInProgress) init1() bool { + var inited bool + inp.init1Once.Do(func() { + inp.table.init1() + inited = true + }) + return inited +} + +func (inp *tableInProgress) init2() bool { + var inited bool + inp.init2Once.Do(func() { + inp.table.init2() + inited = true + }) + return inited +} + +// GetTable returns a Table for a struct type. +func GetTable(typ reflect.Type) *Table { + return _tables.Get(typ) +} + +// RegisterTable registers a struct as SQL table. +// It is usually used to register intermediate table +// in many to many relationship. +func RegisterTable(strct interface{}) { + _tables.Register(strct) +} + +type tables struct { + tables sync.Map + + mu sync.RWMutex + inProgress map[reflect.Type]*tableInProgress +} + +func newTables() *tables { + return &tables{ + inProgress: make(map[reflect.Type]*tableInProgress), + } +} + +func (t *tables) Register(strct interface{}) { + typ := reflect.TypeOf(strct) + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + _ = t.Get(typ) +} + +func (t *tables) get(typ reflect.Type, allowInProgress bool) *Table { + if typ.Kind() != reflect.Struct { + panic(fmt.Errorf("got %s, wanted %s", typ.Kind(), reflect.Struct)) + } + + if v, ok := t.tables.Load(typ); ok { + return v.(*Table) + } + + t.mu.Lock() + + if v, ok := t.tables.Load(typ); ok { + t.mu.Unlock() + return v.(*Table) + } + + var table *Table + + inProgress := t.inProgress[typ] + if inProgress == nil { + table = newTable(typ) + inProgress = newTableInProgress(table) + t.inProgress[typ] = inProgress + } else { + table = inProgress.table + } + + t.mu.Unlock() + + inProgress.init1() + if allowInProgress { + return table + } + + if inProgress.init2() { + t.mu.Lock() + delete(t.inProgress, typ) + t.tables.Store(typ, table) + t.mu.Unlock() + } + + return table +} + +func (t *tables) Get(typ reflect.Type) *Table { + return t.get(typ, false) +} + +func (t *tables) getByName(name types.Safe) *Table { + var found *Table + t.tables.Range(func(key, value interface{}) bool { + t := value.(*Table) + if t.SQLName == name { + found = t + return false + } + return true + }) + return found +} |