// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.

package dbgen

import (
	"context"
	"strings"

	"git.mstar.dev/mstar/linstrom/storage-new/models"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"gorm.io/gorm/schema"

	"gorm.io/gen"
	"gorm.io/gen/field"

	"gorm.io/plugin/dbresolver"
)

func newNote(db *gorm.DB, opts ...gen.DOOption) note {
	_note := note{}

	_note.noteDo.UseDB(db, opts...)
	_note.noteDo.UseModel(&models.Note{})

	tableName := _note.noteDo.TableName()
	_note.ALL = field.NewAsterisk(tableName)
	_note.ID = field.NewString(tableName, "id")
	_note.CreatedAt = field.NewTime(tableName, "created_at")
	_note.UpdatedAt = field.NewTime(tableName, "updated_at")
	_note.DeletedAt = field.NewField(tableName, "deleted_at")
	_note.CreatorId = field.NewString(tableName, "creator_id")
	_note.Remote = field.NewBool(tableName, "remote")
	_note.RawContent = field.NewString(tableName, "raw_content")
	_note.ContentWarning = field.NewField(tableName, "content_warning")
	_note.RepliesTo = field.NewField(tableName, "replies_to")
	_note.Quotes = field.NewField(tableName, "quotes")
	_note.AccessLevel = field.NewField(tableName, "access_level")
	_note.OriginId = field.NewUint(tableName, "origin_id")
	_note.AttachmentRelations = noteHasManyAttachmentRelations{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("AttachmentRelations", "models.NoteToAttachment"),
		Note: struct {
			field.RelationField
			Creator struct {
				field.RelationField
				Server struct {
					field.RelationField
					Icon struct {
						field.RelationField
					}
				}
				Icon struct {
					field.RelationField
				}
				Background struct {
					field.RelationField
				}
				Banner struct {
					field.RelationField
				}
				RemoteInfo struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				InfoFields struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				BeingTypes struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				Tags struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				Relations struct {
					field.RelationField
					User struct {
						field.RelationField
					}
					TargetUser struct {
						field.RelationField
					}
				}
				Pronouns struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				Roles struct {
					field.RelationField
					User struct {
						field.RelationField
					}
					Role struct {
						field.RelationField
					}
				}
				AuthMethods struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
			}
			Origin struct {
				field.RelationField
			}
			AttachmentRelations struct {
				field.RelationField
			}
			EmoteRelations struct {
				field.RelationField
				Note struct {
					field.RelationField
				}
				Emote struct {
					field.RelationField
					Metadata struct {
						field.RelationField
					}
					Server struct {
						field.RelationField
					}
				}
			}
			PingRelations struct {
				field.RelationField
				Note struct {
					field.RelationField
				}
				PingTarget struct {
					field.RelationField
				}
			}
			Tags struct {
				field.RelationField
				Note struct {
					field.RelationField
				}
			}
		}{
			RelationField: field.NewRelation("AttachmentRelations.Note", "models.Note"),
			Creator: struct {
				field.RelationField
				Server struct {
					field.RelationField
					Icon struct {
						field.RelationField
					}
				}
				Icon struct {
					field.RelationField
				}
				Background struct {
					field.RelationField
				}
				Banner struct {
					field.RelationField
				}
				RemoteInfo struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				InfoFields struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				BeingTypes struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				Tags struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				Relations struct {
					field.RelationField
					User struct {
						field.RelationField
					}
					TargetUser struct {
						field.RelationField
					}
				}
				Pronouns struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
				Roles struct {
					field.RelationField
					User struct {
						field.RelationField
					}
					Role struct {
						field.RelationField
					}
				}
				AuthMethods struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}
			}{
				RelationField: field.NewRelation("AttachmentRelations.Note.Creator", "models.User"),
				Server: struct {
					field.RelationField
					Icon struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Server", "models.RemoteServer"),
					Icon: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Server.Icon", "models.MediaMetadata"),
					},
				},
				Icon: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Icon", "models.MediaMetadata"),
				},
				Background: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Background", "models.MediaMetadata"),
				},
				Banner: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Banner", "models.MediaMetadata"),
				},
				RemoteInfo: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.RemoteInfo", "models.UserRemoteLinks"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.RemoteInfo.User", "models.User"),
					},
				},
				InfoFields: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.InfoFields", "models.UserInfoField"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.InfoFields.User", "models.User"),
					},
				},
				BeingTypes: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.BeingTypes", "models.UserToBeing"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.BeingTypes.User", "models.User"),
					},
				},
				Tags: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Tags", "models.UserToTag"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Tags.User", "models.User"),
					},
				},
				Relations: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
					TargetUser struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Relations", "models.UserToUserRelation"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Relations.User", "models.User"),
					},
					TargetUser: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Relations.TargetUser", "models.User"),
					},
				},
				Pronouns: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Pronouns", "models.UserToPronoun"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Pronouns.User", "models.User"),
					},
				},
				Roles: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
					Role struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Roles", "models.UserToRole"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Roles.User", "models.User"),
					},
					Role: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.Roles.Role", "models.Role"),
					},
				},
				AuthMethods: struct {
					field.RelationField
					User struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Creator.AuthMethods", "models.UserAuthMethod"),
					User: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.Creator.AuthMethods.User", "models.User"),
					},
				},
			},
			Origin: struct {
				field.RelationField
			}{
				RelationField: field.NewRelation("AttachmentRelations.Note.Origin", "models.RemoteServer"),
			},
			AttachmentRelations: struct {
				field.RelationField
			}{
				RelationField: field.NewRelation("AttachmentRelations.Note.AttachmentRelations", "models.NoteToAttachment"),
			},
			EmoteRelations: struct {
				field.RelationField
				Note struct {
					field.RelationField
				}
				Emote struct {
					field.RelationField
					Metadata struct {
						field.RelationField
					}
					Server struct {
						field.RelationField
					}
				}
			}{
				RelationField: field.NewRelation("AttachmentRelations.Note.EmoteRelations", "models.NoteToEmote"),
				Note: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.EmoteRelations.Note", "models.Note"),
				},
				Emote: struct {
					field.RelationField
					Metadata struct {
						field.RelationField
					}
					Server struct {
						field.RelationField
					}
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.EmoteRelations.Emote", "models.Emote"),
					Metadata: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.EmoteRelations.Emote.Metadata", "models.MediaMetadata"),
					},
					Server: struct {
						field.RelationField
					}{
						RelationField: field.NewRelation("AttachmentRelations.Note.EmoteRelations.Emote.Server", "models.RemoteServer"),
					},
				},
			},
			PingRelations: struct {
				field.RelationField
				Note struct {
					field.RelationField
				}
				PingTarget struct {
					field.RelationField
				}
			}{
				RelationField: field.NewRelation("AttachmentRelations.Note.PingRelations", "models.NoteToPing"),
				Note: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.PingRelations.Note", "models.Note"),
				},
				PingTarget: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.PingRelations.PingTarget", "models.User"),
				},
			},
			Tags: struct {
				field.RelationField
				Note struct {
					field.RelationField
				}
			}{
				RelationField: field.NewRelation("AttachmentRelations.Note.Tags", "models.NoteTag"),
				Note: struct {
					field.RelationField
				}{
					RelationField: field.NewRelation("AttachmentRelations.Note.Tags.Note", "models.Note"),
				},
			},
		},
		Attachment: struct {
			field.RelationField
		}{
			RelationField: field.NewRelation("AttachmentRelations.Attachment", "models.MediaMetadata"),
		},
	}

	_note.EmoteRelations = noteHasManyEmoteRelations{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("EmoteRelations", "models.NoteToEmote"),
	}

	_note.PingRelations = noteHasManyPingRelations{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("PingRelations", "models.NoteToPing"),
	}

	_note.Tags = noteHasManyTags{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("Tags", "models.NoteTag"),
	}

	_note.Creator = noteBelongsToCreator{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("Creator", "models.User"),
	}

	_note.Origin = noteBelongsToOrigin{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("Origin", "models.RemoteServer"),
	}

	_note.fillFieldMap()

	return _note
}

type note struct {
	noteDo

	ALL                 field.Asterisk
	ID                  field.String
	CreatedAt           field.Time
	UpdatedAt           field.Time
	DeletedAt           field.Field
	CreatorId           field.String
	Remote              field.Bool
	RawContent          field.String
	ContentWarning      field.Field
	RepliesTo           field.Field
	Quotes              field.Field
	AccessLevel         field.Field
	OriginId            field.Uint
	AttachmentRelations noteHasManyAttachmentRelations

	EmoteRelations noteHasManyEmoteRelations

	PingRelations noteHasManyPingRelations

	Tags noteHasManyTags

	Creator noteBelongsToCreator

	Origin noteBelongsToOrigin

	fieldMap map[string]field.Expr
}

func (n note) Table(newTableName string) *note {
	n.noteDo.UseTable(newTableName)
	return n.updateTableName(newTableName)
}

func (n note) As(alias string) *note {
	n.noteDo.DO = *(n.noteDo.As(alias).(*gen.DO))
	return n.updateTableName(alias)
}

func (n *note) updateTableName(table string) *note {
	n.ALL = field.NewAsterisk(table)
	n.ID = field.NewString(table, "id")
	n.CreatedAt = field.NewTime(table, "created_at")
	n.UpdatedAt = field.NewTime(table, "updated_at")
	n.DeletedAt = field.NewField(table, "deleted_at")
	n.CreatorId = field.NewString(table, "creator_id")
	n.Remote = field.NewBool(table, "remote")
	n.RawContent = field.NewString(table, "raw_content")
	n.ContentWarning = field.NewField(table, "content_warning")
	n.RepliesTo = field.NewField(table, "replies_to")
	n.Quotes = field.NewField(table, "quotes")
	n.AccessLevel = field.NewField(table, "access_level")
	n.OriginId = field.NewUint(table, "origin_id")

	n.fillFieldMap()

	return n
}

func (n *note) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
	_f, ok := n.fieldMap[fieldName]
	if !ok || _f == nil {
		return nil, false
	}
	_oe, ok := _f.(field.OrderExpr)
	return _oe, ok
}

func (n *note) fillFieldMap() {
	n.fieldMap = make(map[string]field.Expr, 18)
	n.fieldMap["id"] = n.ID
	n.fieldMap["created_at"] = n.CreatedAt
	n.fieldMap["updated_at"] = n.UpdatedAt
	n.fieldMap["deleted_at"] = n.DeletedAt
	n.fieldMap["creator_id"] = n.CreatorId
	n.fieldMap["remote"] = n.Remote
	n.fieldMap["raw_content"] = n.RawContent
	n.fieldMap["content_warning"] = n.ContentWarning
	n.fieldMap["replies_to"] = n.RepliesTo
	n.fieldMap["quotes"] = n.Quotes
	n.fieldMap["access_level"] = n.AccessLevel
	n.fieldMap["origin_id"] = n.OriginId

}

func (n note) clone(db *gorm.DB) note {
	n.noteDo.ReplaceConnPool(db.Statement.ConnPool)
	return n
}

func (n note) replaceDB(db *gorm.DB) note {
	n.noteDo.ReplaceDB(db)
	return n
}

type noteHasManyAttachmentRelations struct {
	db *gorm.DB

	field.RelationField

	Note struct {
		field.RelationField
		Creator struct {
			field.RelationField
			Server struct {
				field.RelationField
				Icon struct {
					field.RelationField
				}
			}
			Icon struct {
				field.RelationField
			}
			Background struct {
				field.RelationField
			}
			Banner struct {
				field.RelationField
			}
			RemoteInfo struct {
				field.RelationField
				User struct {
					field.RelationField
				}
			}
			InfoFields struct {
				field.RelationField
				User struct {
					field.RelationField
				}
			}
			BeingTypes struct {
				field.RelationField
				User struct {
					field.RelationField
				}
			}
			Tags struct {
				field.RelationField
				User struct {
					field.RelationField
				}
			}
			Relations struct {
				field.RelationField
				User struct {
					field.RelationField
				}
				TargetUser struct {
					field.RelationField
				}
			}
			Pronouns struct {
				field.RelationField
				User struct {
					field.RelationField
				}
			}
			Roles struct {
				field.RelationField
				User struct {
					field.RelationField
				}
				Role struct {
					field.RelationField
				}
			}
			AuthMethods struct {
				field.RelationField
				User struct {
					field.RelationField
				}
			}
		}
		Origin struct {
			field.RelationField
		}
		AttachmentRelations struct {
			field.RelationField
		}
		EmoteRelations struct {
			field.RelationField
			Note struct {
				field.RelationField
			}
			Emote struct {
				field.RelationField
				Metadata struct {
					field.RelationField
				}
				Server struct {
					field.RelationField
				}
			}
		}
		PingRelations struct {
			field.RelationField
			Note struct {
				field.RelationField
			}
			PingTarget struct {
				field.RelationField
			}
		}
		Tags struct {
			field.RelationField
			Note struct {
				field.RelationField
			}
		}
	}
	Attachment struct {
		field.RelationField
	}
}

func (a noteHasManyAttachmentRelations) Where(conds ...field.Expr) *noteHasManyAttachmentRelations {
	if len(conds) == 0 {
		return &a
	}

	exprs := make([]clause.Expression, 0, len(conds))
	for _, cond := range conds {
		exprs = append(exprs, cond.BeCond().(clause.Expression))
	}
	a.db = a.db.Clauses(clause.Where{Exprs: exprs})
	return &a
}

func (a noteHasManyAttachmentRelations) WithContext(ctx context.Context) *noteHasManyAttachmentRelations {
	a.db = a.db.WithContext(ctx)
	return &a
}

func (a noteHasManyAttachmentRelations) Session(session *gorm.Session) *noteHasManyAttachmentRelations {
	a.db = a.db.Session(session)
	return &a
}

func (a noteHasManyAttachmentRelations) Model(m *models.Note) *noteHasManyAttachmentRelationsTx {
	return &noteHasManyAttachmentRelationsTx{a.db.Model(m).Association(a.Name())}
}

type noteHasManyAttachmentRelationsTx struct{ tx *gorm.Association }

func (a noteHasManyAttachmentRelationsTx) Find() (result []*models.NoteToAttachment, err error) {
	return result, a.tx.Find(&result)
}

func (a noteHasManyAttachmentRelationsTx) Append(values ...*models.NoteToAttachment) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Append(targetValues...)
}

func (a noteHasManyAttachmentRelationsTx) Replace(values ...*models.NoteToAttachment) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Replace(targetValues...)
}

func (a noteHasManyAttachmentRelationsTx) Delete(values ...*models.NoteToAttachment) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Delete(targetValues...)
}

func (a noteHasManyAttachmentRelationsTx) Clear() error {
	return a.tx.Clear()
}

func (a noteHasManyAttachmentRelationsTx) Count() int64 {
	return a.tx.Count()
}

type noteHasManyEmoteRelations struct {
	db *gorm.DB

	field.RelationField
}

func (a noteHasManyEmoteRelations) Where(conds ...field.Expr) *noteHasManyEmoteRelations {
	if len(conds) == 0 {
		return &a
	}

	exprs := make([]clause.Expression, 0, len(conds))
	for _, cond := range conds {
		exprs = append(exprs, cond.BeCond().(clause.Expression))
	}
	a.db = a.db.Clauses(clause.Where{Exprs: exprs})
	return &a
}

func (a noteHasManyEmoteRelations) WithContext(ctx context.Context) *noteHasManyEmoteRelations {
	a.db = a.db.WithContext(ctx)
	return &a
}

func (a noteHasManyEmoteRelations) Session(session *gorm.Session) *noteHasManyEmoteRelations {
	a.db = a.db.Session(session)
	return &a
}

func (a noteHasManyEmoteRelations) Model(m *models.Note) *noteHasManyEmoteRelationsTx {
	return &noteHasManyEmoteRelationsTx{a.db.Model(m).Association(a.Name())}
}

type noteHasManyEmoteRelationsTx struct{ tx *gorm.Association }

func (a noteHasManyEmoteRelationsTx) Find() (result []*models.NoteToEmote, err error) {
	return result, a.tx.Find(&result)
}

func (a noteHasManyEmoteRelationsTx) Append(values ...*models.NoteToEmote) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Append(targetValues...)
}

func (a noteHasManyEmoteRelationsTx) Replace(values ...*models.NoteToEmote) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Replace(targetValues...)
}

func (a noteHasManyEmoteRelationsTx) Delete(values ...*models.NoteToEmote) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Delete(targetValues...)
}

func (a noteHasManyEmoteRelationsTx) Clear() error {
	return a.tx.Clear()
}

func (a noteHasManyEmoteRelationsTx) Count() int64 {
	return a.tx.Count()
}

type noteHasManyPingRelations struct {
	db *gorm.DB

	field.RelationField
}

func (a noteHasManyPingRelations) Where(conds ...field.Expr) *noteHasManyPingRelations {
	if len(conds) == 0 {
		return &a
	}

	exprs := make([]clause.Expression, 0, len(conds))
	for _, cond := range conds {
		exprs = append(exprs, cond.BeCond().(clause.Expression))
	}
	a.db = a.db.Clauses(clause.Where{Exprs: exprs})
	return &a
}

func (a noteHasManyPingRelations) WithContext(ctx context.Context) *noteHasManyPingRelations {
	a.db = a.db.WithContext(ctx)
	return &a
}

func (a noteHasManyPingRelations) Session(session *gorm.Session) *noteHasManyPingRelations {
	a.db = a.db.Session(session)
	return &a
}

func (a noteHasManyPingRelations) Model(m *models.Note) *noteHasManyPingRelationsTx {
	return &noteHasManyPingRelationsTx{a.db.Model(m).Association(a.Name())}
}

type noteHasManyPingRelationsTx struct{ tx *gorm.Association }

func (a noteHasManyPingRelationsTx) Find() (result []*models.NoteToPing, err error) {
	return result, a.tx.Find(&result)
}

func (a noteHasManyPingRelationsTx) Append(values ...*models.NoteToPing) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Append(targetValues...)
}

func (a noteHasManyPingRelationsTx) Replace(values ...*models.NoteToPing) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Replace(targetValues...)
}

func (a noteHasManyPingRelationsTx) Delete(values ...*models.NoteToPing) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Delete(targetValues...)
}

func (a noteHasManyPingRelationsTx) Clear() error {
	return a.tx.Clear()
}

func (a noteHasManyPingRelationsTx) Count() int64 {
	return a.tx.Count()
}

type noteHasManyTags struct {
	db *gorm.DB

	field.RelationField
}

func (a noteHasManyTags) Where(conds ...field.Expr) *noteHasManyTags {
	if len(conds) == 0 {
		return &a
	}

	exprs := make([]clause.Expression, 0, len(conds))
	for _, cond := range conds {
		exprs = append(exprs, cond.BeCond().(clause.Expression))
	}
	a.db = a.db.Clauses(clause.Where{Exprs: exprs})
	return &a
}

func (a noteHasManyTags) WithContext(ctx context.Context) *noteHasManyTags {
	a.db = a.db.WithContext(ctx)
	return &a
}

func (a noteHasManyTags) Session(session *gorm.Session) *noteHasManyTags {
	a.db = a.db.Session(session)
	return &a
}

func (a noteHasManyTags) Model(m *models.Note) *noteHasManyTagsTx {
	return &noteHasManyTagsTx{a.db.Model(m).Association(a.Name())}
}

type noteHasManyTagsTx struct{ tx *gorm.Association }

func (a noteHasManyTagsTx) Find() (result []*models.NoteTag, err error) {
	return result, a.tx.Find(&result)
}

func (a noteHasManyTagsTx) Append(values ...*models.NoteTag) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Append(targetValues...)
}

func (a noteHasManyTagsTx) Replace(values ...*models.NoteTag) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Replace(targetValues...)
}

func (a noteHasManyTagsTx) Delete(values ...*models.NoteTag) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Delete(targetValues...)
}

func (a noteHasManyTagsTx) Clear() error {
	return a.tx.Clear()
}

func (a noteHasManyTagsTx) Count() int64 {
	return a.tx.Count()
}

type noteBelongsToCreator struct {
	db *gorm.DB

	field.RelationField
}

func (a noteBelongsToCreator) Where(conds ...field.Expr) *noteBelongsToCreator {
	if len(conds) == 0 {
		return &a
	}

	exprs := make([]clause.Expression, 0, len(conds))
	for _, cond := range conds {
		exprs = append(exprs, cond.BeCond().(clause.Expression))
	}
	a.db = a.db.Clauses(clause.Where{Exprs: exprs})
	return &a
}

func (a noteBelongsToCreator) WithContext(ctx context.Context) *noteBelongsToCreator {
	a.db = a.db.WithContext(ctx)
	return &a
}

func (a noteBelongsToCreator) Session(session *gorm.Session) *noteBelongsToCreator {
	a.db = a.db.Session(session)
	return &a
}

func (a noteBelongsToCreator) Model(m *models.Note) *noteBelongsToCreatorTx {
	return &noteBelongsToCreatorTx{a.db.Model(m).Association(a.Name())}
}

type noteBelongsToCreatorTx struct{ tx *gorm.Association }

func (a noteBelongsToCreatorTx) Find() (result *models.User, err error) {
	return result, a.tx.Find(&result)
}

func (a noteBelongsToCreatorTx) Append(values ...*models.User) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Append(targetValues...)
}

func (a noteBelongsToCreatorTx) Replace(values ...*models.User) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Replace(targetValues...)
}

func (a noteBelongsToCreatorTx) Delete(values ...*models.User) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Delete(targetValues...)
}

func (a noteBelongsToCreatorTx) Clear() error {
	return a.tx.Clear()
}

func (a noteBelongsToCreatorTx) Count() int64 {
	return a.tx.Count()
}

type noteBelongsToOrigin struct {
	db *gorm.DB

	field.RelationField
}

func (a noteBelongsToOrigin) Where(conds ...field.Expr) *noteBelongsToOrigin {
	if len(conds) == 0 {
		return &a
	}

	exprs := make([]clause.Expression, 0, len(conds))
	for _, cond := range conds {
		exprs = append(exprs, cond.BeCond().(clause.Expression))
	}
	a.db = a.db.Clauses(clause.Where{Exprs: exprs})
	return &a
}

func (a noteBelongsToOrigin) WithContext(ctx context.Context) *noteBelongsToOrigin {
	a.db = a.db.WithContext(ctx)
	return &a
}

func (a noteBelongsToOrigin) Session(session *gorm.Session) *noteBelongsToOrigin {
	a.db = a.db.Session(session)
	return &a
}

func (a noteBelongsToOrigin) Model(m *models.Note) *noteBelongsToOriginTx {
	return &noteBelongsToOriginTx{a.db.Model(m).Association(a.Name())}
}

type noteBelongsToOriginTx struct{ tx *gorm.Association }

func (a noteBelongsToOriginTx) Find() (result *models.RemoteServer, err error) {
	return result, a.tx.Find(&result)
}

func (a noteBelongsToOriginTx) Append(values ...*models.RemoteServer) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Append(targetValues...)
}

func (a noteBelongsToOriginTx) Replace(values ...*models.RemoteServer) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Replace(targetValues...)
}

func (a noteBelongsToOriginTx) Delete(values ...*models.RemoteServer) (err error) {
	targetValues := make([]interface{}, len(values))
	for i, v := range values {
		targetValues[i] = v
	}
	return a.tx.Delete(targetValues...)
}

func (a noteBelongsToOriginTx) Clear() error {
	return a.tx.Clear()
}

func (a noteBelongsToOriginTx) Count() int64 {
	return a.tx.Count()
}

type noteDo struct{ gen.DO }

type INoteDo interface {
	gen.SubQuery
	Debug() INoteDo
	WithContext(ctx context.Context) INoteDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() INoteDo
	WriteDB() INoteDo
	As(alias string) gen.Dao
	Session(config *gorm.Session) INoteDo
	Columns(cols ...field.Expr) gen.Columns
	Clauses(conds ...clause.Expression) INoteDo
	Not(conds ...gen.Condition) INoteDo
	Or(conds ...gen.Condition) INoteDo
	Select(conds ...field.Expr) INoteDo
	Where(conds ...gen.Condition) INoteDo
	Order(conds ...field.Expr) INoteDo
	Distinct(cols ...field.Expr) INoteDo
	Omit(cols ...field.Expr) INoteDo
	Join(table schema.Tabler, on ...field.Expr) INoteDo
	LeftJoin(table schema.Tabler, on ...field.Expr) INoteDo
	RightJoin(table schema.Tabler, on ...field.Expr) INoteDo
	Group(cols ...field.Expr) INoteDo
	Having(conds ...gen.Condition) INoteDo
	Limit(limit int) INoteDo
	Offset(offset int) INoteDo
	Count() (count int64, err error)
	Scopes(funcs ...func(gen.Dao) gen.Dao) INoteDo
	Unscoped() INoteDo
	Create(values ...*models.Note) error
	CreateInBatches(values []*models.Note, batchSize int) error
	Save(values ...*models.Note) error
	First() (*models.Note, error)
	Take() (*models.Note, error)
	Last() (*models.Note, error)
	Find() ([]*models.Note, error)
	FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Note, err error)
	FindInBatches(result *[]*models.Note, batchSize int, fc func(tx gen.Dao, batch int) error) error
	Pluck(column field.Expr, dest interface{}) error
	Delete(...*models.Note) (info gen.ResultInfo, err error)
	Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	Updates(value interface{}) (info gen.ResultInfo, err error)
	UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)
	UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)
	UpdateColumns(value interface{}) (info gen.ResultInfo, err error)
	UpdateFrom(q gen.SubQuery) gen.Dao
	Attrs(attrs ...field.AssignExpr) INoteDo
	Assign(attrs ...field.AssignExpr) INoteDo
	Joins(fields ...field.RelationField) INoteDo
	Preload(fields ...field.RelationField) INoteDo
	FirstOrInit() (*models.Note, error)
	FirstOrCreate() (*models.Note, error)
	FindByPage(offset int, limit int) (result []*models.Note, count int64, err error)
	ScanByPage(result interface{}, offset int, limit int) (count int64, err error)
	Scan(result interface{}) (err error)
	Returning(value interface{}, columns ...string) INoteDo
	UnderlyingDB() *gorm.DB
	schema.Tabler

	GetNotesPaged(userId string, pageNr uint, accessLevel uint8) (result []models.Note, err error)
}

// Get all notes by a user, paged, that are a specific access level.
// Ordered by age, descending (newest first)
//
// SELECT * FROM @@table
// WHERE creator_id = @userId AND access_level = @accessLevel
// ORDER BY created_at DESC LIMIT 50 OFFSET @pageNr * 50
func (n noteDo) GetNotesPaged(userId string, pageNr uint, accessLevel uint8) (result []models.Note, err error) {
	var params []interface{}

	var generateSQL strings.Builder
	params = append(params, userId)
	params = append(params, accessLevel)
	params = append(params, pageNr)
	generateSQL.WriteString("SELECT * FROM notes WHERE creator_id = ? AND access_level = ? ORDER BY created_at DESC LIMIT 50 OFFSET ? * 50 ")

	var executeSQL *gorm.DB
	executeSQL = n.UnderlyingDB().Raw(generateSQL.String(), params...).Find(&result) // ignore_security_alert
	err = executeSQL.Error

	return
}

func (n noteDo) Debug() INoteDo {
	return n.withDO(n.DO.Debug())
}

func (n noteDo) WithContext(ctx context.Context) INoteDo {
	return n.withDO(n.DO.WithContext(ctx))
}

func (n noteDo) ReadDB() INoteDo {
	return n.Clauses(dbresolver.Read)
}

func (n noteDo) WriteDB() INoteDo {
	return n.Clauses(dbresolver.Write)
}

func (n noteDo) Session(config *gorm.Session) INoteDo {
	return n.withDO(n.DO.Session(config))
}

func (n noteDo) Clauses(conds ...clause.Expression) INoteDo {
	return n.withDO(n.DO.Clauses(conds...))
}

func (n noteDo) Returning(value interface{}, columns ...string) INoteDo {
	return n.withDO(n.DO.Returning(value, columns...))
}

func (n noteDo) Not(conds ...gen.Condition) INoteDo {
	return n.withDO(n.DO.Not(conds...))
}

func (n noteDo) Or(conds ...gen.Condition) INoteDo {
	return n.withDO(n.DO.Or(conds...))
}

func (n noteDo) Select(conds ...field.Expr) INoteDo {
	return n.withDO(n.DO.Select(conds...))
}

func (n noteDo) Where(conds ...gen.Condition) INoteDo {
	return n.withDO(n.DO.Where(conds...))
}

func (n noteDo) Order(conds ...field.Expr) INoteDo {
	return n.withDO(n.DO.Order(conds...))
}

func (n noteDo) Distinct(cols ...field.Expr) INoteDo {
	return n.withDO(n.DO.Distinct(cols...))
}

func (n noteDo) Omit(cols ...field.Expr) INoteDo {
	return n.withDO(n.DO.Omit(cols...))
}

func (n noteDo) Join(table schema.Tabler, on ...field.Expr) INoteDo {
	return n.withDO(n.DO.Join(table, on...))
}

func (n noteDo) LeftJoin(table schema.Tabler, on ...field.Expr) INoteDo {
	return n.withDO(n.DO.LeftJoin(table, on...))
}

func (n noteDo) RightJoin(table schema.Tabler, on ...field.Expr) INoteDo {
	return n.withDO(n.DO.RightJoin(table, on...))
}

func (n noteDo) Group(cols ...field.Expr) INoteDo {
	return n.withDO(n.DO.Group(cols...))
}

func (n noteDo) Having(conds ...gen.Condition) INoteDo {
	return n.withDO(n.DO.Having(conds...))
}

func (n noteDo) Limit(limit int) INoteDo {
	return n.withDO(n.DO.Limit(limit))
}

func (n noteDo) Offset(offset int) INoteDo {
	return n.withDO(n.DO.Offset(offset))
}

func (n noteDo) Scopes(funcs ...func(gen.Dao) gen.Dao) INoteDo {
	return n.withDO(n.DO.Scopes(funcs...))
}

func (n noteDo) Unscoped() INoteDo {
	return n.withDO(n.DO.Unscoped())
}

func (n noteDo) Create(values ...*models.Note) error {
	if len(values) == 0 {
		return nil
	}
	return n.DO.Create(values)
}

func (n noteDo) CreateInBatches(values []*models.Note, batchSize int) error {
	return n.DO.CreateInBatches(values, batchSize)
}

// Save : !!! underlying implementation is different with GORM
// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values)
func (n noteDo) Save(values ...*models.Note) error {
	if len(values) == 0 {
		return nil
	}
	return n.DO.Save(values)
}

func (n noteDo) First() (*models.Note, error) {
	if result, err := n.DO.First(); err != nil {
		return nil, err
	} else {
		return result.(*models.Note), nil
	}
}

func (n noteDo) Take() (*models.Note, error) {
	if result, err := n.DO.Take(); err != nil {
		return nil, err
	} else {
		return result.(*models.Note), nil
	}
}

func (n noteDo) Last() (*models.Note, error) {
	if result, err := n.DO.Last(); err != nil {
		return nil, err
	} else {
		return result.(*models.Note), nil
	}
}

func (n noteDo) Find() ([]*models.Note, error) {
	result, err := n.DO.Find()
	return result.([]*models.Note), err
}

func (n noteDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*models.Note, err error) {
	buf := make([]*models.Note, 0, batchSize)
	err = n.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error {
		defer func() { results = append(results, buf...) }()
		return fc(tx, batch)
	})
	return results, err
}

func (n noteDo) FindInBatches(result *[]*models.Note, batchSize int, fc func(tx gen.Dao, batch int) error) error {
	return n.DO.FindInBatches(result, batchSize, fc)
}

func (n noteDo) Attrs(attrs ...field.AssignExpr) INoteDo {
	return n.withDO(n.DO.Attrs(attrs...))
}

func (n noteDo) Assign(attrs ...field.AssignExpr) INoteDo {
	return n.withDO(n.DO.Assign(attrs...))
}

func (n noteDo) Joins(fields ...field.RelationField) INoteDo {
	for _, _f := range fields {
		n = *n.withDO(n.DO.Joins(_f))
	}
	return &n
}

func (n noteDo) Preload(fields ...field.RelationField) INoteDo {
	for _, _f := range fields {
		n = *n.withDO(n.DO.Preload(_f))
	}
	return &n
}

func (n noteDo) FirstOrInit() (*models.Note, error) {
	if result, err := n.DO.FirstOrInit(); err != nil {
		return nil, err
	} else {
		return result.(*models.Note), nil
	}
}

func (n noteDo) FirstOrCreate() (*models.Note, error) {
	if result, err := n.DO.FirstOrCreate(); err != nil {
		return nil, err
	} else {
		return result.(*models.Note), nil
	}
}

func (n noteDo) FindByPage(offset int, limit int) (result []*models.Note, count int64, err error) {
	result, err = n.Offset(offset).Limit(limit).Find()
	if err != nil {
		return
	}

	if size := len(result); 0 < limit && 0 < size && size < limit {
		count = int64(size + offset)
		return
	}

	count, err = n.Offset(-1).Limit(-1).Count()
	return
}

func (n noteDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) {
	count, err = n.Count()
	if err != nil {
		return
	}

	err = n.Offset(offset).Limit(limit).Scan(result)
	return
}

func (n noteDo) Scan(result interface{}) (err error) {
	return n.DO.Scan(result)
}

func (n noteDo) Delete(models ...*models.Note) (result gen.ResultInfo, err error) {
	return n.DO.Delete(models)
}

func (n *noteDo) withDO(do gen.Dao) *noteDo {
	n.DO = *do.(*gen.DO)
	return n
}
