package orm
import (
)
type structTableModel struct {
table *Table
rel *Relation
joins []join
root reflect.Value
index []int
strct reflect.Value
structInited bool
structInitErr error
}
var _ TableModel = (*structTableModel)(nil)
func ( *Table) *structTableModel {
return &structTableModel{
table: ,
}
}
func ( reflect.Value) *structTableModel {
return &structTableModel{
table: GetTable(.Type()),
root: ,
strct: ,
}
}
func (*structTableModel) () bool {
return true
}
func ( *structTableModel) () string {
return .table.String()
}
func ( *structTableModel) () bool {
return !.strct.IsValid()
}
func ( *structTableModel) () *Table {
return .table
}
func ( *structTableModel) () *Relation {
return .rel
}
func ( *structTableModel) ( QueryFormatter, []byte, string) ([]byte, bool) {
, := .table.AppendParam(, .strct, )
if {
return , true
}
switch {
case "TableName":
= .FormatQuery(, string(.table.SQLName))
return , true
case "TableAlias":
= append(, .table.Alias...)
return , true
case "TableColumns":
= appendColumns(, .table.Alias, .table.Fields)
return , true
case "Columns":
= appendColumns(, "", .table.Fields)
return , true
case "TablePKs":
= appendColumns(, .table.Alias, .table.PKs)
return , true
case "PKs":
= appendColumns(, "", .table.PKs)
return , true
}
return , false
}
func ( *structTableModel) () reflect.Value {
return .root
}
func ( *structTableModel) () []int {
return .index
}
func ( *structTableModel) () []int {
return .index[:len(.index)-len(.rel.Field.Index)]
}
func ( *structTableModel) () reflect.Kind {
return reflect.Struct
}
func ( *structTableModel) () reflect.Value {
return .strct
}
func ( *structTableModel) ( reflect.Value) {
.strct = .FieldByIndex(.rel.Field.Index)
.structInited = false
}
func ( *structTableModel) () error {
if .structInited {
return .structInitErr
}
.structInited = true
switch .strct.Kind() {
case reflect.Invalid:
.structInitErr = errModelNil
return .structInitErr
case reflect.Interface:
.strct = .strct.Elem()
}
if .strct.Kind() == reflect.Ptr {
if .strct.IsNil() {
.strct.Set(reflect.New(.strct.Type().Elem()))
.strct = .strct.Elem()
} else {
.strct = .strct.Elem()
}
}
.mountJoins()
return nil
}
func ( *structTableModel) () {
for := range .joins {
:= &.joins[]
switch .Rel.Type {
case HasOneRelation, BelongsToRelation:
.JoinModel.Mount(.strct)
}
}
}
func (structTableModel) () error {
return nil
}
func ( *structTableModel) () ColumnScanner {
return
}
func ( *structTableModel) ( ColumnScanner) error {
return nil
}
var _ BeforeScanHook = (*structTableModel)(nil)
func ( *structTableModel) ( context.Context) error {
if !.table.hasFlag(beforeScanHookFlag) {
return nil
}
return callBeforeScanHook(, .strct.Addr())
}
var _ AfterScanHook = (*structTableModel)(nil)
func ( *structTableModel) ( context.Context) error {
if !.table.hasFlag(afterScanHookFlag) || !.structInited {
return nil
}
var error
if := callAfterScanHook(, .strct.Addr()); != nil && == nil {
=
}
for , := range .joins {
switch .Rel.Type {
case HasOneRelation, BelongsToRelation:
if := .JoinModel.AfterScan(); != nil && == nil {
=
}
}
}
return
}
func ( *structTableModel) ( context.Context) error {
if .table.hasFlag(afterSelectHookFlag) {
return callAfterSelectHook(, .strct.Addr())
}
return nil
}
func ( *structTableModel) ( context.Context) (context.Context, error) {
if .table.hasFlag(beforeInsertHookFlag) {
return callBeforeInsertHook(, .strct.Addr())
}
return , nil
}
func ( *structTableModel) ( context.Context) error {
if .table.hasFlag(afterInsertHookFlag) {
return callAfterInsertHook(, .strct.Addr())
}
return nil
}
func ( *structTableModel) ( context.Context) (context.Context, error) {
if .table.hasFlag(beforeUpdateHookFlag) && !.IsNil() {
return callBeforeUpdateHook(, .strct.Addr())
}
return , nil
}
func ( *structTableModel) ( context.Context) error {
if .table.hasFlag(afterUpdateHookFlag) && !.IsNil() {
return callAfterUpdateHook(, .strct.Addr())
}
return nil
}
func ( *structTableModel) ( context.Context) (context.Context, error) {
if .table.hasFlag(beforeDeleteHookFlag) && !.IsNil() {
return callBeforeDeleteHook(, .strct.Addr())
}
return , nil
}
func ( *structTableModel) ( context.Context) error {
if .table.hasFlag(afterDeleteHookFlag) && !.IsNil() {
return callAfterDeleteHook(, .strct.Addr())
}
return nil
}
func ( *structTableModel) (
types.ColumnInfo, types.Reader, int,
) error {
, := .scanColumn(, , )
if {
return
}
if .table.hasFlag(discardUnknownColumnsFlag) || .Name[0] == '_' {
return nil
}
return fmt.Errorf(
"pg: can't find column=%s in %s "+
"(prefix the column with underscore or use discard_unknown_columns)",
.Name, .table,
)
}
func ( *structTableModel) ( types.ColumnInfo, types.Reader, int) (bool, error) {
if == -1 &&
!.structInited &&
.strct.Kind() == reflect.Ptr &&
.strct.IsNil() {
return true, nil
}
if := .initStruct(); != nil {
return true,
}
, := splitColumn(.Name)
if != "" {
if := .GetJoin(); != nil {
:=
.Name =
return .JoinModel.scanColumn(, , )
}
if .table.ModelName == {
:=
.Name =
return .(, , )
}
}
, := .table.FieldsMap[.Name]
if ! {
return false, nil
}
return true, .ScanValue(.strct, , )
}
func ( *structTableModel) ( string) *join {
for := range .joins {
:= &.joins[]
if .Rel.Field.GoName == || .Rel.Field.SQLName == {
return
}
}
return nil
}
func ( *structTableModel) () []join {
return .joins
}
func ( *structTableModel) ( join) *join {
.joins = append(.joins, )
return &.joins[len(.joins)-1]
}
func ( *structTableModel) ( string, func(*Query) (*Query, error)) *join {
return .join(.Value(), , )
}
func ( *structTableModel) (
reflect.Value, string, func(*Query) (*Query, error),
) *join {
:= strings.Split(, ".")
:= make([]int, 0, len())
:= join{
BaseModel: ,
JoinModel: ,
}
var *join
var bool
for , := range {
, := .JoinModel.Table().Relations[]
if ! {
= true
break
}
.Rel =
= append(, .Field.Index...)
if := .JoinModel.GetJoin(); != nil {
.BaseModel = .BaseModel
.JoinModel = .JoinModel
=
} else {
, := newTableModelIndex(.table.Type, , , )
if != nil {
return nil
}
.Parent =
.BaseModel = .JoinModel
.JoinModel =
= .BaseModel.AddJoin()
}
}
if == nil {
return nil
}
if != nil {
.ApplyQuery =
}
if {
:= [len()-1]
if == "_" {
if .Columns == nil {
.Columns = make([]string, 0)
}
} else {
.Columns = append(.Columns, )
}
}
return
}
func ( *structTableModel) () error {
:= .table.SoftDeleteField.Value(.strct)
return .table.SetSoftDeleteField()
}
func ( string) (string, string) {
:= strings.Index(, "__")
if == -1 {
return "",
}
return [:], [+2:]
}